summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xdoc/contributions.txt9
-rw-r--r--indra/llcommon/indra_constants.cpp4
-rw-r--r--indra/llcommon/indra_constants.h4
-rw-r--r--indra/llcommon/llapr.cpp2
-rw-r--r--indra/llcommon/llevents.cpp265
-rw-r--r--indra/llcommon/llevents.h8
-rw-r--r--indra/llcommon/llstring.cpp27
-rw-r--r--indra/llcommon/llstring.h11
-rw-r--r--indra/llmessage/llassetstorage.h4
-rw-r--r--indra/llmessage/llavatarname.cpp23
-rw-r--r--indra/llmessage/llavatarname.h4
-rw-r--r--indra/llmessage/llcorehttputil.cpp2
-rw-r--r--indra/llprimitive/lldaeloader.cpp6
-rw-r--r--indra/llui/llfloater.cpp21
-rw-r--r--indra/llui/llfloater.h4
-rw-r--r--indra/llui/llfolderview.cpp11
-rw-r--r--indra/llui/llfolderview.h3
-rw-r--r--indra/llui/llfolderviewitem.cpp28
-rw-r--r--indra/llui/llfolderviewitem.h8
-rw-r--r--indra/llui/llfolderviewmodel.h1
-rw-r--r--indra/llui/lllineeditor.cpp7
-rw-r--r--indra/llui/lltextbase.cpp26
-rw-r--r--indra/llui/lltextbase.h3
-rw-r--r--indra/llui/lltextutil.cpp20
-rw-r--r--indra/llui/lltextutil.h6
-rw-r--r--indra/llui/lltextvalidate.cpp9
-rw-r--r--indra/llui/lltextvalidate.h1
-rw-r--r--indra/llui/llui.cpp2
-rw-r--r--indra/llui/llurlaction.cpp10
-rw-r--r--indra/llui/llurlaction.h1
-rw-r--r--indra/llui/llview.cpp27
-rw-r--r--indra/llvfs/lldir.cpp7
-rw-r--r--indra/llwindow/llwindow.h2
-rw-r--r--indra/llwindow/llwindowwin32.cpp65
-rw-r--r--indra/llwindow/llwindowwin32.h2
-rw-r--r--indra/newview/CMakeLists.txt5
-rw-r--r--indra/newview/app_settings/commands.xml2
-rw-r--r--indra/newview/app_settings/settings.xml66
-rw-r--r--indra/newview/featuretable.txt2
-rw-r--r--indra/newview/featuretable_linux.txt2
-rw-r--r--indra/newview/featuretable_mac.txt2
-rw-r--r--indra/newview/installers/windows/installer_template.nsi11
-rw-r--r--indra/newview/installers/windows/lang_en-us.nsibin8510 -> 9096 bytes
-rw-r--r--indra/newview/llagent.cpp24
-rw-r--r--indra/newview/llagent.h2
-rw-r--r--indra/newview/llagentwearables.cpp68
-rw-r--r--indra/newview/llagentwearables.h2
-rw-r--r--indra/newview/llaisapi.cpp21
-rw-r--r--indra/newview/llappearancemgr.cpp32
-rw-r--r--indra/newview/llappearancemgr.h10
-rw-r--r--indra/newview/llappviewer.cpp32
-rw-r--r--indra/newview/llappviewer.h3
-rw-r--r--indra/newview/llavataractions.cpp122
-rw-r--r--indra/newview/llavataractions.h5
-rw-r--r--indra/newview/llavatarlist.cpp17
-rw-r--r--indra/newview/llavatarlist.h4
-rw-r--r--indra/newview/llavatarlistitem.cpp22
-rw-r--r--indra/newview/llavatarlistitem.h4
-rw-r--r--indra/newview/llavatarrendernotifier.cpp6
-rw-r--r--indra/newview/llchatbar.cpp5
-rw-r--r--indra/newview/llchathistory.cpp21
-rw-r--r--indra/newview/llcompilequeue.cpp939
-rw-r--r--indra/newview/llcompilequeue.h86
-rw-r--r--indra/newview/llconversationlog.cpp7
-rw-r--r--indra/newview/lldrawpoolterrain.cpp17
-rw-r--r--indra/newview/lleventpoll.cpp9
-rw-r--r--indra/newview/lleventpoll.h8
-rw-r--r--indra/newview/llfeaturemanager.cpp59
-rw-r--r--indra/newview/llfeaturemanager.h4
-rw-r--r--indra/newview/llfloatergesture.cpp3
-rw-r--r--indra/newview/llfloaterimnearbychat.cpp48
-rw-r--r--indra/newview/llfloaterimnearbychathandler.cpp25
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp6
-rw-r--r--indra/newview/llfloaterimsessiontab.h2
-rw-r--r--indra/newview/llfloaternamedesc.cpp22
-rw-r--r--indra/newview/llfloaterpreference.cpp4
-rw-r--r--indra/newview/llfloaterregioninfo.cpp52
-rw-r--r--indra/newview/llfloaterregioninfo.h7
-rw-r--r--indra/newview/llfloaterscriptlimits.cpp10
-rw-r--r--indra/newview/llfloaterscriptlimits.h1
-rw-r--r--indra/newview/llfloatersellland.cpp3
-rw-r--r--indra/newview/llfloatersnapshot.cpp14
-rw-r--r--indra/newview/llfloatersnapshot.h1
-rw-r--r--indra/newview/llfloaterworldmap.cpp4
-rw-r--r--indra/newview/llfloaterworldmap.h2
-rw-r--r--indra/newview/llgiveinventory.cpp4
-rw-r--r--indra/newview/llinspectremoteobject.cpp2
-rw-r--r--indra/newview/llinventorybridge.cpp14
-rw-r--r--indra/newview/llinventorybridge.h1
-rw-r--r--indra/newview/llinventoryfilter.cpp17
-rw-r--r--indra/newview/llinventoryfunctions.cpp6
-rw-r--r--indra/newview/llinventorymodel.cpp17
-rw-r--r--indra/newview/lllocationinputctrl.cpp25
-rw-r--r--indra/newview/lllocationinputctrl.h1
-rw-r--r--indra/newview/lllogchat.cpp8
-rw-r--r--indra/newview/llmanip.h4
-rw-r--r--indra/newview/llmaniptranslate.cpp7
-rw-r--r--indra/newview/llmarketplacefunctions.cpp4
-rw-r--r--indra/newview/llmeshrepository.cpp24
-rw-r--r--indra/newview/llmeshrepository.h4
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp2
-rw-r--r--indra/newview/llpanelmaininventory.cpp20
-rw-r--r--indra/newview/llpanelmaininventory.h1
-rw-r--r--indra/newview/llpaneloutfitedit.cpp3
-rw-r--r--indra/newview/llpaneloutfitedit.h1
-rw-r--r--indra/newview/llpanelpeople.cpp21
-rw-r--r--indra/newview/llpanelpeoplemenus.cpp88
-rw-r--r--indra/newview/llpanelpeoplemenus.h2
-rw-r--r--indra/newview/llpanelprofile.cpp10
-rw-r--r--indra/newview/llpanelsnapshotinventory.cpp17
-rw-r--r--indra/newview/llpanelwearing.cpp253
-rw-r--r--indra/newview/llpanelwearing.h33
-rw-r--r--indra/newview/llpathfindinglinksetlist.cpp7
-rw-r--r--indra/newview/llpresetsmanager.cpp60
-rw-r--r--indra/newview/llpresetsmanager.h2
-rw-r--r--indra/newview/llpreviewnotecard.cpp25
-rw-r--r--indra/newview/llpreviewnotecard.h1
-rw-r--r--indra/newview/llpreviewtexture.cpp38
-rw-r--r--indra/newview/llsidepanelappearance.cpp2
-rw-r--r--indra/newview/llstartup.cpp21
-rw-r--r--indra/newview/lltoast.cpp15
-rw-r--r--indra/newview/lltoast.h2
-rw-r--r--indra/newview/lltoastnotifypanel.cpp9
-rw-r--r--indra/newview/lltoastscriptquestion.cpp19
-rw-r--r--indra/newview/lltoastscriptquestion.h2
-rw-r--r--indra/newview/lltoolmgr.cpp9
-rw-r--r--indra/newview/lltoolmgr.h1
-rw-r--r--indra/newview/lltracker.cpp6
-rw-r--r--indra/newview/lltracker.h2
-rw-r--r--indra/newview/llviewchildren.cpp5
-rw-r--r--indra/newview/llviewerassetupload.cpp7
-rw-r--r--indra/newview/llviewercontrol.cpp7
-rw-r--r--indra/newview/llviewerinventory.cpp38
-rw-r--r--indra/newview/llviewermenu.cpp23
-rw-r--r--indra/newview/llviewermenu.h3
-rw-r--r--indra/newview/llviewermessage.cpp6
-rw-r--r--indra/newview/llviewerobject.cpp58
-rw-r--r--indra/newview/llviewerobject.h4
-rw-r--r--indra/newview/llvieweroctree.cpp2
-rw-r--r--indra/newview/llviewerpartsource.cpp10
-rw-r--r--indra/newview/llviewerregion.cpp5
-rw-r--r--indra/newview/llviewertexture.cpp7
-rw-r--r--indra/newview/llviewertexturelist.cpp22
-rw-r--r--indra/newview/llviewerwearable.cpp7
-rw-r--r--indra/newview/llviewerwearable.h2
-rw-r--r--indra/newview/llviewerwindow.cpp35
-rw-r--r--indra/newview/llviewerwindow.h8
-rw-r--r--indra/newview/llvoavatar.cpp73
-rw-r--r--indra/newview/llvoicevivox.cpp2
-rw-r--r--indra/newview/llvovolume.cpp36
-rw-r--r--indra/newview/llvovolume.h3
-rw-r--r--indra/newview/llwlparamset.cpp17
-rw-r--r--indra/newview/llxmlrpclistener.cpp2
-rw-r--r--indra/newview/skins/default/textures/textures.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_script_queue.xml8
-rw-r--r--indra/newview/skins/default/xui/en/fonts.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_login.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_object_icon.xml14
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_friends_view.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_nearby.xml16
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_nearby_view.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_url_objectim.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_wearing_tab.xml14
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml190
-rw-r--r--indra/newview/skins/default/xui/en/panel_login.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_login_first.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfits_wearing.xml41
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_advanced.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_setup.xml12
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml1
-rwxr-xr-xindra/newview/viewer_manifest.py12
172 files changed, 2998 insertions, 1001 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 9b31e5032a..49c9c2cb1d 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -190,6 +190,13 @@ Ansariel Hiller
STORM-2094
MAINT-5756
MAINT-4677
+ MAINT-6300
+ MAINT-6397
+ MAINT-6432
+ MAINT-6513
+ MAINT-6514
+ MAINT-6552
+ STORM-2133
Aralara Rajal
Arare Chantilly
CHUIBUG-191
@@ -787,6 +794,7 @@ Kitty Barnett
MAINT-6152
MAINT-6153
MAINT-6154
+ MAINT-6568
Kolor Fall
Komiko Okamoto
Korvel Noh
@@ -1262,6 +1270,7 @@ Sovereign Engineer
MAINT-6107
STORM-2107
MAINT-6218
+ MAINT-2141
SpacedOut Frye
VWR-34
VWR-45
diff --git a/indra/llcommon/indra_constants.cpp b/indra/llcommon/indra_constants.cpp
index 60721977cd..7ea42a3fc0 100644
--- a/indra/llcommon/indra_constants.cpp
+++ b/indra/llcommon/indra_constants.cpp
@@ -60,6 +60,10 @@ const LLUUID IMG_SMOKE_POOF ("1e63e323-5fe0-452e-92f8-b98bd0f764e3"); // On d
const LLUUID IMG_BIG_EXPLOSION_1 ("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); // On dataserver
const LLUUID IMG_BIG_EXPLOSION_2 ("9c8eca51-53d5-42a7-bb58-cef070395db8"); // On dataserver
+const LLUUID IMG_ALPHA_GRAD ("e97cf410-8e61-7005-ec06-629eba4cd1fb"); // VIEWER
+const LLUUID IMG_ALPHA_GRAD_2D ("38b86f85-2575-52a9-a531-23108d8da837"); // VIEWER
+const LLUUID IMG_TRANSPARENT ("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"); // VIEWER
+
const LLUUID IMG_BLOOM1 ("3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3bef"); // VIEWER
const LLUUID TERRAIN_DIRT_DETAIL ("0bc58228-74a0-7e83-89bc-5c23464bcec5"); // VIEWER
const LLUUID TERRAIN_GRASS_DETAIL ("63338ede-0037-c4fd-855b-015d77112fc8"); // VIEWER
diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h
index 02f063f5e8..fda84aa5a8 100644
--- a/indra/llcommon/indra_constants.h
+++ b/indra/llcommon/indra_constants.h
@@ -197,6 +197,10 @@ LL_COMMON_API extern const LLUUID IMG_SMOKE_POOF;
LL_COMMON_API extern const LLUUID IMG_BIG_EXPLOSION_1;
LL_COMMON_API extern const LLUUID IMG_BIG_EXPLOSION_2;
+LL_COMMON_API extern const LLUUID IMG_ALPHA_GRAD;
+LL_COMMON_API extern const LLUUID IMG_ALPHA_GRAD_2D;
+LL_COMMON_API extern const LLUUID IMG_TRANSPARENT;
+
LL_COMMON_API extern const LLUUID IMG_BLOOM1;
LL_COMMON_API extern const LLUUID TERRAIN_DIRT_DETAIL;
LL_COMMON_API extern const LLUUID TERRAIN_GRASS_DETAIL;
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index a548c96002..86f407cdb0 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -294,9 +294,11 @@ void LLScopedLock::unlock()
bool ll_apr_warn_status(apr_status_t status)
{
if(APR_SUCCESS == status) return false;
+#if !LL_LINUX
char buf[MAX_STRING]; /* Flawfinder: ignore */
apr_strerror(status, buf, sizeof(buf));
LL_WARNS("APR") << "APR: " << buf << LL_ENDL;
+#endif
return true;
}
diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp
index 645c29d770..e38fc5b2a6 100644
--- a/indra/llcommon/llevents.cpp
+++ b/indra/llcommon/llevents.cpp
@@ -275,6 +275,8 @@ LLEventPumps::~LLEventPumps()
#pragma warning (push)
#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
#endif
+const std::string LLEventPump::ANONYMOUS = std::string();
+
LLEventPump::LLEventPump(const std::string& name, bool tweak):
// Register every new instance with LLEventPumps
@@ -313,145 +315,162 @@ LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventL
const NameList& after,
const NameList& before)
{
- // Check for duplicate name before connecting listener to mSignal
- ConnectionMap::const_iterator found = mConnections.find(name);
- // In some cases the user might disconnect a connection explicitly -- or
- // might use LLEventTrackable to disconnect implicitly. Either way, we can
- // end up retaining in mConnections a zombie connection object that's
- // already been disconnected. Such a connection object can't be
- // reconnected -- nor, in the case of LLEventTrackable, would we want to
- // try, since disconnection happens with the destruction of the listener
- // object. That means it's safe to overwrite a disconnected connection
- // object with the new one we're attempting. The case we want to prevent
- // is only when the existing connection object is still connected.
- if (found != mConnections.end() && found->second.connected())
- {
- throw DupListenerName(std::string("Attempt to register duplicate listener name '") + name +
- "' on " + typeid(*this).name() + " '" + getName() + "'");
- }
- // Okay, name is unique, try to reconcile its dependencies. Specify a new
- // "node" value that we never use for an mSignal placement; we'll fix it
- // later.
- DependencyMap::node_type& newNode = mDeps.add(name, -1.0, after, before);
- // What if this listener has been added, removed and re-added? In that
- // case newNode already has a non-negative value because we never remove a
- // listener from mDeps. But keep processing uniformly anyway in case the
- // listener was added back with different dependencies. Then mDeps.sort()
- // would put it in a different position, and the old newNode placement
- // value would be wrong, so we'd have to reassign it anyway. Trust that
- // re-adding a listener with the same dependencies is the trivial case for
- // mDeps.sort(): it can just replay its cache.
- DependencyMap::sorted_range sorted_range;
- try
- {
- // Can we pick an order that works including this new entry?
- sorted_range = mDeps.sort();
- }
- catch (const DependencyMap::Cycle& e)
- {
- // No: the new node's after/before dependencies have made mDeps
- // unsortable. If we leave the new node in mDeps, it will continue
- // to screw up all future attempts to sort()! Pull it out.
- mDeps.remove(name);
- throw Cycle(std::string("New listener '") + name + "' on " + typeid(*this).name() +
- " '" + getName() + "' would cause cycle: " + e.what());
- }
- // Walk the list to verify that we haven't changed the order.
- float previous = 0.0, myprev = 0.0;
- DependencyMap::sorted_iterator mydmi = sorted_range.end(); // need this visible after loop
- for (DependencyMap::sorted_iterator dmi = sorted_range.begin();
- dmi != sorted_range.end(); ++dmi)
+ float nodePosition = 1.0;
+
+ // if the supplied name is empty we are not interested in the ordering mechanism
+ // and can bypass attempting to find the optimal location to insert the new
+ // listener. We'll just tack it on to the end.
+ if (!name.empty()) // should be the same as testing against ANONYMOUS
{
- // Since we've added the new entry with an invalid placement,
- // recognize it and skip it.
- if (dmi->first == name)
+ // Check for duplicate name before connecting listener to mSignal
+ ConnectionMap::const_iterator found = mConnections.find(name);
+ // In some cases the user might disconnect a connection explicitly -- or
+ // might use LLEventTrackable to disconnect implicitly. Either way, we can
+ // end up retaining in mConnections a zombie connection object that's
+ // already been disconnected. Such a connection object can't be
+ // reconnected -- nor, in the case of LLEventTrackable, would we want to
+ // try, since disconnection happens with the destruction of the listener
+ // object. That means it's safe to overwrite a disconnected connection
+ // object with the new one we're attempting. The case we want to prevent
+ // is only when the existing connection object is still connected.
+ if (found != mConnections.end() && found->second.connected())
{
- // Remember the iterator belonging to our new node, and which
- // placement value was 'previous' at that point.
- mydmi = dmi;
- myprev = previous;
- continue;
+ throw DupListenerName(std::string("Attempt to register duplicate listener name '") + name +
+ "' on " + typeid(*this).name() + " '" + getName() + "'");
}
- // If the new node has rearranged the existing nodes, we'll find
- // that their placement values are no longer in increasing order.
- if (dmi->second < previous)
+ // Okay, name is unique, try to reconcile its dependencies. Specify a new
+ // "node" value that we never use for an mSignal placement; we'll fix it
+ // later.
+ DependencyMap::node_type& newNode = mDeps.add(name, -1.0, after, before);
+ // What if this listener has been added, removed and re-added? In that
+ // case newNode already has a non-negative value because we never remove a
+ // listener from mDeps. But keep processing uniformly anyway in case the
+ // listener was added back with different dependencies. Then mDeps.sort()
+ // would put it in a different position, and the old newNode placement
+ // value would be wrong, so we'd have to reassign it anyway. Trust that
+ // re-adding a listener with the same dependencies is the trivial case for
+ // mDeps.sort(): it can just replay its cache.
+ DependencyMap::sorted_range sorted_range;
+ try
{
- // This is another scenario in which we'd better back out the
- // newly-added node from mDeps -- but don't do it yet, we want to
- // traverse the existing mDeps to report on it!
- // Describe the change to the order of our listeners. Copy
- // everything but the newest listener to a vector we can sort to
- // obtain the old order.
- typedef std::vector< std::pair<float, std::string> > SortNameList;
- SortNameList sortnames;
- for (DependencyMap::sorted_iterator cdmi(sorted_range.begin()), cdmend(sorted_range.end());
- cdmi != cdmend; ++cdmi)
+ // Can we pick an order that works including this new entry?
+ sorted_range = mDeps.sort();
+ }
+ catch (const DependencyMap::Cycle& e)
+ {
+ // No: the new node's after/before dependencies have made mDeps
+ // unsortable. If we leave the new node in mDeps, it will continue
+ // to screw up all future attempts to sort()! Pull it out.
+ mDeps.remove(name);
+ throw Cycle(std::string("New listener '") + name + "' on " + typeid(*this).name() +
+ " '" + getName() + "' would cause cycle: " + e.what());
+ }
+ // Walk the list to verify that we haven't changed the order.
+ float previous = 0.0, myprev = 0.0;
+ DependencyMap::sorted_iterator mydmi = sorted_range.end(); // need this visible after loop
+ for (DependencyMap::sorted_iterator dmi = sorted_range.begin();
+ dmi != sorted_range.end(); ++dmi)
+ {
+ // Since we've added the new entry with an invalid placement,
+ // recognize it and skip it.
+ if (dmi->first == name)
{
- if (cdmi->first != name)
- {
- sortnames.push_back(SortNameList::value_type(cdmi->second, cdmi->first));
- }
+ // Remember the iterator belonging to our new node, and which
+ // placement value was 'previous' at that point.
+ mydmi = dmi;
+ myprev = previous;
+ continue;
}
- std::sort(sortnames.begin(), sortnames.end());
- std::ostringstream out;
- out << "New listener '" << name << "' on " << typeid(*this).name() << " '" << getName()
- << "' would move previous listener '" << dmi->first << "'\nwas: ";
- SortNameList::const_iterator sni(sortnames.begin()), snend(sortnames.end());
- if (sni != snend)
+ // If the new node has rearranged the existing nodes, we'll find
+ // that their placement values are no longer in increasing order.
+ if (dmi->second < previous)
{
- out << sni->second;
- while (++sni != snend)
+ // This is another scenario in which we'd better back out the
+ // newly-added node from mDeps -- but don't do it yet, we want to
+ // traverse the existing mDeps to report on it!
+ // Describe the change to the order of our listeners. Copy
+ // everything but the newest listener to a vector we can sort to
+ // obtain the old order.
+ typedef std::vector< std::pair<float, std::string> > SortNameList;
+ SortNameList sortnames;
+ for (DependencyMap::sorted_iterator cdmi(sorted_range.begin()), cdmend(sorted_range.end());
+ cdmi != cdmend; ++cdmi)
{
- out << ", " << sni->second;
+ if (cdmi->first != name)
+ {
+ sortnames.push_back(SortNameList::value_type(cdmi->second, cdmi->first));
+ }
}
- }
- out << "\nnow: ";
- DependencyMap::sorted_iterator ddmi(sorted_range.begin()), ddmend(sorted_range.end());
- if (ddmi != ddmend)
- {
- out << ddmi->first;
- while (++ddmi != ddmend)
+ std::sort(sortnames.begin(), sortnames.end());
+ std::ostringstream out;
+ out << "New listener '" << name << "' on " << typeid(*this).name() << " '" << getName()
+ << "' would move previous listener '" << dmi->first << "'\nwas: ";
+ SortNameList::const_iterator sni(sortnames.begin()), snend(sortnames.end());
+ if (sni != snend)
{
- out << ", " << ddmi->first;
+ out << sni->second;
+ while (++sni != snend)
+ {
+ out << ", " << sni->second;
+ }
}
+ out << "\nnow: ";
+ DependencyMap::sorted_iterator ddmi(sorted_range.begin()), ddmend(sorted_range.end());
+ if (ddmi != ddmend)
+ {
+ out << ddmi->first;
+ while (++ddmi != ddmend)
+ {
+ out << ", " << ddmi->first;
+ }
+ }
+ // NOW remove the offending listener node.
+ mDeps.remove(name);
+ // Having constructed a description of the order change, inform caller.
+ throw OrderChange(out.str());
}
- // NOW remove the offending listener node.
- mDeps.remove(name);
- // Having constructed a description of the order change, inform caller.
- throw OrderChange(out.str());
+ // This node becomes the previous one.
+ previous = dmi->second;
}
- // This node becomes the previous one.
- previous = dmi->second;
- }
- // We just got done with a successful mDeps.add(name, ...) call. We'd
- // better have found 'name' somewhere in that sorted list!
- assert(mydmi != sorted_range.end());
- // Four cases:
- // 0. name is the only entry: placement 1.0
- // 1. name is the first of several entries: placement (next placement)/2
- // 2. name is between two other entries: placement (myprev + (next placement))/2
- // 3. name is the last entry: placement ceil(myprev) + 1.0
- // Since we've cleverly arranged for myprev to be 0.0 if name is the
- // first entry, this folds down to two cases. Case 1 is subsumed by
- // case 2, and case 0 is subsumed by case 3. So we need only handle
- // cases 2 and 3, which means we need only detect whether name is the
- // last entry. Increment mydmi to see if there's anything beyond.
- if (++mydmi != sorted_range.end())
- {
- // The new node isn't last. Place it between the previous node and
- // the successor.
- newNode = (myprev + mydmi->second)/2.f;
- }
- else
- {
- // The new node is last. Bump myprev up to the next integer, add
- // 1.0 and use that.
- newNode = std::ceil(myprev) + 1.f;
+ // We just got done with a successful mDeps.add(name, ...) call. We'd
+ // better have found 'name' somewhere in that sorted list!
+ assert(mydmi != sorted_range.end());
+ // Four cases:
+ // 0. name is the only entry: placement 1.0
+ // 1. name is the first of several entries: placement (next placement)/2
+ // 2. name is between two other entries: placement (myprev + (next placement))/2
+ // 3. name is the last entry: placement ceil(myprev) + 1.0
+ // Since we've cleverly arranged for myprev to be 0.0 if name is the
+ // first entry, this folds down to two cases. Case 1 is subsumed by
+ // case 2, and case 0 is subsumed by case 3. So we need only handle
+ // cases 2 and 3, which means we need only detect whether name is the
+ // last entry. Increment mydmi to see if there's anything beyond.
+ if (++mydmi != sorted_range.end())
+ {
+ // The new node isn't last. Place it between the previous node and
+ // the successor.
+ newNode = (myprev + mydmi->second) / 2.f;
+ }
+ else
+ {
+ // The new node is last. Bump myprev up to the next integer, add
+ // 1.0 and use that.
+ newNode = std::ceil(myprev) + 1.f;
+ }
+
+ nodePosition = newNode;
}
// Now that newNode has a value that places it appropriately in mSignal,
// connect it.
- LLBoundListener bound = mSignal->connect(newNode, listener);
- mConnections[name] = bound;
+ LLBoundListener bound = mSignal->connect(nodePosition, listener);
+
+ if (!name.empty())
+ { // note that we are not tracking anonymous listeners here either.
+ // This means that it is the caller's responsibility to either assign
+ // to a TempBoundListerer (scoped_connection) or manually disconnect
+ // when done.
+ mConnections[name] = bound;
+ }
return bound;
}
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h
index ba4fcd766e..694951e699 100644
--- a/indra/llcommon/llevents.h
+++ b/indra/llcommon/llevents.h
@@ -365,6 +365,8 @@ typedef boost::signals2::trackable LLEventTrackable;
class LL_COMMON_API LLEventPump: public LLEventTrackable
{
public:
+ static const std::string ANONYMOUS; // constant for anonymous listeners.
+
/**
* Exception thrown by LLEventPump(). You are trying to instantiate an
* LLEventPump (subclass) using the same name as some other instance, and
@@ -476,6 +478,12 @@ public:
* instantiate your listener, then passing the same name on each listen()
* call, allows us to optimize away the second and subsequent dependency
* sorts.
+ *
+ * If name is set to LLEventPump::ANONYMOUS listen will bypass the entire
+ * dependency and ordering calculation. In this case, it is critical that
+ * the result be assigned to a LLTempBoundListener or the listener is
+ * manually disconnected when no longer needed since there will be no
+ * way to later find and disconnect this listener manually.
*
* If (as is typical) you pass a <tt>boost::bind()</tt> expression as @a
* listener, listen() will inspect the components of that expression. If a
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index f3b8999883..c45db3b185 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -576,6 +576,33 @@ std::string utf8str_truncate(const std::string& utf8str, const S32 max_len)
}
}
+std::string utf8str_symbol_truncate(const std::string& utf8str, const S32 symbol_len)
+{
+ if (0 == symbol_len)
+ {
+ return std::string();
+ }
+ if ((S32)utf8str.length() <= symbol_len)
+ {
+ return utf8str;
+ }
+ else
+ {
+ int len = 0, byteIndex = 0;
+ const char* aStr = utf8str.c_str();
+ size_t origSize = utf8str.size();
+
+ for (byteIndex = 0; len < symbol_len && byteIndex < origSize; byteIndex++)
+ {
+ if ((aStr[byteIndex] & 0xc0) != 0x80)
+ {
+ len += 1;
+ }
+ }
+ return utf8str.substr(0, byteIndex);
+ }
+}
+
std::string utf8str_substChar(
const std::string& utf8str,
const llwchar target_char,
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 393f6d7a8c..a40db0f8cc 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -564,6 +564,17 @@ LL_COMMON_API S32 utf8str_compare_insensitive(
const std::string& rhs);
/**
+* @brief Properly truncate a utf8 string to a maximum character count.
+*
+* If symbol_len is longer than the string passed in, the return
+* value == utf8str.
+* @param utf8str A valid utf8 string to truncate.
+* @param symbol_len The maximum number of symbols in the return value.
+* @return Returns a valid utf8 string with symbol count <= max_len.
+*/
+LL_COMMON_API std::string utf8str_symbol_truncate(const std::string& utf8str, const S32 symbol_len);
+
+/**
* @brief Replace all occurences of target_char with replace_char
*
* @param utf8str A utf8 string to process.
diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h
index 4be677a4b0..0f23754096 100644
--- a/indra/llmessage/llassetstorage.h
+++ b/indra/llmessage/llassetstorage.h
@@ -181,6 +181,10 @@ protected:
// Map of known bad assets
typedef std::map<LLUUID,U64,lluuid_less> toxic_asset_map_t;
+// *TODO: these typedefs are passed into the VFS via a legacy C function pointer
+// future project would be to convert these to C++ callables (std::function<>) so that
+// we can use bind and remove the userData parameter.
+//
typedef void (*LLGetAssetCallback)(LLVFS *vfs, const LLUUID &asset_id,
LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status);
diff --git a/indra/llmessage/llavatarname.cpp b/indra/llmessage/llavatarname.cpp
index d12f157910..d2115ee499 100644
--- a/indra/llmessage/llavatarname.cpp
+++ b/indra/llmessage/llavatarname.cpp
@@ -166,7 +166,7 @@ void LLAvatarName::setExpires(F64 expires)
mExpires = LLFrameTimer::getTotalSeconds() + expires;
}
-std::string LLAvatarName::getCompleteName() const
+std::string LLAvatarName::getCompleteName(bool use_parentheses) const
{
std::string name;
if (sUseDisplayNames)
@@ -182,7 +182,14 @@ std::string LLAvatarName::getCompleteName() const
name = mDisplayName;
if(sUseUsernames)
{
- name += " (" + mUsername + ")";
+ if(use_parentheses)
+ {
+ name += " (" + mUsername + ")";
+ }
+ else
+ {
+ name += " [ " + mUsername + " ]";
+ }
}
}
}
@@ -220,7 +227,7 @@ std::string LLAvatarName::getDisplayName() const
}
}
-std::string LLAvatarName::getUserName() const
+std::string LLAvatarName::getUserName(bool lowercase) const
{
std::string name;
if (mLegacyLastName.empty() || (mLegacyLastName == "Resident"))
@@ -238,7 +245,15 @@ std::string LLAvatarName::getUserName() const
}
else
{
- name = mLegacyFirstName + " " + mLegacyLastName;
+ if(lowercase)
+ {
+ name = mLegacyFirstName + "." + mLegacyLastName;
+ LLStringUtil::toLower(name);
+ }
+ else
+ {
+ name = mLegacyFirstName + " " + mLegacyLastName;
+ }
}
return name;
}
diff --git a/indra/llmessage/llavatarname.h b/indra/llmessage/llavatarname.h
index 1cb3ae421f..192f43f07c 100644
--- a/indra/llmessage/llavatarname.h
+++ b/indra/llmessage/llavatarname.h
@@ -65,7 +65,7 @@ public:
// For normal names, returns "James Linden (james.linden)"
// When display names are disabled returns just "James Linden"
- std::string getCompleteName() const;
+ std::string getCompleteName(bool use_parentheses = true) const;
// Returns "James Linden" or "bobsmith123 Resident" for backwards
// compatibility with systems like voice and muting
@@ -80,7 +80,7 @@ public:
// Returns "James Linden" or "bobsmith123 Resident"
// Used where we explicitely prefer or need a non UTF-8 legacy (ASCII) name
// Also used for backwards compatibility with systems like voice and muting
- std::string getUserName() const;
+ std::string getUserName(bool lowercase = false) const;
// Returns "james.linden" or the legacy name for very old names
std::string getAccountName() const { return mUsername; }
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index 7742cbc182..9bf38fb336 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -642,7 +642,7 @@ HttpRequestPumper::HttpRequestPumper(const LLCore::HttpRequest::ptr_t &request)
mHttpRequest(request)
{
mBoundListener = LLEventPumps::instance().obtain("mainloop").
- listen(LLEventPump::inventName(), boost::bind(&HttpRequestPumper::pollRequest, this, _1));
+ listen(LLEventPump::ANONYMOUS, boost::bind(&HttpRequestPumper::pollRequest, this, _1));
}
HttpRequestPumper::~HttpRequestPumper()
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index 720986a411..00bde8dbc3 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -2235,7 +2235,11 @@ std::string LLDAELoader::getElementLabel(daeElement *element)
// retrieve index to distinguish items inside same parent
size_t ind = 0;
parent->getChildren().find(element, ind);
- index_string = "_" + boost::lexical_cast<std::string>(ind);
+
+ if (ind > 0)
+ {
+ index_string = "_" + boost::lexical_cast<std::string>(ind);
+ }
// if parent has a name or ID, use it
std::string name = parent->getAttribute("name");
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 14f75a2352..69038a8627 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -1326,7 +1326,7 @@ void LLFloater::setMinimized(BOOL minimize)
}
mMinimized = FALSE;
-
+ setFrontmost();
// Reshape *after* setting mMinimized
reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE );
}
@@ -1575,6 +1575,7 @@ BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask)
if(offerClickToButton(x, y, mask, BUTTON_TEAR_OFF)) return TRUE;
if(offerClickToButton(x, y, mask, BUTTON_DOCK)) return TRUE;
+ setFrontmost(TRUE, FALSE);
// Otherwise pass to drag handle for movement
return mDragHandle->handleMouseDown(x, y, mask);
}
@@ -1649,7 +1650,7 @@ void LLFloater::setVisibleAndFrontmost(BOOL take_focus,const LLSD& key)
}
}
-void LLFloater::setFrontmost(BOOL take_focus)
+void LLFloater::setFrontmost(BOOL take_focus, BOOL restore)
{
LLMultiFloater* hostp = getHost();
if (hostp)
@@ -1665,7 +1666,7 @@ void LLFloater::setFrontmost(BOOL take_focus)
LLFloaterView * parent = dynamic_cast<LLFloaterView*>( getParent() );
if (parent)
{
- parent->bringToFront(this, take_focus);
+ parent->bringToFront(this, take_focus, restore);
}
// Make sure to set the appropriate transparency type (STORM-732).
@@ -2320,7 +2321,10 @@ void LLFloaterView::restoreAll()
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
{
LLFloater* floaterp = (LLFloater*)*child_it;
- floaterp->setMinimized(FALSE);
+ if (floaterp)
+ {
+ floaterp->setMinimized(FALSE);
+ }
}
// *FIX: make sure dependents are restored
@@ -2394,7 +2398,7 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF
}
-void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
+void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus, BOOL restore)
{
if (!child)
return;
@@ -2478,7 +2482,12 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
{
sendChildToFront(child);
}
- child->setMinimized(FALSE);
+
+ if(restore)
+ {
+ child->setMinimized(FALSE);
+ }
+
if (give_focus && !gFocusMgr.childHasKeyboardFocus(child))
{
child->setFocus(TRUE);
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index ef7c6180d2..165f67499b 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -310,7 +310,7 @@ public:
/*virtual*/ void setVisible(BOOL visible); // do not override
/*virtual*/ void onVisibilityChange ( BOOL new_visibility ); // do not override
- void setFrontmost(BOOL take_focus = TRUE);
+ void setFrontmost(BOOL take_focus = TRUE, BOOL restore = TRUE);
virtual void setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());
// Defaults to false.
@@ -547,7 +547,7 @@ public:
void setCycleMode(BOOL mode) { mFocusCycleMode = mode; }
BOOL getCycleMode() const { return mFocusCycleMode; }
- void bringToFront( LLFloater* child, BOOL give_focus = TRUE );
+ void bringToFront( LLFloater* child, BOOL give_focus = TRUE, BOOL restore = TRUE );
void highlightFocusedFloater();
void unhighlightFocusedFloater();
void focusFrontFloater();
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 3282c5f726..f9664e0658 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -684,6 +684,13 @@ void LLFolderView::draw()
}
}
+ if (mRenameItem && mRenamer && mRenamer->getVisible() && !getVisibleRect().overlaps(mRenamer->getRect()))
+ {
+ // renamer is not connected to the item we are renaming in any form so manage it manually
+ // TODO: consider stopping on any scroll action instead of when out of visible area
+ finishRenamingItem();
+ }
+
// skip over LLFolderViewFolder::draw since we don't want the folder icon, label,
// and arrow for the root folder
LLView::draw();
@@ -1629,9 +1636,9 @@ void LLFolderView::update()
if (mNeedsAutoSelect)
{
LL_RECORD_BLOCK_TIME(FTM_AUTO_SELECT);
- // select new item only if a filtered item not currently selected
+ // select new item only if a filtered item not currently selected and there was a selection
LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
- if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->getViewModelItem()->potentiallyVisible()))
+ if (!mAutoSelectOverride && selected_itemp && !selected_itemp->getViewModelItem()->potentiallyVisible())
{
// these are named variables to get around gcc not binding non-const references to rvalues
// and functor application is inherently non-const to allow for stateful functors
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 114dd7bd2f..b5deefd653 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -242,6 +242,8 @@ public:
bool useLabelSuffix() { return mUseLabelSuffix; }
virtual void updateMenu();
+ void finishRenamingItem( void );
+
// Note: We may eventually have to move that method up the hierarchy to LLFolderViewItem.
LLHandle<LLFolderView> getHandle() const { return getDerivedHandle<LLFolderView>(); }
@@ -255,7 +257,6 @@ protected:
void commitRename( const LLSD& data );
void onRenamerLost();
- void finishRenamingItem( void );
void closeRenamer( void );
bool selectFirstItem();
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 3def0386e1..3d618548c4 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -127,6 +127,8 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
mIsSelected( FALSE ),
mIsCurSelection( FALSE ),
mSelectPending(FALSE),
+ mIsItemCut(false),
+ mCutGeneration(0),
mLabelStyle( LLFontGL::NORMAL ),
mHasVisibleChildren(FALSE),
mIsFolderComplete(true),
@@ -694,6 +696,19 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L
return mIsCurSelection;
}
+/*virtual*/ bool LLFolderViewItem::isFadeItem()
+{
+ LLClipboard& clipboard = LLClipboard::instance();
+ if (mCutGeneration != clipboard.getGeneration())
+ {
+ mCutGeneration = clipboard.getGeneration();
+ mIsItemCut = clipboard.isCutMode()
+ && ((getParentFolder() && getParentFolder()->isFadeItem())
+ || getViewModelItem()->isCutToClipboard());
+ }
+ return mIsItemCut;
+}
+
void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor,
const LLUIColor &focusOutlineColor, const LLUIColor &mouseOverColor)
{
@@ -875,6 +890,12 @@ void LLFolderViewItem::draw()
}
LLColor4 color = (mIsSelected && filled) ? mFontHighlightColor : mFontColor;
+
+ if (isFadeItem())
+ {
+ // Fade out item color to indicate it's being cut
+ color.mV[VALPHA] *= 0.5f;
+ }
drawLabel(font, text_left, y, color, right_x);
//--------------------------------------------------------------------------------//
@@ -882,7 +903,7 @@ void LLFolderViewItem::draw()
//
if (!mLabelSuffix.empty())
{
- font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor,
+ font->renderUTF8( mLabelSuffix, 0, right_x, y, isFadeItem() ? color : (LLColor4)sSuffixColor,
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
S32_MAX, S32_MAX, &right_x, FALSE );
}
@@ -972,6 +993,11 @@ void LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder)
mIndentation = (getParentFolder())
? getParentFolder()->getIndentation() + mLocalIndentation
: 0;
+
+ if(isOpen() && folder->isOpen())
+ {
+ requestArrange();
+ }
}
static LLTrace::BlockTimerStatHandle FTM_ARRANGE("Arrange");
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 0322c8836d..61c39e0175 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -121,8 +121,11 @@ protected:
mIsMouseOverTitle,
mAllowWear,
mAllowDrop,
- mSelectPending;
-
+ mSelectPending,
+ mIsItemCut;
+
+ S32 mCutGeneration;
+
LLUIColor mFontColor;
LLUIColor mFontHighlightColor;
@@ -145,6 +148,7 @@ protected:
virtual void addFolder(LLFolderViewFolder*) { }
virtual bool isHighlightAllowed();
virtual bool isHighlightActive();
+ virtual bool isFadeItem();
virtual bool isFlashing() { return false; }
virtual void setFlashState(bool) { }
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index a395af537a..641241a88c 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -173,6 +173,7 @@ public:
virtual BOOL isItemCopyable() const = 0;
virtual BOOL copyToClipboard() const = 0;
virtual BOOL cutToClipboard() = 0;
+ virtual bool isCutToClipboard() { return false; };
virtual BOOL isClipboardPasteable() const = 0;
virtual void pasteFromClipboard() = 0;
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index a08cf91a69..492c9315d1 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -400,12 +400,7 @@ void LLLineEditor::setText(const LLStringExplicit &new_text)
if (mMaxLengthChars)
{
- LLWString truncated_wstring = utf8str_to_wstring(truncated_utf8);
- if (truncated_wstring.size() > (U32)mMaxLengthChars)
- {
- truncated_wstring = truncated_wstring.substr(0, mMaxLengthChars);
- }
- mText.assign(wstring_to_utf8str(truncated_wstring));
+ mText.assign(utf8str_symbol_truncate(truncated_utf8, mMaxLengthChars));
}
if (all_selected)
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 616c42895c..c7d7535f87 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -177,6 +177,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
: LLUICtrl(p, LLTextViewModelPtr(new LLTextViewModel)),
mURLClickSignal(NULL),
mIsFriendSignal(NULL),
+ mIsObjectBlockedSignal(NULL),
mMaxTextByteLength( p.max_text_length ),
mFont(p.font),
mFontShadow(p.font_shadow),
@@ -268,6 +269,8 @@ LLTextBase::~LLTextBase()
{
mSegments.clear();
delete mURLClickSignal;
+ delete mIsFriendSignal;
+ delete mIsObjectBlockedSignal;
}
void LLTextBase::initFromParams(const LLTextBase::Params& p)
@@ -1942,6 +1945,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
registrar.add("Url.OpenExternal", boost::bind(&LLUrlAction::openURLExternal, url));
registrar.add("Url.Execute", boost::bind(&LLUrlAction::executeSLURL, url, true));
registrar.add("Url.Block", boost::bind(&LLUrlAction::blockObject, url));
+ registrar.add("Url.Unblock", boost::bind(&LLUrlAction::unblockObject, url));
registrar.add("Url.Teleport", boost::bind(&LLUrlAction::teleportToLocation, url));
registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url));
registrar.add("Url.AddFriend", boost::bind(&LLUrlAction::addFriend, url));
@@ -1968,6 +1972,19 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
removeFriendButton->setEnabled(isFriend);
}
}
+
+ if (mIsObjectBlockedSignal)
+ {
+ bool is_blocked = *(*mIsObjectBlockedSignal)(LLUUID(LLUrlAction::getObjectId(url)), LLUrlAction::getObjectName(url));
+ LLView* blockButton = mPopupMenu->getChild<LLView>("block_object");
+ LLView* unblockButton = mPopupMenu->getChild<LLView>("unblock_object");
+
+ if (blockButton && unblockButton)
+ {
+ blockButton->setVisible(!is_blocked);
+ unblockButton->setVisible(is_blocked);
+ }
+ }
if (mPopupMenu)
{
@@ -3022,6 +3039,15 @@ boost::signals2::connection LLTextBase::setIsFriendCallback(const is_friend_sign
return mIsFriendSignal->connect(cb);
}
+boost::signals2::connection LLTextBase::setIsObjectBlockedCallback(const is_blocked_signal_t::slot_type& cb)
+{
+ if (!mIsObjectBlockedSignal)
+ {
+ mIsObjectBlockedSignal = new is_blocked_signal_t();
+ }
+ return mIsObjectBlockedSignal->connect(cb);
+}
+
//
// LLTextSegment
//
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index c6ce5efcb8..85641fd899 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -270,6 +270,7 @@ public:
friend class LLUICtrlFactory;
typedef boost::signals2::signal<bool (const LLUUID& user_id)> is_friend_signal_t;
+ typedef boost::signals2::signal<bool (const LLUUID& blocked_id, const std::string from)> is_blocked_signal_t;
struct LineSpacingParams : public LLInitParam::ChoiceBlock<LineSpacingParams>
{
@@ -456,6 +457,7 @@ public:
virtual void appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo);
boost::signals2::connection setURLClickedCallback(const commit_signal_t::slot_type& cb);
boost::signals2::connection setIsFriendCallback(const is_friend_signal_t::slot_type& cb);
+ boost::signals2::connection setIsObjectBlockedCallback(const is_blocked_signal_t::slot_type& cb);
void setWordWrap(bool wrap);
LLScrollContainer* getScrollContainer() const { return mScroller; }
@@ -685,6 +687,7 @@ protected:
// Used to check if user with given ID is avatar's friend
is_friend_signal_t* mIsFriendSignal;
+ is_blocked_signal_t* mIsObjectBlockedSignal;
LLUIString mLabel; // text label that is visible when no user text provided
};
diff --git a/indra/llui/lltextutil.cpp b/indra/llui/lltextutil.cpp
index fff04b34f2..f6b2ee1dc0 100644
--- a/indra/llui/lltextutil.cpp
+++ b/indra/llui/lltextutil.cpp
@@ -56,6 +56,26 @@ void LLTextUtil::textboxSetHighlightedVal(LLTextBox *txtbox, const LLStyle::Para
txtbox->appendText(text.substr(hl_begin + hl_len), false, normal_style);
}
+void LLTextUtil::textboxSetGreyedVal(LLTextBox *txtbox, const LLStyle::Params& normal_style, const std::string& text, const std::string& greyed)
+{
+ static LLUIColor sGreyedTextColor = LLUIColorTable::instance().getColor("Gray", LLColor4::grey);
+
+ size_t greyed_begin = 0, greyed_len = greyed.size();
+
+ if (greyed_len == 0 || (greyed_begin = text.find(greyed)) == std::string::npos)
+ {
+ txtbox->setText(text, normal_style);
+ return;
+ }
+
+ LLStyle::Params greyed_style = normal_style;
+ greyed_style.color = sGreyedTextColor;
+ txtbox->setText(LLStringUtil::null); // clear text
+ txtbox->appendText(text.substr(0, greyed_begin), false, normal_style);
+ txtbox->appendText(text.substr(greyed_begin, greyed_len), false, greyed_style);
+ txtbox->appendText(text.substr(greyed_begin + greyed_len), false, normal_style);
+}
+
const std::string& LLTextUtil::formatPhoneNumber(const std::string& phone_str)
{
static const std::string PHONE_SEPARATOR = LLUI::sSettingGroups["config"]->getString("AvalinePhoneSeparator");
diff --git a/indra/llui/lltextutil.h b/indra/llui/lltextutil.h
index 1be81ffd62..a9c143e445 100644
--- a/indra/llui/lltextutil.h
+++ b/indra/llui/lltextutil.h
@@ -52,6 +52,12 @@ namespace LLTextUtil
const std::string& text,
const std::string& hl);
+ void textboxSetGreyedVal(
+ LLTextBox *txtbox,
+ const LLStyle::Params& normal_style,
+ const std::string& text,
+ const std::string& greyed);
+
/**
* Formats passed phone number to be more human readable.
*
diff --git a/indra/llui/lltextvalidate.cpp b/indra/llui/lltextvalidate.cpp
index 324ceb7fba..bfe0a5bb5d 100644
--- a/indra/llui/lltextvalidate.cpp
+++ b/indra/llui/lltextvalidate.cpp
@@ -328,6 +328,15 @@ namespace LLTextValidate
return rv;
}
+ bool validateASCIINoLeadingSpace(const LLWString &str)
+ {
+ if (LLStringOps::isSpace(str[0]))
+ {
+ return FALSE;
+ }
+ return validateASCII(str);
+ }
+
// Used for multiline text stored on the server.
// Example is landmark description in Places SP.
bool validateASCIIWithNewLine(const LLWString &str)
diff --git a/indra/llui/lltextvalidate.h b/indra/llui/lltextvalidate.h
index 5c830d7db3..e2b6c313d6 100644
--- a/indra/llui/lltextvalidate.h
+++ b/indra/llui/lltextvalidate.h
@@ -52,6 +52,7 @@ namespace LLTextValidate
bool validateASCIIPrintableNoPipe(const LLWString &str);
bool validateASCIIPrintableNoSpace(const LLWString &str);
bool validateASCII(const LLWString &str);
+ bool validateASCIINoLeadingSpace(const LLWString &str);
bool validateASCIIWithNewLine(const LLWString &str);
}
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index aabc7ed2e4..f790d8e005 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -522,7 +522,7 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)
else
{
std::string part(ti->begin(), ti->end());
- context = context->findChildView(part, recurse);
+ context = context->findChildView(LLURI::unescape(part), recurse);
recurse = false;
}
}
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index 56977c597b..84ea770a8d 100644
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -231,3 +231,13 @@ void LLUrlAction::blockObject(std::string url)
executeSLURL("secondlife:///app/agent/" + object_id + "/block/" + LLURI::escape(object_name));
}
}
+
+void LLUrlAction::unblockObject(std::string url)
+{
+ std::string object_id = getObjectId(url);
+ std::string object_name = getObjectName(url);
+ if (LLUUID::validate(object_id))
+ {
+ executeSLURL("secondlife:///app/agent/" + object_id + "/unblock/" + object_name);
+ }
+}
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index 5497e28bb4..2d2a8dfef1 100644
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -83,6 +83,7 @@ public:
static void addFriend(std::string url);
static void removeFriend(std::string url);
static void blockObject(std::string url);
+ static void unblockObject(std::string url);
/// specify the callbacks to enable this class's functionality
typedef boost::function<void (const std::string&)> url_callback_t;
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 8f7cac1f61..e1d9b1a487 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -391,7 +391,27 @@ static void buildPathname(std::ostream& out, const LLView* view)
buildPathname(out, view->getParent());
// Build pathname into ostream on the way back from recursion.
- out << '/' << view->getName();
+ out << '/';
+
+ // substitute all '/' in name with appropriate code
+ std::string name = view->getName();
+ std::size_t found = name.find('/');
+ std::size_t start = 0;
+ while (found != std::string::npos)
+ {
+ std::size_t sub_len = found - start;
+ if (sub_len > 0)
+ {
+ out << name.substr(start, sub_len);
+ }
+ out << "%2F";
+ start = found + 1;
+ found = name.find('/', start);
+ }
+ if (start < name.size())
+ {
+ out << name.substr(start, name.size() - start);
+ }
}
std::string LLView::getPathname() const
@@ -588,6 +608,11 @@ void LLView::onVisibilityChange ( BOOL new_visibility )
BOOL log_visibility_change = LLViewerEventRecorder::instance().getLoggingStatus();
BOOST_FOREACH(LLView* viewp, mChildList)
{
+ if (!viewp)
+ {
+ continue;
+ }
+
// only views that are themselves visible will have their overall visibility affected by their ancestors
old_visibility=viewp->getVisible();
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index 5f4fb8f4a0..86a15f2ef2 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -531,6 +531,13 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
case LL_PATH_PER_ACCOUNT_CHAT_LOGS:
prefix = getPerAccountChatLogsDir();
+ if (prefix.empty())
+ {
+ // potentially directory was not set yet
+ // intentionally return a blank string to the caller
+ LL_DEBUGS("LLDir") << "Conversation log directory is not yet set" << LL_ENDL;
+ return std::string();
+ }
break;
case LL_PATH_LOGS:
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index 0a30f4c807..a05ba8cbba 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -166,6 +166,8 @@ public:
// Provide native key event data
virtual LLSD getNativeKeyData() { return LLSD::emptyMap(); }
+ // Get system UI size based on DPI (for 96 DPI UI size should be 1.0)
+ virtual F32 getSystemUISize() { return 1.0; }
protected:
LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags);
virtual ~LLWindow();
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 875ffe4cd4..2a39029eee 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -78,6 +78,31 @@ LPWSTR gIconResource = IDI_APPLICATION;
LLW32MsgCallback gAsyncMsgCallback = NULL;
+#ifndef DPI_ENUMS_DECLARED
+
+typedef enum PROCESS_DPI_AWARENESS {
+ PROCESS_DPI_UNAWARE = 0,
+ PROCESS_SYSTEM_DPI_AWARE = 1,
+ PROCESS_PER_MONITOR_DPI_AWARE = 2
+} PROCESS_DPI_AWARENESS;
+
+typedef enum MONITOR_DPI_TYPE {
+ MDT_EFFECTIVE_DPI = 0,
+ MDT_ANGULAR_DPI = 1,
+ MDT_RAW_DPI = 2,
+ MDT_DEFAULT = MDT_EFFECTIVE_DPI
+} MONITOR_DPI_TYPE;
+
+#endif
+
+typedef HRESULT(STDAPICALLTYPE *SetProcessDpiAwarenessType)(_In_ PROCESS_DPI_AWARENESS value);
+
+typedef HRESULT(STDAPICALLTYPE *GetDpiForMonitorType)(
+ _In_ HMONITOR hmonitor,
+ _In_ MONITOR_DPI_TYPE dpiType,
+ _Out_ UINT *dpiX,
+ _Out_ UINT *dpiY);
+
//
// LLWindowWin32
//
@@ -3878,6 +3903,46 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
return FALSE;
}
+F32 LLWindowWin32::getSystemUISize()
+{
+ float scale_value = 0;
+ HWND hWnd = (HWND)getPlatformWindow();
+ HDC hdc = GetDC(hWnd);
+ HMONITOR hMonitor;
+
+ HMODULE hShcore = LoadLibrary(L"shcore.dll");
+
+ if (hShcore != NULL)
+ {
+ SetProcessDpiAwarenessType pSPDA;
+ pSPDA = (SetProcessDpiAwarenessType)GetProcAddress(hShcore, "SetProcessDpiAwareness");
+ GetDpiForMonitorType pGDFM;
+ pGDFM = (GetDpiForMonitorType)GetProcAddress(hShcore, "GetDpiForMonitor");
+ if (pSPDA != NULL && pGDFM != NULL)
+ {
+ pSPDA(PROCESS_PER_MONITOR_DPI_AWARE);
+ POINT pt;
+ UINT dpix = 0, dpiy = 0;
+ HRESULT hr = E_FAIL;
+
+ // Get the DPI for the main monitor, and set the scaling factor
+ pt.x = 1;
+ pt.y = 1;
+ hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
+ hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy);
+ scale_value = dpix / 96.0f;
+ }
+ }
+ else
+ {
+ LL_WARNS() << "Could not load shcore.dll library (included by <ShellScalingAPI.h> from Win 8.1 SDK). Using legacy DPI awareness API of Win XP/7" << LL_ENDL;
+ scale_value = GetDeviceCaps(hdc, LOGPIXELSX) / 96.0f;
+ }
+
+ ReleaseDC(hWnd, hdc);
+ return scale_value;
+}
+
//static
std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList()
{
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 1a775eadaf..1386321912 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -110,6 +110,8 @@ public:
/*virtual*/ void interruptLanguageTextInput();
/*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
+ /*virtual*/ F32 getSystemUISize();
+
LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url );
static std::vector<std::string> getDynamicFallbackFontList();
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 8d863631cf..dce0ea73cd 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1315,13 +1315,10 @@ set(viewer_HEADER_FILES
source_group("CMake Rules" FILES ViewerInstall.cmake)
+#summary.json creation moved to viewer_manifest.py MAINT-6413
# the viewer_version.txt file created here is for passing to viewer_manifest and autobuild
-# the summary.json file is created for the benefit of the TeamCity builds, where
-# it is used to provide descriptive information to the build results page
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt"
"${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}\n")
-file(WRITE "${CMAKE_BINARY_DIR}/summary.json"
- "{\"Type\":\"viewer\",\"Version\":\"${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}\"}\n")
set_source_files_properties(
llversioninfo.cpp tests/llversioninfo_test.cpp
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 2cd6638042..a0d3dc0f99 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -37,7 +37,7 @@
tooltip_ref="Command_Build_Tooltip"
execute_function="Build.Toggle"
execute_parameters="build"
- is_enabled_function="Build.Enabled"
+ is_enabled_function="Build.EnabledOrActive"
is_enabled_parameters="build"
is_running_function="Floater.IsOpen"
is_running_parameters="build"
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index a8d42be2a1..c3d7d67c86 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -3701,6 +3701,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>QueueInventoryFetchTimeout</key>
+ <map>
+ <key>Comment</key>
+ <string>Max time llcompilequeue will wait for inventory fetch to complete (in seconds)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>300.0</real>
+ </map>
<key>FindLandArea</key>
<map>
<key>Comment</key>
@@ -10207,6 +10218,17 @@
<key>Value</key>
<real>1.0</real>
</map>
+ <key>RenderRiggedFactorMultiplier</key>
+ <map>
+ <key>Comment</key>
+ <string>Affects level of detail for worn rigged meshes</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>7.5</real>
+ </map>
<key>RenderWater</key>
<map>
<key>Comment</key>
@@ -11065,6 +11087,28 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>FriendsListHideUsernames</key>
+ <map>
+ <key>Comment</key>
+ <string>Show both Display name and Username in Friend list</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>NearbyListHideUsernames</key>
+ <map>
+ <key>Comment</key>
+ <string>Show both Display name and Username in Nearby list</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>NearbyListShowMap</key>
<map>
<key>Comment</key>
@@ -12759,6 +12803,17 @@
<key>Value</key>
<real>1.0</real>
</map>
+ <key>LastSystemUIScaleFactor</key>
+ <map>
+ <key>Comment</key>
+ <string>Size of system UI during last run. On Windows 100% (96 DPI) system setting is 1.0 UI size</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
<key>UIScrollbarSize</key>
<map>
<key>Comment</key>
@@ -13254,6 +13309,17 @@
<key>Value</key>
<string>1</string>
</map>
+ <key>UpdaterShowReleaseNotes</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables displaying of the Release notes in a web floater after update.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>UploadBakedTexOld</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index be8ea2bab9..e99b94f150 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -32,7 +32,7 @@ RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
-RenderAvatarMaxComplexity 1 80000
+RenderAvatarMaxComplexity 1 350000
RenderAvatarVP 1 1
RenderAutoMuteSurfaceAreaLimit 1 1000.0
RenderCubeMap 1 1
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index ca6c00951d..801a622e93 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -32,7 +32,7 @@ RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
-RenderAvatarMaxComplexity 1 80000
+RenderAvatarMaxComplexity 1 350000
RenderAvatarVP 1 1
RenderAutoMuteSurfaceAreaLimit 1 1000.0
RenderCubeMap 1 1
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index ea69b088f9..1f891ee4d7 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -32,7 +32,7 @@ RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
-RenderAvatarMaxComplexity 1 80000
+RenderAvatarMaxComplexity 1 350000
RenderAvatarVP 1 1
RenderAutoMuteSurfaceAreaLimit 1 1000.0
RenderCubeMap 1 1
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index b8677fd9e4..89317f2793 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -648,6 +648,7 @@ Function un.ProgramFiles
%%DELETE_FILES%%
# Optional/obsolete files. Delete won't fail if they don't exist.
+Delete "$INSTDIR\autorun.bat"
Delete "$INSTDIR\dronesettings.ini"
Delete "$INSTDIR\message_template.msg"
Delete "$INSTDIR\newview.pdb"
@@ -679,6 +680,16 @@ FOLDERFOUND:
NOFOLDER:
+MessageBox MB_YESNO $(DeleteRegistryKeysMB) IDYES DeleteKeys IDNO NoDelete
+
+DeleteKeys:
+ DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Classes\x-grid-location-info"
+ DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Classes\secondlife"
+ DeleteRegKey HKEY_CLASSES_ROOT "x-grid-location-info"
+ DeleteRegKey HKEY_CLASSES_ROOT "secondlife"
+
+NoDelete:
+
FunctionEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi
index 343c312ddc..aa403a961c 100644
--- a/indra/newview/installers/windows/lang_en-us.nsi
+++ b/indra/newview/installers/windows/lang_en-us.nsi
Binary files differ
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index d933537d2e..d8b0787852 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -3895,11 +3895,17 @@ void LLAgent::handleTeleportFinished()
mIsMaturityRatingChangingDuringTeleport = false;
}
- // Init SLM Marketplace connection so we know which UI should be used for the user as a merchant
- // Note: Eventually, all merchant will be migrated to the new SLM system and there will be no reason to show the old UI at all.
- // Note: Some regions will not support the SLM cap for a while so we need to do that check for each teleport.
- // *TODO : Suppress that line from here once the whole grid migrated to SLM and move it to idle_startup() (llstartup.cpp)
- check_merchant_status();
+ if (mRegionp)
+ {
+ if (mRegionp->capabilitiesReceived())
+ {
+ onCapabilitiesReceivedAfterTeleport();
+ }
+ else
+ {
+ mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::onCapabilitiesReceivedAfterTeleport));
+ }
+ }
}
void LLAgent::handleTeleportFailed()
@@ -3931,6 +3937,14 @@ void LLAgent::handleTeleportFailed()
}
}
+/*static*/
+void LLAgent::onCapabilitiesReceivedAfterTeleport()
+{
+
+ check_merchant_status();
+}
+
+
void LLAgent::teleportRequest(
const U64& region_handle,
const LLVector3& pos_local,
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 3a533c2cba..d82ff7a67f 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -676,6 +676,8 @@ private:
void handleTeleportFinished();
void handleTeleportFailed();
+ static void onCapabilitiesReceivedAfterTeleport();
+
//--------------------------------------------------------------------
// Teleport State
//--------------------------------------------------------------------
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index b76a66ab39..170e4063a1 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -62,23 +62,37 @@ using namespace LLAvatarAppearanceDefines;
///////////////////////////////////////////////////////////////////////////////
-// Callback to wear and start editing an item that has just been created.
-void wear_and_edit_cb(const LLUUID& inv_item)
+void set_default_permissions(LLViewerInventoryItem* item)
{
- if (inv_item.isNull()) return;
-
- LLViewerInventoryItem* item = gInventory.getItem(inv_item);
- if (!item) return;
-
- LLPermissions perm = item->getPermissions();
+ llassert(item);
+ LLPermissions perm = item->getPermissions();
+ if (perm.getMaskNextOwner() != LLFloaterPerms::getNextOwnerPerms("Wearables")
+ || perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms("Wearables")
+ || perm.getMaskGroup() != LLFloaterPerms::getGroupPerms("Wearables"))
+ {
perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables"));
perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables"));
perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables"));
+
item->setPermissions(perm);
item->updateServer(FALSE);
- gInventory.updateItem(item);
- gInventory.notifyObservers();
+ }
+}
+
+// Callback to wear and start editing an item that has just been created.
+void wear_and_edit_cb(const LLUUID& inv_item)
+{
+ if (inv_item.isNull()) return;
+
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+ if (!item) return;
+
+ set_default_permissions(item);
+
+ // item was just created, update even if permissions did not changed
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
// Request editing the item after it gets worn.
gAgentWearables.requestEditingWearable(inv_item);
@@ -94,13 +108,8 @@ void wear_cb(const LLUUID& inv_item)
LLViewerInventoryItem* item = gInventory.getItem(inv_item);
if (item)
{
- LLPermissions perm = item->getPermissions();
- perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables"));
- perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables"));
- perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables"));
- item->setPermissions(perm);
+ set_default_permissions(item);
- item->updateServer(FALSE);
gInventory.updateItem(item);
gInventory.notifyObservers();
}
@@ -253,6 +262,7 @@ void LLAgentWearables::AddWearableToAgentInventoryCallback::fire(const LLUUID& i
{
LLAppearanceMgr::instance().addCOFItemLink(inv_item,
new LLUpdateAppearanceAndEditWearableOnDestroy(inv_item), mDescription);
+ editWearable(inv_item);
}
}
@@ -423,7 +433,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
// old_wearable may still be referred to by other inventory items. Revert
// unsaved changes so other inventory items aren't affected by the changes
// that were just saved.
- old_wearable->revertValues();
+ old_wearable->revertValuesWithoutUpdate();
}
void LLAgentWearables::revertWearable(const LLWearableType::EType type, const U32 index)
@@ -1364,6 +1374,30 @@ void LLAgentWearables::findAttachmentsAddRemoveInfo(LLInventoryModel::item_array
// LL_INFOS() << "remove " << remove_count << " add " << add_count << LL_ENDL;
}
+std::vector<LLViewerObject*> LLAgentWearables::getTempAttachments()
+{
+ llvo_vec_t temp_attachs;
+ if (isAgentAvatarValid())
+ {
+ for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); iter != gAgentAvatarp->mAttachmentPoints.end();)
+ {
+ LLVOAvatar::attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject *objectp = (*attachment_iter);
+ if (objectp && objectp->isTempAttachment())
+ {
+ temp_attachs.push_back(objectp);
+ }
+ }
+ }
+ }
+ return temp_attachs;
+}
+
void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remove)
{
if (!isAgentAvatarValid()) return;
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 1004482020..b27698fd8f 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -185,6 +185,8 @@ public:
static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);
+ static llvo_vec_t getTempAttachments();
+
//--------------------------------------------------------------------
// Signals
//--------------------------------------------------------------------
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp
index 3e3d5c7456..648212177b 100644
--- a/indra/newview/llaisapi.cpp
+++ b/indra/newview/llaisapi.cpp
@@ -838,11 +838,11 @@ void AISUpdate::parseEmbeddedCategories(const LLSD& categories)
void AISUpdate::doUpdate()
{
- // Do version/descendent accounting.
+ // Do version/descendant accounting.
for (std::map<LLUUID,S32>::const_iterator catit = mCatDescendentDeltas.begin();
catit != mCatDescendentDeltas.end(); ++catit)
{
- LL_DEBUGS("Inventory") << "descendent accounting for " << catit->first << LL_ENDL;
+ LL_DEBUGS("Inventory") << "descendant accounting for " << catit->first << LL_ENDL;
const LLUUID cat_id(catit->first);
// Don't account for update if we just created this category.
@@ -859,13 +859,13 @@ void AISUpdate::doUpdate()
continue;
}
- // If we have a known descendent count, set that now.
+ // If we have a known descendant count, set that now.
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
if (cat)
{
S32 descendent_delta = catit->second;
S32 old_count = cat->getDescendentCount();
- LL_DEBUGS("Inventory") << "Updating descendent count for "
+ LL_DEBUGS("Inventory") << "Updating descendant count for "
<< cat->getName() << " " << cat_id
<< " with delta " << descendent_delta << " from "
<< old_count << " to " << (old_count+descendent_delta) << LL_ENDL;
@@ -896,7 +896,7 @@ void AISUpdate::doUpdate()
LLUUID category_id(update_it->first);
LLPointer<LLViewerInventoryCategory> new_category = update_it->second;
// Since this is a copy of the category *before* the accounting update, above,
- // we need to transfer back the updated version/descendent count.
+ // we need to transfer back the updated version/descendant count.
LLViewerInventoryCategory* curr_cat = gInventory.getCategory(new_category->getUUID());
if (!curr_cat)
{
@@ -961,7 +961,16 @@ void AISUpdate::doUpdate()
{
LL_WARNS() << "Possible version mismatch for category " << cat->getName()
<< ", viewer version " << cat->getVersion()
- << " server version " << version << LL_ENDL;
+ << " AIS version " << version << " !!!Adjusting local version!!!" << LL_ENDL;
+
+ // the AIS version should be considered the true version. Adjust
+ // our local category model to reflect this version number. Otherwise
+ // it becomes possible to get stuck with the viewer being out of
+ // sync with the inventory system. Under normal circumstances
+ // inventory COF is maintained on the viewer through calls to
+ // LLInventoryModel::accountForUpdate when a changing operation
+ // is performed. This occasionally gets out of sync however.
+ cat->setVersion(version);
}
}
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index cc676550ab..4a4361e94b 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -60,6 +60,8 @@
#include "llcoros.h"
#include "lleventcoro.h"
+#include "llavatarpropertiesprocessor.h"
+
#if LL_MSVC
// disable boost::lexical_cast warning
#pragma warning (disable:4702)
@@ -3359,15 +3361,9 @@ void LLAppearanceMgr::requestServerAppearanceUpdate()
{
if (!mOutstandingAppearanceBakeRequest)
{
-#ifdef APPEARANCEBAKE_AS_IN_AIS_QUEUE
mRerequestAppearanceBake = false;
LLCoprocedureManager::CoProcedure_t proc = boost::bind(&LLAppearanceMgr::serverAppearanceUpdateCoro, this, _1);
LLCoprocedureManager::instance().enqueueCoprocedure("AIS", "LLAppearanceMgr::serverAppearanceUpdateCoro", proc);
-#else
- LLCoros::instance().launch("serverAppearanceUpdateCoro",
- boost::bind(&LLAppearanceMgr::serverAppearanceUpdateCoro, this));
-
-#endif
}
else
{
@@ -3375,17 +3371,8 @@ void LLAppearanceMgr::requestServerAppearanceUpdate()
}
}
-#ifdef APPEARANCEBAKE_AS_IN_AIS_QUEUE
void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter)
-#else
-void LLAppearanceMgr::serverAppearanceUpdateCoro()
-#endif
{
-#ifndef APPEARANCEBAKE_AS_IN_AIS_QUEUE
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(
- new LLCoreHttpUtil::HttpCoroutineAdapter("serverAppearanceUpdateCoro", LLCore::HttpRequest::DEFAULT_POLICY_ID));
-#endif
-
mRerequestAppearanceBake = false;
if (!gAgent.getRegion())
{
@@ -3493,10 +3480,15 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro()
// on multiple machines.
if (result.has("expected"))
{
-
S32 expectedCofVersion = result["expected"].asInteger();
LL_WARNS("Avatar") << "Server expected " << expectedCofVersion << " as COF version" << LL_ENDL;
+ // Force an update texture request for ourself. The message will return
+ // through the UDP and be handled in LLVOAvatar::processAvatarAppearance
+ // this should ensure that we receive a new canonical COF from the sim
+ // host. Hopefully it will return before the timeout.
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(gAgent.getID());
+
bRetry = true;
// Wait for a 1/2 second before trying again. Just to keep from asking too quickly.
if (++retryCount > BAKE_RETRY_MAX_COUNT)
@@ -3924,6 +3916,10 @@ void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)
LL_DEBUGS("Avatar") << "setAttachmentInvLinkEnable => " << (int) val << LL_ENDL;
mAttachmentInvLinkEnabled = val;
}
+boost::signals2::connection LLAppearanceMgr::setAttachmentsChangedCallback(attachments_changed_callback_t cb)
+{
+ return mAttachmentsChangeSignal.connect(cb);
+}
void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)
{
@@ -3950,6 +3946,8 @@ void LLAppearanceMgr::registerAttachment(const LLUUID& item_id)
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
LLAttachmentsMgr::instance().onAttachmentArrived(item_id);
+
+ mAttachmentsChangeSignal();
}
void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
@@ -3970,6 +3968,8 @@ void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
{
//LL_INFOS() << "no link changes, inv link not enabled" << LL_ENDL;
}
+
+ mAttachmentsChangeSignal();
}
BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index bf181cb4ad..07ae5fba86 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -225,14 +225,14 @@ public:
void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; }
std::string getAppearanceServiceURL() const;
+ typedef boost::function<void ()> attachments_changed_callback_t;
+ typedef boost::signals2::signal<void ()> attachments_changed_signal_t;
+ boost::signals2::connection setAttachmentsChangedCallback(attachments_changed_callback_t cb);
+
private:
-#ifdef APPEARANCEBAKE_AS_IN_AIS_QUEUE
void serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter);
-#else
- void serverAppearanceUpdateCoro();
-#endif
static void debugAppearanceUpdateCOF(const LLSD& content);
@@ -272,6 +272,8 @@ private:
LLTimer mInFlightTimer;
static bool mActive;
+ attachments_changed_signal_t mAttachmentsChangeSignal;
+
std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
// Set of temp attachment UUIDs that should be removed
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index b6d02ea2f8..950692a788 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -587,6 +587,7 @@ static void settings_to_globals()
LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures");
LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor");
+ LLVOVolume::sRiggedFactorMultiplier = gSavedSettings.getF32("RenderRiggedFactorMultiplier");
LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
LLVOTree::sTreeFactor = gSavedSettings.getF32("RenderTreeLODFactor");
@@ -696,7 +697,8 @@ LLAppViewer::LLAppViewer()
mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
mFastTimerLogThread(NULL),
mUpdater(new LLUpdaterService()),
- mSettingsLocationList(NULL)
+ mSettingsLocationList(NULL),
+ mIsFirstRun(false)
{
if(NULL != sInstance)
{
@@ -1220,6 +1222,8 @@ bool LLAppViewer::init()
boost::bind(&LLControlGroup::getU32, boost::ref(gSavedSettings), _1),
boost::bind(&LLControlGroup::declareU32, boost::ref(gSavedSettings), _1, _2, _3, LLControlVariable::PERSIST_ALWAYS));
+ showReleaseNotesIfRequired();
+
return true;
}
@@ -2483,7 +2487,10 @@ bool LLAppViewer::initConfiguration()
if (gSavedSettings.getBOOL("FirstRunThisInstall"))
{
- // Note that the "FirstRunThisInstall" settings is currently unused.
+ // Set firstrun flag to indicate that some further init actiona should be taken
+ // like determining screen DPI value and so on
+ mIsFirstRun = true;
+
gSavedSettings.setBOOL("FirstRunThisInstall", FALSE);
}
@@ -3140,7 +3147,8 @@ bool LLAppViewer::initWindow()
.min_width(gSavedSettings.getU32("MinWindowWidth"))
.min_height(gSavedSettings.getU32("MinWindowHeight"))
.fullscreen(gSavedSettings.getBOOL("FullScreen"))
- .ignore_pixel_depth(ignorePixelDepth);
+ .ignore_pixel_depth(ignorePixelDepth)
+ .first_run(mIsFirstRun);
gViewerWindow = new LLViewerWindow(window_params);
@@ -3438,6 +3446,12 @@ std::string LLAppViewer::getViewerInfoString() const
{
support << '\n' << LLTrans::getString("AboutTraffic", args);
}
+
+ // SLT timestamp
+ LLSD substitution;
+ substitution["datetime"] = (S32)time(NULL);//(S32)time_corrected();
+ support << "\n" << LLTrans::getString("AboutTime", substitution);
+
return support.str();
}
@@ -5793,6 +5807,18 @@ void LLAppViewer::launchUpdater()
// LLAppViewer::instance()->forceQuit();
}
+/**
+* Check if user is running a new version of the viewer.
+* Display the Release Notes if it's not overriden by the "UpdaterShowReleaseNotes" setting.
+*/
+void LLAppViewer::showReleaseNotesIfRequired()
+{
+ if (LLVersionInfo::getChannelAndVersion() != gLastRunVersion && gSavedSettings.getBOOL("UpdaterShowReleaseNotes"))
+ {
+ LLSD info(getViewerInfo());
+ LLWeb::loadURLInternal(info["VIEWER_RELEASE_NOTES_URL"]);
+ }
+}
//virtual
void LLAppViewer::setMasterSystemAudioMute(bool mute)
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index b5e674bd7b..d4af2440be 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -254,6 +254,8 @@ private:
void sendLogoutRequest();
void disconnectViewer();
+
+ void showReleaseNotesIfRequired();
// *FIX: the app viewer class should be some sort of singleton, no?
// Perhaps its child class is the singleton and this should be an abstract base.
@@ -316,6 +318,7 @@ private:
// llcorehttp library init/shutdown helper
LLAppCoreHttp mAppCoreHttp;
+ bool mIsFirstRun;
//---------------------------------------------
//*NOTE: Mani - legacy updater stuff
// Still useable?
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 00bc8ebe87..a6e745448a 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -476,13 +476,63 @@ void LLAvatarActions::kick(const LLUUID& id)
}
// static
+void LLAvatarActions::freezeAvatar(const LLUUID& id)
+{
+ std::string fullname;
+ gCacheName->getFullName(id, fullname);
+ LLSD payload;
+ payload["avatar_id"] = id;
+
+ if (!fullname.empty())
+ {
+ LLSD args;
+ args["AVATAR_NAME"] = fullname;
+ LLNotificationsUtil::add("FreezeAvatarFullname", args, payload, handleFreezeAvatar);
+ }
+ else
+ {
+ LLNotificationsUtil::add("FreezeAvatar", LLSD(), payload, handleFreezeAvatar);
+ }
+}
+
+// static
+void LLAvatarActions::ejectAvatar(const LLUUID& id, bool ban_enabled)
+{
+ std::string fullname;
+ gCacheName->getFullName(id, fullname);
+ LLSD payload;
+ payload["avatar_id"] = id;
+ payload["ban_enabled"] = ban_enabled;
+ LLSD args;
+ if (!fullname.empty())
+ {
+ args["AVATAR_NAME"] = fullname;
+ }
+
+ if (ban_enabled)
+ {
+ LLNotificationsUtil::add("EjectAvatarFullname", args, payload, handleEjectAvatar);
+ }
+ else
+ {
+ if (!fullname.empty())
+ {
+ LLNotificationsUtil::add("EjectAvatarFullnameNoBan", args, payload, handleEjectAvatar);
+ }
+ else
+ {
+ LLNotificationsUtil::add("EjectAvatarNoBan", LLSD(), payload, handleEjectAvatar);
+ }
+ }
+}
+
+// static
void LLAvatarActions::freeze(const LLUUID& id)
{
LLSD payload;
payload["avatar_id"] = id;
LLNotifications::instance().add("FreezeUser", LLSD(), payload, handleFreeze);
}
-
// static
void LLAvatarActions::unfreeze(const LLUUID& id)
{
@@ -1133,10 +1183,77 @@ bool LLAvatarActions::handleKick(const LLSD& notification, const LLSD& response)
}
return false;
}
-bool LLAvatarActions::handleFreeze(const LLSD& notification, const LLSD& response)
+
+bool LLAvatarActions::handleFreezeAvatar(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
+ if (0 == option || 1 == option)
+ {
+ U32 flags = 0x0;
+ if (1 == option)
+ {
+ // unfreeze
+ flags |= 0x1;
+ }
+ LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
+ LLMessageSystem* msg = gMessageSystem;
+
+ msg->newMessage("FreezeUser");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->nextBlock("Data");
+ msg->addUUID("TargetID", avatar_id );
+ msg->addU32("Flags", flags );
+ gAgent.sendReliableMessage();
+ }
+ return false;
+}
+
+bool LLAvatarActions::handleEjectAvatar(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (2 == option)
+ {
+ return false;
+ }
+ LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
+ bool ban_enabled = notification["payload"]["ban_enabled"].asBoolean();
+
+ if (0 == option)
+ {
+ LLMessageSystem* msg = gMessageSystem;
+ U32 flags = 0x0;
+ msg->newMessage("EjectUser");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID() );
+ msg->addUUID("SessionID", gAgent.getSessionID() );
+ msg->nextBlock("Data");
+ msg->addUUID("TargetID", avatar_id );
+ msg->addU32("Flags", flags );
+ gAgent.sendReliableMessage();
+ }
+ else if (ban_enabled)
+ {
+ LLMessageSystem* msg = gMessageSystem;
+
+ U32 flags = 0x1;
+ msg->newMessage("EjectUser");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID() );
+ msg->addUUID("SessionID", gAgent.getSessionID() );
+ msg->nextBlock("Data");
+ msg->addUUID("TargetID", avatar_id );
+ msg->addU32("Flags", flags );
+ gAgent.sendReliableMessage();
+ }
+ return false;
+}
+
+bool LLAvatarActions::handleFreeze(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
if (option == 0)
{
LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
@@ -1153,6 +1270,7 @@ bool LLAvatarActions::handleFreeze(const LLSD& notification, const LLSD& respons
}
return false;
}
+
bool LLAvatarActions::handleUnfreeze(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index bd0ac24e93..256d44d820 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -173,6 +173,9 @@ public:
*/
static void inviteToGroup(const LLUUID& id);
+ static void freezeAvatar(const LLUUID& id);
+
+ static void ejectAvatar(const LLUUID& id, bool ban_enabled = false);
/**
* Kick avatar off grid
*/
@@ -242,6 +245,8 @@ private:
static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response);
static bool handleRemove(const LLSD& notification, const LLSD& response);
static bool handlePay(const LLSD& notification, const LLSD& response, LLUUID avatar_id);
+ static bool handleFreezeAvatar(const LLSD& notification, const LLSD& response);
+ static bool handleEjectAvatar(const LLSD& notification, const LLSD& response);
static bool handleKick(const LLSD& notification, const LLSD& response);
static bool handleFreeze(const LLSD& notification, const LLSD& response);
static bool handleUnfreeze(const LLSD& notification, const LLSD& response);
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index 8846d1317d..513f25e301 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -140,6 +140,7 @@ LLAvatarList::LLAvatarList(const Params& p)
, mShowProfileBtn(p.show_profile_btn)
, mShowSpeakingIndicator(p.show_speaking_indicator)
, mShowPermissions(p.show_permissions_granted)
+, mShowCompleteName(false)
{
setCommitOnSelectionChange(true);
@@ -174,6 +175,11 @@ void LLAvatarList::setShowIcons(std::string param_name)
mShowIcons = gSavedSettings.getBOOL(mIconParamName);
}
+std::string LLAvatarList::getAvatarName(LLAvatarName av_name)
+{
+ return mShowCompleteName? av_name.getCompleteName(false) : av_name.getDisplayName();
+}
+
// virtual
void LLAvatarList::draw()
{
@@ -279,7 +285,7 @@ void LLAvatarList::refresh()
LLAvatarName av_name;
have_names &= LLAvatarNameCache::get(buddy_id, &av_name);
- if (!have_filter || findInsensitive(av_name.getDisplayName(), mNameFilter))
+ if (!have_filter || findInsensitive(getAvatarName(av_name), mNameFilter))
{
if (nadded >= ADD_LIMIT)
{
@@ -297,7 +303,7 @@ void LLAvatarList::refresh()
}
else
{
- std::string display_name = av_name.getDisplayName();
+ std::string display_name = getAvatarName(av_name);
addNewItem(buddy_id,
display_name.empty() ? waiting_str : display_name,
LLAvatarTracker::instance().isBuddyOnline(buddy_id));
@@ -327,7 +333,7 @@ void LLAvatarList::refresh()
const LLUUID& buddy_id = it->asUUID();
LLAvatarName av_name;
have_names &= LLAvatarNameCache::get(buddy_id, &av_name);
- if (!findInsensitive(av_name.getDisplayName(), mNameFilter))
+ if (!findInsensitive(getAvatarName(av_name), mNameFilter))
{
removeItemByUUID(buddy_id);
modified = true;
@@ -381,6 +387,7 @@ void LLAvatarList::updateAvatarNames()
for( std::vector<LLPanel*>::const_iterator it = items.begin(); it != items.end(); it++)
{
LLAvatarListItem* item = static_cast<LLAvatarListItem*>(*it);
+ item->setShowCompleteName(mShowCompleteName);
item->updateAvatarName();
}
mNeedUpdateNames = false;
@@ -400,7 +407,7 @@ bool LLAvatarList::filterHasMatches()
// If name has not been loaded yet we consider it as a match.
// When the name will be loaded the filter will be applied again(in refresh()).
- if (have_name && !findInsensitive(av_name.getDisplayName(), mNameFilter))
+ if (have_name && !findInsensitive(getAvatarName(av_name), mNameFilter))
{
continue;
}
@@ -434,6 +441,7 @@ S32 LLAvatarList::notifyParent(const LLSD& info)
void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_online, EAddPosition pos)
{
LLAvatarListItem* item = new LLAvatarListItem();
+ item->setShowCompleteName(mShowCompleteName);
// This sets the name as a side effect
item->setAvatarId(id, mSessionID, mIgnoreOnlineStatus);
item->setOnline(mIgnoreOnlineStatus ? true : is_online);
@@ -445,6 +453,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is
item->showSpeakingIndicator(mShowSpeakingIndicator);
item->setShowPermissions(mShowPermissions);
+
item->setDoubleClickCallback(boost::bind(&LLAvatarList::onItemDoubleClicked, this, _1, _2, _3, _4));
addItem(item, id, pos);
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 3542577ae3..1a672c279b 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -83,6 +83,7 @@ public:
void setShowIcons(std::string param_name);
bool getIconsVisible() const { return mShowIcons; }
const std::string getIconParamName() const{return mIconParamName;}
+ std::string getAvatarName(LLAvatarName av_name);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
@@ -100,6 +101,8 @@ public:
void addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name);
void handleDisplayNamesOptionChanged();
+ void setShowCompleteName(bool show) { mShowCompleteName = show;};
+
protected:
void refresh();
@@ -126,6 +129,7 @@ private:
bool mShowProfileBtn;
bool mShowSpeakingIndicator;
bool mShowPermissions;
+ bool mShowCompleteName;
LLTimer* mLITUpdateTimer; // last interaction time update timer
std::string mIconParamName;
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 3e6c817dd6..af3fac91bc 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -77,8 +77,10 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/)
mShowInfoBtn(true),
mShowProfileBtn(true),
mShowPermissions(false),
+ mShowCompleteName(false),
mHovered(false),
- mAvatarNameCacheConnection()
+ mAvatarNameCacheConnection(),
+ mGreyOutUsername("")
{
if (not_from_ui_factory)
{
@@ -399,14 +401,28 @@ void LLAvatarListItem::updateAvatarName()
void LLAvatarListItem::setNameInternal(const std::string& name, const std::string& highlight)
{
- LLTextUtil::textboxSetHighlightedVal(mAvatarName, mAvatarNameStyle, name, highlight);
+ if(mShowCompleteName && highlight.empty())
+ {
+ LLTextUtil::textboxSetGreyedVal(mAvatarName, mAvatarNameStyle, name, mGreyOutUsername);
+ }
+ else
+ {
+ LLTextUtil::textboxSetHighlightedVal(mAvatarName, mAvatarNameStyle, name, highlight);
+ }
}
void LLAvatarListItem::onAvatarNameCache(const LLAvatarName& av_name)
{
mAvatarNameCacheConnection.disconnect();
- setAvatarName(av_name.getDisplayName());
+ mGreyOutUsername = "";
+ std::string name_string = mShowCompleteName? av_name.getCompleteName(false) : av_name.getDisplayName();
+ if(av_name.getCompleteName() != av_name.getUserName())
+ {
+ mGreyOutUsername = "[ " + av_name.getUserName(true) + " ]";
+ LLStringUtil::toLower(mGreyOutUsername);
+ }
+ setAvatarName(name_string);
setAvatarToolTip(av_name.getUserName());
//requesting the list to resort
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index 7ef35a746e..36d18114aa 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -106,6 +106,7 @@ public:
void setShowPermissions(bool show) { mShowPermissions = show; };
void showLastInteractionTime(bool show);
void setAvatarIconVisible(bool visible);
+ void setShowCompleteName(bool show) { mShowCompleteName = show;};
const LLUUID& getAvatarId() const;
std::string getAvatarName() const;
@@ -218,6 +219,9 @@ private:
/// true when the mouse pointer is hovering over this item
bool mHovered;
+ bool mShowCompleteName;
+ std::string mGreyOutUsername;
+
void fetchAvatarName();
boost::signals2::connection mAvatarNameCacheConnection;
diff --git a/indra/newview/llavatarrendernotifier.cpp b/indra/newview/llavatarrendernotifier.cpp
index a13e142e16..24934fdb73 100644
--- a/indra/newview/llavatarrendernotifier.cpp
+++ b/indra/newview/llavatarrendernotifier.cpp
@@ -63,7 +63,7 @@ mLatestAgentComplexity(0),
mLatestOverLimitPct(0.0f),
mShowOverLimitAgents(false),
mNotifyOutfitLoading(false),
-mLastCofVersion(-1),
+mLastCofVersion(LLViewerInventoryCategory::VERSION_UNKNOWN),
mLastOutfitRezStatus(-1),
mLastSkeletonSerialNum(-1)
{
@@ -207,8 +207,8 @@ void LLAvatarRenderNotifier::updateNotificationState()
mLastSkeletonSerialNum = gAgentAvatarp->mLastSkeletonSerialNum;
}
else if (mLastCofVersion >= 0
- && (mLastCofVersion != gAgentAvatarp->mLastUpdateRequestCOFVersion
- || mLastSkeletonSerialNum != gAgentAvatarp->mLastSkeletonSerialNum))
+ && (mLastCofVersion != LLAppearanceMgr::instance().getCOFVersion()
+ || mLastSkeletonSerialNum != gAgentAvatarp->mLastSkeletonSerialNum))
{
// version mismatch in comparison to previous outfit - outfit changed
mNotifyOutfitLoading = true;
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 00fa6dd979..54c6c985d6 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -311,7 +311,8 @@ LLWString LLChatBar::stripChannelNumber(const LLWString &mesg, S32* channel)
}
else if (mesg[0] == '/'
&& mesg[1]
- && LLStringOps::isDigit(mesg[1]))
+ && (LLStringOps::isDigit(mesg[1])
+ || (mesg[1] == '-' && mesg[2] && LLStringOps::isDigit(mesg[2]))))
{
// This a special "/20" speak on a channel
S32 pos = 0;
@@ -325,7 +326,7 @@ LLWString LLChatBar::stripChannelNumber(const LLWString &mesg, S32* channel)
channel_string.push_back(c);
pos++;
}
- while(c && pos < 64 && LLStringOps::isDigit(c));
+ while(c && pos < 64 && (LLStringOps::isDigit(c) || (pos == 1 && c == '-')));
// Move the pointer forward to the first non-whitespace char
// Check isspace before looping, so we can handle "/33foo"
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 4b426081d0..5d2997688f 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -156,6 +156,10 @@ public:
LLFloaterSidePanelContainer::showPanel("people", "panel_people",
LLSD().with("people_panel_tab_name", "blocked_panel").with("blocked_to_select", getAvatarId()));
}
+ else if (level == "unblock")
+ {
+ LLMuteList::getInstance()->remove(LLMute(getAvatarId(), mFrom, LLMute::OBJECT));
+ }
else if (level == "map")
{
std::string url = "secondlife://" + mObjectData["slurl"].asString();
@@ -169,6 +173,20 @@ public:
}
+ bool onObjectIconContextMenuItemVisible(const LLSD& userdata)
+ {
+ std::string level = userdata.asString();
+ if (level == "is_blocked")
+ {
+ return LLMuteList::getInstance()->isMuted(getAvatarId(), mFrom, LLMute::flagTextChat);
+ }
+ else if (level == "not_blocked")
+ {
+ return !LLMuteList::getInstance()->isMuted(getAvatarId(), mFrom, LLMute::flagTextChat);
+ }
+ return false;
+ }
+
void onAvatarIconContextMenuItemClicked(const LLSD& userdata)
{
std::string level = userdata.asString();
@@ -275,6 +293,7 @@ public:
registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2));
registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2));
registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2));
+ registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2));
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mPopupMenuHandleAvatar = menu->getHandle();
@@ -719,6 +738,8 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
editor_params.trusted_content = false;
mEditor = LLUICtrlFactory::create<LLTextEditor>(editor_params, this);
mEditor->setIsFriendCallback(LLAvatarActions::isFriend);
+ mEditor->setIsObjectBlockedCallback(boost::bind(&LLMuteList::isMuted, LLMuteList::getInstance(), _1, _2, 0));
+
}
LLSD LLChatHistory::getValue() const
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 219bcf0eb0..7721e67290 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -62,6 +62,57 @@
#include "llviewerassetupload.h"
#include "llcorehttputil.h"
+namespace
+{
+
+ const std::string QUEUE_EVENTPUMP_NAME("ScriptActionQueue");
+
+
+ class ObjectInventoryFetcher: public LLVOInventoryListener
+ {
+ public:
+ typedef boost::shared_ptr<ObjectInventoryFetcher> ptr_t;
+
+ ObjectInventoryFetcher(LLEventPump &pump, LLViewerObject* object, void* user_data) :
+ mPump(pump),
+ LLVOInventoryListener()
+ {
+ registerVOInventoryListener(object, this);
+ }
+
+ virtual void inventoryChanged(LLViewerObject* object,
+ LLInventoryObject::object_list_t* inventory,
+ S32 serial_num,
+ void* user_data);
+
+ void fetchInventory()
+ {
+ requestVOInventory();
+ }
+
+ const LLInventoryObject::object_list_t & getInventoryList() const { return mInventoryList; }
+
+ private:
+ LLInventoryObject::object_list_t mInventoryList;
+ LLEventPump & mPump;
+ };
+
+ class HandleScriptUserData
+ {
+ public:
+ HandleScriptUserData(const std::string &pumpname) :
+ mPumpname(pumpname)
+ { }
+
+ const std::string &getPumpName() const { return mPumpname; }
+
+ private:
+ std::string mPumpname;
+ };
+
+
+}
+
// *NOTE$: A minor specialization of LLScriptAssetUpload, it does not require a buffer
// (and does not save a buffer to the vFS) and it finds the compile queue window and
// displays a compiling message.
@@ -149,47 +200,6 @@ BOOL LLFloaterScriptQueue::postBuild()
return TRUE;
}
-// This is the callback method for the viewer object currently being
-// worked on.
-// NOT static, virtual!
-void LLFloaterScriptQueue::inventoryChanged(LLViewerObject* viewer_object,
- LLInventoryObject::object_list_t* inv,
- S32,
- void* q_id)
-{
- LL_INFOS() << "LLFloaterScriptQueue::inventoryChanged() for object "
- << viewer_object->getID() << LL_ENDL;
-
- //Remove this listener from the object since its
- //listener callback is now being executed.
-
- //We remove the listener here because the function
- //removeVOInventoryListener removes the listener from a ViewerObject
- //which it internally stores.
-
- //If we call this further down in the function, calls to handleInventory
- //and nextObject may update the internally stored viewer object causing
- //the removal of the incorrect listener from an incorrect object.
-
- //Fixes SL-6119:Recompile scripts fails to complete
- removeVOInventoryListener();
-
- if (viewer_object && inv && (viewer_object->getID() == mCurrentObjectID) )
- {
- handleInventory(viewer_object, inv);
- }
- else
- {
- // something went wrong...
- // note that we're not working on this one, and move onto the
- // next object in the list.
- LL_WARNS() << "No inventory for " << mCurrentObjectID
- << LL_ENDL;
- nextObject();
- }
-}
-
-
// static
void LLFloaterScriptQueue::onCloseBtn(void* user_data)
{
@@ -197,9 +207,10 @@ void LLFloaterScriptQueue::onCloseBtn(void* user_data)
self->closeFloater();
}
-void LLFloaterScriptQueue::addObject(const LLUUID& id)
+void LLFloaterScriptQueue::addObject(const LLUUID& id, std::string name)
{
- mObjectIDs.push_back(id);
+ ObjectData obj = { id, name };
+ mObjectList.push_back(obj);
}
BOOL LLFloaterScriptQueue::start()
@@ -208,7 +219,7 @@ BOOL LLFloaterScriptQueue::start()
LLStringUtil::format_map_t args;
args["[START]"] = mStartString;
- args["[COUNT]"] = llformat ("%d", mObjectIDs.size());
+ args["[COUNT]"] = llformat ("%d", mObjectList.size());
buffer = getString ("Starting", args);
getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM);
@@ -216,74 +227,24 @@ BOOL LLFloaterScriptQueue::start()
return startQueue();
}
-BOOL LLFloaterScriptQueue::isDone() const
+void LLFloaterScriptQueue::addProcessingMessage(const std::string &message, const LLSD &args)
{
- return (mCurrentObjectID.isNull() && (mObjectIDs.size() == 0));
-}
+ std::string buffer(LLTrans::getString(message, args));
-// go to the next object. If no objects left, it falls out silently
-// and waits to be killed by the window being closed.
-BOOL LLFloaterScriptQueue::nextObject()
-{
- U32 count;
- BOOL successful_start = FALSE;
- do
- {
- count = mObjectIDs.size();
- LL_INFOS() << "LLFloaterScriptQueue::nextObject() - " << count
- << " objects left to process." << LL_ENDL;
- mCurrentObjectID.setNull();
- if(count > 0)
- {
- successful_start = popNext();
- }
- LL_INFOS() << "LLFloaterScriptQueue::nextObject() "
- << (successful_start ? "successful" : "unsuccessful")
- << LL_ENDL;
- } while((mObjectIDs.size() > 0) && !successful_start);
- if(isDone() && !mDone)
- {
- mDone = true;
- getChild<LLScrollListCtrl>("queue output")->addSimpleElement(getString("Done"), ADD_BOTTOM);
- getChildView("close")->setEnabled(TRUE);
- }
- return successful_start;
+ getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM);
}
-// returns true if the queue has started, otherwise false. This
-// method pops the top object off of the queue.
-BOOL LLFloaterScriptQueue::popNext()
+void LLFloaterScriptQueue::addStringMessage(const std::string &message)
{
- // get the first element off of the container, and attempt to get
- // the inventory.
- BOOL rv = FALSE;
- S32 count = mObjectIDs.size();
- if(mCurrentObjectID.isNull() && (count > 0))
- {
- mCurrentObjectID = mObjectIDs.at(0);
- LL_INFOS() << "LLFloaterScriptQueue::popNext() - mCurrentID: "
- << mCurrentObjectID << LL_ENDL;
- mObjectIDs.erase(mObjectIDs.begin());
- LLViewerObject* obj = gObjectList.findObject(mCurrentObjectID);
- if(obj)
- {
- LL_INFOS() << "LLFloaterScriptQueue::popNext() requesting inv for "
- << mCurrentObjectID << LL_ENDL;
- LLUUID* id = new LLUUID(getKey().asUUID());
- registerVOInventoryListener(obj,id);
- requestVOInventory();
- rv = TRUE;
- }
- }
- return rv;
+ getChild<LLScrollListCtrl>("queue output")->addSimpleElement(message, ADD_BOTTOM);
}
-BOOL LLFloaterScriptQueue::startQueue()
+
+BOOL LLFloaterScriptQueue::isDone() const
{
- return nextObject();
+ return (mCurrentObjectID.isNull() && (mObjectList.size() == 0));
}
-
///----------------------------------------------------------------------------
/// Class LLFloaterCompileQueue
///----------------------------------------------------------------------------
@@ -306,7 +267,7 @@ void LLFloaterCompileQueue::experienceIdsReceived( const LLSD& content )
{
mExperienceIds.insert(it->asUUID());
}
- nextObject();
+// nextObject();
}
BOOL LLFloaterCompileQueue::hasExperience( const LLUUID& id ) const
@@ -314,188 +275,289 @@ BOOL LLFloaterCompileQueue::hasExperience( const LLUUID& id ) const
return mExperienceIds.find(id) != mExperienceIds.end();
}
+// //Attempt to record this asset ID. If it can not be inserted into the set
+// //then it has already been processed so return false.
+// bool LLFloaterCompileQueue::checkAssetId(const LLUUID &assetId)
+// {
+// std::pair<uuid_list_t::iterator, bool> result = mAssetIds.insert(assetId);
+// return result.second;
+// }
-void LLFloaterCompileQueue::handleInventory(LLViewerObject *viewer_object,
- LLInventoryObject::object_list_t* inv)
+void LLFloaterCompileQueue::handleHTTPResponse(std::string pumpName, const LLSD &expresult)
{
- // find all of the lsl, leaving off duplicates. We'll remove
- // all matching asset uuids on compilation success.
+ LLEventPumps::instance().post(pumpName, expresult);
+}
- typedef std::multimap<LLUUID, LLPointer<LLInventoryItem> > uuid_item_map;
- uuid_item_map asset_item_map;
+// *TODO: handleSCriptRetrieval is passed into the VFS via a legacy C function pointer
+// future project would be to convert these to C++ callables (std::function<>) so that
+// we can use bind and remove the userData parameter.
+//
+void LLFloaterCompileQueue::handleScriptRetrieval(LLVFS *vfs, const LLUUID& assetId,
+ LLAssetType::EType type, void* userData, S32 status, LLExtStat extStatus)
+{
+ LLSD result(LLSD::emptyMap());
- LLInventoryObject::object_list_t::const_iterator it = inv->begin();
- LLInventoryObject::object_list_t::const_iterator end = inv->end();
- for ( ; it != end; ++it)
- {
- if((*it)->getType() == LLAssetType::AT_LSL_TEXT)
- {
- LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
- // Check permissions before allowing the user to retrieve data.
- if (item->getPermissions().allowModifyBy(gAgent.getID(), gAgent.getGroupID()) &&
- item->getPermissions().allowCopyBy(gAgent.getID(), gAgent.getGroupID()) )
- {
- LLPointer<LLViewerInventoryItem> script = new LLViewerInventoryItem(item);
- mCurrentScripts.push_back(script);
- asset_item_map.insert(std::make_pair(item->getAssetUUID(), item));
- }
- }
- }
+ result["asset_id"] = assetId;
+ if (status)
+ {
+ result["error"] = status;
+
+ if (status == LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE)
+ {
+ result["message"] = LLTrans::getString("CompileQueueProblemDownloading") + (":");
+ result["alert"] = LLTrans::getString("CompileQueueScriptNotFound");
+ }
+ else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
+ {
+ result["message"] = LLTrans::getString("CompileQueueInsufficientPermFor") + (":");
+ result["alert"] = LLTrans::getString("CompileQueueInsufficientPermDownload");
+ }
+ else
+ {
+ result["message"] = LLTrans::getString("CompileQueueUnknownFailure");
+ }
+ }
- if (asset_item_map.empty())
- {
- // There are no scripts in this object. move on.
- nextObject();
- }
- else
- {
- // request all of the assets.
- uuid_item_map::iterator iter;
- for(iter = asset_item_map.begin(); iter != asset_item_map.end(); iter++)
- {
- LLInventoryItem *itemp = iter->second;
- LLScriptQueueData* datap = new LLScriptQueueData(getKey().asUUID(),
- viewer_object->getID(), itemp);
-
- LLExperienceCache::instance().fetchAssociatedExperience(itemp->getParentUUID(), itemp->getUUID(),
- boost::bind(&LLFloaterCompileQueue::requestAsset, datap, _1));
- }
- }
-}
+ LLEventPumps::instance().post(((HandleScriptUserData *)userData)->getPumpName(), result);
+}
-void LLFloaterCompileQueue::requestAsset( LLScriptQueueData* datap, const LLSD& experience )
+/*static*/
+void LLFloaterCompileQueue::processExperienceIdResults(LLSD result, LLUUID parent)
{
- LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", datap->mQueueID);
- if(!queue)
- {
- delete datap;
- return;
- }
- if(experience.has(LLExperienceCache::EXPERIENCE_ID))
- {
- datap->mExperienceId=experience[LLExperienceCache::EXPERIENCE_ID].asUUID();
- if(!queue->hasExperience(datap->mExperienceId))
- {
- std::string buffer = LLTrans::getString("CompileNoExperiencePerm", LLSD::emptyMap()
- .with("SCRIPT", datap->mItem->getName())
- .with("EXPERIENCE", experience[LLExperienceCache::NAME].asString()));
-
- queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM);
- queue->removeItemByItemID(datap->mItem->getUUID());
- delete datap;
- return;
- }
- }
- //LL_INFOS() << "ITEM NAME 2: " << names.get(i) << LL_ENDL;
- gAssetStorage->getInvItemAsset(datap->mHost,
- gAgent.getID(),
- gAgent.getSessionID(),
- datap->mItem->getPermissions().getOwner(),
- datap->mTaskId,
- datap->mItem->getUUID(),
- datap->mItem->getAssetUUID(),
- datap->mItem->getType(),
- LLFloaterCompileQueue::scriptArrived,
- (void*)datap);
+ LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", parent);
+ if (!queue)
+ return;
+
+ queue->experienceIdsReceived(result["experience_ids"]);
+
+ LLHandle<LLFloaterScriptQueue> hFloater(queue->getDerivedHandle<LLFloaterScriptQueue>());
+
+ fnQueueAction_t fn = boost::bind(LLFloaterCompileQueue::processScript,
+ queue->getDerivedHandle<LLFloaterCompileQueue>(), _1, _2, _3);
+
+
+ LLCoros::instance().launch("ScriptQueueCompile", boost::bind(LLFloaterScriptQueue::objectScriptProcessingQueueCoro,
+ queue->mStartString,
+ hFloater,
+ queue->mObjectList,
+ fn));
+
}
-/*static*/
-void LLFloaterCompileQueue::finishLSLUpload(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, std::string scriptName, LLUUID queueId)
+bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloater,
+ const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)
{
+ LLSD result;
+ LLFloaterCompileQueue *that = hfloater.get();
+ bool monocompile = that->mMono;
+ F32 fetch_timeout = gSavedSettings.getF32("QueueInventoryFetchTimeout");
+
+ if (!that)
+ return false;
- LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", LLSD(queueId));
- if (queue)
+ // Initial test to see if we can (or should) attempt to compile the script.
+ LLInventoryItem *item = dynamic_cast<LLInventoryItem *>(inventory);
{
- // Bytecode save completed
- if (response["compiled"])
+
+ if (!item->getPermissions().allowModifyBy(gAgent.getID(), gAgent.getGroupID()) ||
+ !item->getPermissions().allowCopyBy(gAgent.getID(), gAgent.getGroupID()))
{
- std::string message = std::string("Compilation of \"") + scriptName + std::string("\" succeeded");
+ std::string buffer = "Skipping: " + item->getName() + "(Permissions)";
+ that->addStringMessage(buffer);
+ return true;
+ }
- queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(message, ADD_BOTTOM);
- LL_INFOS() << message << LL_ENDL;
+// if (!that->checkAssetId(item->getAssetUUID()))
+// {
+// std::string buffer = "Skipping: " + item->getName() + "(Repeat)";
+// that->addStringMessage(buffer);
+// return true;
+// }
+ }
+ that = NULL;
+
+ // Attempt to retrieve the experience
+ LLUUID experienceId;
+ {
+ LLExperienceCache::instance().fetchAssociatedExperience(inventory->getParentUUID(), inventory->getUUID(),
+ boost::bind(&LLFloaterCompileQueue::handleHTTPResponse, pump.getName(), _1));
+
+ result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout,
+ LLSD().with("timeout", LLSD::Boolean(true)));
+
+ that = hfloater.get();
+ if (!that)
+ {
+ return false;
}
- else
+
+ if (result.has("timeout") && result["timeout"].asBoolean())
{
- LLSD compile_errors = response["errors"];
- for (LLSD::array_const_iterator line = compile_errors.beginArray();
- line < compile_errors.endArray(); line++)
- {
- std::string str = line->asString();
- str.erase(std::remove(str.begin(), str.end(), '\n'), str.end());
+ LLStringUtil::format_map_t args;
+ args["[OBJECT_NAME]"] = inventory->getName();
+ std::string buffer = that->getString("Timeout", args);
+ that->addStringMessage(buffer);
+ return true;
+ }
- queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(str, ADD_BOTTOM);
+ if (result.has(LLExperienceCache::EXPERIENCE_ID))
+ {
+ experienceId = result[LLExperienceCache::EXPERIENCE_ID].asUUID();
+ if (!that->hasExperience(experienceId))
+ {
+ that->addProcessingMessage("CompileNoExperiencePerm", LLSD()
+ .with("SCRIPT", inventory->getName())
+ .with("EXPERIENCE", result[LLExperienceCache::NAME].asString()));
+ return true;
}
- LL_INFOS() << response["errors"] << LL_ENDL;
}
}
+ that = NULL;
+
+ {
+ HandleScriptUserData userData(pump.getName());
+
+
+ // request the asset
+ gAssetStorage->getInvItemAsset(LLHost(),
+ gAgent.getID(),
+ gAgent.getSessionID(),
+ item->getPermissions().getOwner(),
+ object->getID(),
+ item->getUUID(),
+ item->getAssetUUID(),
+ item->getType(),
+ &LLFloaterCompileQueue::handleScriptRetrieval,
+ &userData);
+
+ result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout,
+ LLSD().with("timeout", LLSD::Boolean(true)));
+ }
+
+ that = hfloater.get();
+ if (!that)
+ {
+ return false;
+ }
+
+ if (result.has("timeout"))
+ {
+ if (result.has("timeout") && result["timeout"].asBoolean())
+ {
+ LLStringUtil::format_map_t args;
+ args["[OBJECT_NAME]"] = inventory->getName();
+ std::string buffer = that->getString("Timeout", args);
+ that->addStringMessage(buffer);
+ return true;
+ }
+ }
+
+ if (result.has("error"))
+ {
+ LL_WARNS("SCRIPTQ") << "Inventory fetch returned with error. Code: " << result["error"].asString() << LL_ENDL;
+ std::string buffer = result["message"].asString() + " " + inventory->getName();
+ that->addStringMessage(buffer);
+
+ if (result.has("alert"))
+ {
+ LLSD args;
+ args["MESSAGE"] = result["alert"].asString();
+ LLNotificationsUtil::add("SystemMessage", args);
+ }
+ return true;
+ }
+
+ LLUUID assetId = result["asset_id"];
+ that = NULL;
+
+
+ std::string url = object->getRegion()->getCapability("UpdateScriptTask");
+
+
+ {
+ LLResourceUploadInfo::ptr_t uploadInfo(new LLQueuedScriptAssetUpload(object->getID(),
+ inventory->getUUID(),
+ assetId,
+ monocompile ? LLScriptAssetUpload::MONO : LLScriptAssetUpload::LSL2,
+ true,
+ inventory->getName(),
+ LLUUID(),
+ experienceId,
+ boost::bind(&LLFloaterCompileQueue::handleHTTPResponse, pump.getName(), _4)));
+
+ LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
+ }
+
+ result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout, LLSD().with("timeout", LLSD::Boolean(true)));
+
+ that = hfloater.get();
+ if (!that)
+ {
+ return false;
+ }
+
+ if (result.has("timeout"))
+ {
+ if (result.has("timeout") && result["timeout"].asBoolean())
+ {
+ LLStringUtil::format_map_t args;
+ args["[OBJECT_NAME]"] = inventory->getName();
+ std::string buffer = that->getString("Timeout", args);
+ that->addStringMessage(buffer);
+ return true;
+ }
+ }
+
+ // Bytecode save completed
+ if (result["compiled"])
+ {
+ std::string buffer = std::string("Compilation of \"") + inventory->getName() + std::string("\" succeeded");
+
+ that->addStringMessage(buffer);
+ LL_INFOS() << buffer << LL_ENDL;
+ }
+ else
+ {
+ LLSD compile_errors = result["errors"];
+ std::string buffer = std::string("Compilation of \"") + inventory->getName() + std::string("\" failed:");
+ that->addStringMessage(buffer);
+ for (LLSD::array_const_iterator line = compile_errors.beginArray();
+ line < compile_errors.endArray(); line++)
+ {
+ std::string str = line->asString();
+ str.erase(std::remove(str.begin(), str.end(), '\n'), str.end());
+
+ that->addStringMessage(str);
+ }
+ LL_INFOS() << result["errors"] << LL_ENDL;
+ }
+
+ return true;
}
-// This is the callback for when each script arrives
-// static
-void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
- LLAssetType::EType type,
- void* user_data, S32 status, LLExtStat ext_status)
+bool LLFloaterCompileQueue::startQueue()
{
- LL_INFOS() << "LLFloaterCompileQueue::scriptArrived()" << LL_ENDL;
- LLScriptQueueData* data = (LLScriptQueueData*)user_data;
- if(!data)
- {
- return;
- }
- LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", data->mQueueID);
-
- std::string buffer;
- if(queue && (0 == status))
- {
- LLViewerObject* object = gObjectList.findObject(data->mTaskId);
- if (object)
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ std::string lookup_url = region->getCapability("GetCreatorExperiences");
+ if (!lookup_url.empty())
{
- std::string url = object->getRegion()->getCapability("UpdateScriptTask");
- std::string scriptName = data->mItem->getName();
-
- LLBufferedAssetUploadInfo::taskUploadFinish_f proc = boost::bind(&LLFloaterCompileQueue::finishLSLUpload, _1, _2, _3, _4,
- scriptName, data->mQueueID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t success =
+ boost::bind(&LLFloaterCompileQueue::processExperienceIdResults, _1, getKey().asUUID());
- LLResourceUploadInfo::ptr_t uploadInfo(new LLQueuedScriptAssetUpload(data->mTaskId, data->mItem->getUUID(), asset_id,
- (queue->mMono) ? LLScriptAssetUpload::MONO : LLScriptAssetUpload::LSL2,
- true, scriptName, data->mQueueID, data->mExperienceId, proc));
+ LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t failure =
+ boost::bind(&LLFloaterCompileQueue::processExperienceIdResults, LLSD(), getKey().asUUID());
- LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
+ LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(lookup_url,
+ success, failure);
+ return TRUE;
}
- }
- else
- {
- if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status )
- {
- LLSD args;
- args["MESSAGE"] = LLTrans::getString("CompileQueueScriptNotFound");
- LLNotificationsUtil::add("SystemMessage", args);
-
- buffer = LLTrans::getString("CompileQueueProblemDownloading") + (": ") + data->mItem->getName();
- }
- else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
- {
- LLSD args;
- args["MESSAGE"] = LLTrans::getString("CompileQueueInsufficientPermDownload");
- LLNotificationsUtil::add("SystemMessage", args);
-
- buffer = LLTrans::getString("CompileQueueInsufficientPermFor") + (": ") + data->mItem->getName();
- }
- else
- {
- buffer = LLTrans::getString("CompileQueueUnknownFailure") + (" ") + data->mItem->getName();
- }
-
- LL_WARNS() << "Problem downloading script asset." << LL_ENDL;
- if(queue) queue->removeItemByItemID(data->mItem->getUUID());
- }
- if(queue && (buffer.size() > 0))
- {
- queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM);
- }
- delete data;
+ }
+
+ return true;
}
@@ -514,40 +576,42 @@ LLFloaterResetQueue::~LLFloaterResetQueue()
{
}
-void LLFloaterResetQueue::handleInventory(LLViewerObject* viewer_obj,
- LLInventoryObject::object_list_t* inv)
+bool LLFloaterResetQueue::resetObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater,
+ const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)
+{
+ LLFloaterScriptQueue *that = hfloater.get();
+ if (that)
+ {
+ std::string buffer;
+ buffer = that->getString("Resetting") + (": ") + inventory->getName();
+ that->addStringMessage(buffer);
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_ScriptReset);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_Script);
+ msg->addUUIDFast(_PREHASH_ObjectID, object->getID());
+ msg->addUUIDFast(_PREHASH_ItemID, inventory->getUUID());
+ msg->sendReliable(object->getRegion()->getHost());
+
+ return true;
+}
+
+bool LLFloaterResetQueue::startQueue()
{
- // find all of the lsl, leaving off duplicates. We'll remove
- // all matching asset uuids on compilation success.
+ fnQueueAction_t fn = boost::bind(LLFloaterResetQueue::resetObjectScripts,
+ getDerivedHandle<LLFloaterScriptQueue>(), _1, _2, _3);
- LLInventoryObject::object_list_t::const_iterator it = inv->begin();
- LLInventoryObject::object_list_t::const_iterator end = inv->end();
- for ( ; it != end; ++it)
- {
- if((*it)->getType() == LLAssetType::AT_LSL_TEXT)
- {
- LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
-
- if (object)
- {
- LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
- std::string buffer;
- buffer = getString("Resetting") + (": ") + item->getName();
- getChild<LLScrollListCtrl>("queue output")->addSimpleElement(buffer, ADD_BOTTOM);
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_ScriptReset);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_Script);
- msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID());
- msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID());
- msg->sendReliable(object->getRegion()->getHost());
- }
- }
- }
+ LLCoros::instance().launch("ScriptResetQueue", boost::bind(LLFloaterScriptQueue::objectScriptProcessingQueueCoro,
+ mStartString,
+ getDerivedHandle<LLFloaterScriptQueue>(),
+ mObjectList,
+ fn));
- nextObject();
+ return true;
}
///----------------------------------------------------------------------------
@@ -565,44 +629,46 @@ LLFloaterRunQueue::~LLFloaterRunQueue()
{
}
-void LLFloaterRunQueue::handleInventory(LLViewerObject* viewer_obj,
- LLInventoryObject::object_list_t* inv)
+bool LLFloaterRunQueue::runObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater,
+ const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)
{
- // find all of the lsl, leaving off duplicates. We'll remove
- // all matching asset uuids on compilation success.
- LLInventoryObject::object_list_t::const_iterator it = inv->begin();
- LLInventoryObject::object_list_t::const_iterator end = inv->end();
- for ( ; it != end; ++it)
- {
- if((*it)->getType() == LLAssetType::AT_LSL_TEXT)
- {
- LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
-
- if (object)
- {
- LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
- LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
- std::string buffer;
- buffer = getString("Running") + (": ") + item->getName();
- list->addSimpleElement(buffer, ADD_BOTTOM);
-
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_SetScriptRunning);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_Script);
- msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID());
- msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID());
- msg->addBOOLFast(_PREHASH_Running, TRUE);
- msg->sendReliable(object->getRegion()->getHost());
- }
- }
- }
+ LLFloaterScriptQueue *that = hfloater.get();
+ if (that)
+ {
+ std::string buffer;
+ buffer = that->getString("Running") + (": ") + inventory->getName();
+ that->addStringMessage(buffer);
+ }
- nextObject();
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_SetScriptRunning);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_Script);
+ msg->addUUIDFast(_PREHASH_ObjectID, object->getID());
+ msg->addUUIDFast(_PREHASH_ItemID, inventory->getUUID());
+ msg->addBOOLFast(_PREHASH_Running, TRUE);
+ msg->sendReliable(object->getRegion()->getHost());
+
+ return true;
}
+bool LLFloaterRunQueue::startQueue()
+{
+ LLHandle<LLFloaterScriptQueue> hFloater(getDerivedHandle<LLFloaterScriptQueue>());
+ fnQueueAction_t fn = boost::bind(LLFloaterRunQueue::runObjectScripts, hFloater, _1, _2, _3);
+
+ LLCoros::instance().launch("ScriptRunQueue", boost::bind(LLFloaterScriptQueue::objectScriptProcessingQueueCoro,
+ mStartString,
+ hFloater,
+ mObjectList,
+ fn));
+
+ return true;
+}
+
+
///----------------------------------------------------------------------------
/// Class LLFloaterNotRunQueue
///----------------------------------------------------------------------------
@@ -618,96 +684,171 @@ LLFloaterNotRunQueue::~LLFloaterNotRunQueue()
{
}
-void LLFloaterCompileQueue::removeItemByItemID(const LLUUID& asset_id)
+bool LLFloaterNotRunQueue::stopObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater,
+ const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)
{
- LL_INFOS() << "LLFloaterCompileQueue::removeItemByAssetID()" << LL_ENDL;
- for(S32 i = 0; i < mCurrentScripts.size(); )
- {
- if(asset_id == mCurrentScripts.at(i)->getUUID())
- {
- vector_replace_with_last(mCurrentScripts, mCurrentScripts.begin() + i);
- }
- else
- {
- ++i;
- }
- }
- if(mCurrentScripts.empty())
- {
- nextObject();
- }
+ LLFloaterScriptQueue *that = hfloater.get();
+ if (that)
+ {
+ std::string buffer;
+ buffer = that->getString("NotRunning") + (": ") + inventory->getName();
+ that->addStringMessage(buffer);
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_SetScriptRunning);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_Script);
+ msg->addUUIDFast(_PREHASH_ObjectID, object->getID());
+ msg->addUUIDFast(_PREHASH_ItemID, inventory->getUUID());
+ msg->addBOOLFast(_PREHASH_Running, FALSE);
+ msg->sendReliable(object->getRegion()->getHost());
+
+ return true;
}
-BOOL LLFloaterCompileQueue::startQueue()
+bool LLFloaterNotRunQueue::startQueue()
{
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- std::string lookup_url=region->getCapability("GetCreatorExperiences");
- if(!lookup_url.empty())
- {
- LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t success =
- boost::bind(&LLFloaterCompileQueue::processExperienceIdResults, _1, getKey().asUUID());
+ LLHandle<LLFloaterScriptQueue> hFloater(getDerivedHandle<LLFloaterScriptQueue>());
- LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t failure =
- boost::bind(&LLFloaterCompileQueue::processExperienceIdResults, LLSD(), getKey().asUUID());
+ fnQueueAction_t fn = boost::bind(&LLFloaterNotRunQueue::stopObjectScripts, hFloater, _1, _2, _3);
+ LLCoros::instance().launch("ScriptQueueNotRun", boost::bind(LLFloaterScriptQueue::objectScriptProcessingQueueCoro,
+ mStartString,
+ hFloater,
+ mObjectList,
+ fn));
- LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(lookup_url,
- success, failure);
- return TRUE;
- }
- }
- return nextObject();
+ return true;
}
-/*static*/
-void LLFloaterCompileQueue::processExperienceIdResults(LLSD result, LLUUID parent)
+///----------------------------------------------------------------------------
+/// Local function definitions
+///----------------------------------------------------------------------------
+void ObjectInventoryFetcher::inventoryChanged(LLViewerObject* object,
+ LLInventoryObject::object_list_t* inventory, S32 serial_num, void* user_data)
{
- LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", parent);
- if (!queue)
- return;
+ mInventoryList.clear();
+ mInventoryList.assign(inventory->begin(), inventory->end());
+
+ mPump.post(LLSD().with("changed", LLSD::Boolean(true)));
- queue->experienceIdsReceived(result["experience_ids"]);
}
-void LLFloaterNotRunQueue::handleInventory(LLViewerObject* viewer_obj,
- LLInventoryObject::object_list_t* inv)
+void LLFloaterScriptQueue::objectScriptProcessingQueueCoro(std::string action, LLHandle<LLFloaterScriptQueue> hfloater,
+ object_data_list_t objectList, fnQueueAction_t func)
{
- // find all of the lsl, leaving off duplicates. We'll remove
- // all matching asset uuids on compilation success.
- LLInventoryObject::object_list_t::const_iterator it = inv->begin();
- LLInventoryObject::object_list_t::const_iterator end = inv->end();
- for ( ; it != end; ++it)
- {
- if((*it)->getType() == LLAssetType::AT_LSL_TEXT)
- {
- LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
-
- if (object)
- {
- LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
- LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
- std::string buffer;
- buffer = getString("NotRunning") + (": ") +item->getName();
- list->addSimpleElement(buffer, ADD_BOTTOM);
-
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_SetScriptRunning);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_Script);
- msg->addUUIDFast(_PREHASH_ObjectID, viewer_obj->getID());
- msg->addUUIDFast(_PREHASH_ItemID, (*it)->getUUID());
- msg->addBOOLFast(_PREHASH_Running, FALSE);
- msg->sendReliable(object->getRegion()->getHost());
- }
- }
- }
+ LLCoros::set_consuming(true);
+ LLFloaterScriptQueue * floater(NULL);
+ LLEventMailDrop maildrop(QUEUE_EVENTPUMP_NAME, true);
+ F32 fetch_timeout = gSavedSettings.getF32("QueueInventoryFetchTimeout");
+
+// floater = hfloater.get();
+// floater->addProcessingMessage("Starting",
+// LLSD()
+// .with("[START]", action)
+// .with("[COUNT]", LLSD::Integer(objectList.size())));
+// floater = NULL;
+
+ for (object_data_list_t::iterator itObj(objectList.begin()); (itObj != objectList.end()); ++itObj)
+ {
+ bool firstForObject = true;
+ LLUUID object_id = (*itObj).mObjectId;
+ LL_INFOS("SCRIPTQ") << "Next object in queue with ID=" << object_id.asString() << LL_ENDL;
- nextObject();
-}
+ LLPointer<LLViewerObject> obj = gObjectList.findObject(object_id);
+ LLInventoryObject::object_list_t inventory;
+ if (obj)
+ {
+ ObjectInventoryFetcher::ptr_t fetcher(new ObjectInventoryFetcher(maildrop, obj, NULL));
-///----------------------------------------------------------------------------
-/// Local function definitions
-///----------------------------------------------------------------------------
+ fetcher->fetchInventory();
+
+ floater = hfloater.get();
+ if (floater)
+ {
+ LLStringUtil::format_map_t args;
+ args["[OBJECT_NAME]"] = (*itObj).mObjectName;
+ floater->addStringMessage(floater->getString("LoadingObjInv", args));
+ }
+
+ LLSD result = llcoro::suspendUntilEventOnWithTimeout(maildrop, fetch_timeout,
+ LLSD().with("timeout", LLSD::Boolean(true)));
+
+ if (result.has("timeout") && result["timeout"].asBoolean())
+ {
+ LL_WARNS("SCRIPTQ") << "Unable to retrieve inventory for object " << object_id.asString() <<
+ ". Skipping to next object." << LL_ENDL;
+
+ // floater could have been closed
+ floater = hfloater.get();
+ if (floater)
+ {
+ LLStringUtil::format_map_t args;
+ args["[OBJECT_NAME]"] = (*itObj).mObjectName;
+ floater->addStringMessage(floater->getString("Timeout", args));
+ }
+
+ continue;
+ }
+
+ inventory.assign(fetcher->getInventoryList().begin(), fetcher->getInventoryList().end());
+ }
+ else
+ {
+ LL_WARNS("SCRIPTQ") << "Unable to retrieve object with ID of " << object_id <<
+ ". Skipping to next." << LL_ENDL;
+ continue;
+ }
+
+ // TODO: Get the name of the object we are looking at here so that we can display it below.
+ //std::string objName = (dynamic_cast<LLInventoryObject *>(obj.get()))->getName();
+ LL_DEBUGS("SCRIPTQ") << "Object has " << inventory.size() << " items." << LL_ENDL;
+
+ for (LLInventoryObject::object_list_t::iterator itInv = inventory.begin();
+ itInv != inventory.end(); ++itInv)
+ {
+ floater = hfloater.get();
+ if (!floater)
+ {
+ LL_WARNS("SCRIPTQ") << "Script Queue floater closed! Canceling remaining ops" << LL_ENDL;
+ break;
+ }
+
+ // note, we have a smart pointer to the obj above... but if we didn't we'd check that
+ // it still exists here.
+
+ if (((*itInv)->getType() == LLAssetType::AT_LSL_TEXT))
+ {
+ LL_DEBUGS("SCRIPTQ") << "Inventory item " << (*itInv)->getUUID().asString() << "\"" << (*itInv)->getName() << "\"" << LL_ENDL;
+ if (firstForObject)
+ {
+ //floater->addStringMessage(objName + ":");
+ firstForObject = false;
+ }
+
+ if (!func(obj, (*itInv), maildrop))
+ {
+ continue;
+ }
+ }
+
+ llcoro::suspend();
+ }
+ // Just test to be sure the floater is still present before calling the func
+ if (!hfloater.get())
+ {
+ LL_WARNS("SCRIPTQ") << "Script Queue floater dismissed." << LL_ENDL;
+ break;
+ }
+
+ }
+
+ floater = hfloater.get();
+ if (floater)
+ {
+ floater->addStringMessage("Done");
+ floater->getChildView("close")->setEnabled(TRUE);
+ }
+}
diff --git a/indra/newview/llcompilequeue.h b/indra/newview/llcompilequeue.h
index 46bcb9746b..1b3d8f83a0 100644
--- a/indra/newview/llcompilequeue.h
+++ b/indra/newview/llcompilequeue.h
@@ -37,6 +37,8 @@
#include "llviewerinventory.h"
+#include "llevents.h"
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFloaterScriptQueue
//
@@ -48,7 +50,7 @@
// scripts manipulated.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLFloaterScriptQueue : public LLFloater, public LLVOInventoryListener
+class LLFloaterScriptQueue : public LLFloater/*, public LLVOInventoryListener*/
{
public:
LLFloaterScriptQueue(const LLSD& key);
@@ -59,34 +61,23 @@ public:
void setMono(bool mono) { mMono = mono; }
// addObject() accepts an object id.
- void addObject(const LLUUID& id);
+ void addObject(const LLUUID& id, std::string name);
// start() returns TRUE if the queue has started, otherwise FALSE.
BOOL start();
-protected:
- // This is the callback method for the viewer object currently
- // being worked on.
- /*virtual*/ void inventoryChanged(LLViewerObject* obj,
- LLInventoryObject::object_list_t* inv,
- S32 serial_num,
- void* queue);
-
- // This is called by inventoryChanged
- virtual void handleInventory(LLViewerObject* viewer_obj,
- LLInventoryObject::object_list_t* inv) = 0;
+ void addProcessingMessage(const std::string &message, const LLSD &args);
+ void addStringMessage(const std::string &message);
+ std::string getStartString() const { return mStartString; }
+
+protected:
static void onCloseBtn(void* user_data);
// returns true if this is done
BOOL isDone() const;
- virtual BOOL startQueue();
-
- // go to the next object. If no objects left, it falls out
- // silently and waits to be killed by the deleteIfDone() callback.
- BOOL nextObject();
- BOOL popNext();
+ virtual bool startQueue() = 0;
void setStartString(const std::string& s) { mStartString = s; }
@@ -96,12 +87,23 @@ protected:
LLButton* mCloseBtn;
// Object Queue
- std::vector<LLUUID> mObjectIDs;
+ struct ObjectData
+ {
+ LLUUID mObjectId;
+ std::string mObjectName;
+ };
+ typedef std::vector<ObjectData> object_data_list_t;
+
+ object_data_list_t mObjectList;
LLUUID mCurrentObjectID;
bool mDone;
std::string mStartString;
bool mMono;
+
+ typedef boost::function<bool(const LLPointer<LLViewerObject> &, LLInventoryObject*, LLEventPump &)> fnQueueAction_t;
+ static void objectScriptProcessingQueueCoro(std::string action, LLHandle<LLFloaterScriptQueue> hfloater, object_data_list_t objectList, fnQueueAction_t func);
+
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -122,8 +124,6 @@ class LLFloaterCompileQueue : public LLFloaterScriptQueue
{
friend class LLFloaterReg;
public:
- // remove any object in mScriptScripts with the matching uuid.
- void removeItemByItemID(const LLUUID& item_id);
void experienceIdsReceived( const LLSD& content );
BOOL hasExperience(const LLUUID& id)const;
@@ -132,27 +132,17 @@ protected:
LLFloaterCompileQueue(const LLSD& key);
virtual ~LLFloaterCompileQueue();
- // This is called by inventoryChanged
- virtual void handleInventory(LLViewerObject* viewer_obj,
- LLInventoryObject::object_list_t* inv);
-
- static void requestAsset(struct LLScriptQueueData* datap, const LLSD& experience);
+ virtual bool startQueue();
+ static bool processScript(LLHandle<LLFloaterCompileQueue> hfloater, const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump);
- static void finishLSLUpload(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, std::string scriptName, LLUUID queueId);
-
- // This is the callback for when each script arrives
- static void scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
- LLAssetType::EType type,
- void* user_data, S32 status, LLExtStat ext_status);
-
- virtual BOOL startQueue();
-protected:
- LLViewerInventoryItem::item_array_t mCurrentScripts;
+ //bool checkAssetId(const LLUUID &assetId);
+ static void handleHTTPResponse(std::string pumpName, const LLSD &expresult);
+ static void handleScriptRetrieval(LLVFS *vfs, const LLUUID& assetId, LLAssetType::EType type, void* userData, S32 status, LLExtStat extStatus);
private:
static void processExperienceIdResults(LLSD result, LLUUID parent);
-
+ //uuid_list_t mAssetIds; // list of asset IDs processed.
uuid_list_t mExperienceIds;
};
@@ -169,9 +159,9 @@ protected:
LLFloaterResetQueue(const LLSD& key);
virtual ~LLFloaterResetQueue();
- // This is called by inventoryChanged
- virtual void handleInventory(LLViewerObject* viewer_obj,
- LLInventoryObject::object_list_t* inv);
+ static bool resetObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater, const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump);
+
+ virtual bool startQueue();
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -186,10 +176,10 @@ class LLFloaterRunQueue : public LLFloaterScriptQueue
protected:
LLFloaterRunQueue(const LLSD& key);
virtual ~LLFloaterRunQueue();
-
- // This is called by inventoryChanged
- virtual void handleInventory(LLViewerObject* viewer_obj,
- LLInventoryObject::object_list_t* inv);
+
+ static bool runObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater, const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump);
+
+ virtual bool startQueue();
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -205,9 +195,9 @@ protected:
LLFloaterNotRunQueue(const LLSD& key);
virtual ~LLFloaterNotRunQueue();
- // This is called by inventoryChanged
- virtual void handleInventory(LLViewerObject* viewer_obj,
- LLInventoryObject::object_list_t* inv);
+ static bool stopObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater, const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump);
+
+ virtual bool startQueue();
};
#endif // LL_LLCOMPILEQUEUE_H
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 05c7e6caa5..4e69896b69 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -448,7 +448,12 @@ bool LLConversationLog::moveLog(const std::string &originDirectory, const std::s
std::string LLConversationLog::getFileName()
{
std::string filename = "conversation";
- return gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename) + ".log";
+ std::string log_address = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename);
+ if (!log_address.empty())
+ {
+ log_address += ".log";
+ }
+ return log_address;
}
bool LLConversationLog::saveToFile(const std::string& filename)
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 33675bd261..b716a76543 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -62,28 +62,15 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
LLFacePool(POOL_TERRAIN),
mTexturep(texturep)
{
- U32 format = GL_ALPHA8;
- U32 int_format = GL_ALPHA;
-
// Hack!
sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale");
sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
- mAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient.tga",
- FTT_LOCAL_FILE,
- TRUE, LLGLTexture::BOOST_UI,
- LLViewerTexture::FETCHED_TEXTURE,
- format, int_format,
- LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb"));
+ mAlphaRampImagep = LLViewerTextureManager::getFetchedTexture(IMG_ALPHA_GRAD);
//gGL.getTexUnit(0)->bind(mAlphaRampImagep.get());
mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
- m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient_2d.j2c",
- FTT_LOCAL_FILE,
- TRUE, LLGLTexture::BOOST_UI,
- LLViewerTexture::FETCHED_TEXTURE,
- format, int_format,
- LLUUID("38b86f85-2575-52a9-a531-23108d8da837"));
+ m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTexture(IMG_ALPHA_GRAD_2D);
//gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 7178042b32..cc77b407ae 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -40,12 +40,14 @@
#include "llcorehttputil.h"
#include "lleventfilter.h"
+#include "boost/make_shared.hpp"
+
namespace LLEventPolling
{
namespace Details
{
- class LLEventPollImpl
+ class LLEventPollImpl: public boost::enable_shared_from_this<LLEventPollImpl>
{
public:
LLEventPollImpl(const LLHost &sender);
@@ -113,7 +115,7 @@ namespace Details
{
std::string coroname =
LLCoros::instance().launch("LLEventPollImpl::eventPollCoro",
- boost::bind(&LLEventPollImpl::eventPollCoro, this, url));
+ boost::bind(&LLEventPollImpl::eventPollCoro, this->shared_from_this(), url));
LL_INFOS("LLEventPollImpl") << coroname << " with url '" << url << LL_ENDL;
}
}
@@ -273,8 +275,7 @@ namespace Details
LLEventPoll::LLEventPoll(const std::string& poll_url, const LLHost& sender):
mImpl()
{
- mImpl = boost::unique_ptr<LLEventPolling::Details::LLEventPollImpl>
- (new LLEventPolling::Details::LLEventPollImpl(sender));
+ mImpl = boost::make_shared<LLEventPolling::Details::LLEventPollImpl>(sender);
mImpl->start(poll_url);
}
diff --git a/indra/newview/lleventpoll.h b/indra/newview/lleventpoll.h
index e2afd9226b..65766dbb2a 100644
--- a/indra/newview/lleventpoll.h
+++ b/indra/newview/lleventpoll.h
@@ -27,12 +27,6 @@
#ifndef LL_LLEVENTPOLL_H
#define LL_LLEVENTPOLL_H
-#include "boost/move/unique_ptr.hpp"
-
-namespace boost
-{
- using ::boost::movelib::unique_ptr; // move unique_ptr into the boost namespace.
-}
class LLHost;
@@ -57,7 +51,7 @@ public:
private:
- boost::unique_ptr<LLEventPolling::Details::LLEventPollImpl> mImpl;
+ boost::shared_ptr<LLEventPolling::Details::LLEventPollImpl> mImpl;
};
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 7f1c981a3c..d4ba230feb 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -809,3 +809,62 @@ void LLFeatureManager::applyBaseMasks()
maskFeatures("safe");
}
}
+
+LLSD LLFeatureManager::getRecommendedSettingsMap()
+{
+ // Create the map and fill it with the hardware recommended settings.
+ // It's needed to create an initial Default graphics preset (MAINT-6435).
+ // The process is similar to the one LLFeatureManager::applyRecommendedSettings() does.
+
+ LLSD map(LLSD::emptyMap());
+
+ loadGPUClass();
+ U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5));
+ LL_INFOS("RenderInit") << "Getting the map of recommended settings for level " << level << LL_ENDL;
+
+ applyBaseMasks();
+ std::string features(isValidGraphicsLevel(level) ? getNameForGraphicsLevel(level) : "Low");
+
+ maskFeatures(features);
+
+ LLControlVariable* ctrl = gSavedSettings.getControl("RenderQualityPerformance"); // include the quality value for correct preset loading
+ map["RenderQualityPerformance"]["Value"] = (LLSD::Integer)level;
+ map["RenderQualityPerformance"]["Comment"] = ctrl->getComment();;
+ map["RenderQualityPerformance"]["Persist"] = 1;
+ map["RenderQualityPerformance"]["Type"] = LLControlGroup::typeEnumToString(ctrl->type());
+
+
+
+ for (feature_map_t::iterator mIt = mFeatures.begin(); mIt != mFeatures.end(); ++mIt)
+ {
+ LLControlVariable* ctrl = gSavedSettings.getControl(mIt->first);
+ if (ctrl == NULL)
+ {
+ LL_WARNS() << "AHHH! Control setting " << mIt->first << " does not exist!" << LL_ENDL;
+ continue;
+ }
+
+ if (ctrl->isType(TYPE_BOOLEAN))
+ {
+ map[mIt->first]["Value"] = (LLSD::Boolean)getRecommendedValue(mIt->first);
+ }
+ else if (ctrl->isType(TYPE_S32) || ctrl->isType(TYPE_U32))
+ {
+ map[mIt->first]["Value"] = (LLSD::Integer)getRecommendedValue(mIt->first);
+ }
+ else if (ctrl->isType(TYPE_F32))
+ {
+ map[mIt->first]["Value"] = (LLSD::Real)getRecommendedValue(mIt->first);
+ }
+ else
+ {
+ LL_WARNS() << "AHHH! Control variable is not a numeric type!" << LL_ENDL;
+ continue;
+ }
+ map[mIt->first]["Comment"] = ctrl->getComment();;
+ map[mIt->first]["Persist"] = 1;
+ map[mIt->first]["Type"] = LLControlGroup::typeEnumToString(ctrl->type());
+ }
+
+ return map;
+}
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index 12ea691b49..c3d87cea0b 100644
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -157,7 +157,9 @@ public:
// load the dynamic GPU/feature table from a website
void fetchHTTPTables();
-
+
+ LLSD getRecommendedSettingsMap();
+
protected:
bool loadGPUClass();
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index 7da65a9a7c..d842106146 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -528,7 +528,8 @@ void LLFloaterGesture::onCopyPasteAction(const LLSD& command)
LLInventoryItem* item = gInventory.getItem(*it);
if(item && item->getInventoryType() == LLInventoryType::IT_GESTURE)
{
- LLClipboard::instance().addToClipboard(item->getUUID(),LLAssetType::AT_GESTURE);
+ LLWString item_name = utf8str_to_wstring(item->getName());
+ LLClipboard::instance().addToClipboard(item_name, 0, item_name.size());
}
}
}
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 7a989806a1..257b39a7dd 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -798,7 +798,8 @@ LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32*
}
else if (mesg[0] == '/'
&& mesg[1]
- && LLStringOps::isDigit(mesg[1]))
+ && (LLStringOps::isDigit(mesg[1])
+ || (mesg[1] == '-' && mesg[2] && LLStringOps::isDigit(mesg[2]))))
{
// This a special "/20" speak on a channel
S32 pos = 0;
@@ -812,7 +813,7 @@ LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32*
channel_string.push_back(c);
pos++;
}
- while(c && pos < 64 && LLStringOps::isDigit(c));
+ while(c && pos < 64 && (LLStringOps::isDigit(c) || (pos==1 && c =='-')));
// Move the pointer forward to the first non-whitespace char
// Check isspace before looping, so we can handle "/33foo"
@@ -837,19 +838,36 @@ LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32*
void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
{
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_ChatFromViewer);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_ChatData);
- msg->addStringFast(_PREHASH_Message, utf8_out_text);
- msg->addU8Fast(_PREHASH_Type, type);
- msg->addS32("Channel", channel);
-
- gAgent.sendReliableMessage();
-
- add(LLStatViewer::CHAT_COUNT, 1);
+ LLMessageSystem* msg = gMessageSystem;
+
+ if (channel >= 0)
+ {
+ msg->newMessageFast(_PREHASH_ChatFromViewer);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_ChatData);
+ msg->addStringFast(_PREHASH_Message, utf8_out_text);
+ msg->addU8Fast(_PREHASH_Type, type);
+ msg->addS32("Channel", channel);
+
+ }
+ else
+ {
+ // Hack: ChatFromViewer doesn't allow negative channels
+ msg->newMessage("ScriptDialogReply");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgentID);
+ msg->addUUID("SessionID", gAgentSessionID);
+ msg->nextBlock("Data");
+ msg->addUUID("ObjectID", gAgentID);
+ msg->addS32("ChatChannel", channel);
+ msg->addS32("ButtonIndex", 0);
+ msg->addString("ButtonLabel", utf8_out_text);
+ }
+
+ gAgent.sendReliableMessage();
+ add(LLStatViewer::CHAT_COUNT, 1);
}
class LLChatCommandHandler : public LLCommandHandler
diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
index 1f85c5ac1b..9fd731ed56 100644
--- a/indra/newview/llfloaterimnearbychathandler.cpp
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -601,12 +601,31 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
toast_msg = chat_msg.mText;
}
+ bool chat_overlaps = false;
+ if(nearby_chat->getChatHistory())
+ {
+ LLRect chat_rect = nearby_chat->getChatHistory()->calcScreenRect();
+ for (std::list<LLView*>::const_iterator child_iter = gFloaterView->getChildList()->begin();
+ child_iter != gFloaterView->getChildList()->end(); ++child_iter)
+ {
+ LLView *view = *child_iter;
+ const LLRect& rect = view->getRect();
+ if(view->isInVisibleChain() && (rect.overlaps(chat_rect)))
+ {
+ if(!nearby_chat->getChatHistory()->hasAncestor(view))
+ {
+ chat_overlaps = true;
+ }
+ break;
+ }
+ }
+ }
//Don't show nearby toast, if conversation is visible and selected
if ((nearby_chat->hasFocus()) ||
(LLFloater::isVisible(nearby_chat) && nearby_chat->isTornOff() && !nearby_chat->isMinimized()) ||
- ((im_box->getSelectedSession().isNull() &&
- ((LLFloater::isVisible(im_box) && !im_box->isMinimized() && im_box->isFrontmost())
- || (LLFloater::isVisible(nearby_chat) && !nearby_chat->isMinimized() && nearby_chat->isFrontmost())))))
+ ((im_box->getSelectedSession().isNull() && !chat_overlaps &&
+ ((LLFloater::isVisible(im_box) && !nearby_chat->isTornOff() && !im_box->isMinimized())
+ || (LLFloater::isVisible(nearby_chat) && nearby_chat->isTornOff() && !nearby_chat->isMinimized())))))
{
if(nearby_chat->isMessagePaneExpanded())
{
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 357b635594..2cd94c592a 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -1094,6 +1094,12 @@ void LLFloaterIMSessionTab::saveCollapsedState()
gSavedPerAccountSettings.setBOOL("NearbyChatIsNotCollapsed", isMessagePaneExpanded());
}
}
+
+LLView* LLFloaterIMSessionTab::getChatHistory()
+{
+ return mChatHistory;
+}
+
BOOL LLFloaterIMSessionTab::handleKeyHere(KEY key, MASK mask )
{
BOOL handled = FALSE;
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index e7b05a584b..1b4922fd73 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -103,6 +103,8 @@ public:
void restoreFloater();
void saveCollapsedState();
+ LLView* getChatHistory();
+
protected:
// callback for click on any items of the visual states menu
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index 135bbb335e..4a5732aecf 100644
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
@@ -42,6 +42,8 @@
#include "llfloaterperms.h"
#include "llviewercontrol.h"
#include "llviewermenufile.h" // upload_new_resource()
+#include "llstatusbar.h" // can_afford_transaction()
+#include "llnotificationsutil.h"
#include "lluictrlfactory.h"
#include "llstring.h"
#include "lleconomy.h"
@@ -161,12 +163,15 @@ void LLFloaterNameDesc::onBtnOK( )
LLAssetStorage::LLStoreAssetCallback callback = NULL;
S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
- void *nruserdata = NULL;
- std::string display_name = LLStringUtil::null;
- LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(
+ if (can_afford_transaction(expected_upload_cost))
+ {
+ void *nruserdata = NULL;
+ std::string display_name = LLStringUtil::null;
+
+ LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(
mFilenameAndPath,
- getChild<LLUICtrl>("name_form")->getValue().asString(),
+ getChild<LLUICtrl>("name_form")->getValue().asString(),
getChild<LLUICtrl>("description_form")->getValue().asString(), 0,
LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
LLFloaterPerms::getNextOwnerPerms("Uploads"),
@@ -174,7 +179,14 @@ void LLFloaterNameDesc::onBtnOK( )
LLFloaterPerms::getEveryonePerms("Uploads"),
expected_upload_cost));
- upload_new_resource(uploadInfo, callback, nruserdata);
+ upload_new_resource(uploadInfo, callback, nruserdata);
+ }
+ else
+ {
+ LLSD args;
+ args["COST"] = llformat("%d", expected_upload_cost);
+ LLNotificationsUtil::add("ErrorTextureCannotAfford", args);
+ }
closeFloater(false);
}
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 36bdcf4d89..20d8119606 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1411,7 +1411,7 @@ void LLAvatarComplexityControls::setIndirectMaxArc()
else
{
// This is the inverse of the calculation in updateMaxComplexity
- indirect_max_arc = (U32)((log(max_arc) - MIN_ARC_LOG) / ARC_LIMIT_MAP_SCALE) + MIN_INDIRECT_ARC_LIMIT;
+ indirect_max_arc = (U32)ll_round(((log(F32(max_arc)) - MIN_ARC_LOG) / ARC_LIMIT_MAP_SCALE)) + MIN_INDIRECT_ARC_LIMIT;
}
gSavedSettings.setU32("IndirectMaxComplexity", indirect_max_arc);
}
@@ -1930,7 +1930,7 @@ void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* valu
{
// if this is changed, the inverse calculation in setIndirectMaxArc
// must be changed to match
- max_arc = (U32)exp(MIN_ARC_LOG + (ARC_LIMIT_MAP_SCALE * (indirect_value - MIN_INDIRECT_ARC_LIMIT)));
+ max_arc = (U32)ll_round(exp(MIN_ARC_LOG + (ARC_LIMIT_MAP_SCALE * (indirect_value - MIN_INDIRECT_ARC_LIMIT))));
}
gSavedSettings.setU32("RenderAvatarMaxComplexity", (U32)max_arc);
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 4eacd728c3..843dbbf25e 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -412,6 +412,11 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
panel->getChild<LLUICtrl>("object_bonus_spin")->setValue(LLSD(object_bonus_factor) );
panel->getChild<LLUICtrl>("access_combo")->setValue(LLSD(sim_access) );
+ LLPanelRegionGeneralInfo* panel_general = LLFloaterRegionInfo::getPanelGeneral();
+ if (panel)
+ {
+ panel_general->setObjBonusFactor(object_bonus_factor);
+ }
// detect teen grid for maturity
@@ -465,6 +470,16 @@ LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant()
}
// static
+LLPanelRegionGeneralInfo* LLFloaterRegionInfo::getPanelGeneral()
+{
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
+ if (!floater) return NULL;
+ LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
+ LLPanelRegionGeneralInfo* panel = (LLPanelRegionGeneralInfo*)tab->getChild<LLPanel>("General");
+ return panel;
+}
+
+// static
LLPanelRegionTerrainInfo* LLFloaterRegionInfo::getPanelRegionTerrain()
{
LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
@@ -717,7 +732,42 @@ BOOL LLPanelRegionGeneralInfo::postBuild()
childSetAction("im_btn", onClickMessage, this);
// childSetAction("manage_telehub_btn", onClickManageTelehub, this);
- return LLPanelRegionInfo::postBuild();
+ LLUICtrl* apply_btn = findChild<LLUICtrl>("apply_btn");
+ if (apply_btn)
+ {
+ apply_btn->setCommitCallback(boost::bind(&LLPanelRegionGeneralInfo::onBtnSet, this));
+ }
+
+ refresh();
+ return TRUE;
+}
+
+void LLPanelRegionGeneralInfo::onBtnSet()
+{
+ if(mObjBonusFactor == getChild<LLUICtrl>("object_bonus_spin")->getValue().asReal())
+ {
+ if (sendUpdate())
+ {
+ disableButton("apply_btn");
+ }
+ }
+ else
+ {
+ LLNotificationsUtil::add("ChangeObjectBonusFactor", LLSD(), LLSD(), boost::bind(&LLPanelRegionGeneralInfo::onChangeObjectBonus, this, _1, _2));
+ }
+}
+
+bool LLPanelRegionGeneralInfo::onChangeObjectBonus(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ if (sendUpdate())
+ {
+ disableButton("apply_btn");
+ }
+ }
+ return false;
}
void LLPanelRegionGeneralInfo::onClickKick()
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index 46f2b42137..dbb0ad05e9 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -95,6 +95,7 @@ public:
static LLPanelEstateCovenant* getPanelCovenant();
static LLPanelRegionTerrainInfo* getPanelRegionTerrain();
static LLPanelRegionExperiences* getPanelExperiences();
+ static LLPanelRegionGeneralInfo* getPanelGeneral();
// from LLPanel
virtual void refresh();
@@ -183,6 +184,9 @@ public:
// LLPanel
virtual BOOL postBuild();
+ void onBtnSet();
+ void setObjBonusFactor(F32 object_bonus_factor) {mObjBonusFactor = object_bonus_factor;}
+
protected:
virtual BOOL sendUpdate();
void onClickKick();
@@ -191,6 +195,9 @@ protected:
bool onKickAllCommit(const LLSD& notification, const LLSD& response);
static void onClickMessage(void* userdata);
bool onMessageCommit(const LLSD& notification, const LLSD& response);
+ bool onChangeObjectBonus(const LLSD& notification, const LLSD& response);
+
+ F32 mObjBonusFactor;
};
diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp
index 7b8fc5b35b..eae16b9f03 100644
--- a/indra/newview/llfloaterscriptlimits.cpp
+++ b/indra/newview/llfloaterscriptlimits.cpp
@@ -660,6 +660,8 @@ BOOL LLPanelScriptLimitsRegionMemory::postBuild()
{
return FALSE;
}
+ list->setCommitCallback(boost::bind(&LLPanelScriptLimitsRegionMemory::checkButtonsEnabled, this));
+ checkButtonsEnabled();
//set all columns to resizable mode even if some columns will be empty
for(S32 column = 0; column < list->getNumColumns(); column++)
@@ -750,6 +752,14 @@ void LLPanelScriptLimitsRegionMemory::clearList()
getChild<LLUICtrl>("parcels_listed")->setValue(LLSD(msg_empty_string));
mObjectListItems.clear();
+ checkButtonsEnabled();
+}
+
+void LLPanelScriptLimitsRegionMemory::checkButtonsEnabled()
+{
+ LLScrollListCtrl* list = getChild<LLScrollListCtrl>("scripts_list");
+ getChild<LLButton>("highlight_btn")->setEnabled(list->getNumSelected() > 0);
+ getChild<LLButton>("return_btn")->setEnabled(list->getNumSelected() > 0);
}
// static
diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h
index e3cbbd185f..2ac3862b4f 100644
--- a/indra/newview/llfloaterscriptlimits.h
+++ b/indra/newview/llfloaterscriptlimits.h
@@ -113,6 +113,7 @@ public:
void showBeacon();
void returnObjectsFromParcel(S32 local_id);
void returnObjects();
+ void checkButtonsEnabled();
private:
void onNameCache(const LLUUID& id,
diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp
index 0cb37dabe7..b139e5daf5 100644
--- a/indra/newview/llfloatersellland.cpp
+++ b/indra/newview/llfloatersellland.cpp
@@ -257,7 +257,6 @@ void LLFloaterSellLandUI::setBadge(const char* id, Badge badge)
static std::string badgeOK("badge_ok.j2c");
static std::string badgeNote("badge_note.j2c");
static std::string badgeWarn("badge_warn.j2c");
- static std::string badgeError("badge_error.j2c");
std::string badgeName;
switch (badge)
@@ -266,7 +265,7 @@ void LLFloaterSellLandUI::setBadge(const char* id, Badge badge)
case BADGE_OK: badgeName = badgeOK; break;
case BADGE_NOTE: badgeName = badgeNote; break;
case BADGE_WARN: badgeName = badgeWarn; break;
- case BADGE_ERROR: badgeName = badgeError; break;
+ case BADGE_ERROR: badgeName = badgeWarn; break;
}
getChild<LLUICtrl>(id)->setValue(badgeName);
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index afec981d56..b906671c7f 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -1418,6 +1418,20 @@ void LLFloaterSnapshot::postPanelSwitch()
}
// static
+void LLFloaterSnapshot::inventorySaveFailed()
+{
+ LLFloaterSnapshot* instance = findInstance();
+ if (!instance)
+ {
+ llassert(instance != NULL);
+ return;
+ }
+
+ instance->impl.updateControls(instance);
+ instance->impl.setStatus(Impl::STATUS_FINISHED, false, "inventory");
+}
+
+// static
LLPointer<LLImageFormatted> LLFloaterSnapshot::getImageData()
{
// FIXME: May not work for textures.
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 0bb9474bb5..eb3a94999b 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -61,6 +61,7 @@ public:
static BOOL saveLocal();
static void postSave();
static void postPanelSwitch();
+ static void inventorySaveFailed();
static LLPointer<LLImageFormatted> getImageData();
static const LLVector3d& getPosTakenGlobal();
static void setAgentEmail(const std::string& email);
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index ece3e10faa..c67feb8158 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -963,10 +963,10 @@ F32 LLFloaterWorldMap::getDistanceToDestination(const LLVector3d &destination,
}
-void LLFloaterWorldMap::clearLocationSelection(BOOL clear_ui)
+void LLFloaterWorldMap::clearLocationSelection(BOOL clear_ui, BOOL dest_reached)
{
LLCtrlListInterface *list = mListSearchResults;
- if (list)
+ if (list && (!dest_reached || (list->getItemCount() == 1)))
{
list->operateOnAll(LLCtrlListInterface::OP_DELETE);
}
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index 7ce8dae9a9..c5801c8819 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -94,7 +94,7 @@ public:
// A z_attenuation of 0.0f collapses the distance into the X-Y plane
F32 getDistanceToDestination(const LLVector3d& pos_global, F32 z_attenuation = 0.5f) const;
- void clearLocationSelection(BOOL clear_ui = FALSE);
+ void clearLocationSelection(BOOL clear_ui = FALSE, BOOL dest_reached = FALSE);
void clearAvatarSelection(BOOL clear_ui = FALSE);
void clearLandmarkSelection(BOOL clear_ui = FALSE);
diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp
index a9bf8a9a50..97cc7684e4 100644
--- a/indra/newview/llgiveinventory.cpp
+++ b/indra/newview/llgiveinventory.cpp
@@ -248,7 +248,7 @@ bool LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
gInventory.collectDescendentsIf (cat->getUUID(),
cats,
items,
- LLInventoryModel::EXCLUDE_TRASH,
+ LLInventoryModel::INCLUDE_TRASH,
giveable);
S32 count = cats.size();
bool complete = true;
@@ -499,7 +499,7 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
gInventory.collectDescendentsIf (cat->getUUID(),
cats,
items,
- LLInventoryModel::EXCLUDE_TRASH,
+ LLInventoryModel::INCLUDE_TRASH,
giveable);
bool give_successful = true;
diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp
index a12ec390af..b64df2bd47 100644
--- a/indra/newview/llinspectremoteobject.cpp
+++ b/indra/newview/llinspectremoteobject.cpp
@@ -181,7 +181,7 @@ void LLInspectRemoteObject::update()
getChild<LLUICtrl>("map_btn")->setEnabled(! mSLurl.empty());
// disable the Block button if we don't have the object ID (will this ever happen?)
- getChild<LLUICtrl>("block_btn")->setEnabled(! mObjectID.isNull());
+ getChild<LLUICtrl>("block_btn")->setEnabled(!mObjectID.isNull() && !LLMuteList::getInstance()->isMuted(mObjectID));
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 26c9b40fb1..f4bf38f65d 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -286,6 +286,16 @@ BOOL LLInvFVBridge::cutToClipboard()
return FALSE;
}
+// virtual
+bool LLInvFVBridge::isCutToClipboard()
+{
+ if (LLClipboard::instance().isCutMode())
+ {
+ return LLClipboard::instance().isOnClipboard(mUUID);
+ }
+ return false;
+}
+
// Callback for cutToClipboard if DAMA required...
BOOL LLInvFVBridge::callback_cutToClipboard(const LLSD& notification, const LLSD& response)
{
@@ -307,9 +317,7 @@ BOOL LLInvFVBridge::perform_cutToClipboard()
if (obj && isItemMovable() && isItemRemovable())
{
LLClipboard::instance().setCutMode(true);
- BOOL added_to_clipboard = LLClipboard::instance().addToClipboard(mUUID);
- removeObject(&gInventory, mUUID); // Always perform the remove even if the object couldn't make it to the clipboard
- return added_to_clipboard;
+ return LLClipboard::instance().addToClipboard(mUUID);
}
return FALSE;
}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 9053c61171..df25e01688 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -116,6 +116,7 @@ public:
virtual BOOL isItemCopyable() const { return FALSE; }
virtual BOOL copyToClipboard() const;
virtual BOOL cutToClipboard();
+ virtual bool isCutToClipboard();
virtual BOOL isClipboardPasteable() const;
virtual BOOL isClipboardPasteableAsLink() const;
virtual void pasteFromClipboard() {}
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 003bbcafed..e995c138b4 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -84,21 +84,18 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)
bool LLInventoryFilter::check(const LLFolderViewModelItem* item)
{
const LLFolderViewModelItemInventory* listener = dynamic_cast<const LLFolderViewModelItemInventory*>(item);
- // Clipboard cut items are *always* filtered so we need this value upfront
- const BOOL passed_clipboard = (listener ? checkAgainstClipboard(listener->getUUID()) : TRUE);
// If it's a folder and we're showing all folders, return automatically.
const BOOL is_folder = listener->getInventoryType() == LLInventoryType::IT_CATEGORY;
if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS))
{
- return passed_clipboard;
+ return true;
}
bool passed = (mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) != std::string::npos : true);
passed = passed && checkAgainstFilterType(listener);
passed = passed && checkAgainstPermissions(listener);
passed = passed && checkAgainstFilterLinks(listener);
- passed = passed && passed_clipboard;
return passed;
}
@@ -108,9 +105,8 @@ bool LLInventoryFilter::check(const LLInventoryItem* item)
const bool passed_string = (mFilterSubString.size() ? item->getName().find(mFilterSubString) != std::string::npos : true);
const bool passed_filtertype = checkAgainstFilterType(item);
const bool passed_permissions = checkAgainstPermissions(item);
- const bool passed_clipboard = checkAgainstClipboard(item->getUUID());
- return passed_filtertype && passed_permissions && passed_clipboard && passed_string;
+ return passed_filtertype && passed_permissions && passed_string;
}
bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const
@@ -129,13 +125,10 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const
bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
{
- // Always check against the clipboard
- const BOOL passed_clipboard = checkAgainstClipboard(folder_id);
-
// we're showing all folders, overriding filter
if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)
{
- return passed_clipboard;
+ return true;
}
// when applying a filter, matching folders get their contents downloaded first
@@ -201,7 +194,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
LLViewerInventoryItem* item = gInventory.getItem(folder_id);
if (item && item->getActualType() == LLAssetType::AT_LINK_FOLDER)
{
- return passed_clipboard;
+ return true;
}
if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY)
@@ -216,7 +209,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
return false;
}
- return passed_clipboard;
+ return true;
}
bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInventory* listener) const
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index e3cb4d57ef..d8f019374e 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -287,7 +287,11 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc
LL_INFOS("SLM") << "Unlist and clear version folder as the version folder is not at the right place anymore!!" << LL_ENDL;
LLMarketplaceData::instance().setVersionFolder(listing_uuid, LLUUID::null,1);
}
- else if (version_folder_uuid.notNull() && LLMarketplaceData::instance().getActivationState(version_folder_uuid) && (count_descendants_items(version_folder_uuid) == 0) && !LLMarketplaceData::instance().isUpdating(version_folder_uuid,version_depth))
+ else if (version_folder_uuid.notNull()
+ && gInventory.isCategoryComplete(version_folder_uuid)
+ && LLMarketplaceData::instance().getActivationState(version_folder_uuid)
+ && (count_descendants_items(version_folder_uuid) == 0)
+ && !LLMarketplaceData::instance().isUpdating(version_folder_uuid,version_depth))
{
LL_INFOS("SLM") << "Unlist as the version folder is empty of any item!!" << LL_ENDL;
LLNotificationsUtil::add("AlertMerchantVersionFolderEmpty");
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 9a33e210ff..5230e8dff9 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -582,7 +582,7 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
// Add the category to the internal representation
LLPointer<LLViewerInventoryCategory> cat =
new LLViewerInventoryCategory(id, parent_id, preferred_type, name, gAgent.getID());
- cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL);
+ cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
cat->setDescendentCount(0);
LLCategoryUpdate update(cat->getParentUUID(), 1);
accountForUpdate(update);
@@ -640,7 +640,7 @@ void LLInventoryModel::createNewCategoryCoro(std::string url, LLSD postData, inv
result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
result["name"].asString(), gAgent.getID());
- cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL);
+ cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
cat->setDescendentCount(0);
LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
@@ -914,8 +914,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, category_id);
if( item_array )
{
+ LLInventoryModel::LLCategoryUpdate update(category_id, 1);
+ gInventory.accountForUpdate(update);
+
// *FIX: bit of a hack to call update server from here...
- new_item->updateServer(TRUE);
+ new_item->updateParentOnServer(FALSE);
item_array->push_back(new_item);
}
else
@@ -956,9 +959,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
item_array = get_ptr_in_map(mParentChildItemTree, parent_id);
if(item_array)
{
+ LLInventoryModel::LLCategoryUpdate update(parent_id, 1);
+ gInventory.accountForUpdate(update);
// *FIX: bit of a hack to call update server from
// here...
- new_item->updateServer(TRUE);
+ new_item->updateParentOnServer(FALSE);
item_array->push_back(new_item);
}
else
@@ -1045,7 +1050,6 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32
if(old_cat)
{
// We already have an old category, modify its values
- U32 mask = LLInventoryObserver::NONE;
LLUUID old_parent_id = old_cat->getParentUUID();
LLUUID new_parent_id = cat->getParentUUID();
if(old_parent_id != new_parent_id)
@@ -1100,7 +1104,8 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32
item_array_t* itemsp = new item_array_t;
mParentChildCategoryTree[new_cat->getUUID()] = catsp;
mParentChildItemTree[new_cat->getUUID()] = itemsp;
- addChangedMask(LLInventoryObserver::ADD, cat->getUUID());
+ mask |= LLInventoryObserver::ADD;
+ addChangedMask(mask, cat->getUUID());
}
}
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 8d21fda8f9..53b2ca2b74 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -64,6 +64,9 @@
#include "llurllineeditorctrl.h"
#include "llagentui.h"
+#include "llmenuoptionpathfindingrebakenavmesh.h"
+#include "llpathfindingmanager.h"
+
//============================================================================
/*
* "ADD LANDMARK" BUTTON UPDATING LOGIC
@@ -1194,6 +1197,18 @@ bool LLLocationInputCtrl::onLocationContextMenuItemEnabled(const LLSD& userdata)
return false;
}
+void LLLocationInputCtrl::callbackRebakeRegion(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0) // OK
+ {
+ if (LLPathfindingManager::getInstance() != NULL)
+ {
+ LLMenuOptionPathfindingRebakeNavmesh::getInstance()->sendRequestRebakeNavmesh();
+ }
+ }
+}
+
void LLLocationInputCtrl::onParcelIconClick(EParcelIcon icon)
{
switch (icon)
@@ -1211,6 +1226,16 @@ void LLLocationInputCtrl::onParcelIconClick(EParcelIcon icon)
LLNotificationsUtil::add("NoBuild");
break;
case PATHFINDING_DIRTY_ICON:
+ if (LLPathfindingManager::getInstance() != NULL)
+ {
+ LLMenuOptionPathfindingRebakeNavmesh *rebakeInstance = LLMenuOptionPathfindingRebakeNavmesh::getInstance();
+ if (rebakeInstance && rebakeInstance->canRebakeRegion() && (rebakeInstance->getMode() == LLMenuOptionPathfindingRebakeNavmesh::kRebakeNavMesh_Available))
+ {
+ LLNotificationsUtil::add("PathfindingDirtyRebake", LLSD(), LLSD(),
+ boost::bind(&LLLocationInputCtrl::callbackRebakeRegion, this, _1, _2));
+ break;
+ }
+ }
LLNotificationsUtil::add("PathfindingDirty");
break;
case PATHFINDING_DISABLED_ICON:
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
index cd6fd24077..da71bab6c1 100644
--- a/indra/newview/lllocationinputctrl.h
+++ b/indra/newview/lllocationinputctrl.h
@@ -166,6 +166,7 @@ private:
// callbacks
bool onLocationContextMenuItemEnabled(const LLSD& userdata);
void onLocationContextMenuItemClicked(const LLSD& userdata);
+ void callbackRebakeRegion(const LLSD& notification, const LLSD& response);
void onParcelIconClick(EParcelIcon icon);
void createNavMeshStatusListenerForCurrentRegion();
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 4116e38f11..485d4677b1 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -244,7 +244,10 @@ std::string LLLogChat::makeLogFileName(std::string filename)
filename = cleanFileName(filename);
filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename);
- filename += '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+ if (!filename.empty())
+ {
+ filename += '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+ }
return filename;
}
@@ -904,7 +907,7 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
std::string stuff = matches[IDX_STUFF];
boost::match_results<std::string::const_iterator> name_and_text;
if (!boost::regex_match(stuff, name_and_text, NAME_AND_TEXT)) return false;
-
+
bool has_name = name_and_text[IDX_NAME].matched;
std::string name = name_and_text[IDX_NAME];
@@ -956,7 +959,6 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
im[LL_IM_FROM] = name;
}
-
im[LL_IM_TEXT] = name_and_text[IDX_TEXT];
return true; //parsed name and message text, maybe have a timestamp too
}
diff --git a/indra/newview/llmanip.h b/indra/newview/llmanip.h
index 1fb05e047a..69881e8589 100644
--- a/indra/newview/llmanip.h
+++ b/indra/newview/llmanip.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file llmanip.h
* @brief LLManip class definition
*
@@ -37,7 +37,7 @@ class LLToolComposite;
class LLVector3;
class LLObjectSelection;
-const S32 MIN_DIVISION_PIXEL_WIDTH = 9;
+const S32 MIN_DIVISION_PIXEL_WIDTH = 3;
class LLManip : public LLTool
{
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index b4259a456c..3975d3980b 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llmaniptranslate.cpp
* @brief LLManipTranslate class implementation
*
@@ -548,12 +548,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
if (off_axis_magnitude > mSnapOffsetMeters)
{
mInSnapRegime = TRUE;
- LLVector3 mouse_down_offset(mDragCursorStartGlobal - mDragSelectionStartGlobal);
LLVector3 cursor_snap_agent = gAgent.getPosAgentFromGlobal(cursor_point_snap_line);
- if (!gSavedSettings.getBOOL("SnapToMouseCursor"))
- {
- cursor_snap_agent -= mouse_down_offset;
- }
F32 cursor_grid_dist = (cursor_snap_agent - mGridOrigin) * axis_f;
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 6cc7a0fc99..54f95520db 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -773,7 +773,9 @@ void LLMarketplaceData::getMerchantStatusCoro()
std::string url = getSLMConnectURL("/merchant");
if (url.empty())
{
- LL_INFOS("Marketplace") << "No marketplace capability on Sim" << LL_ENDL;
+ LL_WARNS("Marketplace") << "No marketplace capability on Sim" << LL_ENDL;
+ setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE);
+ return;
}
LLSD result = httpAdapter->getAndSuspend(httpRequest, url, httpOpts);
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 0aaed3e286..27b26efa51 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -3906,8 +3906,8 @@ void LLMeshRepository::buildHull(const LLVolumeParams& params, S32 detail)
bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
{
- LLSD mesh = mThread->getMeshHeader(mesh_id);
- if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
+ const LLSD* mesh = mThread->getMeshHeader(mesh_id);
+ if (mesh && mesh->has("physics_mesh") && (*mesh)["physics_mesh"].has("size") && ((*mesh)["physics_mesh"]["size"].asInteger() > 0))
{
return true;
}
@@ -3921,27 +3921,26 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
return false;
}
-LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id)
+const LLSD* LLMeshRepository::getMeshHeader(const LLUUID& mesh_id)
{
LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH);
return mThread->getMeshHeader(mesh_id);
}
-LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id)
+const LLSD* LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id)
{
- static LLSD dummy_ret;
if (mesh_id.notNull())
{
LLMutexLock lock(mHeaderMutex);
mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
- if (iter != mMeshHeader.end())
+ if (iter != mMeshHeader.end() && mMeshHeaderSize[mesh_id] > 0)
{
- return iter->second;
+ return &(iter->second);
}
}
- return dummy_ret;
+ return NULL;
}
@@ -4034,6 +4033,13 @@ void LLMeshRepository::uploadError(LLSD& args)
//static
F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value)
{
+ if (header.has("404")
+ || !header.has("lowest_lod")
+ || (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION))
+ {
+ return 0.f;
+ }
+
F32 max_distance = 512.f;
F32 dlowest = llmin(radius/0.03f, max_distance);
@@ -4093,7 +4099,7 @@ F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32
}
}
- F32 max_area = 102932.f; //area of circle that encompasses region
+ F32 max_area = 102944.f; //area of circle that encompasses region (see MAINT-6559)
F32 min_area = 1.f;
F32 high_area = llmin(F_PI*dmid*dmid, max_area);
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index d35c44397b..8a1166522f 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -305,7 +305,7 @@ public:
bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
- LLSD& getMeshHeader(const LLUUID& mesh_id);
+ const LLSD* getMeshHeader(const LLUUID& mesh_id);
void notifyLoadedMeshes();
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
@@ -506,7 +506,7 @@ public:
bool meshRezEnabled();
- LLSD& getMeshHeader(const LLUUID& mesh_id);
+ const LLSD* getMeshHeader(const LLUUID& mesh_id);
void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures,
bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload = true,
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index b2164c1f21..d17f5494a0 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -199,7 +199,7 @@ void LLPanelGroupGeneral::setupCtrls(LLPanel* panel_group)
mGroupNameEditor = panel_group->getChild<LLLineEditor>("group_name_editor");
- mGroupNameEditor->setPrevalidate( LLTextValidate::validateASCII );
+ mGroupNameEditor->setPrevalidate( LLTextValidate::validateASCIINoLeadingSpace );
}
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 4229419fce..c779ba5cdd 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -150,6 +150,7 @@ BOOL LLPanelMainInventory::postBuild()
LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
if (recent_items_panel)
{
+ // assign default values until we will be sure that we have setting to restore
recent_items_panel->setSinceLogoff(TRUE);
recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
@@ -181,6 +182,7 @@ BOOL LLPanelMainInventory::postBuild()
LLParamSDParser parser;
parser.readSD(recent_items, p);
recent_items_panel->getFilter().fromParams(p);
+ recent_items_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::RECENTITEMS_SORT_ORDER));
}
}
@@ -372,7 +374,14 @@ void LLPanelMainInventory::setSortBy(const LLSD& userdata)
}
getActivePanel()->setSortOrder(sort_order_mask);
- gSavedSettings.setU32("InventorySortOrder", sort_order_mask);
+ if ("Recent Items" == getActivePanel()->getName())
+ {
+ gSavedSettings.setU32("RecentItemsSortOrder", sort_order_mask);
+ }
+ else
+ {
+ gSavedSettings.setU32("InventorySortOrder", sort_order_mask);
+ }
}
// static
@@ -1143,6 +1152,15 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
}
}
+void LLPanelMainInventory::onVisibilityChange( BOOL new_visibility )
+{
+ if(!new_visibility)
+ {
+ mMenuAdd->setVisible(FALSE);
+ getActivePanel()->getRootFolder()->finishRenamingItem();
+ }
+}
+
bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata)
{
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index 21f0ca0cae..290e2e5f47 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -72,6 +72,7 @@ public:
std::string& tooltip_msg);
/*virtual*/ void changed(U32);
/*virtual*/ void draw();
+ /*virtual*/ void onVisibilityChange ( BOOL new_visibility );
LLInventoryPanel* getPanel() { return mActivePanel; }
LLInventoryPanel* getActivePanel() { return mActivePanel; }
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 8331c152e2..8b9941c0ca 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -1059,9 +1059,6 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void)
case LLAssetType::AT_BODYPART:
applyListViewFilter(LVIT_BODYPART);
break;
- case LLAssetType::AT_GESTURE:
- applyListViewFilter(LVIT_GESTURES);
- break;
case LLAssetType::AT_CLOTHING:
default:
applyListViewFilter(LVIT_CLOTHING);
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index 841bb4337a..30870daf40 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -80,7 +80,6 @@ public:
{
LVIT_ALL = 0,
LVIT_CLOTHING,
- LVIT_GESTURES,
LVIT_BODYPART,
LVIT_ATTACHMENT,
LVIT_SHAPE,
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 73b928f014..bc177abc57 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -611,9 +611,11 @@ BOOL LLPanelPeople::postBuild()
mOnlineFriendList->setNoItemsCommentText(getString("no_friends_online"));
mOnlineFriendList->setShowIcons("FriendsListShowIcons");
mOnlineFriendList->showPermissions("FriendsListShowPermissions");
+ mOnlineFriendList->setShowCompleteName(!gSavedSettings.getBOOL("FriendsListHideUsernames"));
mAllFriendList->setNoItemsCommentText(getString("no_friends"));
mAllFriendList->setShowIcons("FriendsListShowIcons");
mAllFriendList->showPermissions("FriendsListShowPermissions");
+ mAllFriendList->setShowCompleteName(!gSavedSettings.getBOOL("FriendsListHideUsernames"));
LLPanel* nearby_tab = getChild<LLPanel>(NEARBY_TAB_NAME);
nearby_tab->setVisibleCallback(boost::bind(&Updater::setActive, mNearbyListUpdater, _2));
@@ -622,6 +624,7 @@ BOOL LLPanelPeople::postBuild()
mNearbyList->setNoItemsMsg(getString("no_one_near"));
mNearbyList->setNoFilteredItemsMsg(getString("no_one_filtered_near"));
mNearbyList->setShowIcons("NearbyListShowIcons");
+ mNearbyList->setShowCompleteName(!gSavedSettings.getBOOL("NearbyListHideUsernames"));
mMiniMap = (LLNetMap*)getChildView("Net Map",true);
mMiniMap->setToolTipMsg(gSavedSettings.getBOOL("DoubleClickTeleport") ?
getString("AltMiniMapToolTipMsg") : getString("MiniMapToolTipMsg"));
@@ -1342,6 +1345,16 @@ void LLPanelPeople::onFriendsViewSortMenuItemClicked(const LLSD& userdata)
mAllFriendList->showPermissions(show_permissions);
mOnlineFriendList->showPermissions(show_permissions);
}
+ else if (chosen_item == "view_usernames")
+ {
+ bool hide_usernames = !gSavedSettings.getBOOL("FriendsListHideUsernames");
+ gSavedSettings.setBOOL("FriendsListHideUsernames", hide_usernames);
+
+ mAllFriendList->setShowCompleteName(!hide_usernames);
+ mAllFriendList->handleDisplayNamesOptionChanged();
+ mOnlineFriendList->setShowCompleteName(!hide_usernames);
+ mOnlineFriendList->handleDisplayNamesOptionChanged();
+ }
}
void LLPanelPeople::onGroupsViewSortMenuItemClicked(const LLSD& userdata)
@@ -1374,6 +1387,14 @@ void LLPanelPeople::onNearbyViewSortMenuItemClicked(const LLSD& userdata)
{
setSortOrder(mNearbyList, E_SORT_BY_DISTANCE);
}
+ else if (chosen_item == "view_usernames")
+ {
+ bool hide_usernames = !gSavedSettings.getBOOL("NearbyListHideUsernames");
+ gSavedSettings.setBOOL("NearbyListHideUsernames", hide_usernames);
+
+ mNearbyList->setShowCompleteName(!hide_usernames);
+ mNearbyList->handleDisplayNamesOptionChanged();
+ }
}
bool LLPanelPeople::onNearbyViewSortMenuItemCheck(const LLSD& userdata)
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index a5f59dbf4a..65769ff526 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -38,9 +38,14 @@
#include "llavataractions.h"
#include "llcallingcard.h" // for LLAvatarTracker
#include "lllogchat.h"
+#include "llparcel.h"
#include "llviewermenu.h" // for gMenuHolder
#include "llconversationmodel.h"
#include "llviewerobjectlist.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+#include "llvoavatarself.h"
+#include "roles_constants.h"
namespace LLPanelPeopleMenus
{
@@ -77,9 +82,13 @@ LLContextMenu* PeopleContextMenu::createMenu()
registrar.add("Avatar.InviteToGroup", boost::bind(&LLAvatarActions::inviteToGroup, id));
registrar.add("Avatar.TeleportRequest", boost::bind(&PeopleContextMenu::requestTeleport, this));
registrar.add("Avatar.Calllog", boost::bind(&LLAvatarActions::viewChatHistory, id));
+ registrar.add("Avatar.Freeze", boost::bind(&LLAvatarActions::freezeAvatar, id));
+ registrar.add("Avatar.Eject", boost::bind(&PeopleContextMenu::eject, this));
+
enable_registrar.add("Avatar.EnableItem", boost::bind(&PeopleContextMenu::enableContextMenuItem, this, _2));
enable_registrar.add("Avatar.CheckItem", boost::bind(&PeopleContextMenu::checkContextMenuItem, this, _2));
+ enable_registrar.add("Avatar.EnableFreezeEject", boost::bind(&PeopleContextMenu::enableFreezeEject, this, _2));
// create the context menu from the XUI
menu = createFromFile("menu_people_nearby.xml");
@@ -258,6 +267,50 @@ bool PeopleContextMenu::checkContextMenuItem(const LLSD& userdata)
return false;
}
+bool PeopleContextMenu::enableFreezeEject(const LLSD& userdata)
+{
+ if((gAgent.getID() == mUUIDs.front()) || (mUUIDs.size() != 1))
+ {
+ return false;
+ }
+
+ const LLUUID& id = mUUIDs.front();
+
+ // Use avatar_id if available, otherwise default to right-click avatar
+ LLVOAvatar* avatar = NULL;
+ if (id.notNull())
+ {
+ LLViewerObject* object = gObjectList.findObject(id);
+ if (object)
+ {
+ if( !object->isAvatar() )
+ {
+ object = NULL;
+ }
+ avatar = (LLVOAvatar*) object;
+ }
+ }
+ if (!avatar) return false;
+
+ // Gods can always freeze
+ if (gAgent.isGodlike()) return true;
+
+ // Estate owners / managers can freeze
+ // Parcel owners can also freeze
+ const LLVector3& pos = avatar->getPositionRegion();
+ const LLVector3d& pos_global = avatar->getPositionGlobal();
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos_global)->getParcel();
+ LLViewerRegion* region = avatar->getRegion();
+ if (!region) return false;
+
+ bool new_value = region->isOwnedSelf(pos);
+ if (!new_value || region->isOwnedGroup(pos))
+ {
+ new_value = LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_ADMIN);
+ }
+ return new_value;
+}
+
void PeopleContextMenu::requestTeleport()
{
// boost::bind cannot recognize overloaded method LLAvatarActions::teleportRequest(),
@@ -272,6 +325,39 @@ void PeopleContextMenu::offerTeleport()
LLAvatarActions::offerTeleport(mUUIDs);
}
+void PeopleContextMenu::eject()
+{
+ if((gAgent.getID() == mUUIDs.front()) || (mUUIDs.size() != 1))
+ {
+ return;
+ }
+
+ const LLUUID& id = mUUIDs.front();
+
+ // Use avatar_id if available, otherwise default to right-click avatar
+ LLVOAvatar* avatar = NULL;
+ if (id.notNull())
+ {
+ LLViewerObject* object = gObjectList.findObject(id);
+ if (object)
+ {
+ if( !object->isAvatar() )
+ {
+ object = NULL;
+ }
+ avatar = (LLVOAvatar*) object;
+ }
+ }
+ if (!avatar) return;
+ LLSD payload;
+ payload["avatar_id"] = avatar->getID();
+ std::string fullname = avatar->getFullname();
+
+ const LLVector3d& pos = avatar->getPositionGlobal();
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos)->getParcel();
+ LLAvatarActions::ejectAvatar(id ,LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_MANAGE_BANNED));
+}
+
void PeopleContextMenu::startConference()
{
uuid_vec_t uuids;
@@ -320,6 +406,8 @@ void NearbyPeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
items.push_back(std::string("share"));
items.push_back(std::string("pay"));
items.push_back(std::string("block_unblock"));
+ items.push_back(std::string("freeze"));
+ items.push_back(std::string("eject"));
}
hide_context_entries(menu, items, disabled_items);
diff --git a/indra/newview/llpanelpeoplemenus.h b/indra/newview/llpanelpeoplemenus.h
index 9767bab89f..5ed20e0064 100644
--- a/indra/newview/llpanelpeoplemenus.h
+++ b/indra/newview/llpanelpeoplemenus.h
@@ -46,7 +46,9 @@ protected:
private:
bool enableContextMenuItem(const LLSD& userdata);
bool checkContextMenuItem(const LLSD& userdata);
+ bool enableFreezeEject(const LLSD& userdata);
void offerTeleport();
+ void eject();
void startConference();
void requestTeleport();
};
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index e795e7eedb..184238c40c 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -176,6 +176,16 @@ public:
return true;
}
+ if (verb == "unblock")
+ {
+ if (params.size() > 2)
+ {
+ const std::string object_name = params[2].asString();
+ LLMute mute(avatar_id, object_name, LLMute::OBJECT);
+ LLMuteList::getInstance()->remove(mute);
+ }
+ return true;
+ }
return false;
}
};
diff --git a/indra/newview/llpanelsnapshotinventory.cpp b/indra/newview/llpanelsnapshotinventory.cpp
index c55e230b5e..a2d1752c6a 100644
--- a/indra/newview/llpanelsnapshotinventory.cpp
+++ b/indra/newview/llpanelsnapshotinventory.cpp
@@ -34,6 +34,8 @@
#include "llfloatersnapshot.h" // FIXME: replace with a snapshot storage model
#include "llpanelsnapshot.h"
#include "llviewercontrol.h" // gSavedSettings
+#include "llstatusbar.h" // can_afford_transaction()
+#include "llnotificationsutil.h"
/**
* The panel provides UI for saving snapshot as an inventory texture.
@@ -102,6 +104,17 @@ void LLPanelSnapshotInventory::onResolutionCommit(LLUICtrl* ctrl)
void LLPanelSnapshotInventory::onSend()
{
- LLFloaterSnapshot::saveTexture();
- LLFloaterSnapshot::postSave();
+ S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+ if (can_afford_transaction(expected_upload_cost))
+ {
+ LLFloaterSnapshot::saveTexture();
+ LLFloaterSnapshot::postSave();
+ }
+ else
+ {
+ LLSD args;
+ args["COST"] = llformat("%d", expected_upload_cost);
+ LLNotificationsUtil::add("ErrorPhotoCannotAfford", args);
+ LLFloaterSnapshot::inventorySaveFailed();
+ }
}
diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp
index d86a8b4480..796372ba04 100644
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -30,13 +30,19 @@
#include "lltoggleablemenu.h"
+#include "llagent.h"
+#include "llaccordionctrl.h"
+#include "llaccordionctrltab.h"
#include "llappearancemgr.h"
#include "llfloatersidepanelcontainer.h"
#include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
#include "llinventorymodel.h"
#include "llinventoryobserver.h"
#include "llmenubutton.h"
+#include "llscrolllistctrl.h"
#include "llviewermenu.h"
+#include "llviewerregion.h"
#include "llwearableitemslist.h"
#include "llsdserialize.h"
#include "llclipboard.h"
@@ -94,6 +100,7 @@ protected:
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("Wearing.Edit", boost::bind(&edit_outfit));
+ registrar.add("Wearing.ShowOriginal", boost::bind(show_item_original, mUUIDs.front()));
registrar.add("Wearing.TakeOff",
boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
registrar.add("Wearing.Detach",
@@ -144,11 +151,48 @@ protected:
menu->setItemVisible("take_off", allow_take_off);
menu->setItemVisible("detach", allow_detach);
menu->setItemVisible("edit_outfit_separator", allow_take_off || allow_detach);
+ menu->setItemVisible("show_original", mUUIDs.size() == 1);
+ menu->setItemVisible("edit_item", FALSE);
}
};
//////////////////////////////////////////////////////////////////////////
+class LLTempAttachmentsContextMenu : public LLListContextMenu
+{
+public:
+ LLTempAttachmentsContextMenu(LLPanelWearing* panel_wearing)
+ : mPanelWearing(panel_wearing)
+ {}
+protected:
+ /* virtual */ LLContextMenu* createMenu()
+ {
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+
+ registrar.add("Wearing.EditItem", boost::bind(&LLPanelWearing::onEditAttachment, mPanelWearing));
+ registrar.add("Wearing.Detach", boost::bind(&LLPanelWearing::onRemoveAttachment, mPanelWearing));
+ LLContextMenu* menu = createFromFile("menu_wearing_tab.xml");
+
+ updateMenuItemsVisibility(menu);
+
+ return menu;
+ }
+
+ void updateMenuItemsVisibility(LLContextMenu* menu)
+ {
+ menu->setItemVisible("take_off", FALSE);
+ menu->setItemVisible("detach", TRUE);
+ menu->setItemVisible("edit_outfit_separator", TRUE);
+ menu->setItemVisible("show_original", FALSE);
+ menu->setItemVisible("edit_item", TRUE);
+ menu->setItemVisible("edit", FALSE);
+ }
+
+ LLPanelWearing* mPanelWearing;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
std::string LLPanelAppearanceTab::sFilterSubString = LLStringUtil::null;
static LLPanelInjector<LLPanelWearing> t_panel_wearing("panel_wearing");
@@ -157,30 +201,47 @@ LLPanelWearing::LLPanelWearing()
: LLPanelAppearanceTab()
, mCOFItemsList(NULL)
, mIsInitialized(false)
+ , mAttachmentsChangedConnection()
{
mCategoriesObserver = new LLInventoryCategoriesObserver();
mGearMenu = new LLWearingGearMenu(this);
mContextMenu = new LLWearingContextMenu();
+ mAttachmentsMenu = new LLTempAttachmentsContextMenu(this);
}
LLPanelWearing::~LLPanelWearing()
{
delete mGearMenu;
delete mContextMenu;
+ delete mAttachmentsMenu;
if (gInventory.containsObserver(mCategoriesObserver))
{
gInventory.removeObserver(mCategoriesObserver);
}
delete mCategoriesObserver;
+
+ if (mAttachmentsChangedConnection.connected())
+ {
+ mAttachmentsChangedConnection.disconnect();
+ }
}
BOOL LLPanelWearing::postBuild()
{
+ mAccordionCtrl = getChild<LLAccordionCtrl>("wearables_accordion");
+ mWearablesTab = getChild<LLAccordionCtrlTab>("tab_wearables");
+ mAttachmentsTab = getChild<LLAccordionCtrlTab>("tab_temp_attachments");
+ mAttachmentsTab->setDropDownStateChangedCallback(boost::bind(&LLPanelWearing::onAccordionTabStateChanged, this));
+
mCOFItemsList = getChild<LLWearableItemsList>("cof_items_list");
mCOFItemsList->setRightMouseDownCallback(boost::bind(&LLPanelWearing::onWearableItemsListRightClick, this, _1, _2, _3));
+ mTempItemsList = getChild<LLScrollListCtrl>("temp_attachments_list");
+ mTempItemsList->setFgUnselectedColor(LLColor4::white);
+ mTempItemsList->setRightMouseDownCallback(boost::bind(&LLPanelWearing::onTempAttachmentsListRightClick, this, _1, _2, _3));
+
LLMenuButton* menu_gear_btn = getChild<LLMenuButton>("options_gear_btn");
menu_gear_btn->setMenu(mGearMenu->getMenu());
@@ -221,6 +282,44 @@ void LLPanelWearing::onOpen(const LLSD& /*info*/)
}
}
+void LLPanelWearing::draw()
+{
+ if (mUpdateTimer.getStarted() && (mUpdateTimer.getElapsedTimeF32() > 0.1))
+ {
+ mUpdateTimer.stop();
+ updateAttachmentsList();
+ }
+ LLPanel::draw();
+}
+
+void LLPanelWearing::onAccordionTabStateChanged()
+{
+ if(mAttachmentsTab->isExpanded())
+ {
+ startUpdateTimer();
+ mAttachmentsChangedConnection = LLAppearanceMgr::instance().setAttachmentsChangedCallback(boost::bind(&LLPanelWearing::startUpdateTimer, this));
+ }
+ else
+ {
+ if (mAttachmentsChangedConnection.connected())
+ {
+ mAttachmentsChangedConnection.disconnect();
+ }
+ }
+}
+
+void LLPanelWearing::startUpdateTimer()
+{
+ if (!mUpdateTimer.getStarted())
+ {
+ mUpdateTimer.start();
+ }
+ else
+ {
+ mUpdateTimer.reset();
+ }
+}
+
// virtual
void LLPanelWearing::setFilterSubString(const std::string& string)
{
@@ -249,6 +348,124 @@ bool LLPanelWearing::isActionEnabled(const LLSD& userdata)
return false;
}
+void LLPanelWearing::updateAttachmentsList()
+{
+ std::vector<LLViewerObject*> attachs = LLAgentWearables::getTempAttachments();
+ mTempItemsList->deleteAllItems();
+ mAttachmentsMap.clear();
+ if(!attachs.empty())
+ {
+ if(!populateAttachmentsList())
+ {
+ requestAttachmentDetails();
+ }
+ }
+ else
+ {
+ std::string no_attachments = getString("no_attachments");
+ LLSD row;
+ row["columns"][0]["column"] = "text";
+ row["columns"][0]["value"] = no_attachments;
+ row["columns"][0]["font"] = "SansSerifBold";
+ mTempItemsList->addElement(row);
+ }
+}
+
+bool LLPanelWearing::populateAttachmentsList(bool update)
+{
+ bool populated = true;
+ if(mTempItemsList)
+ {
+ mTempItemsList->deleteAllItems();
+ mAttachmentsMap.clear();
+ std::vector<LLViewerObject*> attachs = LLAgentWearables::getTempAttachments();
+
+ std::string icon_name = LLInventoryIcon::getIconName(LLAssetType::AT_OBJECT, LLInventoryType::IT_OBJECT);
+ for (std::vector<LLViewerObject*>::iterator iter = attachs.begin();
+ iter != attachs.end(); ++iter)
+ {
+ LLViewerObject *attachment = *iter;
+ LLSD row;
+ row["id"] = attachment->getID();
+ row["columns"][0]["column"] = "icon";
+ row["columns"][0]["type"] = "icon";
+ row["columns"][0]["value"] = icon_name;
+ row["columns"][1]["column"] = "text";
+ if(mObjectNames.count(attachment->getID()) && !mObjectNames[attachment->getID()].empty())
+ {
+ row["columns"][1]["value"] = mObjectNames[attachment->getID()];
+ }
+ else if(update)
+ {
+ row["columns"][1]["value"] = attachment->getID();
+ populated = false;
+ }
+ else
+ {
+ row["columns"][1]["value"] = "Loading...";
+ populated = false;
+ }
+ mTempItemsList->addElement(row);
+ mAttachmentsMap[attachment->getID()] = attachment;
+ }
+ }
+ return populated;
+}
+
+void LLPanelWearing::requestAttachmentDetails()
+{
+ LLSD body;
+ std::string url = gAgent.getRegion()->getCapability("AttachmentResources");
+ if (!url.empty())
+ {
+ LLCoros::instance().launch("LLPanelWearing::getAttachmentLimitsCoro",
+ boost::bind(&LLPanelWearing::getAttachmentLimitsCoro, this, url));
+ }
+}
+
+void LLPanelWearing::getAttachmentLimitsCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getAttachmentLimitsCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS() << "Unable to retrieve attachment limits." << LL_ENDL;
+ return;
+ }
+
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ setAttachmentDetails(result);
+}
+
+
+void LLPanelWearing::setAttachmentDetails(LLSD content)
+{
+ mObjectNames.clear();
+ S32 number_attachments = content["attachments"].size();
+ for(int i = 0; i < number_attachments; i++)
+ {
+ S32 number_objects = content["attachments"][i]["objects"].size();
+ for(int j = 0; j < number_objects; j++)
+ {
+ LLUUID task_id = content["attachments"][i]["objects"][j]["id"].asUUID();
+ std::string name = content["attachments"][i]["objects"][j]["name"].asString();
+ mObjectNames[task_id] = name;
+ }
+ }
+ if(!mObjectNames.empty())
+ {
+ populateAttachmentsList(true);
+ }
+}
+
boost::signals2::connection LLPanelWearing::setSelectionChangeCallback(commit_callback_t cb)
{
if (!mCOFItemsList) return boost::signals2::connection();
@@ -268,6 +485,20 @@ void LLPanelWearing::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
mContextMenu->show(ctrl, selected_uuids, x, y);
}
+void LLPanelWearing::onTempAttachmentsListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
+{
+ LLScrollListCtrl* list = dynamic_cast<LLScrollListCtrl*>(ctrl);
+ if (!list) return;
+ list->selectItemAt(x, y, MASK_NONE);
+ uuid_vec_t selected_uuids;
+
+ if(list->getCurrentID().notNull())
+ {
+ selected_uuids.push_back(list->getCurrentID());
+ mAttachmentsMenu->show(ctrl, selected_uuids, x, y);
+ }
+}
+
bool LLPanelWearing::hasItemSelected()
{
return mCOFItemsList->getSelectedItem() != NULL;
@@ -278,6 +509,28 @@ void LLPanelWearing::getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const
mCOFItemsList->getSelectedUUIDs(selected_uuids);
}
+void LLPanelWearing::onEditAttachment()
+{
+ LLScrollListItem* item = mTempItemsList->getFirstSelected();
+ if (item)
+ {
+ LLSelectMgr::getInstance()->deselectAll();
+ LLSelectMgr::getInstance()->selectObjectAndFamily(mAttachmentsMap[item->getUUID()]);
+ handle_object_edit();
+ }
+}
+
+void LLPanelWearing::onRemoveAttachment()
+{
+ LLScrollListItem* item = mTempItemsList->getFirstSelected();
+ if (item)
+ {
+ LLSelectMgr::getInstance()->deselectAll();
+ LLSelectMgr::getInstance()->selectObjectAndFamily(mAttachmentsMap[item->getUUID()]);
+ LLSelectMgr::getInstance()->sendDropAttachment();
+ }
+}
+
void LLPanelWearing::copyToClipboard()
{
std::string text;
diff --git a/indra/newview/llpanelwearing.h b/indra/newview/llpanelwearing.h
index 9a212b3cca..c5cb79092a 100644
--- a/indra/newview/llpanelwearing.h
+++ b/indra/newview/llpanelwearing.h
@@ -31,9 +31,14 @@
// newview
#include "llpanelappearancetab.h"
+#include "llselectmgr.h"
+#include "lltimer.h"
+class LLAccordionCtrl;
+class LLAccordionCtrlTab;
class LLInventoryCategoriesObserver;
class LLListContextMenu;
+class LLScrollListCtrl;
class LLWearableItemsList;
class LLWearingGearMenu;
@@ -52,6 +57,8 @@ public:
/*virtual*/ BOOL postBuild();
+ /*virtual*/ void draw();
+
/*virtual*/ void onOpen(const LLSD& info);
/*virtual*/ void setFilterSubString(const std::string& string);
@@ -62,17 +69,43 @@ public:
/*virtual*/ void copyToClipboard();
+ void startUpdateTimer();
+ void updateAttachmentsList();
+
boost::signals2::connection setSelectionChangeCallback(commit_callback_t cb);
bool hasItemSelected();
+ bool populateAttachmentsList(bool update = false);
+ void onAccordionTabStateChanged();
+ void setAttachmentDetails(LLSD content);
+ void requestAttachmentDetails();
+ void onEditAttachment();
+ void onRemoveAttachment();
+
private:
void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
+ void onTempAttachmentsListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
+
+ void getAttachmentLimitsCoro(std::string url);
LLInventoryCategoriesObserver* mCategoriesObserver;
LLWearableItemsList* mCOFItemsList;
+ LLScrollListCtrl* mTempItemsList;
LLWearingGearMenu* mGearMenu;
LLListContextMenu* mContextMenu;
+ LLListContextMenu* mAttachmentsMenu;
+
+ LLAccordionCtrlTab* mWearablesTab;
+ LLAccordionCtrlTab* mAttachmentsTab;
+ LLAccordionCtrl* mAccordionCtrl;
+
+ std::map<LLUUID, LLViewerObject*> mAttachmentsMap;
+
+ std::map<LLUUID, std::string> mObjectNames;
+
+ boost::signals2::connection mAttachmentsChangedConnection;
+ LLFrameTimer mUpdateTimer;
bool mIsInitialized;
};
diff --git a/indra/newview/llpathfindinglinksetlist.cpp b/indra/newview/llpathfindinglinksetlist.cpp
index b886e46765..eb7b95552e 100644
--- a/indra/newview/llpathfindinglinksetlist.cpp
+++ b/indra/newview/llpathfindinglinksetlist.cpp
@@ -204,7 +204,10 @@ void LLPathfindingLinksetList::parseLinksetListData(const LLSD& pLinksetListData
{
const std::string& uuid(linksetDataIter->first);
const LLSD& linksetData = linksetDataIter->second;
- LLPathfindingObjectPtr linksetPtr(new LLPathfindingLinkset(uuid, linksetData));
- objectMap.insert(std::pair<std::string, LLPathfindingObjectPtr>(uuid, linksetPtr));
+ if(linksetData.size() != 0)
+ {
+ LLPathfindingObjectPtr linksetPtr(new LLPathfindingLinkset(uuid, linksetData));
+ objectMap.insert(std::pair<std::string, LLPathfindingObjectPtr>(uuid, linksetPtr));
+ }
}
}
diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp
index d95546f11d..836f63bffa 100644
--- a/indra/newview/llpresetsmanager.cpp
+++ b/indra/newview/llpresetsmanager.cpp
@@ -38,6 +38,7 @@
#include "llviewercontrol.h"
#include "llfloaterpreference.h"
#include "llfloaterreg.h"
+#include "llfeaturemanager.h"
LLPresetsManager::LLPresetsManager()
{
@@ -60,7 +61,7 @@ void LLPresetsManager::createMissingDefault()
LL_INFOS() << "No default preset found -- creating one at " << default_file << LL_ENDL;
// Write current graphic settings as the default
- savePreset(PRESETS_GRAPHIC, PRESETS_DEFAULT);
+ savePreset(PRESETS_GRAPHIC, PRESETS_DEFAULT, true);
}
else
{
@@ -103,8 +104,7 @@ void LLPresetsManager::loadPresetNamesFromDir(const std::string& dir, preset_nam
if (found)
{
std::string path = gDirUtilp->add(dir, file);
- std::string name = gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true);
-
+ std::string name = LLURI::unescape(gDirUtilp->getBaseFileName(path, /*strip_exten = */ true));
LL_DEBUGS() << " Found preset '" << name << "'" << LL_ENDL;
if (PRESETS_DEFAULT != name)
@@ -134,7 +134,7 @@ void LLPresetsManager::loadPresetNamesFromDir(const std::string& dir, preset_nam
presets = mPresetNames;
}
-bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string name)
+bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string name, bool createDefault)
{
if (LLTrans::getString(PRESETS_DEFAULT) == name)
{
@@ -146,11 +146,10 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n
if(PRESETS_GRAPHIC == subdirectory)
{
- gSavedSettings.setString("PresetGraphicActive", name);
-
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
- if (instance)
+ if (instance && !createDefault)
{
+ gSavedSettings.setString("PresetGraphicActive", name);
instance->getControlNames(name_list);
LL_DEBUGS() << "saving preset '" << name << "'; " << name_list.size() << " names" << LL_ENDL;
name_list.push_back("PresetGraphicActive");
@@ -170,23 +169,36 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n
LL_ERRS() << "Invalid presets directory '" << subdirectory << "'" << LL_ENDL;
}
- if (name_list.size() > 1) // if the active preset name is the only thing in the list, don't save the list
+ if (name_list.size() > 1 // if the active preset name is the only thing in the list, don't save the list
+ || (createDefault && name == PRESETS_DEFAULT && subdirectory == PRESETS_GRAPHIC)) // or create a default graphics preset from hw recommended settings
{
// make an empty llsd
LLSD paramsData(LLSD::emptyMap());
- for (std::vector<std::string>::iterator it = name_list.begin(); it != name_list.end(); ++it)
+ if (createDefault)
{
- std::string ctrl_name = *it;
- LLControlVariable* ctrl = gSavedSettings.getControl(ctrl_name).get();
- std::string comment = ctrl->getComment();
- std::string type = LLControlGroup::typeEnumToString(ctrl->type());
- LLSD value = ctrl->getValue();
-
- paramsData[ctrl_name]["Comment"] = comment;
- paramsData[ctrl_name]["Persist"] = 1;
- paramsData[ctrl_name]["Type"] = type;
- paramsData[ctrl_name]["Value"] = value;
+ paramsData = LLFeatureManager::getInstance()->getRecommendedSettingsMap();
+ if (gSavedSettings.getU32("RenderAvatarMaxComplexity") == 0)
+ {
+ // use the recommended setting as an initial one (MAINT-6435)
+ gSavedSettings.setU32("RenderAvatarMaxComplexity", paramsData["RenderAvatarMaxComplexity"]["Value"].asInteger());
+ }
+ }
+ else
+ {
+ for (std::vector<std::string>::iterator it = name_list.begin(); it != name_list.end(); ++it)
+ {
+ std::string ctrl_name = *it;
+ LLControlVariable* ctrl = gSavedSettings.getControl(ctrl_name).get();
+ std::string comment = ctrl->getComment();
+ std::string type = LLControlGroup::typeEnumToString(ctrl->type());
+ LLSD value = ctrl->getValue();
+
+ paramsData[ctrl_name]["Comment"] = comment;
+ paramsData[ctrl_name]["Persist"] = 1;
+ paramsData[ctrl_name]["Type"] = type;
+ paramsData[ctrl_name]["Value"] = value;
+ }
}
std::string pathName(getPresetsDir(subdirectory) + gDirUtilp->getDirDelimiter() + LLURI::escape(name) + ".xml");
@@ -203,10 +215,12 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n
LL_DEBUGS() << "saved preset '" << name << "'; " << paramsData.size() << " parameters" << LL_ENDL;
- gSavedSettings.setString("PresetGraphicActive", name);
-
- // signal interested parties
- triggerChangeSignal();
+ if (!createDefault)
+ {
+ gSavedSettings.setString("PresetGraphicActive", name);
+ // signal interested parties
+ triggerChangeSignal();
+ }
}
else
{
diff --git a/indra/newview/llpresetsmanager.h b/indra/newview/llpresetsmanager.h
index ac4f0c010c..21f9885f27 100644
--- a/indra/newview/llpresetsmanager.h
+++ b/indra/newview/llpresetsmanager.h
@@ -56,7 +56,7 @@ public:
static std::string getPresetsDir(const std::string& subdirectory);
void setPresetNamesInComboBox(const std::string& subdirectory, LLComboBox* combo, EDefaultOptions default_option);
void loadPresetNamesFromDir(const std::string& dir, preset_name_list_t& presets, EDefaultOptions default_option);
- bool savePreset(const std::string& subdirectory, std::string name);
+ bool savePreset(const std::string& subdirectory, std::string name, bool createDefault = false);
void loadPreset(const std::string& subdirectory, std::string name);
bool deletePreset(const std::string& subdirectory, std::string name);
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 20c43bc432..510d91839d 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -94,7 +94,8 @@ BOOL LLPreviewNotecard::postBuild()
if (item)
{
getChild<LLUICtrl>("desc")->setValue(item->getDescription());
- getChildView("Delete")->setEnabled(true);
+ BOOL source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(item->getUUID(), gInventory.getLibraryRootFolderID());
+ getChildView("Delete")->setEnabled(!source_library);
}
getChild<LLLineEditor>("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
@@ -219,6 +220,7 @@ void LLPreviewNotecard::loadAsset()
BOOL is_owner = gAgent.allowOperation(PERM_OWNER, perm, GP_OBJECT_MANIPULATE);
BOOL allow_copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE);
BOOL allow_modify = canModify(mObjectUUID, item);
+ BOOL source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID());
if (allow_copy || gAgent.isGodlike())
{
@@ -288,7 +290,7 @@ void LLPreviewNotecard::loadAsset()
getChildView("lock")->setVisible( TRUE);
}
- if(allow_modify || is_owner)
+ if((allow_modify || is_owner) && !source_library)
{
getChildView("Delete")->setEnabled(TRUE);
}
@@ -435,6 +437,23 @@ void LLPreviewNotecard::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId,
}
}
+void LLPreviewNotecard::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId)
+{
+
+ LLSD floater_key;
+ floater_key["taskid"] = taskId;
+ floater_key["itemid"] = itemId;
+ LLPreviewNotecard* nc = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", floater_key);
+ if (nc)
+ {
+ if (nc->hasEmbeddedInventory())
+ {
+ gVFS->removeFile(newAssetId, LLAssetType::AT_NOTECARD);
+ }
+ nc->setAssetId(newAssetId);
+ nc->refreshFromInventory();
+ }
+}
bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
{
@@ -483,7 +502,7 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
else if (!mObjectUUID.isNull() && !task_url.empty())
{
uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mObjectUUID, mItemUUID, LLAssetType::AT_NOTECARD, buffer,
- boost::bind(&LLPreviewNotecard::finishInventoryUpload, _1, _3, LLUUID::null)));
+ boost::bind(&LLPreviewNotecard::finishTaskUpload, _1, _3, mObjectUUID)));
url = task_url;
}
diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h
index ba571995f6..017c4485ba 100644
--- a/indra/newview/llpreviewnotecard.h
+++ b/indra/newview/llpreviewnotecard.h
@@ -96,6 +96,7 @@ protected:
bool handleConfirmDeleteDialog(const LLSD& notification, const LLSD& response);
static void finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId);
+ static void finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId);
protected:
LLViewerTextEditor* mEditor;
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 2a2c51be40..645a77e42a 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -38,6 +38,7 @@
#include "llimagetga.h"
#include "llimagepng.h"
#include "llinventory.h"
+#include "llinventorymodel.h"
#include "llnotificationsutil.h"
#include "llresmgr.h"
#include "lltrans.h"
@@ -120,18 +121,22 @@ BOOL LLPreviewTexture::postBuild()
childSetAction("save_tex_btn", LLPreviewTexture::onSaveAsBtn, this);
getChildView("save_tex_btn")->setVisible( true);
getChildView("save_tex_btn")->setEnabled(canSaveAs());
-
- if (!mCopyToInv)
- {
- const LLInventoryItem* item = getItem();
-
- if (item)
- {
- childSetCommitCallback("desc", LLPreview::onText, this);
- getChild<LLUICtrl>("desc")->setValue(item->getDescription());
- getChild<LLLineEditor>("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
- }
- }
+
+ const LLInventoryItem* item = getItem();
+ if (item)
+ {
+ if (!mCopyToInv)
+ {
+ childSetCommitCallback("desc", LLPreview::onText, this);
+ getChild<LLUICtrl>("desc")->setValue(item->getDescription());
+ getChild<LLLineEditor>("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
+ }
+ BOOL source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(item->getUUID(), gInventory.getLibraryRootFolderID());
+ if (source_library)
+ {
+ getChildView("Discard")->setEnabled(false);
+ }
+ }
// Fill in ratios list with common aspect ratio values
mRatiosList.clear();
@@ -526,6 +531,15 @@ void LLPreviewTexture::loadAsset()
// check that we can copy inworld items into inventory
getChildView("Keep")->setEnabled(mIsCopyable);
}
+ else
+ {
+ // check that we can remove item
+ BOOL source_library = gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID());
+ if (source_library)
+ {
+ getChildView("Discard")->setEnabled(false);
+ }
+ }
}
LLPreview::EAssetStatus LLPreviewTexture::getAssetStatus()
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 86135ee6e8..f07f0ed86c 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -383,7 +383,7 @@ void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_cam
void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLViewerWearable *wearable, BOOL disable_camera_switch)
{
- if (!mEditWearable || mEditWearable->getVisible() == visible)
+ if (!mEditWearable || ((mEditWearable->getWearable() == wearable) && mEditWearable->getVisible() == visible))
{
// visibility isn't changing, hence nothing to do
return;
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 88fbd233b8..4e81d78455 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -687,6 +687,11 @@ bool idle_startup()
gRememberPassword = gSavedSettings.getBOOL("RememberPassword");
show_connect_box = TRUE;
}
+
+ //setup map of datetime strings to codes and slt & local time offset from utc
+ // *TODO: Does this need to be here?
+ LLStringOps::setupDatetimeInfo(false);
+
// Go to the next startup state
LLStartUp::setStartupState( STATE_BROWSER_INIT );
return FALSE;
@@ -766,7 +771,11 @@ bool idle_startup()
LL_DEBUGS("AppInit") << "FirstLoginThisInstall off" << LL_ENDL;
}
}
-
+ display_startup();
+ if (gViewerWindow->getSystemUIScaleFactorChanged())
+ {
+ LLViewerWindow::showSystemUIScaleFactorChanged();
+ }
LLStartUp::setStartupState( STATE_LOGIN_WAIT ); // Wait for user input
}
else
@@ -1139,9 +1148,6 @@ bool idle_startup()
LLNotificationsUtil::add("ErrorMessage", args, LLSD(), login_alert_done);
}
}
- //setup map of datetime strings to codes and slt & local time offset from utc
- // *TODO: Does this need to be here?
- LLStringOps::setupDatetimeInfo (false);
transition_back_to_login_panel(emsg.str());
show_connect_box = true;
}
@@ -3310,6 +3316,13 @@ bool process_login_success_response()
{
time_t now = time(NULL);
gUTCOffset = (server_utc_time - now);
+
+ // Print server timestamp
+ LLSD substitution;
+ substitution["datetime"] = (S32)server_utc_time;
+ std::string timeStr = "[month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second, datetime, slt]";
+ LLStringUtil::format(timeStr, substitution);
+ LL_INFOS("AppInit") << "Server SLT timestamp: " << timeStr << ". Server-viewer time offset before correction: " << gUTCOffset << "s" << LL_ENDL;
}
}
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 7020ac0c65..edde7c8076 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -202,6 +202,21 @@ void LLToast::hide()
}
}
+/*virtual*/
+void LLToast::setFocus(BOOL b)
+{
+ if (b && !hasFocus() && mPanel)
+ {
+ LLModalDialog::setFocus(TRUE);
+ // mostly for buttons
+ mPanel->setFocus(TRUE);
+ }
+ else
+ {
+ LLModalDialog::setFocus(b);
+ }
+}
+
void LLToast::onFocusLost()
{
if(mWrapperPanel && !isBackgroundVisible())
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index f02d7c2a1a..cd92189012 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -150,6 +150,8 @@ public:
//
virtual void hide();
+ /*virtual*/ void setFocus(BOOL b);
+
/*virtual*/ void onFocusLost();
/*virtual*/ void onFocusReceived();
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 98ed2f0fc4..e3a856be5c 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -103,7 +103,7 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt
p.image_color_disabled(LLUIColorTable::instance().getColor("ButtonCautionImageColor"));
}
// for the scriptdialog buttons we use fixed button size. This is a limit!
- if (!mIsScriptDialog && font->getWidth(form_element["text"].asString()) > BUTTON_WIDTH)
+ if (!mIsScriptDialog && font->getWidth(form_element["text"].asString()) > (BUTTON_WIDTH-2*HPAD))
{
p.rect.width = 1;
p.auto_resize = true;
@@ -160,7 +160,11 @@ void LLToastNotifyPanel::updateButtonsLayout(const std::vector<index_button_pair
}
LLButton* btn = it->second;
LLRect btn_rect(btn->getRect());
- if (left + btn_rect.getWidth() > max_width)// whether there is still some place for button+h_pad in the mControlPanel
+ if (buttons.size() == 1) // for the one-button forms, center that button
+ {
+ left = (max_width - btn_rect.getWidth()) / 2;
+ }
+ else if (left + btn_rect.getWidth() > max_width)// whether there is still some place for button+h_pad in the mControlPanel
{
// looks like we need to add button to the next row
left = 0;
@@ -321,6 +325,7 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
mTextBox->setContentTrusted(is_content_trusted);
mTextBox->setValue(mNotification->getMessage());
mTextBox->setIsFriendCallback(LLAvatarActions::isFriend);
+ mTextBox->setIsObjectBlockedCallback(boost::bind(&LLMuteList::isMuted, LLMuteList::getInstance(), _1, _2, 0));
// add buttons for a script notification
if (mIsTip)
diff --git a/indra/newview/lltoastscriptquestion.cpp b/indra/newview/lltoastscriptquestion.cpp
index 91ba8c0247..7a3a1d8fd7 100644
--- a/indra/newview/lltoastscriptquestion.cpp
+++ b/indra/newview/lltoastscriptquestion.cpp
@@ -54,6 +54,19 @@ BOOL LLToastScriptQuestion::postBuild()
return TRUE;
}
+
+// virtual
+void LLToastScriptQuestion::setFocus(BOOL b)
+{
+ LLToastPanel::setFocus(b);
+ // toast can fade out and disappear with focus ON, so reset to default anyway
+ LLButton* dfbutton = getDefaultButton();
+ if (dfbutton && dfbutton->getVisible() && dfbutton->getEnabled())
+ {
+ dfbutton->setFocus(b);
+ }
+}
+
void LLToastScriptQuestion::snapToMessageHeight()
{
LLTextBox* mMessage = getChild<LLTextBox>("top_info_message");
@@ -118,6 +131,12 @@ void LLToastScriptQuestion::createButtons()
button->setRect(rect);
buttons_width += rect.getWidth() + LEFT_PAD;
+
+ if (form_element.has("default") && form_element["default"].asBoolean())
+ {
+ button->setFocus(TRUE);
+ setDefaultBtn(button);
+ }
}
}
}
diff --git a/indra/newview/lltoastscriptquestion.h b/indra/newview/lltoastscriptquestion.h
index 3a557f60f6..a756f88415 100644
--- a/indra/newview/lltoastscriptquestion.h
+++ b/indra/newview/lltoastscriptquestion.h
@@ -39,6 +39,8 @@ public:
virtual BOOL postBuild();
virtual ~LLToastScriptQuestion(){};
+ /*virtual*/ void setFocus(BOOL b);
+
private:
void snapToMessageHeight();
diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp
index 2f8e464b71..b0e3b5bf89 100644
--- a/indra/newview/lltoolmgr.cpp
+++ b/indra/newview/lltoolmgr.cpp
@@ -83,6 +83,7 @@ LLToolMgr::LLToolMgr()
// Not a panel, register these callbacks globally.
LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.Active", boost::bind(&LLToolMgr::inEdit, this));
LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.Enabled", boost::bind(&LLToolMgr::canEdit, this));
+ LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.EnabledOrActive", boost::bind(&LLToolMgr::buildEnabledOrActive, this));
LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Build.Toggle", boost::bind(&LLToolMgr::toggleBuildMode, this, _2));
LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Marketplace.Enabled", boost::bind(&LLToolMgr::canAccessMarketplace, this));
LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Marketplace.Toggle", boost::bind(&LLToolMgr::toggleMarketplace, this, _2));
@@ -264,17 +265,21 @@ bool LLToolMgr::canEdit()
return LLViewerParcelMgr::getInstance()->allowAgentBuild();
}
+bool LLToolMgr::buildEnabledOrActive()
+{
+ return inEdit() || canEdit();
+}
+
void LLToolMgr::toggleBuildMode(const LLSD& sdname)
{
const std::string& param = sdname.asString();
+ LLFloaterReg::toggleInstanceOrBringToFront("build");
if (param == "build" && !canEdit())
{
return;
}
- LLFloaterReg::toggleInstanceOrBringToFront("build");
-
bool build_visible = LLFloaterReg::instanceVisible("build");
if (build_visible)
{
diff --git a/indra/newview/lltoolmgr.h b/indra/newview/lltoolmgr.h
index a3c1045aac..e5b45750d9 100644
--- a/indra/newview/lltoolmgr.h
+++ b/indra/newview/lltoolmgr.h
@@ -54,6 +54,7 @@ public:
bool inEdit();
bool canEdit();
+ bool buildEnabledOrActive();
bool canAccessMarketplace();
void toggleBuildMode(const LLSD& sdname);
void toggleMarketplace(const LLSD& sdname);
diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp
index f611d0503f..b015cde45d 100644
--- a/indra/newview/lltracker.cpp
+++ b/indra/newview/lltracker.cpp
@@ -183,7 +183,7 @@ void LLTracker::render3D()
F32 dist = gFloaterWorldMap->getDistanceToDestination(pos_global, 0.5f);
if (dist < DESTINATION_REACHED_RADIUS)
{
- instance()->stopTrackingLocation();
+ instance()->stopTrackingLocation(FALSE,TRUE);
}
else
{
@@ -655,13 +655,13 @@ void LLTracker::stopTrackingLandmark(BOOL clear_ui)
}
-void LLTracker::stopTrackingLocation(BOOL clear_ui)
+void LLTracker::stopTrackingLocation(BOOL clear_ui, BOOL dest_reached)
{
purgeBeaconText();
mTrackedLocationName.assign("");
mIsTrackingLocation = FALSE;
mTrackedPositionGlobal.zeroVec();
- gFloaterWorldMap->clearLocationSelection(clear_ui);
+ gFloaterWorldMap->clearLocationSelection(clear_ui, dest_reached);
mTrackingStatus = TRACKING_NOTHING;
mTrackingLocationType = LOCATION_NOTHING;
}
diff --git a/indra/newview/lltracker.h b/indra/newview/lltracker.h
index 218f3430a6..a1c5052c1b 100644
--- a/indra/newview/lltracker.h
+++ b/indra/newview/lltracker.h
@@ -116,7 +116,7 @@ protected:
void stopTrackingAll(BOOL clear_ui = FALSE);
void stopTrackingAvatar(BOOL clear_ui = FALSE);
- void stopTrackingLocation(BOOL clear_ui = FALSE);
+ void stopTrackingLocation(BOOL clear_ui = FALSE, BOOL dest_reached = FALSE);
void stopTrackingLandmark(BOOL clear_ui = FALSE);
void drawMarker(const LLVector3d& pos_global, const LLColor4& color);
diff --git a/indra/newview/llviewchildren.cpp b/indra/newview/llviewchildren.cpp
index 5c5bbdc8f5..32b2f7e9f5 100644
--- a/indra/newview/llviewchildren.cpp
+++ b/indra/newview/llviewchildren.cpp
@@ -79,8 +79,9 @@ void LLViewChildren::setBadge(const std::string& id, Badge badge, bool visible)
default:
case BADGE_OK: child->setValue(std::string("badge_ok.j2c")); break;
case BADGE_NOTE: child->setValue(std::string("badge_note.j2c")); break;
- case BADGE_WARN: child->setValue(std::string("badge_warn.j2c")); break;
- case BADGE_ERROR: child->setValue(std::string("badge_error.j2c")); break;
+ case BADGE_WARN:
+ case BADGE_ERROR:
+ child->setValue(std::string("badge_warn.j2c")); break;
}
}
}
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index f0dafec240..497ff4d2bf 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -837,5 +837,12 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res
}
}
+ // Let the Snapshot floater know we have failed uploading.
+ LLFloater* floater_snapshot = LLFloaterReg::findInstance("snapshot");
+ if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot)
+ {
+ floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory")));
+ }
+
}
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 16f40fb747..5e74e9f019 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -207,6 +207,12 @@ static bool handleVolumeLODChanged(const LLSD& newvalue)
return true;
}
+static bool handleRiggedLODChanged(const LLSD& newvalue)
+{
+ LLVOVolume::sRiggedFactorMultiplier = (F32)newvalue.asReal();
+ return true;
+}
+
static bool handleAvatarLODChanged(const LLSD& newvalue)
{
LLVOAvatar::sLODFactor = (F32) newvalue.asReal();
@@ -619,6 +625,7 @@ void settings_setup_listeners()
gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2));
+ gSavedSettings.getControl("RenderRiggedFactorMultiplier")->getSignal()->connect(boost::bind(&handleRiggedLODChanged, _2));
gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2));
gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2));
gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _2));
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index d0813544f8..0bbe9fa2c2 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1007,6 +1007,22 @@ void activate_gesture_cb(const LLUUID& inv_item)
LLGestureMgr::instance().activateGesture(inv_item);
}
+void set_default_permissions(LLViewerInventoryItem* item, std::string perm_type)
+{
+ llassert(item);
+ LLPermissions perm = item->getPermissions();
+ if (perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms(perm_type)
+ || perm.getMaskGroup() != LLFloaterPerms::getGroupPerms(perm_type))
+ {
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms(perm_type));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms(perm_type));
+
+ item->setPermissions(perm);
+
+ item->updateServer(FALSE);
+ }
+}
+
void create_script_cb(const LLUUID& inv_item)
{
if (!inv_item.isNull())
@@ -1014,13 +1030,9 @@ void create_script_cb(const LLUUID& inv_item)
LLViewerInventoryItem* item = gInventory.getItem(inv_item);
if (item)
{
- LLPermissions perm = item->getPermissions();
- perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Scripts"));
- perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Scripts"));
-
- item->setPermissions(perm);
+ set_default_permissions(item, "Scripts");
- item->updateServer(FALSE);
+ // item was just created, update even if permissions did not changed
gInventory.updateItem(item);
gInventory.notifyObservers();
}
@@ -1036,13 +1048,8 @@ void create_gesture_cb(const LLUUID& inv_item)
LLViewerInventoryItem* item = gInventory.getItem(inv_item);
if (item)
{
- LLPermissions perm = item->getPermissions();
- perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Gestures"));
- perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Gestures"));
+ set_default_permissions(item, "Gestures");
- item->setPermissions(perm);
-
- item->updateServer(FALSE);
gInventory.updateItem(item);
gInventory.notifyObservers();
@@ -1061,13 +1068,8 @@ void create_notecard_cb(const LLUUID& inv_item)
LLViewerInventoryItem* item = gInventory.getItem(inv_item);
if (item)
{
- LLPermissions perm = item->getPermissions();
- perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Notecards"));
- perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Notecards"));
-
- item->setPermissions(perm);
+ set_default_permissions(item, "Notecards");
- item->updateServer(FALSE);
gInventory.updateItem(item);
gInventory.notifyObservers();
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 99a9ed1d75..46f03f9971 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -397,13 +397,15 @@ void set_merchant_SLM_menu()
gToolBarView->enableCommand(command->id(), true);
}
-void check_merchant_status()
+void check_merchant_status(bool force)
{
if (!gSavedSettings.getBOOL("InventoryOutboxDisplayBoth"))
{
- // Reset the SLM status: we actually want to check again, that's the point of calling check_merchant_status()
- LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED);
-
+ if (force)
+ {
+ // Reset the SLM status: we actually want to check again, that's the point of calling check_merchant_status()
+ LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED);
+ }
// Hide SLM related menu item
gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible(FALSE);
@@ -6986,20 +6988,25 @@ class LLAvatarCall : public view_listener_t
namespace
{
- struct QueueObjects : public LLSelectedObjectFunctor
+ struct QueueObjects : public LLSelectedNodeFunctor
{
BOOL scripted;
BOOL modifiable;
LLFloaterScriptQueue* mQueue;
QueueObjects(LLFloaterScriptQueue* q) : mQueue(q), scripted(FALSE), modifiable(FALSE) {}
- virtual bool apply(LLViewerObject* obj)
+ virtual bool apply(LLSelectNode* node)
{
+ LLViewerObject* obj = node->getObject();
+ if (!obj)
+ {
+ return true;
+ }
scripted = obj->flagScripted();
modifiable = obj->permModify();
if( scripted && modifiable )
{
- mQueue->addObject(obj->getID());
+ mQueue->addObject(obj->getID(), node->mName);
return false;
}
else
@@ -7015,7 +7022,7 @@ void queue_actions(LLFloaterScriptQueue* q, const std::string& msg)
QueueObjects func(q);
LLSelectMgr *mgr = LLSelectMgr::getInstance();
LLObjectSelectionHandle selectHandle = mgr->getSelection();
- bool fail = selectHandle->applyToObjects(&func);
+ bool fail = selectHandle->applyToNodes(&func);
if(fail)
{
if ( !func.scripted )
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index b7bdf00157..a553bb79a2 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -83,7 +83,7 @@ BOOL enable_god_full(void* user_data);
BOOL enable_god_liaison(void* user_data);
BOOL enable_god_basic(void* user_data);
void set_underclothes_menu_options();
-void check_merchant_status();
+void check_merchant_status(bool force = false);
void exchange_callingcard(const LLUUID& dest_id);
@@ -108,6 +108,7 @@ void handle_look_at_selection(const LLSD& param);
void handle_zoom_to_object(LLUUID object_id);
void handle_object_return();
void handle_object_delete();
+void handle_object_edit();
void handle_buy_land();
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 92df3866f7..3925154c0f 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1639,7 +1639,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
LLDiscardAgentOffer* discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID);
discard_agent_offer->startFetch();
- if (catp || (itemp && itemp->isFinished()))
+ if ((catp && gInventory.isCategoryComplete(mObjectID)) || (itemp && itemp->isFinished()))
{
discard_agent_offer->done();
}
@@ -4719,7 +4719,9 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
{
if (!gAudiop)
{
+#if !LL_LINUX
LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
+#endif
return;
}
@@ -4781,7 +4783,9 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data)
{
if (!gAudiop)
{
+#if !LL_LINUX
LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
+#endif
return;
}
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 5edc3c9745..72a8595845 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -133,6 +133,7 @@ std::map<std::string, U32> LLViewerObject::sObjectDataMap;
// JC 3/18/2003
const F32 PHYSICS_TIMESTEP = 1.f / 45.f;
+const F64 INV_REQUEST_EXPIRE_TIME_SEC = 60.f;
static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object");
@@ -245,7 +246,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mInventory(NULL),
mInventorySerialNum(0),
mRegionp( regionp ),
- mInventoryPending(FALSE),
+ mInvRequestExpireTime(0.f),
mInventoryDirty(FALSE),
mDead(FALSE),
mOrphaned(FALSE),
@@ -1434,10 +1435,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
setChanged(MOVED | SILHOUETTE);
}
- else if (mText.notNull())
+ else
{
- mText->markDead();
- mText = NULL;
+ if (mText.notNull())
+ {
+ mText->markDead();
+ mText = NULL;
+ }
+ mHudText.clear();
}
std::string media_url;
@@ -1812,10 +1817,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
setChanged(TEXTURE);
}
- else if(mText.notNull())
+ else
{
- mText->markDead();
- mText = NULL;
+ if (mText.notNull())
+ {
+ mText->markDead();
+ mText = NULL;
+ }
+ mHudText.clear();
}
std::string media_url;
@@ -2832,6 +2841,15 @@ void LLViewerObject::removeInventoryListener(LLVOInventoryListener* listener)
}
}
+BOOL LLViewerObject::isInventoryPending()
+{
+ if (mInvRequestExpireTime == 0.f || mInvRequestExpireTime < LLFrameTimer::getTotalSeconds())
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
void LLViewerObject::clearInventoryListeners()
{
for_each(mInventoryCallbacks.begin(), mInventoryCallbacks.end(), DeletePointer());
@@ -2870,7 +2888,7 @@ void LLViewerObject::requestInventory()
void LLViewerObject::fetchInventoryFromServer()
{
- if (!mInventoryPending)
+ if (mInvRequestExpireTime == 0.f || mInvRequestExpireTime < LLFrameTimer::getTotalSeconds())
{
delete mInventory;
LLMessageSystem* msg = gMessageSystem;
@@ -2883,7 +2901,7 @@ void LLViewerObject::fetchInventoryFromServer()
msg->sendReliable(mRegionp->getHost());
// this will get reset by dirtyInventory or doInventoryCallback
- mInventoryPending = TRUE;
+ mInvRequestExpireTime = LLFrameTimer::getTotalSeconds() + INV_REQUEST_EXPIRE_TIME_SEC;
}
}
@@ -3099,7 +3117,7 @@ void LLViewerObject::doInventoryCallback()
mInventoryCallbacks.erase(curiter);
}
}
- mInventoryPending = FALSE;
+ mInvRequestExpireTime = 0.f;
}
void LLViewerObject::removeInventory(const LLUUID& item_id)
@@ -4990,8 +5008,26 @@ void LLViewerObject::initHudText()
void LLViewerObject::restoreHudText()
{
- if(mText)
+ if (mHudText.empty())
+ {
+ if (mText)
+ {
+ mText->markDead();
+ mText = NULL;
+ }
+ }
+ else
{
+ if (!mText)
+ {
+ initHudText();
+ }
+ else
+ {
+ // Restore default values
+ mText->setZCompare(TRUE);
+ mText->setDoFade(TRUE);
+ }
mText->setColor(mHudTextColor);
mText->setString(mHudText);
}
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index cb8acfdcf8..b95190c554 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -437,7 +437,7 @@ public:
// viewer object has the inventory stored locally.
void registerInventoryListener(LLVOInventoryListener* listener, void* user_data);
void removeInventoryListener(LLVOInventoryListener* listener);
- BOOL isInventoryPending() { return mInventoryPending; }
+ BOOL isInventoryPending();
void clearInventoryListeners();
bool hasInventoryListeners();
void requestInventory();
@@ -757,7 +757,7 @@ protected:
S16 mInventorySerialNum;
LLViewerRegion *mRegionp; // Region that this object belongs to.
- BOOL mInventoryPending;
+ F64 mInvRequestExpireTime;
BOOL mInventoryDirty;
BOOL mDead;
BOOL mOrphaned; // This is an orphaned child
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 023f1b92ba..86591ff4df 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -465,7 +465,7 @@ LLViewerOctreeGroup::LLViewerOctreeGroup(OctreeNode* node)
{
LLVector4a tmp;
tmp.splat(0.f);
- mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] =
+ mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[1] =
mObjectExtents[0] = mObjectExtents[1] = tmp;
mBounds[0] = node->getCenter();
diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp
index 7efa821bbf..814060f4f2 100644
--- a/indra/newview/llviewerpartsource.cpp
+++ b/indra/newview/llviewerpartsource.cpp
@@ -441,10 +441,20 @@ LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewer
return NULL;
}
+ F32 prev_max_age = pssp->mPartSysData.mMaxAge;
+ F32 prev_start_age = pssp->mPartSysData.mStartAge;
if (!pssp->mPartSysData.unpackBlock(block_num))
{
return NULL;
}
+ else if (pssp->mPartSysData.mMaxAge
+ && (prev_max_age != pssp->mPartSysData.mMaxAge || prev_start_age != pssp->mPartSysData.mStartAge))
+ {
+ // reusing existing pss, so reset time to allow particles to start again
+ pssp->mLastUpdateTime = 0.f;
+ pssp->mLastPartTime = 0.f;
+ }
+
if (pssp->mPartSysData.mTargetUUID.notNull())
{
LLViewerObject *target_objp = gObjectList.findObject(pssp->mPartSysData.mTargetUUID);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index cac2ed8585..899ab3a371 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -264,17 +264,18 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
}
S32 id = ++mHttpResponderID;
- ++mSeedCapAttempts;
LLSD capabilityNames = LLSD::emptyArray();
buildCapabilityNames(capabilityNames);
LL_INFOS("AppInit", "Capabilities") << "Requesting seed from " << url
- << " (attempt #" << mSeedCapAttempts << ")" << LL_ENDL;
+ << " (attempt #" << mSeedCapAttempts + 1 << ")" << LL_ENDL;
regionp = NULL;
result = httpAdapter->postAndSuspend(httpRequest, url, capabilityNames);
+ ++mSeedCapAttempts;
+
regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
if (!regionp) //region was removed
{
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index db4b555eca..178aa1e646 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1200,7 +1200,7 @@ void LLViewerFetchedTexture::loadFromFastCache()
{
S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;
S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS;
- if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
+ if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
{
// scale oversized icon, no need to give more work to gl
mRawImage->scale(expected_width, expected_height);
@@ -1875,7 +1875,8 @@ bool LLViewerFetchedTexture::updateFetch()
static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false);
static LLCachedControl<F32> sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold", 0.2);
static LLCachedControl<S32> sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost", 3);
- if(textures_decode_disabled)
+ if(textures_decode_disabled ||
+ (gUseWireframe && mBoostLevel < LLGLTexture::BOOST_AVATAR_BAKED_SELF)) // don't fetch the surface textures in wireframe mode
{
return false;
}
@@ -1980,7 +1981,7 @@ bool LLViewerFetchedTexture::updateFetch()
{
S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;
S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS;
- if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
+ if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
{
// scale oversized icon, no need to give more work to gl
mRawImage->scale(expected_width, expected_height);
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 08f6143861..d7080051da 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -171,13 +171,27 @@ void LLViewerTextureList::doPreloadImages()
mImagePreloads.insert(image);
}
image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE,
- 0,0,LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"));
+ 0, 0, IMG_TRANSPARENT);
if (image)
{
image->setAddressMode(LLTexUnit::TAM_WRAP);
mImagePreloads.insert(image);
}
-
+ image = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient.tga", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE,
+ GL_ALPHA8, GL_ALPHA, IMG_ALPHA_GRAD);
+ if (image)
+ {
+ image->setAddressMode(LLTexUnit::TAM_CLAMP);
+ mImagePreloads.insert(image);
+ }
+ image = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient_2d.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE,
+ GL_ALPHA8, GL_ALPHA, IMG_ALPHA_GRAD_2D);
+ if (image)
+ {
+ image->setAddressMode(LLTexUnit::TAM_CLAMP);
+ mImagePreloads.insert(image);
+ }
+
LLPointer<LLImageRaw> img_blak_square_tex(new LLImageRaw(2, 2, 3));
memset(img_blak_square_tex->getData(), 0, img_blak_square_tex->getDataSize());
LLPointer<LLViewerFetchedTexture> img_blak_square(new LLViewerFetchedTexture(img_blak_square_tex, FTT_DEFAULT, FALSE));
@@ -188,7 +202,7 @@ void LLViewerTextureList::doPreloadImages()
static std::string get_texture_list_name()
{
- return gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "texture_list_" + gSavedSettings.getString("LoginLocation") + ".xml");
+ return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml");
}
void LLViewerTextureList::doPrefetchImages()
@@ -293,7 +307,7 @@ void LLViewerTextureList::shutdown()
break;
}
- if (count > 0 && !gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "").empty())
+ if (count > 0 && !gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "").empty())
{
std::string filename = get_texture_list_name();
llofstream file;
diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp
index 0f73515b5d..88eb13e7cd 100644
--- a/indra/newview/llviewerwearable.cpp
+++ b/indra/newview/llviewerwearable.cpp
@@ -451,7 +451,7 @@ void LLViewerWearable::copyDataFrom(const LLViewerWearable* src)
// Probably reduntant, but ensure that the newly created wearable is not dirty by setting current value of params in new wearable
// to be the same as the saved values (which were loaded from src at param->cloneParam(this))
- revertValues();
+ revertValuesWithoutUpdate();
}
void LLViewerWearable::setItemID(const LLUUID& item_id)
@@ -471,6 +471,11 @@ void LLViewerWearable::revertValues()
}
}
+void LLViewerWearable::revertValuesWithoutUpdate()
+{
+ LLWearable::revertValues();
+}
+
void LLViewerWearable::saveValues()
{
LLWearable::saveValues();
diff --git a/indra/newview/llviewerwearable.h b/indra/newview/llviewerwearable.h
index 62cd5e21ad..cc99f6af2f 100644
--- a/indra/newview/llviewerwearable.h
+++ b/indra/newview/llviewerwearable.h
@@ -85,6 +85,8 @@ public:
/*virtual*/ void revertValues();
/*virtual*/ void saveValues();
+ void revertValuesWithoutUpdate();
+
// Something happened that requires the wearable's label to be updated (e.g. worn/unworn).
/*virtual*/void setUpdated() const;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index c17c50fd88..f47a37fcda 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1655,7 +1655,8 @@ LLViewerWindow::LLViewerWindow(const Params& p)
mResDirty(false),
mStatesDirty(false),
mCurrResolutionIndex(0),
- mProgressView(NULL)
+ mProgressView(NULL),
+ mSystemUIScaleFactorChanged(false)
{
// gKeyboard is still NULL, so it doesn't do LLWindowListener any good to
// pass its value right now. Instead, pass it a nullary function that
@@ -1743,6 +1744,16 @@ LLViewerWindow::LLViewerWindow(const Params& p)
gSavedSettings.setS32("FullScreenHeight",scr.mY);
}
+
+ F32 system_scale_factor = mWindow->getSystemUISize();
+ if (p.first_run || gSavedSettings.getF32("LastSystemUIScaleFactor") != system_scale_factor)
+ {
+ mSystemUIScaleFactorChanged = true;
+ gSavedSettings.setF32("LastSystemUIScaleFactor", system_scale_factor);
+ gSavedSettings.setF32("UIScaleFactor", system_scale_factor);
+ }
+
+
// Get the real window rect the window was created with (since there are various OS-dependent reasons why
// the size of a window or fullscreen context may have been adjusted slightly...)
F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor");
@@ -1838,6 +1849,28 @@ LLViewerWindow::LLViewerWindow(const Params& p)
mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);
}
+//static
+void LLViewerWindow::showSystemUIScaleFactorChanged()
+{
+ LLNotificationsUtil::add("SystemUIScaleFactorChanged", LLSD(), LLSD(), onSystemUIScaleFactorChanged);
+}
+
+//static
+bool LLViewerWindow::onSystemUIScaleFactorChanged(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if(option == 0)
+ {
+ LLFloaterReg::toggleInstanceOrBringToFront("preferences");
+ LLFloater* pref_floater = LLFloaterReg::getInstance("preferences");
+ LLTabContainer* tab_container = pref_floater->getChild<LLTabContainer>("pref core");
+ tab_container->selectTabByName("advanced1");
+
+ }
+ return false;
+}
+
+
void LLViewerWindow::initGLDefaults()
{
gGL.setSceneBlendType(LLRender::BT_ALPHA);
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index ad06f00234..afe80358ca 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -155,7 +155,8 @@ public:
min_width,
min_height;
Optional<bool> fullscreen,
- ignore_pixel_depth;
+ ignore_pixel_depth,
+ first_run;
Params();
};
@@ -418,6 +419,9 @@ public:
void calcDisplayScale();
static LLRect calcScaledRect(const LLRect & rect, const LLVector2& display_scale);
+ bool getSystemUIScaleFactorChanged() { return mSystemUIScaleFactorChanged; }
+ static void showSystemUIScaleFactorChanged();
+
private:
bool shouldShowToolTipFor(LLMouseHandler *mh);
@@ -431,6 +435,7 @@ private:
S32 getChatConsoleBottomPad(); // Vertical padding for child console rect, varied by bottom clutter
LLRect getChatConsoleRect(); // Get optimal cosole rect.
+ static bool onSystemUIScaleFactorChanged(const LLSD& notification, const LLSD& response);
private:
LLWindow* mWindow; // graphical window object
bool mActive;
@@ -509,6 +514,7 @@ private:
LLPointer<LLViewerObject> mDragHoveredObject;
static LLTrace::SampleStatHandle<> sMouseVelocityStat;
+ bool mSystemUIScaleFactorChanged; // system UI scale factor changed from last run
};
//
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index b9dd43f061..cdc7e20c2c 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -7313,7 +7313,6 @@ bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32
//-----------------------------------------------------------------------------
void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
{
- static S32 largestSelfCOFSeen(LLViewerInventoryCategory::VERSION_UNKNOWN);
LL_DEBUGS("Avatar") << "starts" << LL_ENDL;
bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
@@ -7348,43 +7347,34 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
return;
}
- S32 this_update_cof_version = contents.mCOFVersion;
- S32 last_update_request_cof_version = mLastUpdateRequestCOFVersion;
+ S32 thisAppearanceVersion(contents.mCOFVersion);
+ if (isSelf())
+ { // In the past this was considered to be the canonical COF version,
+ // that is no longer the case. The canonical version is maintained
+ // by the AIS code and should match the COF version there. Even so,
+ // we must prevent rolling this one backwards backwards or processing
+ // stale versions.
- if( isSelf() )
- {
- LL_DEBUGS("Avatar") << "this_update_cof_version " << this_update_cof_version
- << " last_update_request_cof_version " << last_update_request_cof_version
- << " my_cof_version " << LLAppearanceMgr::instance().getCOFVersion() << LL_ENDL;
+ S32 aisCOFVersion(LLAppearanceMgr::instance().getCOFVersion());
+
+ LL_DEBUGS("Avatar") << "handling self appearance message #" << thisAppearanceVersion <<
+ " (highest seen #" << mLastUpdateReceivedCOFVersion <<
+ ") (AISCOF=#" << aisCOFVersion << ")" << LL_ENDL;
- if (largestSelfCOFSeen > this_update_cof_version)
+ if (mLastUpdateReceivedCOFVersion >= thisAppearanceVersion)
{
- LL_WARNS("Avatar") << "Already processed appearance for COF version " <<
- largestSelfCOFSeen << ", discarding appearance with COF " << this_update_cof_version << LL_ENDL;
+ LL_WARNS("Avatar") << "Stale appearance received #" << thisAppearanceVersion <<
+ " attempt to roll back from #" << mLastUpdateReceivedCOFVersion <<
+ "... dropping." << LL_ENDL;
+ return;
+ }
+ if (isEditingAppearance())
+ {
+ LL_DEBUGS("Avatar") << "Editing appearance. Dropping appearance update." << LL_ENDL;
return;
}
- largestSelfCOFSeen = this_update_cof_version;
-
- }
- else
- {
- LL_DEBUGS("Avatar") << "appearance message received" << LL_ENDL;
- }
-
- // Check for stale update.
- if (isSelf()
- && (this_update_cof_version < last_update_request_cof_version))
- {
- LL_WARNS() << "Stale appearance update, wanted version " << last_update_request_cof_version
- << ", got " << this_update_cof_version << LL_ENDL;
- return;
- }
- if (isSelf() && isEditingAppearance())
- {
- LL_DEBUGS("Avatar") << "ignoring appearance message while in appearance edit" << LL_ENDL;
- return;
- }
+ }
// SUNSHINE CLEANUP - is this case OK now?
S32 num_params = contents.mParamWeights.size();
@@ -7399,13 +7389,17 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
}
// No backsies zone - if we get here, the message should be valid and usable, will be processed.
- LL_INFOS("Avatar") << "Processing appearance message version " << this_update_cof_version << LL_ENDL;
+ LL_INFOS("Avatar") << "Processing appearance message version " << thisAppearanceVersion << LL_ENDL;
- // Note:
- // RequestAgentUpdateAppearanceResponder::onRequestRequested()
- // assumes that cof version is only updated with server-bake
- // appearance messages.
- mLastUpdateReceivedCOFVersion = this_update_cof_version;
+ if (isSelf())
+ {
+ // Note:
+ // locally the COF is maintained via LLInventoryModel::accountForUpdate
+ // which is called from various places. This should match the simhost's
+ // idea of what the COF version is. AIS however maintains its own version
+ // of the COF that should be considered canonical.
+ mLastUpdateReceivedCOFVersion = thisAppearanceVersion;
+ }
if (applyParsedTEMessage(contents.mTEContents) > 0 && isChanged(TEXTURE))
{
@@ -7528,7 +7522,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
// Got an update for some other avatar
// Ignore updates for self, because we have a more authoritative value in the preferences.
setHoverOffset(contents.mHoverOffset);
- LL_INFOS("Avatar") << avString() << "setting hover to " << contents.mHoverOffset[2] << LL_ENDL;
+ LL_DEBUGS("Avatar") << avString() << "setting hover to " << contents.mHoverOffset[2] << LL_ENDL;
}
if (!contents.mHoverOffsetWasSet && !isSelf())
@@ -8151,6 +8145,7 @@ U32 LLVOAvatar::getPartitionType() const
//static
void LLVOAvatar::updateImpostors()
{
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
LLCharacter::sAllowInstancesChange = FALSE;
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 07427e0377..189ed54993 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -427,7 +427,7 @@ void LLVivoxVoiceClient::connectorCreate()
void LLVivoxVoiceClient::connectorShutdown()
{
- if(!mConnectorEstablished)
+ if(mConnectorEstablished)
{
std::ostringstream stream;
stream
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 8f0b233f01..5fc571bf1d 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -86,6 +86,7 @@ BOOL gAnimateTextures = TRUE;
//extern BOOL gHideSelectedObjects;
F32 LLVOVolume::sLODFactor = 1.f;
+F32 LLVOVolume::sRiggedFactorMultiplier = 6.f;
F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop
F32 LLVOVolume::sDistanceFactor = 1.0f;
S32 LLVOVolume::sNumLODChanges = 0;
@@ -1213,18 +1214,18 @@ void LLVOVolume::sculpt()
}
}
-S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius)
+S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius, F32 lod_factor)
{
S32 cur_detail;
if (LLPipeline::sDynamicLOD)
{
// We've got LOD in the profile, and in the twist. Use radius.
- F32 tan_angle = (LLVOVolume::sLODFactor*radius)/distance;
+ F32 tan_angle = (lod_factor*radius) / distance;
cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f));
}
else
{
- cur_detail = llclamp((S32) (sqrtf(radius)*LLVOVolume::sLODFactor*4.f), 0, 3);
+ cur_detail = llclamp((S32)(sqrtf(radius)*lod_factor*4.f), 0, 3);
}
return cur_detail;
}
@@ -1240,6 +1241,7 @@ BOOL LLVOVolume::calcLOD()
F32 radius;
F32 distance;
+ F32 lod_factor = LLVOVolume::sLODFactor;
if (mDrawable->isState(LLDrawable::RIGGED))
{
@@ -1251,22 +1253,27 @@ BOOL LLVOVolume::calcLOD()
return FALSE;
}
+ // Note: when changing, take note that a lot of rigged meshes have only one LOD.
+ lod_factor *= LLVOVolume::sRiggedFactorMultiplier;
distance = avatar->mDrawable->mDistanceWRTCamera;
- radius = avatar->getBinRadius();
+ F32 avatar_radius = avatar->getBinRadius();
+ F32 object_radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length();
+ radius = object_radius * LLVOVolume::sRiggedFactorMultiplier;
+ radius = llmin(radius, avatar_radius);
}
else
{
distance = mDrawable->mDistanceWRTCamera;
radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length();
}
-
+
//hold onto unmodified distance for debugging
//F32 debug_distance = distance;
-
+
distance *= sDistanceFactor;
- F32 rampDist = LLVOVolume::sLODFactor * 2;
-
+ F32 rampDist = lod_factor * 2;
+
if (distance < rampDist)
{
// Boost LOD when you're REALLY close
@@ -1279,7 +1286,8 @@ BOOL LLVOVolume::calcLOD()
distance *= F_PI/3.f;
cur_detail = computeLODDetail(ll_round(distance, 0.01f),
- ll_round(radius, 0.01f));
+ ll_round(radius, 0.01f),
+ lod_factor);
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) &&
@@ -1753,7 +1761,10 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
compiled = TRUE;
lodOrSculptChanged(drawable, compiled);
- genBBoxes(FALSE);
+ if (!mLODChanged)
+ {
+ genBBoxes(FALSE);
+ }
}
// it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local
else
@@ -3627,8 +3638,9 @@ F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes, F32* unscaled_v
F32 radius = getScale().length()*0.5f;
if (isMesh())
- {
- LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID());
+ {
+ const LLSD* header_ptr = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID());
+ LLSD header = header_ptr ? *header_ptr : LLSD();
return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD, unscaled_value);
}
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index a331908320..ca9917069b 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -327,7 +327,7 @@ public:
void clearRiggedVolume();
protected:
- S32 computeLODDetail(F32 distance, F32 radius);
+ S32 computeLODDetail(F32 distance, F32 radius, F32 lod_factor);
BOOL calcLOD();
LLFace* addFace(S32 face_index);
void updateTEData();
@@ -379,6 +379,7 @@ private:
public:
static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop
static F32 sLODFactor; // LOD scale factor
+ static F32 sRiggedFactorMultiplier; // Worn rigged LOD scale factor multiplier
static F32 sDistanceFactor; // LOD distance factor
static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;
diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp
index 066cb9a0ac..482a2a61e2 100644
--- a/indra/newview/llwlparamset.cpp
+++ b/indra/newview/llwlparamset.cpp
@@ -288,14 +288,6 @@ void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight)
{
// set up the iterators
- // keep cloud positions and coverage the same
- /// TODO masking will do this later
- F32 cloudPos1X = (F32) mParamValues["cloud_pos_density1"][0].asReal();
- F32 cloudPos1Y = (F32) mParamValues["cloud_pos_density1"][1].asReal();
- F32 cloudPos2X = (F32) mParamValues["cloud_pos_density2"][0].asReal();
- F32 cloudPos2Y = (F32) mParamValues["cloud_pos_density2"][1].asReal();
- F32 cloudCover = (F32) mParamValues["cloud_shadow"][0].asReal();
-
LLSD srcVal;
LLSD destVal;
@@ -379,15 +371,6 @@ void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight)
setSunAngle((1 - weight) * srcSunAngle + weight * destSunAngle);
setEastAngle((1 - weight) * srcEastAngle + weight * destEastAngle);
-
- // now setup the sun properly
-
- // reset those cloud positions
- mParamValues["cloud_pos_density1"][0] = cloudPos1X;
- mParamValues["cloud_pos_density1"][1] = cloudPos1Y;
- mParamValues["cloud_pos_density2"][0] = cloudPos2X;
- mParamValues["cloud_pos_density2"][1] = cloudPos2Y;
- mParamValues["cloud_shadow"][0] = cloudCover;
}
void LLWLParamSet::updateCloudScrolling(void)
diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp
index 97a9eb7f5f..cc3645131d 100644
--- a/indra/newview/llxmlrpclistener.cpp
+++ b/indra/newview/llxmlrpclistener.cpp
@@ -322,7 +322,7 @@ public:
mBoundListener =
LLEventPumps::instance().
obtain("mainloop").
- listen(LLEventPump::inventName(), boost::bind(&Poller::poll, this, _1));
+ listen(LLEventPump::ANONYMOUS, boost::bind(&Poller::poll, this, _1));
LL_INFOS("LLXMLRPCListener") << mMethod << " request sent to " << mUri << LL_ENDL;
}
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 72037a84b3..85f4ae587a 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -774,6 +774,9 @@ with the same filename but different name
<texture name="default_land_picture.j2c" />
<texture name="default_profile_picture.j2c" />
<texture name="locked_image.j2c" />
+ <texture name="badge_note.j2c" />
+ <texture name="badge_warn.j2c" />
+ <texture name="badge_ok.j2c" />
<texture name="materials_ui_x_24.png" />
<texture name="Progress_1" file_name="icons/Progress_1.png" preload="true" />
diff --git a/indra/newview/skins/default/xui/en/floater_script_queue.xml b/indra/newview/skins/default/xui/en/floater_script_queue.xml
index f4aca7bb3d..0982683a7f 100644
--- a/indra/newview/skins/default/xui/en/floater_script_queue.xml
+++ b/indra/newview/skins/default/xui/en/floater_script_queue.xml
@@ -29,6 +29,14 @@
name="NotRunning">
Not running
</floater.string>
+ <floater.string
+ name="Timeout">
+ Timeout: [OBJECT_NAME]
+ </floater.string>
+ <floater.string
+ name="LoadingObjInv">
+ Loading inventory for: [OBJECT_NAME]
+ </floater.string>
<button
follows="right|bottom"
height="24"
diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml
index 170b7177fb..550af03683 100644
--- a/indra/newview/skins/default/xui/en/fonts.xml
+++ b/indra/newview/skins/default/xui/en/fonts.xml
@@ -10,8 +10,10 @@
<file>ArialUni.ttf</file>
</os>
<os name="Mac">
+ <file>ヒラギノ角ゴシック W3.ttc</file>
<file>ヒラギノ角ゴ Pro W3.otf</file>
<file>ヒラギノ角ゴ ProN W3.otf</file>
+ <file>ヒラギノ明朝 ProN W3.ttc</file>
<file>AppleGothic.dfont</file>
<file>AppleGothic.ttf</file>
<file>AppleSDGothicNeo-Regular.otf</file>
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index 419ec359a6..dcf2da52f1 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -140,13 +140,6 @@
function="Advanced.ShowDebugSettings"
parameter="all" />
</menu_item_call>
- <menu_item_call
- label="UI/Color Settings"
- name="UI/Color Settings">
- <menu_item_call.on_click
- function="Advanced.ShowDebugSettings"
- parameter="skin" />
- </menu_item_call>
<menu_item_separator />
<menu_item_call
label="XUI Preview Tool"
diff --git a/indra/newview/skins/default/xui/en/menu_object_icon.xml b/indra/newview/skins/default/xui/en/menu_object_icon.xml
index 2d4f1792c2..5137aea72a 100644
--- a/indra/newview/skins/default/xui/en/menu_object_icon.xml
+++ b/indra/newview/skins/default/xui/en/menu_object_icon.xml
@@ -23,6 +23,20 @@
<menu_item_call.on_click
function="ObjectIcon.Action"
parameter="block" />
+ <menu_item_call.on_visible
+ function="ObjectIcon.Visible"
+ parameter="not_blocked" />
+ </menu_item_call>
+ <menu_item_call
+ label="Unblock"
+ layout="topleft"
+ name="Unblock">
+ <menu_item_call.on_click
+ function="ObjectIcon.Action"
+ parameter="unblock" />
+ <menu_item_call.on_visible
+ function="ObjectIcon.Visible"
+ parameter="is_blocked" />
</menu_item_call>
<menu_item_separator
layout="topleft" />
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
index 8790fde7c5..b5a4b87acd 100644
--- a/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
@@ -40,6 +40,14 @@
function="CheckControl"
parameter="FriendsListShowPermissions" />
</menu_item_check>
+ <menu_item_check name="view_usernames" label="Hide usernames">
+ <menu_item_check.on_click
+ function="People.Friends.ViewSort.Action"
+ parameter="view_usernames" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="FriendsListHideUsernames" />
+ </menu_item_check>
<menu_item_check name="view_conversation" label="View Conversation Log...">
<menu_item_check.on_check
function="Floater.Visible"
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby.xml b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
index f12226ebeb..c1500d4e7c 100644
--- a/indra/newview/skins/default/xui/en/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
@@ -143,4 +143,20 @@
function="Avatar.EnableItem"
parameter="can_block" />
</menu_item_check>
+ <menu_item_call
+ label="Freeze"
+ name="freeze">
+ <menu_item_call.on_click
+ function="Avatar.Freeze" />
+ <menu_item_call.on_visible
+ function="Avatar.EnableFreezeEject"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Eject"
+ name="eject">
+ <menu_item_call.on_click
+ function="Avatar.Eject" />
+ <menu_item_call.on_visible
+ function="Avatar.EnableFreezeEject"/>
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
index da88ca9f4d..a9f6b8045d 100644
--- a/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
@@ -50,4 +50,12 @@
function="ToggleControl"
parameter="NearbyListShowMap" />
</menu_item_check>
+ <menu_item_check name="view_usernames" label="Hide usernames">
+ <menu_item_check.on_click
+ function="People.Nearby.ViewSort.Action"
+ parameter="view_usernames" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="NearbyListHideUsernames" />
+ </menu_item_check>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_url_objectim.xml b/indra/newview/skins/default/xui/en/menu_url_objectim.xml
index b9d003b841..41d40b389a 100644
--- a/indra/newview/skins/default/xui/en/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_objectim.xml
@@ -16,6 +16,13 @@
<menu_item_call.on_click
function="Url.Block" />
</menu_item_call>
+ <menu_item_call
+ label="Unblock"
+ layout="topleft"
+ name="unblock_object">
+ <menu_item_call.on_click
+ function="Url.Unblock" />
+ </menu_item_call>
<menu_item_separator
layout="topleft" />
<menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 0a492fb37b..b189d1038f 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -806,7 +806,7 @@
<menu_item_check.on_click
function="Build.Toggle" />
<menu_item_check.on_enable
- function="Build.Enabled" />
+ function="Build.EnabledOrActive" />
</menu_item_check>
<menu
create_jump_keys="true"
diff --git a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml
index 2d54e69601..75c1de24aa 100644
--- a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml
@@ -27,4 +27,18 @@
<on_click
function="Wearing.Edit" />
</menu_item_call>
+ <menu_item_call
+ label="Edit"
+ layout="topleft"
+ name="edit_item">
+ <on_click
+ function="Wearing.EditItem" />
+ </menu_item_call>
+ <menu_item_call
+ label="Show Original"
+ layout="topleft"
+ name="show_original">
+ <on_click
+ function="Wearing.ShowOriginal" />
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 492d963653..54e90ac496 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -832,6 +832,13 @@ If you no longer wish to have these abilities granted to this role, disable them
</notification>
<notification
+ icon="notify.tga"
+ name="GroupBanUserOnBanlist"
+ type="notify">
+Some residents have not been sent an invite due to being banned from the group.
+ </notification>
+
+ <notification
icon="alertmodal.tga"
name="AttachmentDrop"
type="alertmodal">
@@ -1150,6 +1157,22 @@ Error encoding snapshot.
<notification
icon="alertmodal.tga"
+ name="ErrorPhotoCannotAfford"
+ type="alertmodal">
+ You need L$[COST] to save a photo to your inventory. You may either buy L$ or save the photo to your computer instead.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ErrorTextureCannotAfford"
+ type="alertmodal">
+ You need L$[COST] to save a texture to your inventory. You may either buy L$ or save the photo to your computer instead.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="ErrorUploadingPostcard"
type="alertmodal">
There was a problem sending a snapshot due to the following reason: [REASON]
@@ -3523,6 +3546,19 @@ Teleport all Residents in this region home?
<notification
icon="alertmodal.tga"
+ name="ChangeObjectBonusFactor"
+ type="alertmodal">
+ Lowering the object bonus after builds have been established in a region may cause objects to be returned or deleted. Are you sure you want to change object bonus?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Confirm changing object bonus factor"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="EstateObjectReturn"
type="alertmodal">
Are you sure you want to return objects owned by [USER_NAME]?
@@ -3636,6 +3672,13 @@ Can&apos;t add estate owner to estate &apos;Banned Resident&apos; list.
<notification
icon="alertmodal.tga"
+ name="ProblemAddingEstateManagerBanned"
+ type="alertmodal">
+Unable to add banned resident to estate manager list.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="CanNotChangeAppearanceUntilLoaded"
type="alertmodal">
Can&apos;t change appearance until clothing and shape are loaded.
@@ -4030,6 +4073,18 @@ Do you want to open your Web browser to view this content?
<notification
icon="alertmodal.tga"
+ name="SystemUIScaleFactorChanged"
+ type="alertmodal">
+System UI size factor has changed since last run. Do you want to open UI size adjustment settings page?
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="WebLaunchJoinNow"
type="alertmodal">
Go to your [http://secondlife.com/account/ Dashboard] to manage your account?
@@ -4149,6 +4204,14 @@ Leave Group?
</notification>
<notification
+ icon="notify.tga"
+ name="GroupDepart"
+ type="notify">
+You have left the group &apos;[group_name]&apos;.
+ <tag>group</tag>
+ </notification>
+
+ <notification
icon="alertmodal.tga"
name="OwnerCannotLeaveGroup"
type="alertmodal">
@@ -4160,6 +4223,17 @@ Leave Group?
</notification>
<notification
+ icon="alertmodal.tga"
+ name="GroupDepartError"
+ type="alertmodal">
+ Unable to leave group.
+ <tag>group</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
icon="alert.tga"
name="ConfirmKick"
type="alert">
@@ -5281,6 +5355,17 @@ There are too many prims selected. Please select [MAX_PRIM_COUNT] or fewer prim
</notification>
<notification
+ icon="alertmodal.tga"
+ name="TooManyScriptsSelected"
+ type="alertmodal">
+Too many scripts in the objects selected. Please select fewer objects and try again
+ <tag>fail</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
icon="alertmodal.tga"
name="ProblemImportingEstateCovenant"
type="alertmodal">
@@ -5699,6 +5784,17 @@ Warning: The &apos;Pay object&apos; click action has been set, but it will only
<notification
icon="alertmodal.tga"
+ name="PaymentBlockedButtonMismatch"
+ type="alertmodal">
+ Payment stopped: the price paid does not match any of the pay buttons set for this object.
+ <tag>fail</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="OpenObjectCannotCopy"
type="alertmodal">
There are no items in this object that you are allowed to copy.
@@ -6872,6 +6968,15 @@ This area has building disabled. You can&apos;t build or rez objects here.
</notification>
<notification
+ icon="notify.tga"
+ name="AutopilotCanceled"
+ persist="true"
+ type="notify">
+ <unique/>
+Autopilot canceled
+ </notification>
+
+ <notification
icon="notify.tga"
name="PathfindingDirty"
persist="true"
@@ -6881,6 +6986,19 @@ This area has building disabled. You can&apos;t build or rez objects here.
</notification>
<notification
+ icon="notify.tga"
+ name="PathfindingDirtyRebake"
+ persist="true"
+ type="notify">
+ <unique/>
+ The region has pending pathfinding changes. If you have build rights, you may rebake the region by clicking on the “Rebake region” button.
+ <usetemplate
+ name="okbutton"
+ yestext="Rebake region"
+ />
+ </notification>
+
+ <notification
icon="notify.tga"
name="DynamicPathfindingDisabled"
persist="true"
@@ -8272,8 +8390,18 @@ Appearance has been saved to XML to [PATH]
<notification icon="notifytip.tga"
name="AppearanceToXMLFailed" type="notifytip">
Failed to save appearance to XML.
+ </notification>
+
+ <notification
icon="notifytip.tga"
- name="PresetNotDeleted"
+ name="PresetNotSaved"
+ type="notifytip">
+Error saving preset [NAME].
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="PresetNotDeleted"
type="notifytip">
Error deleting preset [NAME].
</notification>
@@ -8752,23 +8880,6 @@ Click and drag anywhere on the world to rotate your view
</notification>
<notification
- name="PopupAttempt"
- icon="Popup_Caution"
- type="browser">
- A pop-up was prevented from opening.
- <form name="form">
- <ignore name="ignore"
- control="MediaEnablePopups"
- invert_control="true"
- text="Enable all pop-ups"/>
- <button default="true"
- index="0"
- name="open"
- text="Open pop-up window"/>
- </form>
- </notification>
-
- <notification
icon="alertmodal.tga"
name="SOCKS_NOT_PERMITTED"
type="alertmodal">
@@ -9750,6 +9861,14 @@ Can't move object '[OBJECT_NAME]' to
<notification
icon="alertmodal.tga"
+ name="NoParcelPermsNoObject"
+ type="notify">
+ <tag>fail</tag>
+Copy failed because you lack access to that parcel.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="CantMoveObjectRegionVersion"
type="notify">
<tag>fail</tag>
@@ -9785,6 +9904,17 @@ You don't have permission to modify that object
<notification
icon="alertmodal.tga"
+ name="TooMuchObjectInventorySelected"
+ type="alertmodal">
+ <tag>fail</tag>
+ Too many objects with large inventory are selected. Please select fewer objects and try again.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="CantEnablePhysObjContributesToNav"
type="notify">
<tag>fail</tag>
@@ -9882,6 +10012,22 @@ Cannot save to object contents: This would modify the attachment permissions.
<notification
icon="alertmodal.tga"
+ name="AttachmentHasTooMuchInventory"
+ type="notify">
+ <tag>fail</tag>
+Your attachments contain too much inventory to add more.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="IllegalAttachment"
+ type="notify">
+ <tag>fail</tag>
+The attachment has requested a nonexistent point on the avatar. It has been attached to the chest instead.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="TooManyScripts"
type="notify">
<tag>fail</tag>
@@ -10920,6 +11066,14 @@ Money transfers to objects are currently disabled in this region.
<notification
icon="alertmodal.tga"
+ name="DroppedMoneyTransferRequest"
+ type="notify">
+ <tag>fail</tag>
+Unable to make payment due to system load.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="CantPayNoAgent"
type="notify">
<tag>fail</tag>
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index 183ae2e824..ded814bbeb 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -67,7 +67,7 @@
follows="left|top"
height="32"
left_pad="-11"
- max_length_bytes="16"
+ max_length_chars="16"
text_pad_left="8"
name="password_edit"
label="Password"
diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml
index d1416ece82..35b80c56ab 100644
--- a/indra/newview/skins/default/xui/en/panel_login_first.xml
+++ b/indra/newview/skins/default/xui/en/panel_login_first.xml
@@ -124,7 +124,7 @@
width="200"
height="32"
left="220"
- max_length_bytes="16"
+ max_length_chars="16"
name="password_edit"
label="Password"
text_pad_left="8"
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml
index d85b778db2..42a7974316 100644
--- a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml
@@ -9,6 +9,26 @@
name="Wearing"
top="0"
width="312">
+<panel.string
+ name="no_attachments">
+ No attachments worn.
+ </panel.string>
+ <accordion
+ fit_parent="true"
+ follows="all"
+ height="400"
+ layout="topleft"
+ left="0"
+ single_expansion="true"
+ top="0"
+ name="wearables_accordion"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
+ width="309">
+ <accordion_tab
+ layout="topleft"
+ name="tab_wearables"
+ title="Wearables">
<wearable_items_list
follows="all"
height="400"
@@ -20,6 +40,27 @@
top="0"
width="309"
worn_indication_enabled="false" />
+ </accordion_tab>
+ <accordion_tab
+ layout="topleft"
+ name="tab_temp_attachments"
+ title="Temporary attachments">
+ <scroll_list
+ draw_heading="false"
+ left="3"
+ width="309"
+ height="400"
+ follows="all"
+ name="temp_attachments_list">
+ <scroll_list.columns
+ name="icon"
+ width="15" />
+ <scroll_list.columns
+ name="text"
+ width="210" />
+ </scroll_list>
+ </accordion_tab>
+ </accordion>
<panel
background_visible="true"
follows="bottom|left|right"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index 3e96160834..4a5117adac 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -138,7 +138,7 @@
initial_value="1"
layout="topleft"
left_pad="0"
- max_val="1.5"
+ max_val="2.0"
min_val="0.75"
name="ui_scale_slider"
top_pad="-14"
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 0b605cf6f7..c20f9b2c51 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -273,6 +273,18 @@
name="update_willing_to_test"
width="400"
top_pad="5"/>
+ <check_box
+ top_delta="4"
+ enabled="true"
+ follows="left|top"
+ height="14"
+ control_name="UpdaterShowReleaseNotes"
+ label="Show Release Notes after update"
+ left_delta="0"
+ mouse_opaque="true"
+ name="update_show_release_notes"
+ width="400"
+ top_pad="5"/>
<text
type="string"
length="1"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index ae63546082..b19c6756bc 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -54,6 +54,7 @@ LLCEFLib/CEF Version: [LLCEFLIB_VERSION]
Voice Server Version: [VOICE_VERSION]
</string>
<string name="AboutTraffic">Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)</string>
+ <string name="AboutTime">[month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt]</string>
<string name="ErrorFetchingServerReleaseNotesURL">Error fetching server release notes URL.</string>
<string name="BuildConfiguration">Build Configuration</string>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 1c77cf805e..f3d89bb866 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -30,6 +30,7 @@ import sys
import os.path
import shutil
import errno
+import json
import re
import tarfile
import time
@@ -181,9 +182,16 @@ class ViewerManifest(LLManifest):
self.path("*.tga")
self.end_prefix("local_assets")
- # Files in the newview/ directory
+ # File in the newview/ directory
self.path("gpu_table.txt")
- # The summary.json file gets left in the build directory by newview/CMakeLists.txt.
+
+ #summary.json. Standard with exception handling is fine. If we can't open a new file for writing, we have worse problems
+ summary_dict = {"Type":"viewer","Version":'.'.join(self.args['version']),"Channel":self.channel_with_pkg_suffix()}
+ with open(os.path.join(os.pardir,'summary.json'), 'w') as summary_handle:
+ json.dump(summary_dict,summary_handle)
+
+ #we likely no longer need the test, since we will throw an exception above, but belt and suspenders and we get the
+ #return code for free.
if not self.path2basename(os.pardir, "summary.json"):
print "No summary.json file"