summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorLoren Shih <seraph@lindenlab.com>2009-12-14 10:39:59 -0500
committerLoren Shih <seraph@lindenlab.com>2009-12-14 10:39:59 -0500
commitaad8d99af2b4a29d055dccb1c3fbea7a46fcb843 (patch)
tree96b398bd405344f42753e58afbb02092882715cb /indra
parent3e75137f26c099185677e1160570860e07a56595 (diff)
parenta763409647a5a8d82f2f1c54223b998877c3b72d (diff)
automated merge viewer2.0->viewer2.0
Diffstat (limited to 'indra')
-rw-r--r--indra/llmessage/llregionflags.h2
-rw-r--r--indra/llplugin/llpluginsharedmemory.cpp12
-rw-r--r--indra/llplugin/llpluginsharedmemory.h53
-rw-r--r--indra/llui/llhelp.h2
-rw-r--r--indra/newview/CMakeLists.txt6
-rw-r--r--indra/newview/app_settings/settings.xml22
-rw-r--r--indra/newview/character/avatar_lad.xml2
-rw-r--r--indra/newview/llappviewer.cpp10
-rw-r--r--indra/newview/llavatarpropertiesprocessor.cpp12
-rw-r--r--indra/newview/llcommanddispatcherlistener.cpp47
-rw-r--r--indra/newview/llcommanddispatcherlistener.h30
-rw-r--r--indra/newview/llcommandhandler.cpp3
-rw-r--r--indra/newview/llfloaterland.cpp20
-rw-r--r--indra/newview/llfloaterparcel.cpp6
-rw-r--r--indra/newview/llfloaterregioninfo.cpp33
-rw-r--r--indra/newview/llfloaterregioninfo.h3
-rw-r--r--indra/newview/llfloaterreporter.cpp32
-rw-r--r--indra/newview/llfloaterreporter.h1
-rw-r--r--indra/newview/llfloatertools.cpp22
-rw-r--r--indra/newview/llfloatervoicedevicesettings.cpp32
-rw-r--r--indra/newview/llfloatervoicedevicesettings.h1
-rw-r--r--indra/newview/llfolderviewitem.cpp6
-rw-r--r--indra/newview/llfolderviewitem.h4
-rw-r--r--indra/newview/llinventorybridge.cpp139
-rw-r--r--indra/newview/llinventorybridge.h4
-rwxr-xr-xindra/newview/llmediadataclient.cpp789
-rwxr-xr-xindra/newview/llmediadataclient.h90
-rw-r--r--indra/newview/llpanellogin.cpp12
-rw-r--r--indra/newview/llpanellogin.h5
-rw-r--r--indra/newview/llpanelloginlistener.cpp34
-rw-r--r--indra/newview/llpanelloginlistener.h30
-rw-r--r--indra/newview/llpanelmaininventory.cpp54
-rw-r--r--indra/newview/llpanelmaininventory.h2
-rw-r--r--indra/newview/llpanelmediasettingsgeneral.cpp9
-rw-r--r--indra/newview/llpanelmediasettingsgeneral.h2
-rw-r--r--indra/newview/llpanelmediasettingssecurity.cpp3
-rw-r--r--indra/newview/llpanelpicks.cpp99
-rw-r--r--indra/newview/llpanelpicks.h3
-rw-r--r--indra/newview/llpanelplaces.cpp16
-rw-r--r--indra/newview/llpanelprimmediacontrols.cpp145
-rw-r--r--indra/newview/llpanelprimmediacontrols.h2
-rw-r--r--indra/newview/llpreviewtexture.cpp32
-rw-r--r--indra/newview/llpreviewtexture.h3
-rw-r--r--indra/newview/llsidepanelinventory.cpp14
-rw-r--r--indra/newview/llsidepanelinventory.h1
-rw-r--r--indra/newview/llsidepanelinventorysubpanel.cpp7
-rw-r--r--indra/newview/llsidepanelinventorysubpanel.h1
-rw-r--r--indra/newview/llsidepaneliteminfo.cpp32
-rw-r--r--indra/newview/llsidepaneliteminfo.h1
-rw-r--r--indra/newview/llsidepaneltaskinfo.cpp4
-rw-r--r--indra/newview/llstartup.cpp3
-rw-r--r--indra/newview/lltexturefetch.cpp4
-rw-r--r--indra/newview/llurldispatcher.cpp3
-rw-r--r--indra/newview/llurldispatcherlistener.cpp58
-rw-r--r--indra/newview/llurldispatcherlistener.h32
-rw-r--r--indra/newview/llviewerhelp.cpp30
-rw-r--r--indra/newview/llviewerhelp.h11
-rw-r--r--indra/newview/llviewerinventory.cpp19
-rw-r--r--indra/newview/llviewerinventory.h3
-rw-r--r--indra/newview/llviewermedia.cpp68
-rw-r--r--indra/newview/llviewermedia.h5
-rw-r--r--indra/newview/llviewermenu.cpp11
-rw-r--r--indra/newview/llviewermenufile.cpp26
-rw-r--r--indra/newview/llviewertexture.cpp3
-rw-r--r--indra/newview/llvoavatar.cpp16
-rw-r--r--indra/newview/llvoiceclient.cpp12
-rw-r--r--indra/newview/llvoiceclient.h2
-rw-r--r--indra/newview/llvovolume.cpp108
-rw-r--r--indra/newview/llvovolume.h10
-rw-r--r--indra/newview/llwaterparammanager.cpp8
-rw-r--r--indra/newview/llwlparammanager.cpp8
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml13
-rw-r--r--indra/newview/skins/default/xui/en/floater_buy_currency.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_texture.xml11
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml5
-rw-r--r--indra/newview/skins/default/xui/en/floater_voice_controls.xml20
-rw-r--r--indra/newview/skins/default/xui/en/floater_water.xml1
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_login.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml12
-rw-r--r--indra/newview/skins/default/xui/en/mime_types_linux.xml442
-rw-r--r--indra/newview/skins/default/xui/en/mime_types_mac.xml442
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml19
-rw-r--r--indra/newview/skins/default/xui/en/panel_media_settings_general.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_general.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_sound.xml41
-rw-r--r--indra/newview/skins/default/xui/en/panel_prim_media_controls.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_covenant.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_debug.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_estate.xml33
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_general.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_terrain.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_texture.xml1
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_item_info.xml9
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_task_info.xml11
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml8
-rw-r--r--indra/newview/tests/llmediadataclient_test.cpp405
-rwxr-xr-xindra/newview/viewer_manifest.py2
-rw-r--r--indra/test_apps/llplugintest/llmediaplugintest.cpp4
100 files changed, 2821 insertions, 1020 deletions
diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h
index 232478577c..40e4a4268d 100644
--- a/indra/llmessage/llregionflags.h
+++ b/indra/llmessage/llregionflags.h
@@ -92,7 +92,7 @@ const U32 REGION_FLAGS_DENY_ANONYMOUS = (1 << 23);
const U32 REGION_FLAGS_ALLOW_PARCEL_CHANGES = (1 << 26);
-const U32 REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER = (1 << 27);
+// const U32 REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER = (1 << 27); // We no longer support ELAR
const U32 REGION_FLAGS_ALLOW_VOICE = (1 << 28);
diff --git a/indra/llplugin/llpluginsharedmemory.cpp b/indra/llplugin/llpluginsharedmemory.cpp
index 3c69a69d28..9c18b410c7 100644
--- a/indra/llplugin/llpluginsharedmemory.cpp
+++ b/indra/llplugin/llpluginsharedmemory.cpp
@@ -1,6 +1,6 @@
/**
* @file llpluginsharedmemory.cpp
- * @brief LLPluginSharedMemory manages a shared memory segment for use by the LLPlugin API.
+ * LLPluginSharedMemory manages a shared memory segment for use by the LLPlugin API.
*
* @cond
* $LicenseInfo:firstyear=2008&license=viewergpl$
@@ -96,6 +96,10 @@ std::string LLPluginSharedMemory::createName(void)
return newname.str();
}
+/**
+ * @brief LLPluginSharedMemoryImpl is the platform-dependent implementation of LLPluginSharedMemory. TODO:DOC is this necessary/sufficient? kinda obvious.
+ *
+ */
class LLPluginSharedMemoryPlatformImpl
{
public:
@@ -112,6 +116,9 @@ public:
};
+/**
+ * Constructor. Creates a shared memory segment.
+ */
LLPluginSharedMemory::LLPluginSharedMemory()
{
mSize = 0;
@@ -121,6 +128,9 @@ LLPluginSharedMemory::LLPluginSharedMemory()
mImpl = new LLPluginSharedMemoryPlatformImpl;
}
+/**
+ * Destructor. Uses destroy() and detach() to ensure shared memory segment is cleaned up.
+ */
LLPluginSharedMemory::~LLPluginSharedMemory()
{
if(mNeedsDestroy)
diff --git a/indra/llplugin/llpluginsharedmemory.h b/indra/llplugin/llpluginsharedmemory.h
index 4014620c52..00c54ef08c 100644
--- a/indra/llplugin/llpluginsharedmemory.h
+++ b/indra/llplugin/llpluginsharedmemory.h
@@ -1,6 +1,5 @@
/**
* @file llpluginsharedmemory.h
- * @brief LLPluginSharedMemory manages a shared memory segment for use by the LLPlugin API.
*
* @cond
* $LicenseInfo:firstyear=2008&license=viewergpl$
@@ -36,6 +35,10 @@
class LLPluginSharedMemoryPlatformImpl;
+/**
+ * @brief LLPluginSharedMemory manages a shared memory segment for use by the LLPlugin API.
+ *
+ */
class LLPluginSharedMemory
{
LOG_CLASS(LLPluginSharedMemory);
@@ -46,16 +49,62 @@ public:
// Parent will use create/destroy, child will use attach/detach.
// Message transactions will ensure child attaches after parent creates and detaches before parent destroys.
- // create() implicitly creates a name for the segment which is guaranteed to be unique on the host at the current time.
+ /**
+ * Creates a shared memory segment, with a name which is guaranteed to be unique on the host at the current time. Used by parent.
+ * Message transactions will (? TODO:DOC - should? must?) ensure child attaches after parent creates and detaches before parent destroys.
+ *
+ * @param[in] size Shared memory size in TODO:DOC units = bytes?.
+ *
+ * @return False for failure, true for success.
+ */
bool create(size_t size);
+ /**
+ * Destroys a shared memory segment. Used by parent.
+ * Message transactions will (? TODO:DOC - should? must?) ensure child attaches after parent creates and detaches before parent destroys.
+ *
+ * @return True. TODO:DOC - always returns true. Is this the intended behavior?
+ */
bool destroy(void);
+ /**
+ * Creates and attaches a name to a shared memory segment. TODO:DOC what's the difference between attach() and create()?
+ *
+ * @param[in] name Name to attach to memory segment
+ * @param[in] size Size of memory segment TODO:DOC in bytes?
+ *
+ * @return False on failure, true otherwise.
+ */
bool attach(const std::string &name, size_t size);
+ /**
+ * Detaches shared memory segment.
+ *
+ * @return False on failure, true otherwise.
+ */
bool detach(void);
+ /**
+ * Checks if shared memory is mapped to a non-null address.
+ *
+ * @return True if memory address is non-null, false otherwise.
+ */
bool isMapped(void) const { return (mMappedAddress != NULL); };
+ /**
+ * Get pointer to shared memory.
+ *
+ * @return Pointer to shared memory.
+ */
void *getMappedAddress(void) const { return mMappedAddress; };
+ /**
+ * Get size of shared memory.
+ *
+ * @return Size of shared memory in bytes. TODO:DOC are bytes the correct unit?
+ */
size_t getSize(void) const { return mSize; };
+ /**
+ * Get name of shared memory.
+ *
+ * @return Name of shared memory.
+ */
std::string getName() const { return mName; };
private:
diff --git a/indra/llui/llhelp.h b/indra/llui/llhelp.h
index 82c3bc385f..938419d374 100644
--- a/indra/llui/llhelp.h
+++ b/indra/llui/llhelp.h
@@ -42,6 +42,8 @@ class LLHelp
virtual std::string defaultTopic() = 0;
// return topic to use before the user logs in
virtual std::string preLoginTopic() = 0;
+ // return topic to use for the top-level help, invoked by F1
+ virtual std::string f1HelpTopic() = 0;
};
#endif // headerguard
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index be6bce8054..72630cc413 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -104,6 +104,7 @@ set(viewer_SOURCE_FILES
llclassifiedstatsresponder.cpp
llcloud.cpp
llcolorswatch.cpp
+ llcommanddispatcherlistener.cpp
llcommandhandler.cpp
llcommandlineparser.cpp
llcompilequeue.cpp
@@ -324,6 +325,7 @@ set(viewer_SOURCE_FILES
llpanellandmarks.cpp
llpanellandmedia.cpp
llpanellogin.cpp
+ llpanelloginlistener.cpp
llpanellookinfo.cpp
llpanelmaininventory.cpp
llpanelmediasettingsgeneral.cpp
@@ -444,6 +446,7 @@ set(viewer_SOURCE_FILES
lluploaddialog.cpp
llurl.cpp
llurldispatcher.cpp
+ llurldispatcherlistener.cpp
llurlhistory.cpp
llurllineeditorctrl.cpp
llurlsimstring.cpp
@@ -611,6 +614,7 @@ set(viewer_HEADER_FILES
llclassifiedstatsresponder.h
llcloud.h
llcolorswatch.h
+ llcommanddispatcherlistener.h
llcommandhandler.h
llcommandlineparser.h
llcompilequeue.h
@@ -826,6 +830,7 @@ set(viewer_HEADER_FILES
llpanellandmarks.h
llpanellandmedia.h
llpanellogin.h
+ llpanelloginlistener.h
llpanellookinfo.h
llpanelmaininventory.h
llpanelmediasettingsgeneral.h
@@ -950,6 +955,7 @@ set(viewer_HEADER_FILES
lluploaddialog.h
llurl.h
llurldispatcher.h
+ llurldispatcherlistener.h
llurlhistory.h
llurllineeditorctrl.h
llurlsimstring.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 289e900eaf..eed84671c1 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -5515,6 +5515,28 @@
<key>Value</key>
<real>5.0</real>
</map>
+ <key>PrimMediaMaxSortedQueueSize</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum number of objects the viewer will load media for initially</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>100000</integer>
+ </map>
+ <key>PrimMediaMaxRoundRobinQueueSize</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum number of objects the viewer will continuously update media for</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>100000</integer>
+ </map>
<key>ProbeHardwareOnStartup</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml
index d7182dfaab..ae89eb4413 100644
--- a/indra/newview/character/avatar_lad.xml
+++ b/indra/newview/character/avatar_lad.xml
@@ -9283,7 +9283,7 @@ render_pass="bump">
wearable="skin"
edit_group="skin_facedetail"
edit_group_order="3"
- name="wrinkles"
+ name="Wrinkles"
label_min="Less"
label_max="More"
value_min="0"
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 9a1b749ba7..3250343b25 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -746,7 +746,15 @@ bool LLAppViewer::init()
LLViewerJointMesh::updateVectorize();
// load MIME type -> media impl mappings
- LLMIMETypes::parseMIMETypes( std::string("mime_types.xml") );
+ std::string mime_types_name;
+#if LL_DARWIN
+ mime_types_name = "mime_types_mac.xml";
+#elif LL_LINUX
+ mime_types_name = "mime_types_linux.xml";
+#else
+ mime_types_name = "mime_types.xml";
+#endif
+ LLMIMETypes::parseMIMETypes( mime_types_name );
// Copy settings to globals. *TODO: Remove or move to appropriage class initializers
settings_to_globals();
diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
index 7cda2d31e6..33e5046f50 100644
--- a/indra/newview/llavatarpropertiesprocessor.cpp
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -440,11 +440,17 @@ void LLAvatarPropertiesProcessor::notifyObservers(const LLUUID& id,void* data, E
// Copy the map (because observers may delete themselves when updated?)
LLAvatarPropertiesProcessor::observer_multimap_t observers = mObservers;
- observer_multimap_t::iterator oi = observers.lower_bound(id);
- observer_multimap_t::iterator end = observers.upper_bound(id);
+ observer_multimap_t::iterator oi = observers.begin();
+ observer_multimap_t::iterator end = observers.end();
for (; oi != end; ++oi)
{
- oi->second->processProperties(data,type);
+ // only notify observers for the same agent, or if the observer
+ // didn't know the agent ID and passed a NULL id.
+ const LLUUID &agent_id = oi->first;
+ if (agent_id == id || agent_id.isNull())
+ {
+ oi->second->processProperties(data,type);
+ }
}
}
diff --git a/indra/newview/llcommanddispatcherlistener.cpp b/indra/newview/llcommanddispatcherlistener.cpp
new file mode 100644
index 0000000000..00a20de30e
--- /dev/null
+++ b/indra/newview/llcommanddispatcherlistener.cpp
@@ -0,0 +1,47 @@
+/**
+ * @file llcommanddispatcherlistener.cpp
+ * @author Nat Goodspeed
+ * @date 2009-12-10
+ * @brief Implementation for llcommanddispatcherlistener.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "llviewerprecompiledheaders.h"
+// associated header
+#include "llcommanddispatcherlistener.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "llcommandhandler.h"
+
+LLCommandDispatcherListener::LLCommandDispatcherListener(/* LLCommandDispatcher* instance */):
+ LLEventAPI("LLCommandDispatcher", "Access to LLCommandHandler commands") /* ,
+ mDispatcher(instance) */
+{
+ add("dispatch",
+ "Execute a command registered as an LLCommandHandler,\n"
+ "passing any required parameters:\n"
+ "[\"cmd\"] string command name\n"
+ "[\"params\"] array of parameters, as if from components of URL path\n"
+ "[\"query\"] map of parameters, as if from ?key1=val&key2=val\n"
+ "[\"trusted\"] boolean indicating trusted browser [default true]",
+ &LLCommandDispatcherListener::dispatch);
+}
+
+void LLCommandDispatcherListener::dispatch(const LLSD& params) const
+{
+ // For most purposes, we expect callers to want to be trusted.
+ bool trusted_browser = true;
+ if (params.has("trusted"))
+ {
+ // But for testing, allow a caller to specify untrusted.
+ trusted_browser = params["trusted"].asBoolean();
+ }
+ LLCommandDispatcher::dispatch(params["cmd"], params["params"], params["query"], NULL,
+ trusted_browser);
+}
diff --git a/indra/newview/llcommanddispatcherlistener.h b/indra/newview/llcommanddispatcherlistener.h
new file mode 100644
index 0000000000..d0070ddd71
--- /dev/null
+++ b/indra/newview/llcommanddispatcherlistener.h
@@ -0,0 +1,30 @@
+/**
+ * @file llcommanddispatcherlistener.h
+ * @author Nat Goodspeed
+ * @date 2009-12-10
+ * @brief LLEventAPI for LLCommandDispatcher
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLCOMMANDDISPATCHERLISTENER_H)
+#define LL_LLCOMMANDDISPATCHERLISTENER_H
+
+#include "lleventapi.h"
+class LLCommandDispatcher;
+class LLSD;
+
+class LLCommandDispatcherListener: public LLEventAPI
+{
+public:
+ LLCommandDispatcherListener(/* LLCommandDispatcher* instance */); // all static members
+
+private:
+ void dispatch(const LLSD& params) const;
+
+ //LLCommandDispatcher* mDispatcher;
+};
+
+#endif /* ! defined(LL_LLCOMMANDDISPATCHERLISTENER_H) */
diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp
index 1d92661ea2..8c7e7bea83 100644
--- a/indra/newview/llcommandhandler.cpp
+++ b/indra/newview/llcommandhandler.cpp
@@ -35,12 +35,15 @@
#include "llcommandhandler.h"
#include "llnotificationsutil.h"
+#include "llcommanddispatcherlistener.h"
// system includes
#include <boost/tokenizer.hpp>
#define THROTTLE_PERIOD 15 // required secs between throttled commands
+static LLCommandDispatcherListener sCommandDispatcherListener;
+
//---------------------------------------------------------------------------
// Underlying registry for command handlers, not directly accessible.
//---------------------------------------------------------------------------
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index ed0f24d160..5b03292b22 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -2300,7 +2300,7 @@ void LLPanelLandAccess::refresh()
mListBanned->deleteAllItems();
LLParcel *parcel = mParcel->getParcel();
-
+
// Display options
if (parcel)
{
@@ -2396,22 +2396,40 @@ void LLPanelLandAccess::refresh()
mListBanned->addNameItem(entry.mID, ADD_SORTED, TRUE, suffix);
}
}
+
+ LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
+ if(region)
+ {
+ std::string region_access = "(";
+ region_access += region->getSimAccessString();
+ region_access += ")";
+ childSetLabelArg( "public_access", "[MATURITY]", region_access );
+ }
+ else
+ {
+ childSetLabelArg( "public_access", "[MATURITY]", std::string() );
+ }
+
if(parcel->getRegionDenyAnonymousOverride())
{
childSetValue("limit_payment", TRUE);
+ childSetLabelArg( "limit_payment", "[ESTATE_PAYMENT_LIMIT]", getString("access_estate_defined") );
}
else
{
childSetValue("limit_payment", (parcel->getParcelFlag(PF_DENY_ANONYMOUS)));
+ childSetLabelArg( "limit_payment", "[ESTATE_PAYMENT_LIMIT]", std::string() );
}
if(parcel->getRegionDenyAgeUnverifiedOverride())
{
childSetValue("limit_age_verified", TRUE);
+ childSetLabelArg( "limit_age_verified", "[ESTATE_AGE_LIMIT]", getString("access_estate_defined") );
}
else
{
childSetValue("limit_age_verified", (parcel->getParcelFlag(PF_DENY_AGEUNVERIFIED)));
+ childSetLabelArg( "limit_age_verified", "[ESTATE_AGE_LIMIT]", std::string() );
}
BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST);
diff --git a/indra/newview/llfloaterparcel.cpp b/indra/newview/llfloaterparcel.cpp
index 88a39a495f..e2be784116 100644
--- a/indra/newview/llfloaterparcel.cpp
+++ b/indra/newview/llfloaterparcel.cpp
@@ -40,6 +40,7 @@
// viewer project includes
#include "llcommandhandler.h"
#include "llpanelplace.h"
+#include "llsidetray.h"
// linden library includes
#include "lluuid.h"
@@ -70,7 +71,10 @@ public:
{
if (parcel_id.notNull())
{
- LLFloaterReg::showInstance("parcel_info", LLSD(parcel_id));
+ LLSD key;
+ key["type"] = "remote_place";
+ key["id"] = parcel_id;
+ LLSideTray::getInstance()->showPanel("panel_places", key);
return true;
}
}
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 05a46ad894..8a26078f3d 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -88,8 +88,6 @@
#include "lltrans.h"
#include "llagentui.h"
-#define ELAR_ENABLED 0 // Enable when server support is implemented
-
const S32 TERRAIN_TEXTURE_COUNT = 4;
const S32 CORNER_COUNT = 4;
@@ -1995,11 +1993,6 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)
childSetEnabled("remove_banned_avatar_btn", god || owner || manager);
childSetEnabled("message_estate_btn", god || owner || manager);
childSetEnabled("kick_user_from_estate_btn", god || owner || manager);
-#if ELAR_ENABLED
- childSetEnabled("abuse_email_address", god || owner || manager);
-#else
- childSetEnabled("abuse_email_address", false);
-#endif
// estate managers can't add estate managers
childSetEnabled("add_estate_manager_btn", god || owner);
@@ -2065,8 +2058,6 @@ BOOL LLPanelEstateInfo::postBuild()
initCtrl("limit_payment");
initCtrl("limit_age_verified");
initCtrl("voice_chat_check");
- getChild<LLUICtrl>("abuse_email_address")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeAnything, this));
- getChild<LLLineEditor>("abuse_email_address")->setKeystrokeCallback(onChangeText, this);
// set up the use global time checkbox
getChild<LLUICtrl>("use_global_time_check")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeUseGlobalTime, this));
@@ -2276,8 +2267,6 @@ bool LLPanelEstateInfo::commitEstateInfoCaps()
}
body["sun_hour"] = sun_hour;
- body["owner_abuse_email"] = childGetValue("abuse_email_address").asString();
-
// we use a responder so that we can re-get the data after committing to the database
LLHTTPClient::post(url, body, new LLEstateChangeInfoResponder(this));
return true;
@@ -2436,16 +2425,6 @@ void LLPanelEstateInfo::setOwnerName(const std::string& name)
childSetValue("estate_owner", LLSD(name));
}
-const std::string LLPanelEstateInfo::getAbuseEmailAddress() const
-{
- return childGetValue("abuse_email_address").asString();
-}
-
-void LLPanelEstateInfo::setAbuseEmailAddress(const std::string& address)
-{
- childSetValue("abuse_email_address", LLSD(address));
-}
-
void LLPanelEstateInfo::setAccessAllowedEnabled(bool enable_agent,
bool enable_group,
bool enable_ban)
@@ -2954,18 +2933,6 @@ bool LLDispatchEstateUpdateInfo::operator()(
std::string estate_name = strings[0].c_str(); // preserve c_str() call!
panel->setEstateName(estate_name);
-#if ELAR_ENABLED
- if (strings.size() > 9)
- {
- std::string abuse_email = strings[9].c_str(); // preserve c_str() call!
- panel->setAbuseEmailAddress(abuse_email);
- }
- else
-#endif
- {
- panel->setAbuseEmailAddress(panel->getString("email_unsupported"));
- }
-
LLViewerRegion* regionp = gAgent.getRegion();
LLUUID owner_id(strings[1]);
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index a3b91223b7..704166d106 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -330,9 +330,6 @@ public:
const std::string getOwnerName() const;
void setOwnerName(const std::string& name);
- const std::string getAbuseEmailAddress() const;
- void setAbuseEmailAddress(const std::string& address);
-
// If visible from mainland, allowed agent and allowed groups
// are ignored, so must disable UI.
void setAccessAllowedEnabled(bool enable_agent, bool enable_group, bool enable_ban);
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 408303a1e0..932e49c79b 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -95,7 +95,6 @@ const U32 INCLUDE_SCREENSHOT = 0x01 << 0;
LLFloaterReporter::LLFloaterReporter(const LLSD& key)
: LLFloater(key),
mReportType(COMPLAINT_REPORT),
- mEmailToEstateOwner(FALSE),
mObjectID(),
mScreenID(),
mAbuserID(),
@@ -117,18 +116,7 @@ void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg)
if ( LLFloaterReg::instanceVisible("reporter") )
{
- LLFloaterReporter *f = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
- BOOL email_to_estate_owner = ( region_flags & REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER );
- f->mEmailToEstateOwner = email_to_estate_owner;
-
- if ( email_to_estate_owner )
- {
- LLNotificationsUtil::add("HelpReportAbuseEmailEO");
- }
- else
- {
- LLNotificationsUtil::add("HelpReportAbuseEmailLL");
- }
+ LLNotificationsUtil::add("HelpReportAbuseEmailLL");
};
}
// virtual
@@ -218,17 +206,7 @@ LLFloaterReporter::~LLFloaterReporter()
// virtual
void LLFloaterReporter::draw()
{
- // this is set by a static callback sometime after the dialog is created.
- // Only disable screenshot for abuse reports to estate owners
- if ( mEmailToEstateOwner )
- {
- childSetValue("screen_check", FALSE );
- childSetEnabled("screen_check", FALSE );
- }
- else
- {
- childSetEnabled("screen_check", TRUE );
- }
+ childSetEnabled("screen_check", TRUE );
LLFloater::draw();
}
@@ -637,11 +615,7 @@ LLSD LLFloaterReporter::gatherReport()
LLUUID screenshot_id = LLUUID::null;
if (childGetValue("screen_check"))
{
-
- if ( mEmailToEstateOwner == FALSE )
- {
- screenshot_id = childGetValue("screenshot");
- }
+ screenshot_id = childGetValue("screenshot");
};
LLSD report = LLSD::emptyMap();
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index 917f513641..a3776f3d27 100644
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -124,7 +124,6 @@ private:
private:
EReportType mReportType;
- BOOL mEmailToEstateOwner;
LLUUID mObjectID;
LLUUID mScreenID;
LLUUID mAbuserID;
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 6ba032c152..7fb71d4d4f 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -991,7 +991,7 @@ S32 LLFloaterTools::calcRenderCost()
if (viewer_volume)
{
cost += viewer_volume->getRenderCost(textures);
- cost += textures.size() * 5;
+ cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST;
textures.clear();
}
}
@@ -1080,7 +1080,7 @@ void LLFloaterTools::getMediaState()
{
LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
LLViewerObject* first_object = selected_objects->getFirstObject();
- LLLineEditor* media_info = getChild<LLLineEditor>("media_info");
+ LLTextBox* media_info = getChild<LLTextBox>("media_info");
if( !(first_object
&& first_object->getPCode() == LL_PCODE_VOLUME
@@ -1088,12 +1088,6 @@ void LLFloaterTools::getMediaState()
))
{
childSetEnabled("Add_Media", FALSE);
-/* childSetEnabled("media_tex", FALSE);
- childSetEnabled("add_media", FALSE);
- childSetEnabled("delete_media", FALSE);
- childSetEnabled("edit_media", FALSE);
- childSetEnabled("media_info", FALSE);
- media_info->setEnabled(FALSE);*/
media_info->clear();
clearMediaSettings();
return;
@@ -1105,13 +1099,6 @@ void LLFloaterTools::getMediaState()
if(!has_media_capability)
{
childSetEnabled("Add_Media", FALSE);
- /* childSetEnabled("media_tex", FALSE);
- childSetEnabled("add_media", FALSE);
- childSetEnabled("delete_media", FALSE);
- childSetEnabled("edit_media", FALSE);
- childSetEnabled("media_info", FALSE);
- media_info->setEnabled(FALSE);
- media_info->clear();*/
LL_WARNS("LLFloaterTools: media") << "Media not enabled (no capability) in this region!" << LL_ENDL;
clearMediaSettings();
return;
@@ -1233,7 +1220,6 @@ void LLFloaterTools::getMediaState()
childSetEnabled( "edit_media", bool_has_media & editable );
childSetEnabled( "delete_media", bool_has_media & editable );
childSetEnabled( "add_media", ( ! bool_has_media ) & editable );
- media_info->setEnabled(false);
// TODO: display a list of all media on the face - use 'identical' flag
}
else // not all face has media but at least one does.
@@ -1260,8 +1246,6 @@ void LLFloaterTools::getMediaState()
}
}
- media_info->setEnabled(false);
- media_info->setTentative(true);
childSetEnabled("media_tex", TRUE);
childSetEnabled( "edit_media", TRUE);
childSetEnabled( "delete_media", TRUE);
@@ -1392,7 +1376,7 @@ void LLFloaterTools::updateMediaTitle()
if ( ! media_title.empty() )
{
// update the UI widget
- LLLineEditor* media_title_field = getChild<LLLineEditor>("media_info");
+ LLTextBox* media_title_field = getChild<LLTextBox>("media_info");
if ( media_title_field )
{
media_title_field->setText( media_title );
diff --git a/indra/newview/llfloatervoicedevicesettings.cpp b/indra/newview/llfloatervoicedevicesettings.cpp
index 43024a4bd0..3951f4291f 100644
--- a/indra/newview/llfloatervoicedevicesettings.cpp
+++ b/indra/newview/llfloatervoicedevicesettings.cpp
@@ -40,7 +40,6 @@
#include "llcombobox.h"
#include "llfocusmgr.h"
#include "lliconctrl.h"
-#include "llsliderctrl.h"
#include "llviewercontrol.h"
#include "llvoiceclient.h"
#include "llvoicechannel.h"
@@ -61,9 +60,6 @@ LLPanelVoiceDeviceSettings::LLPanelVoiceDeviceSettings()
mOutputDevice = gSavedSettings.getString("VoiceOutputAudioDevice");
mDevicesUpdated = FALSE;
- // grab "live" mic volume level
- mMicVolume = gSavedSettings.getF32("AudioLevelMic");
-
// ask for new device enumeration
// now do this in onOpen() instead...
//gVoiceClient->refreshDeviceLists();
@@ -75,10 +71,6 @@ LLPanelVoiceDeviceSettings::~LLPanelVoiceDeviceSettings()
BOOL LLPanelVoiceDeviceSettings::postBuild()
{
- LLSlider* volume_slider = getChild<LLSlider>("mic_volume_slider");
- // set mic volume tuning slider based on last mic volume setting
- volume_slider->setValue(mMicVolume);
-
childSetCommitCallback("voice_input_device", onCommitInputDevice, this);
childSetCommitCallback("voice_output_device", onCommitOutputDevice, this);
@@ -157,15 +149,6 @@ void LLPanelVoiceDeviceSettings::apply()
gSavedSettings.setString("VoiceOutputAudioDevice", s);
mOutputDevice = s;
}
-
- // assume we are being destroyed by closing our embedding window
- LLSlider* volume_slider = getChild<LLSlider>("mic_volume_slider");
- if(volume_slider)
- {
- F32 slider_value = (F32)volume_slider->getValue().asReal();
- gSavedSettings.setF32("AudioLevelMic", slider_value);
- mMicVolume = slider_value;
- }
}
void LLPanelVoiceDeviceSettings::cancel()
@@ -178,22 +161,12 @@ void LLPanelVoiceDeviceSettings::cancel()
if(mCtrlOutputDevices)
mCtrlOutputDevices->setSimple(mOutputDevice);
-
- gSavedSettings.setF32("AudioLevelMic", mMicVolume);
- LLSlider* volume_slider = getChild<LLSlider>("mic_volume_slider");
- if(volume_slider)
- {
- volume_slider->setValue(mMicVolume);
- }
}
void LLPanelVoiceDeviceSettings::refresh()
{
- //grab current volume
- LLSlider* volume_slider = getChild<LLSlider>("mic_volume_slider");
- // set mic volume tuning slider based on last mic volume setting
- F32 current_volume = (F32)volume_slider->getValue().asReal();
- gVoiceClient->tuningSetMicVolume(current_volume);
+ // update the live input level display
+ gVoiceClient->tuningSetMicVolume();
// Fill in popup menus
mCtrlInputDevices = getChild<LLComboBox>("voice_input_device");
@@ -263,7 +236,6 @@ void LLPanelVoiceDeviceSettings::initialize()
{
mInputDevice = gSavedSettings.getString("VoiceInputAudioDevice");
mOutputDevice = gSavedSettings.getString("VoiceOutputAudioDevice");
- mMicVolume = gSavedSettings.getF32("AudioLevelMic");
mDevicesUpdated = FALSE;
// ask for new device enumeration
diff --git a/indra/newview/llfloatervoicedevicesettings.h b/indra/newview/llfloatervoicedevicesettings.h
index d67283d0a2..20958af780 100644
--- a/indra/newview/llfloatervoicedevicesettings.h
+++ b/indra/newview/llfloatervoicedevicesettings.h
@@ -56,7 +56,6 @@ protected:
static void onCommitInputDevice(LLUICtrl* ctrl, void* user_data);
static void onCommitOutputDevice(LLUICtrl* ctrl, void* user_data);
- F32 mMicVolume;
std::string mInputDevice;
std::string mOutputDevice;
class LLComboBox *mCtrlInputDevices;
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 5bef306485..fe793fbcb8 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -40,6 +40,7 @@
#include "llinventoryfilter.h"
#include "llpanel.h"
#include "llviewercontrol.h" // gSavedSettings
+#include "llviewerinventory.h"
#include "llviewerwindow.h" // Argh, only for setCursor()
// linden library includes
@@ -603,6 +604,11 @@ const std::string& LLFolderViewItem::getSearchableLabel() const
return mSearchableLabel;
}
+LLViewerInventoryItem * LLFolderViewItem::getInventoryItem(void)
+{
+ return gInventory.getItem(getListener()->getUUID());
+}
+
std::string LLFolderViewItem::getName( void ) const
{
if(mListener)
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index 0ea031108b..43a5fd8de5 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -45,6 +45,7 @@ class LLFolderViewListenerFunctor;
class LLInventoryFilter;
class LLMenuGL;
class LLUIImage;
+class LLViewerInventoryItem;
// These are grouping of inventory types.
// Order matters when sorting system folders to the top.
@@ -281,6 +282,9 @@ public:
const LLFolderViewEventListener* getListener( void ) const { return mListener; }
LLFolderViewEventListener* getListener( void ) { return mListener; }
+
+ // Gets the inventory item if it exists (null otherwise)
+ LLViewerInventoryItem * getInventoryItem(void);
// just rename the object.
void rename(const std::string& new_name);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 3746e9cfeb..26a8a707b8 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -506,12 +506,59 @@ void hide_context_entries(LLMenuGL& menu,
}
}
+bool isWornLink(LLUUID link_id)
+{
+ LLViewerInventoryItem *link = gInventory.getItem(link_id);
+ if (!link)
+ return false;
+ LLViewerInventoryItem *item = link->getLinkedItem();
+ if (!item)
+ return false;
+
+ switch(item->getType())
+ {
+ case LLAssetType::AT_OBJECT:
+ {
+ LLVOAvatarSelf* my_avatar = gAgent.getAvatarObject();
+ if(my_avatar && my_avatar->isWearingAttachment(item->getUUID()))
+ return true;
+ }
+ break;
+
+ case LLAssetType::AT_BODYPART:
+ case LLAssetType::AT_CLOTHING:
+ if(gAgentWearables.isWearingItem(item->getUUID()))
+ return true;
+ break;
+
+ case LLAssetType::AT_GESTURE:
+ if (LLGestureManager::instance().isGestureActive(item->getUUID()))
+ return true;
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
// Helper for commonly-used entries
void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
std::vector<std::string> &items,
std::vector<std::string> &disabled_items, U32 flags)
{
const LLInventoryObject *obj = getInventoryObject();
+
+ bool is_sidepanel = isInOutfitsSidePanel();
+ if (is_sidepanel)
+ {
+ // Sidepanel includes restricted menu.
+ if (obj && obj->getIsLinkType() && !isWornLink(mUUID))
+ {
+ items.push_back(std::string("Remove Link"));
+ }
+ return;
+ }
+
if (obj)
{
if (obj->getIsLinkType())
@@ -566,6 +613,12 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
}
items.push_back(std::string("Paste Separator"));
+
+ if (obj && obj->getIsLinkType() && !isWornLink(mUUID))
+ {
+ items.push_back(std::string("Remove Link"));
+ }
+
items.push_back(std::string("Delete"));
if (!isItemRemovable())
{
@@ -913,6 +966,16 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid)
}
}
+bool LLInvFVBridge::isInOutfitsSidePanel() const
+{
+ LLInventoryPanel *my_panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
+ LLPanelOutfitsInventory *outfit_panel =
+ dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));
+ if (!outfit_panel)
+ return false;
+ return outfit_panel->isAccordionPanel(my_panel);
+}
+
// +=================================================+
// | InventoryFVBridgeBuilder |
// +=================================================+
@@ -2386,19 +2449,6 @@ void LLFolderBridge::staticFolderOptionsMenu()
sSelf->folderOptionsMenu();
}
-bool isInOutfitsSidePanel(LLPanel *panel)
-{
- LLInventoryPanel *my_panel = dynamic_cast<LLInventoryPanel*>(panel);
- LLPanelOutfitsInventory *outfit_panel =
- dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));
- if (!outfit_panel)
- return false;
- return outfit_panel->isAccordionPanel(my_panel);
-
- //LLInventoryPanel *outfit_inv_panel = outfit_panel ? outfit_panel->getActivePanel(): NULL;
- //return (my_panel && (my_panel == outfit_inv_panel));
-}
-
void LLFolderBridge::folderOptionsMenu()
{
std::vector<std::string> disabled_items;
@@ -2412,13 +2462,12 @@ void LLFolderBridge::folderOptionsMenu()
// BAP change once we're no longer treating regular categories as ensembles.
const bool is_ensemble = category && (type == LLFolderType::FT_NONE ||
LLFolderType::lookupIsEnsembleType(type));
- const bool is_sidepanel = isInOutfitsSidePanel(mInventoryPanel.get());
// calling card related functionality for folders.
+ const bool is_sidepanel = isInOutfitsSidePanel();
if (is_sidepanel)
{
- mItems.clear();
mItems.push_back("Rename");
mItems.push_back("Delete");
}
@@ -2488,14 +2537,13 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
mDisabledItems.clear();
lldebugs << "LLFolderBridge::buildContextMenu()" << llendl;
+
// std::vector<std::string> disabled_items;
LLInventoryModel* model = getInventoryModel();
if(!model) return;
const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
const LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
- mItems.clear(); //adding code to clear out member Items (which means Items should not have other data here at this point)
- mDisabledItems.clear(); //adding code to clear out disabled members from previous
if (lost_and_found_id == mUUID)
{
// This is the lost+found folder.
@@ -2524,7 +2572,7 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
LLViewerInventoryCategory *cat = getCategory();
// BAP removed protected check to re-enable standard ops in untyped folders.
// Not sure what the right thing is to do here.
- if (!isCOFFolder() && cat /*&&
+ if (!isCOFFolder() && cat && cat->getPreferredType()!=LLFolderType::FT_OUTFIT /*&&
LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType())*/)
{
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
@@ -3150,6 +3198,22 @@ void LLTextureBridge::openItem()
}
}
+bool LLTextureBridge::canSaveTexture(void)
+{
+ const LLInventoryModel* model = getInventoryModel();
+ if(!model)
+ {
+ return false;
+ }
+
+ const LLViewerInventoryItem *item = model->getItem(mUUID);
+ if (item)
+ {
+ return item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED);
+ }
+ return false;
+}
+
void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
lldebugs << "LLTextureBridge::buildContextMenu()" << llendl;
@@ -3174,6 +3238,10 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Texture Separator"));
items.push_back(std::string("Save As"));
+ if (!canSaveTexture())
+ {
+ disabled_items.push_back(std::string("Save As"));
+ }
}
hide_context_entries(menu, items, disabled_items);
}
@@ -3776,8 +3844,13 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
- items.push_back(std::string("Open"));
- items.push_back(std::string("Properties"));
+ bool is_sidepanel = isInOutfitsSidePanel();
+
+ if (!is_sidepanel)
+ {
+ items.push_back(std::string("Open"));
+ items.push_back(std::string("Properties"));
+ }
getClipboardEntries(true, items, disabled_items, flags);
@@ -4101,13 +4174,18 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
- items.push_back(std::string("Properties"));
+ bool is_sidepanel = isInOutfitsSidePanel();
+
+ if (!is_sidepanel)
+ {
+ items.push_back(std::string("Properties"));
+ }
- LLInventoryItem *item = getItem();
getClipboardEntries(true, items, disabled_items, flags);
LLObjectBridge::sContextMenuItemID = mUUID;
+ LLInventoryItem *item = getItem();
if(item)
{
LLVOAvatarSelf* avatarp = gAgent.getAvatarObject();
@@ -4533,19 +4611,23 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
can_open = FALSE;
}
- if (can_open)
+
+ bool is_sidepanel = isInOutfitsSidePanel();
+
+ if (can_open && !is_sidepanel)
{
items.push_back(std::string("Open"));
}
- items.push_back(std::string("Properties"));
+ if (!is_sidepanel)
+ {
+ items.push_back(std::string("Properties"));
+ }
getClipboardEntries(true, items, disabled_items, flags);
items.push_back(std::string("Wearable Separator"));
- items.push_back(std::string("Wearable Wear"));
- items.push_back(std::string("Wearable Add"));
items.push_back(std::string("Wearable Edit"));
if ((flags & FIRST_SELECTED_ITEM) == 0)
@@ -4575,6 +4657,8 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
+ items.push_back(std::string("Wearable Wear"));
+ items.push_back(std::string("Wearable Add"));
disabled_items.push_back(std::string("Take Off"));
}
break;
@@ -4744,7 +4828,8 @@ void LLWearableBridge::onEditOnAvatar(void* user_data)
void LLWearableBridge::editOnAvatar()
{
- const LLWearable* wearable = gAgentWearables.getWearableFromItemID(mUUID);
+ LLUUID linked_id = gInventory.getLinkedItemID(mUUID);
+ const LLWearable* wearable = gAgentWearables.getWearableFromItemID(linked_id);
if( wearable )
{
// Set the tab to the right wearable.
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 63be9dcdb8..117e32c6be 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -182,6 +182,9 @@ public:
// LLInvFVBridge functionality
virtual void clearDisplayName() {}
+ // Allow context menus to be customized for side panel.
+ bool isInOutfitsSidePanel() const;
+
protected:
LLInvFVBridge(LLInventoryPanel* inventory, const LLUUID& uuid);
@@ -377,6 +380,7 @@ public:
protected:
LLTextureBridge(LLInventoryPanel* inventory, const LLUUID& uuid, LLInventoryType::EType type) :
LLItemBridge(inventory, uuid), mInvType(type) {}
+ bool canSaveTexture(void);
LLInventoryType::EType mInvType;
};
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index 3c337961e1..2694075a58 100755
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -58,251 +58,342 @@
// - Any request that gets a 503 still goes through the retry logic
//
+//
+// Forward decls
+//
const F32 LLMediaDataClient::QUEUE_TIMER_DELAY = 1.0; // seconds(s)
const F32 LLMediaDataClient::UNAVAILABLE_RETRY_TIMER_DELAY = 5.0; // secs
const U32 LLMediaDataClient::MAX_RETRIES = 4;
+const U32 LLMediaDataClient::MAX_SORTED_QUEUE_SIZE = 10000;
+const U32 LLMediaDataClient::MAX_ROUND_ROBIN_QUEUE_SIZE = 10000;
+
+// << operators
+std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::request_queue_t &q);
+std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &q);
//////////////////////////////////////////////////////////////////////////////////////
//
-// LLMediaDataClient::Request
+// LLMediaDataClient
//
//////////////////////////////////////////////////////////////////////////////////////
-/*static*/U32 LLMediaDataClient::Request::sNum = 0;
-LLMediaDataClient::Request::Request(const std::string &cap_name,
- const LLSD& sd_payload,
- LLMediaDataClientObject *obj,
- LLMediaDataClient *mdc)
- : mCapName(cap_name),
- mPayload(sd_payload),
- mObject(obj),
- mNum(++sNum),
- mRetryCount(0),
- mMDC(mdc)
+LLMediaDataClient::LLMediaDataClient(F32 queue_timer_delay,
+ F32 retry_timer_delay,
+ U32 max_retries,
+ U32 max_sorted_queue_size,
+ U32 max_round_robin_queue_size)
+ : mQueueTimerDelay(queue_timer_delay),
+ mRetryTimerDelay(retry_timer_delay),
+ mMaxNumRetries(max_retries),
+ mMaxSortedQueueSize(max_sorted_queue_size),
+ mMaxRoundRobinQueueSize(max_round_robin_queue_size),
+ mQueueTimerIsRunning(false),
+ mCurrentQueueIsTheSortedQueue(true)
{
}
-LLMediaDataClient::Request::~Request()
+LLMediaDataClient::~LLMediaDataClient()
{
- LL_DEBUGS("LLMediaDataClient") << "~Request" << (*this) << LL_ENDL;
- mMDC = NULL;
- mObject = NULL;
-}
+ stopQueueTimer();
-
-std::string LLMediaDataClient::Request::getCapability() const
-{
- return getObject()->getCapabilityUrl(getCapName());
+ // This should clear the queue, and hopefully call all the destructors.
+ LL_DEBUGS("LLMediaDataClient") << "~LLMediaDataClient destructor: queue: " <<
+ (isEmpty() ? "<empty> " : "<not empty> ") << LL_ENDL;
+
+ mSortedQueue.clear();
+ mRoundRobinQueue.clear();
}
-// Helper function to get the "type" of request, which just pokes around to
-// discover it.
-LLMediaDataClient::Request::Type LLMediaDataClient::Request::getType() const
+bool LLMediaDataClient::isEmpty() const
{
- if (mCapName == "ObjectMediaNavigate")
- {
- return NAVIGATE;
- }
- else if (mCapName == "ObjectMedia")
- {
- const std::string &verb = mPayload["verb"];
- if (verb == "GET")
- {
- return GET;
- }
- else if (verb == "UPDATE")
- {
- return UPDATE;
- }
- }
- llassert(false);
- return GET;
+ return mSortedQueue.empty() && mRoundRobinQueue.empty();
}
-const char *LLMediaDataClient::Request::getTypeAsString() const
+bool LLMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &object)
{
- Type t = getType();
- switch (t)
- {
- case GET:
- return "GET";
- break;
- case UPDATE:
- return "UPDATE";
- break;
- case NAVIGATE:
- return "NAVIGATE";
- break;
- }
- return "";
+ return (LLMediaDataClient::findOrRemove(mSortedQueue, object, false/*remove*/, LLMediaDataClient::Request::ANY).notNull()
+ || (LLMediaDataClient::findOrRemove(mRoundRobinQueue, object, false/*remove*/, LLMediaDataClient::Request::ANY).notNull()));
}
-
-void LLMediaDataClient::Request::reEnqueue() const
+bool LLMediaDataClient::removeFromQueue(const LLMediaDataClientObject::ptr_t &object)
{
- // I sure hope this doesn't deref a bad pointer:
- mMDC->enqueue(this);
+ bool removedFromSortedQueue = LLMediaDataClient::findOrRemove(mSortedQueue, object, true/*remove*/, LLMediaDataClient::Request::ANY).notNull();
+ bool removedFromRoundRobinQueue = LLMediaDataClient::findOrRemove(mRoundRobinQueue, object, true/*remove*/, LLMediaDataClient::Request::ANY).notNull();
+ return removedFromSortedQueue || removedFromRoundRobinQueue;
}
-F32 LLMediaDataClient::Request::getRetryTimerDelay() const
+//static
+LLMediaDataClient::request_ptr_t LLMediaDataClient::findOrRemove(request_queue_t &queue, const LLMediaDataClientObject::ptr_t &obj, bool remove, LLMediaDataClient::Request::Type type)
{
- return (mMDC == NULL) ? LLMediaDataClient::UNAVAILABLE_RETRY_TIMER_DELAY :
- mMDC->mRetryTimerDelay;
+ request_ptr_t result;
+ request_queue_t::iterator iter = queue.begin();
+ request_queue_t::iterator end = queue.end();
+ while (iter != end)
+ {
+ if (obj->getID() == (*iter)->getObject()->getID() && (type == LLMediaDataClient::Request::ANY || type == (*iter)->getType()))
+ {
+ result = *iter;
+ if (remove) queue.erase(iter);
+ break;
+ }
+ iter++;
+ }
+ return result;
}
-U32 LLMediaDataClient::Request::getMaxNumRetries() const
+void LLMediaDataClient::request(const LLMediaDataClientObject::ptr_t &object, const LLSD &payload)
{
- return (mMDC == NULL) ? LLMediaDataClient::MAX_RETRIES : mMDC->mMaxNumRetries;
+ if (object.isNull() || ! object->hasMedia()) return;
+
+ // Push the object on the queue
+ enqueue(new Request(getCapabilityName(), payload, object, this));
}
-std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &r)
+void LLMediaDataClient::enqueue(const Request *request)
{
- s << "<request>"
- << "<num>" << r.getNum() << "</num>"
- << "<type>" << r.getTypeAsString() << "</type>"
- << "<object_id>" << r.getObject()->getID() << "</object_id>"
- << "<num_retries>" << r.getRetryCount() << "</num_retries>"
- << "</request> ";
- return s;
+ if (request->isNew())
+ {
+ // Add to sorted queue
+ if (LLMediaDataClient::findOrRemove(mSortedQueue, request->getObject(), true/*remove*/, request->getType()).notNull())
+ {
+ LL_DEBUGS("LLMediaDataClient") << "REMOVING OLD request for " << *request << " ALREADY THERE!" << LL_ENDL;
+ }
+
+ LL_DEBUGS("LLMediaDataClient") << "Queuing SORTED request for " << *request << LL_ENDL;
+
+ // Sadly, we have to const-cast because items put into the queue are not const
+ mSortedQueue.push_back(const_cast<LLMediaDataClient::Request*>(request));
+
+ LL_DEBUGS("LLMediaDataClient") << "SORTED queue:" << mSortedQueue << LL_ENDL;
+ }
+ else {
+ if (mRoundRobinQueue.size() > mMaxRoundRobinQueueSize)
+ {
+ LL_INFOS_ONCE("LLMediaDataClient") << "RR QUEUE MAXED OUT!!!" << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClient") << "Not queuing " << *request << LL_ENDL;
+ return;
+ }
+
+ // ROUND ROBIN: if it is there, and it is a GET request, leave it. If not, put at front!
+ request_ptr_t existing_request;
+ if (request->getType() == Request::GET)
+ {
+ existing_request = LLMediaDataClient::findOrRemove(mRoundRobinQueue, request->getObject(), false/*remove*/, request->getType());
+ }
+ if (existing_request.isNull())
+ {
+ LL_DEBUGS("LLMediaDataClient") << "Queuing RR request for " << *request << LL_ENDL;
+ // Push the request on the pending queue
+ // Sadly, we have to const-cast because items put into the queue are not const
+ mRoundRobinQueue.push_front(const_cast<LLMediaDataClient::Request*>(request));
+
+ LL_DEBUGS("LLMediaDataClient") << "RR queue:" << mRoundRobinQueue << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("LLMediaDataClient") << "ALREADY THERE: NOT Queuing request for " << *request << LL_ENDL;
+
+ existing_request->markSent(false);
+ }
+ }
+ // Start the timer if not already running
+ startQueueTimer();
}
-
-//////////////////////////////////////////////////////////////////////////////////////
-//
-// LLMediaDataClient::Responder::RetryTimer
-//
-//////////////////////////////////////////////////////////////////////////////////////
-
-LLMediaDataClient::Responder::RetryTimer::RetryTimer(F32 time, Responder *mdr)
- : LLEventTimer(time), mResponder(mdr)
+void LLMediaDataClient::startQueueTimer()
{
+ if (! mQueueTimerIsRunning)
+ {
+ LL_DEBUGS("LLMediaDataClient") << "starting queue timer (delay=" << mQueueTimerDelay << " seconds)" << LL_ENDL;
+ // LLEventTimer automagically takes care of the lifetime of this object
+ new QueueTimer(mQueueTimerDelay, this);
+ }
+ else {
+ LL_DEBUGS("LLMediaDataClient") << "not starting queue timer (it's already running, right???)" << LL_ENDL;
+ }
}
-// virtual
-LLMediaDataClient::Responder::RetryTimer::~RetryTimer()
+void LLMediaDataClient::stopQueueTimer()
{
- LL_DEBUGS("LLMediaDataClient") << "~RetryTimer" << *(mResponder->getRequest()) << LL_ENDL;
-
- // XXX This is weird: Instead of doing the work in tick() (which re-schedules
- // a timer, which might be risky), do it here, in the destructor. Yes, it is very odd.
- // Instead of retrying, we just put the request back onto the queue
- LL_INFOS("LLMediaDataClient") << "RetryTimer fired for: " << *(mResponder->getRequest()) << "retrying" << LL_ENDL;
- mResponder->getRequest()->reEnqueue();
-
- // Release the ref to the responder.
- mResponder = NULL;
+ mQueueTimerIsRunning = false;
}
-// virtual
-BOOL LLMediaDataClient::Responder::RetryTimer::tick()
+bool LLMediaDataClient::processQueueTimer()
{
- // Don't fire again
- return TRUE;
+ sortQueue();
+
+ if(!isEmpty())
+ {
+ LL_INFOS("LLMediaDataClient") << "QueueTimer::tick() started, SORTED queue size is: " << mSortedQueue.size()
+ << ", RR queue size is: " << mRoundRobinQueue.size() << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() started, SORTED queue is: " << mSortedQueue << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() started, RR queue is: " << mRoundRobinQueue << LL_ENDL;
+ }
+
+ serviceQueue();
+
+ LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() finished, SORTED queue size is: " << mSortedQueue.size()
+ << ", RR queue size is: " << mRoundRobinQueue.size() << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() finished, SORTED queue is: " << mSortedQueue << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() finished, RR queue is: " << mRoundRobinQueue << LL_ENDL;
+
+ return isEmpty();
}
-
-//////////////////////////////////////////////////////////////////////////////////////
-//
-// LLMediaDataClient::Responder
-//
-//////////////////////////////////////////////////////////////////////////////////////
-
-LLMediaDataClient::Responder::Responder(const request_ptr_t &request)
- : mRequest(request)
+void LLMediaDataClient::sortQueue()
{
+ if(!mSortedQueue.empty())
+ {
+ // Score all items first
+ request_queue_t::iterator iter = mSortedQueue.begin();
+ request_queue_t::iterator end = mSortedQueue.end();
+ while (iter != end)
+ {
+ (*iter)->updateScore();
+ iter++;
+ }
+
+ // Re-sort the list...
+ // NOTE: should this be a stable_sort? If so we need to change to using a vector.
+ mSortedQueue.sort(LLMediaDataClient::compareRequests);
+
+ // ...then cull items over the max
+ U32 size = mSortedQueue.size();
+ if (size > mMaxSortedQueueSize)
+ {
+ U32 num_to_cull = (size - mMaxSortedQueueSize);
+ LL_INFOS("LLMediaDataClient") << "sorted queue MAXED OUT! Culling "
+ << num_to_cull << " items" << LL_ENDL;
+ while (num_to_cull-- > 0)
+ {
+ mSortedQueue.pop_back();
+ }
+ }
+ }
}
-LLMediaDataClient::Responder::~Responder()
+// static
+bool LLMediaDataClient::compareRequests(const request_ptr_t &o1, const request_ptr_t &o2)
{
- LL_DEBUGS("LLMediaDataClient") << "~Responder" << *(getRequest()) << LL_ENDL;
- mRequest = NULL;
+ if (o2.isNull()) return true;
+ if (o1.isNull()) return false;
+ return ( o1->getScore() > o2->getScore() );
}
-/*virtual*/
-void LLMediaDataClient::Responder::error(U32 status, const std::string& reason)
-{
- if (status == HTTP_SERVICE_UNAVAILABLE)
+void LLMediaDataClient::serviceQueue()
+{
+ request_queue_t *queue_p = getCurrentQueue();
+
+ // quick retry loop for cases where we shouldn't wait for the next timer tick
+ while(true)
{
- F32 retry_timeout = mRequest->getRetryTimerDelay();
-
- mRequest->incRetryCount();
+ if (queue_p->empty())
+ {
+ LL_DEBUGS("LLMediaDataClient") << "queue empty: " << (*queue_p) << LL_ENDL;
+ break;
+ }
- if (mRequest->getRetryCount() < mRequest->getMaxNumRetries())
+ // Peel one off of the items from the queue, and execute request
+ request_ptr_t request = queue_p->front();
+ llassert(!request.isNull());
+ const LLMediaDataClientObject *object = (request.isNull()) ? NULL : request->getObject();
+ llassert(NULL != object);
+
+ // Check for conditions that would make us just pop and rapidly loop through
+ // the queue.
+ if(request.isNull() ||
+ request->isMarkedSent() ||
+ NULL == object ||
+ object->isDead() ||
+ !object->hasMedia())
{
- LL_INFOS("LLMediaDataClient") << *mRequest << "got SERVICE_UNAVAILABLE...retrying in " << retry_timeout << " seconds" << LL_ENDL;
+ if (request.isNull())
+ {
+ LL_INFOS("LLMediaDataClient") << "Skipping NULL request" << LL_ENDL;
+ }
+ else {
+ LL_INFOS("LLMediaDataClient") << "Skipping : " << *request << " "
+ << ((request->isMarkedSent()) ? " request is marked sent" :
+ ((NULL == object) ? " object is NULL " :
+ ((object->isDead()) ? "object is dead" :
+ ((!object->hasMedia()) ? "object has no media!" : "BADNESS!")))) << LL_ENDL;
+ }
+ queue_p->pop_front();
+ continue; // jump back to the start of the quick retry loop
+ }
+
+ // Next, ask if this is "interesting enough" to fetch. If not, just stop
+ // and wait for the next timer go-round. Only do this for the sorted
+ // queue.
+ if (mCurrentQueueIsTheSortedQueue && !object->isInterestingEnough())
+ {
+ LL_DEBUGS("LLMediaDataClient") << "Not fetching " << *request << ": not interesting enough" << LL_ENDL;
+ break;
+ }
+
+ // Finally, try to send the HTTP message to the cap url
+ std::string url = request->getCapability();
+ bool maybe_retry = false;
+ if (!url.empty())
+ {
+ const LLSD &sd_payload = request->getPayload();
+ LL_INFOS("LLMediaDataClient") << "Sending request for " << *request << LL_ENDL;
+
+ // Call the subclass for creating the responder
+ LLHTTPClient::post(url, sd_payload, createResponder(request));
+ }
+ else {
+ LL_INFOS("LLMediaDataClient") << "NOT Sending request for " << *request << ": empty cap url!" << LL_ENDL;
+ maybe_retry = true;
+ }
- // Start timer (instances are automagically tracked by
- // InstanceTracker<> and LLEventTimer)
- new RetryTimer(F32(retry_timeout/*secs*/), this);
+ bool exceeded_retries = request->getRetryCount() > mMaxNumRetries;
+ if (maybe_retry && ! exceeded_retries) // Try N times before giving up
+ {
+ // We got an empty cap, but in that case we will retry again next
+ // timer fire.
+ request->incRetryCount();
}
else {
- LL_INFOS("LLMediaDataClient") << *mRequest << "got SERVICE_UNAVAILABLE...retry count " <<
- mRequest->getRetryCount() << " exceeds " << mRequest->getMaxNumRetries() << ", not retrying" << LL_ENDL;
+ if (exceeded_retries)
+ {
+ LL_WARNS("LLMediaDataClient") << "Could not send request " << *request << " for "
+ << mMaxNumRetries << " tries...popping object id " << object->getID() << LL_ENDL;
+ // XXX Should we bring up a warning dialog??
+ }
+
+ queue_p->pop_front();
+
+ if (! mCurrentQueueIsTheSortedQueue) {
+ // Round robin
+ request->markSent(true);
+ mRoundRobinQueue.push_back(request);
+ }
}
+
+ // end of quick loop -- any cases where we want to loop will use 'continue' to jump back to the start.
+ break;
}
- else {
- std::string msg = boost::lexical_cast<std::string>(status) + ": " + reason;
- LL_WARNS("LLMediaDataClient") << *mRequest << " http error(" << msg << ")" << LL_ENDL;
- }
+
+ swapCurrentQueue();
}
-
-/*virtual*/
-void LLMediaDataClient::Responder::result(const LLSD& content)
+void LLMediaDataClient::swapCurrentQueue()
{
- LL_INFOS("LLMediaDataClient") << *mRequest << "result : " << ll_print_sd(content) << LL_ENDL;
+ // Swap
+ mCurrentQueueIsTheSortedQueue = !mCurrentQueueIsTheSortedQueue;
+ // If its empty, swap back
+ if (getCurrentQueue()->empty())
+ {
+ mCurrentQueueIsTheSortedQueue = !mCurrentQueueIsTheSortedQueue;
+ }
}
-
-//////////////////////////////////////////////////////////////////////////////////////
-//
-// LLMediaDataClient::Comparator
-//
-//////////////////////////////////////////////////////////////////////////////////////
-
-// static
-bool LLMediaDataClient::compareRequests(const request_ptr_t &o1, const request_ptr_t &o2)
+LLMediaDataClient::request_queue_t *LLMediaDataClient::getCurrentQueue()
{
- if (o2.isNull()) return true;
- if (o1.isNull()) return false;
-
- // The score is intended to be a measure of how close an object is or
- // how much screen real estate (interest) it takes up
- // Further away = lower score.
- // Lesser interest = lower score
- // For instance, here are some cases:
- // 1: Two items with no impl, closest one wins
- // 2: Two items with an impl: interest should rule, but distance is
- // still taken into account (i.e. something really close might take
- // precedence over a large item far away)
- // 3: One item with an impl, another without: item with impl wins
- // (XXX is that what we want?)
- // Calculate the scores for each.
- F64 o1_score = getObjectScore(o1->getObject());
- F64 o2_score = getObjectScore(o2->getObject());
- return ( o1_score > o2_score );
+ return (mCurrentQueueIsTheSortedQueue) ? &mSortedQueue : &mRoundRobinQueue;
}
-// static
-F64 LLMediaDataClient::getObjectScore(const LLMediaDataClientObject::ptr_t &obj)
-{
- // *TODO: make this less expensive?
- F64 dist = obj->getDistanceFromAvatar() + 0.1; // avoids div by 0
- // square the distance so that they are in the same "unit magnitude" as
- // the interest (which is an area)
- dist *= dist;
- F64 interest = obj->getTotalMediaInterest() + 1.0;
-
- return interest/dist;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////
-//
-// LLMediaDataClient::PriorityQueue
-// Queue of LLMediaDataClientObject smart pointers to request media for.
-//
-//////////////////////////////////////////////////////////////////////////////////////
-
// dump the queue
std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::request_queue_t &q)
{
@@ -318,22 +409,6 @@ std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::request_queue
return s;
}
-// find the given object in the queue.
-bool LLMediaDataClient::find(const LLMediaDataClientObject::ptr_t &obj) const
-{
- request_queue_t::const_iterator iter = pRequestQueue->begin();
- request_queue_t::const_iterator end = pRequestQueue->end();
- while (iter != end)
- {
- if (obj->getID() == (*iter)->getObject()->getID())
- {
- return true;
- }
- iter++;
- }
- return false;
-}
-
//////////////////////////////////////////////////////////////////////////////////////
//
// LLMediaDataClient::QueueTimer
@@ -342,7 +417,7 @@ bool LLMediaDataClient::find(const LLMediaDataClientObject::ptr_t &obj) const
//////////////////////////////////////////////////////////////////////////////////////
LLMediaDataClient::QueueTimer::QueueTimer(F32 time, LLMediaDataClient *mdc)
- : LLEventTimer(time), mMDC(mdc)
+: LLEventTimer(time), mMDC(mdc)
{
mMDC->setIsRunning(true);
}
@@ -357,177 +432,224 @@ LLMediaDataClient::QueueTimer::~QueueTimer()
// virtual
BOOL LLMediaDataClient::QueueTimer::tick()
{
- if (NULL == mMDC->pRequestQueue)
- {
- // Shutting down? stop.
- LL_DEBUGS("LLMediaDataClient") << "queue gone" << LL_ENDL;
- return TRUE;
- }
-
- request_queue_t &queue = *(mMDC->pRequestQueue);
+ if (mMDC.isNull()) return TRUE;
+ return mMDC->processQueueTimer();
+}
- if(!queue.empty())
- {
- LL_INFOS("LLMediaDataClient") << "QueueTimer::tick() started, queue is: " << queue << LL_ENDL;
- // Re-sort the list every time...
- // XXX Is this really what we want?
- queue.sort(LLMediaDataClient::compareRequests);
- }
+//////////////////////////////////////////////////////////////////////////////////////
+//
+// LLMediaDataClient::Responder::RetryTimer
+//
+//////////////////////////////////////////////////////////////////////////////////////
+
+LLMediaDataClient::Responder::RetryTimer::RetryTimer(F32 time, Responder *mdr)
+: LLEventTimer(time), mResponder(mdr)
+{
+}
+
+// virtual
+LLMediaDataClient::Responder::RetryTimer::~RetryTimer()
+{
+ LL_DEBUGS("LLMediaDataClient") << "~RetryTimer" << *(mResponder->getRequest()) << LL_ENDL;
- // quick retry loop for cases where we shouldn't wait for the next timer tick
- while(true)
- {
- if (queue.empty())
- {
- LL_DEBUGS("LLMediaDataClient") << "queue empty: " << queue << LL_ENDL;
- return TRUE;
- }
+ // XXX This is weird: Instead of doing the work in tick() (which re-schedules
+ // a timer, which might be risky), do it here, in the destructor. Yes, it is very odd.
+ // Instead of retrying, we just put the request back onto the queue
+ LL_INFOS("LLMediaDataClient") << "RetryTimer fired for: " << *(mResponder->getRequest()) << " retrying" << LL_ENDL;
+ mResponder->getRequest()->reEnqueue();
- // Peel one off of the items from the queue, and execute request
- request_ptr_t request = queue.front();
- llassert(!request.isNull());
- const LLMediaDataClientObject *object = (request.isNull()) ? NULL : request->getObject();
- bool performed_request = false;
- bool error = false;
- llassert(NULL != object);
+ // Release the ref to the responder.
+ mResponder = NULL;
+}
- if(object->isDead())
- {
- // This object has been marked dead. Pop it and move on to the next item in the queue immediately.
- LL_INFOS("LLMediaDataClient") << "Skipping " << *request << ": object is dead!" << LL_ENDL;
- queue.pop_front();
- continue; // jump back to the start of the quick retry loop
- }
+// virtual
+BOOL LLMediaDataClient::Responder::RetryTimer::tick()
+{
+ // Don't fire again
+ return TRUE;
+}
- if (NULL != object && object->hasMedia())
- {
- std::string url = request->getCapability();
- if (!url.empty())
- {
- const LLSD &sd_payload = request->getPayload();
- LL_INFOS("LLMediaDataClient") << "Sending request for " << *request << LL_ENDL;
- // Call the subclass for creating the responder
- LLHTTPClient::post(url, sd_payload, mMDC->createResponder(request));
- performed_request = true;
- }
- else {
- LL_INFOS("LLMediaDataClient") << "NOT Sending request for " << *request << ": empty cap url!" << LL_ENDL;
- }
- }
- else {
- if (request.isNull())
- {
- LL_WARNS("LLMediaDataClient") << "Not Sending request: NULL request!" << LL_ENDL;
- }
- else if (NULL == object)
- {
- LL_WARNS("LLMediaDataClient") << "Not Sending request for " << *request << " NULL object!" << LL_ENDL;
- }
- else if (!object->hasMedia())
- {
- LL_WARNS("LLMediaDataClient") << "Not Sending request for " << *request << " hasMedia() is false!" << LL_ENDL;
- }
- error = true;
- }
- bool exceeded_retries = request->getRetryCount() > mMDC->mMaxNumRetries;
- if (performed_request || exceeded_retries || error) // Try N times before giving up
- {
- if (exceeded_retries)
- {
- LL_WARNS("LLMediaDataClient") << "Could not send request " << *request << " for "
- << mMDC->mMaxNumRetries << " tries...popping object id " << object->getID() << LL_ENDL;
- // XXX Should we bring up a warning dialog??
- }
- queue.pop_front();
- }
- else {
- request->incRetryCount();
- }
-
- // end of quick retry loop -- any cases where we want to loop will use 'continue' to jump back to the start.
- break;
- }
+//////////////////////////////////////////////////////////////////////////////////////
+//
+// LLMediaDataClient::Request
+//
+//////////////////////////////////////////////////////////////////////////////////////
+/*static*/U32 LLMediaDataClient::Request::sNum = 0;
- LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() finished, queue is now: " << (*(mMDC->pRequestQueue)) << LL_ENDL;
+LLMediaDataClient::Request::Request(const char *cap_name,
+ const LLSD& sd_payload,
+ LLMediaDataClientObject *obj,
+ LLMediaDataClient *mdc)
+: mCapName(cap_name),
+ mPayload(sd_payload),
+ mObject(obj),
+ mNum(++sNum),
+ mRetryCount(0),
+ mMDC(mdc),
+ mMarkedSent(false),
+ mScore((F64)0.0)
+{
+}
- return queue.empty();
+LLMediaDataClient::Request::~Request()
+{
+ LL_DEBUGS("LLMediaDataClient") << "~Request" << (*this) << LL_ENDL;
+ mMDC = NULL;
+ mObject = NULL;
}
-
-void LLMediaDataClient::startQueueTimer()
+
+
+std::string LLMediaDataClient::Request::getCapability() const
{
- if (! mQueueTimerIsRunning)
+ return getObject()->getCapabilityUrl(getCapName());
+}
+
+// Helper function to get the "type" of request, which just pokes around to
+// discover it.
+LLMediaDataClient::Request::Type LLMediaDataClient::Request::getType() const
+{
+ if (0 == strcmp(mCapName, "ObjectMediaNavigate"))
{
- LL_INFOS("LLMediaDataClient") << "starting queue timer (delay=" << mQueueTimerDelay << " seconds)" << LL_ENDL;
- // LLEventTimer automagically takes care of the lifetime of this object
- new QueueTimer(mQueueTimerDelay, this);
+ return NAVIGATE;
}
- else {
- LL_DEBUGS("LLMediaDataClient") << "not starting queue timer (it's already running, right???)" << LL_ENDL;
+ else if (0 == strcmp(mCapName, "ObjectMedia"))
+ {
+ const std::string &verb = mPayload["verb"];
+ if (verb == "GET")
+ {
+ return GET;
+ }
+ else if (verb == "UPDATE")
+ {
+ return UPDATE;
+ }
}
+ llassert(false);
+ return GET;
}
-
-void LLMediaDataClient::stopQueueTimer()
+
+const char *LLMediaDataClient::Request::getTypeAsString() const
{
- mQueueTimerIsRunning = false;
+ Type t = getType();
+ switch (t)
+ {
+ case GET:
+ return "GET";
+ break;
+ case UPDATE:
+ return "UPDATE";
+ break;
+ case NAVIGATE:
+ return "NAVIGATE";
+ break;
+ case ANY:
+ return "ANY";
+ break;
+ }
+ return "";
}
-
-void LLMediaDataClient::request(const LLMediaDataClientObject::ptr_t &object, const LLSD &payload)
+
+
+void LLMediaDataClient::Request::reEnqueue() const
{
- if (object.isNull() || ! object->hasMedia()) return;
+ // I sure hope this doesn't deref a bad pointer:
+ mMDC->enqueue(this);
+}
- // Push the object on the priority queue
- enqueue(new Request(getCapabilityName(), payload, object, this));
+F32 LLMediaDataClient::Request::getRetryTimerDelay() const
+{
+ return (mMDC == NULL) ? LLMediaDataClient::UNAVAILABLE_RETRY_TIMER_DELAY :
+ mMDC->mRetryTimerDelay;
}
-void LLMediaDataClient::enqueue(const Request *request)
+U32 LLMediaDataClient::Request::getMaxNumRetries() const
{
- LL_INFOS("LLMediaDataClient") << "Queuing request for " << *request << LL_ENDL;
- // Push the request on the priority queue
- // Sadly, we have to const-cast because items put into the queue are not const
- pRequestQueue->push_back(const_cast<LLMediaDataClient::Request*>(request));
- LL_DEBUGS("LLMediaDataClient") << "Queue:" << (*pRequestQueue) << LL_ENDL;
- // Start the timer if not already running
- startQueueTimer();
+ return (mMDC == NULL) ? LLMediaDataClient::MAX_RETRIES : mMDC->mMaxNumRetries;
}
+void LLMediaDataClient::Request::markSent(bool flag)
+{
+ if (mMarkedSent != flag)
+ {
+ mMarkedSent = flag;
+ if (!mMarkedSent)
+ {
+ mNum = ++sNum;
+ }
+ }
+}
+
+void LLMediaDataClient::Request::updateScore()
+{
+ F64 tmp = mObject->getMediaInterest();
+ if (tmp != mScore)
+ {
+ LL_DEBUGS("LLMediaDataClient") << "Score for " << mObject->getID() << " changed from " << mScore << " to " << tmp << LL_ENDL;
+ mScore = tmp;
+ }
+}
+
+std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &r)
+{
+ s << "request: num=" << r.getNum()
+ << " type=" << r.getTypeAsString()
+ << " ID=" << r.getObject()->getID()
+ << " #retries=" << r.getRetryCount();
+ return s;
+}
+
+
//////////////////////////////////////////////////////////////////////////////////////
//
-// LLMediaDataClient
+// LLMediaDataClient::Responder
//
//////////////////////////////////////////////////////////////////////////////////////
-LLMediaDataClient::LLMediaDataClient(F32 queue_timer_delay,
- F32 retry_timer_delay,
- U32 max_retries)
- : mQueueTimerDelay(queue_timer_delay),
- mRetryTimerDelay(retry_timer_delay),
- mMaxNumRetries(max_retries),
- mQueueTimerIsRunning(false)
+LLMediaDataClient::Responder::Responder(const request_ptr_t &request)
+: mRequest(request)
{
- pRequestQueue = new request_queue_t();
}
-LLMediaDataClient::~LLMediaDataClient()
+LLMediaDataClient::Responder::~Responder()
{
- stopQueueTimer();
-
- // This should clear the queue, and hopefully call all the destructors.
- LL_DEBUGS("LLMediaDataClient") << "~LLMediaDataClient destructor: queue: " <<
- (pRequestQueue->empty() ? "<empty> " : "<not empty> ") << (*pRequestQueue) << LL_ENDL;
- delete pRequestQueue;
- pRequestQueue = NULL;
+ LL_DEBUGS("LLMediaDataClient") << "~Responder" << *(getRequest()) << LL_ENDL;
+ mRequest = NULL;
}
-bool LLMediaDataClient::isEmpty() const
+/*virtual*/
+void LLMediaDataClient::Responder::error(U32 status, const std::string& reason)
{
- return (NULL == pRequestQueue) ? true : pRequestQueue->empty();
+ if (status == HTTP_SERVICE_UNAVAILABLE)
+ {
+ F32 retry_timeout = mRequest->getRetryTimerDelay();
+
+ mRequest->incRetryCount();
+
+ if (mRequest->getRetryCount() < mRequest->getMaxNumRetries())
+ {
+ LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retrying in " << retry_timeout << " seconds" << LL_ENDL;
+
+ // Start timer (instances are automagically tracked by
+ // InstanceTracker<> and LLEventTimer)
+ new RetryTimer(F32(retry_timeout/*secs*/), this);
+ }
+ else {
+ LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retry count " <<
+ mRequest->getRetryCount() << " exceeds " << mRequest->getMaxNumRetries() << ", not retrying" << LL_ENDL;
+ }
+ }
+ else {
+ std::string msg = boost::lexical_cast<std::string>(status) + ": " + reason;
+ LL_WARNS("LLMediaDataClient") << *mRequest << " http error(" << msg << ")" << LL_ENDL;
+ }
}
-bool LLMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &object) const
+/*virtual*/
+void LLMediaDataClient::Responder::result(const LLSD& content)
{
- return (NULL == pRequestQueue) ? false : find(object);
+ LL_DEBUGS("LLMediaDataClient") << *mRequest << " result : " << ll_print_sd(content) << LL_ENDL;
}
//////////////////////////////////////////////////////////////////////////////////////
@@ -569,7 +691,7 @@ void LLObjectMediaDataClient::updateMedia(LLMediaDataClientObject *object)
}
sd_payload[LLTextureEntry::OBJECT_MEDIA_DATA_KEY] = object_media_data;
- LL_INFOS("LLMediaDataClient") << "update media data: " << object->getID() << " " << ll_print_sd(sd_payload) << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClient") << "update media data: " << object->getID() << " " << ll_print_sd(sd_payload) << LL_ENDL;
request(object, sd_payload);
}
@@ -581,7 +703,7 @@ void LLObjectMediaDataClient::Responder::result(const LLSD& content)
llassert(type == LLMediaDataClient::Request::GET || type == LLMediaDataClient::Request::UPDATE)
if (type == LLMediaDataClient::Request::GET)
{
- LL_INFOS("LLMediaDataClient") << *(getRequest()) << "GET returned: " << ll_print_sd(content) << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClient") << *(getRequest()) << " GET returned: " << ll_print_sd(content) << LL_ENDL;
// Look for an error
if (content.has("error"))
@@ -598,12 +720,13 @@ void LLObjectMediaDataClient::Responder::result(const LLSD& content)
if (object_id != getRequest()->getObject()->getID())
{
// NOT good, wrong object id!!
- LL_WARNS("LLMediaDataClient") << *(getRequest()) << "DROPPING response with wrong object id (" << object_id << ")" << LL_ENDL;
+ LL_WARNS("LLMediaDataClient") << *(getRequest()) << " DROPPING response with wrong object id (" << object_id << ")" << LL_ENDL;
return;
}
// Otherwise, update with object media data
- getRequest()->getObject()->updateObjectMediaData(content[LLTextureEntry::OBJECT_MEDIA_DATA_KEY]);
+ getRequest()->getObject()->updateObjectMediaData(content[LLTextureEntry::OBJECT_MEDIA_DATA_KEY],
+ content[LLTextureEntry::MEDIA_VERSION_KEY]);
}
}
else if (type == LLMediaDataClient::Request::UPDATE)
diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h
index 812e9cbdec..75d32e707b 100755
--- a/indra/newview/llmediadataclient.h
+++ b/indra/newview/llmediadataclient.h
@@ -55,15 +55,19 @@ public:
// Does this object have media?
virtual bool hasMedia() const = 0;
// Update the object's media data to the given array
- virtual void updateObjectMediaData(LLSD const &media_data_array) = 0;
- // Return the distance from the object to the avatar
- virtual F64 getDistanceFromAvatar() const = 0;
+ virtual void updateObjectMediaData(LLSD const &media_data_array, const std::string &version_string) = 0;
// Return the total "interest" of the media (on-screen area)
- virtual F64 getTotalMediaInterest() const = 0;
+ virtual F64 getMediaInterest() const = 0;
// Return the given cap url
virtual std::string getCapabilityUrl(const std::string &name) const = 0;
// Return whether the object has been marked dead
virtual bool isDead() const = 0;
+ // Returns a media version number for the object
+ virtual U32 getMediaVersion() const = 0;
+ // Returns whether the object is "interesting enough" to fetch
+ virtual bool isInterestingEnough() const = 0;
+ // Returns whether we've seen this object yet or not
+ virtual bool isNew() const = 0;
// smart pointer
typedef LLPointer<LLMediaDataClientObject> ptr_t;
@@ -79,11 +83,15 @@ public:
const static F32 QUEUE_TIMER_DELAY;// = 1.0; // seconds(s)
const static F32 UNAVAILABLE_RETRY_TIMER_DELAY;// = 5.0; // secs
const static U32 MAX_RETRIES;// = 4;
+ const static U32 MAX_SORTED_QUEUE_SIZE;// = 10000;
+ const static U32 MAX_ROUND_ROBIN_QUEUE_SIZE;// = 10000;
// Constructor
LLMediaDataClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY,
F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY,
- U32 max_retries = MAX_RETRIES);
+ U32 max_retries = MAX_RETRIES,
+ U32 max_sorted_queue_size = MAX_SORTED_QUEUE_SIZE,
+ U32 max_round_robin_queue_size = MAX_ROUND_ROBIN_QUEUE_SIZE);
// Make the request
void request(const LLMediaDataClientObject::ptr_t &object, const LLSD &payload);
@@ -94,7 +102,13 @@ public:
bool isEmpty() const;
// Returns true iff the given object is in the queue
- bool isInQueue(const LLMediaDataClientObject::ptr_t &object) const;
+ bool isInQueue(const LLMediaDataClientObject::ptr_t &object);
+
+ // Remove the given object from the queue. Returns true iff the given object is removed.
+ bool removeFromQueue(const LLMediaDataClientObject::ptr_t &object);
+
+ // Called only by the Queue timer and tests (potentially)
+ bool processQueueTimer();
protected:
// Destructor
@@ -107,11 +121,12 @@ protected:
enum Type {
GET,
UPDATE,
- NAVIGATE
+ NAVIGATE,
+ ANY
};
- Request(const std::string &cap_name, const LLSD& sd_payload, LLMediaDataClientObject *obj, LLMediaDataClient *mdc);
- const std::string &getCapName() const { return mCapName; }
+ Request(const char *cap_name, const LLSD& sd_payload, LLMediaDataClientObject *obj, LLMediaDataClient *mdc);
+ const char *getCapName() const { return mCapName; }
const LLSD &getPayload() const { return mPayload; }
LLMediaDataClientObject *getObject() const { return mObject; }
@@ -132,6 +147,12 @@ protected:
F32 getRetryTimerDelay() const;
U32 getMaxNumRetries() const;
+ bool isNew() const { return mObject.notNull() ? mObject->isNew() : false; }
+ void markSent(bool flag);
+ bool isMarkedSent() const { return mMarkedSent; }
+ void updateScore();
+ F64 getScore() const { return mScore; }
+
public:
friend std::ostream& operator<<(std::ostream &s, const Request &q);
@@ -139,14 +160,16 @@ protected:
virtual ~Request(); // use unref();
private:
- std::string mCapName;
+ const char *mCapName;
LLSD mPayload;
LLMediaDataClientObject::ptr_t mObject;
// Simple tracking
- const U32 mNum;
+ U32 mNum;
static U32 sNum;
U32 mRetryCount;
-
+ F64 mScore;
+ bool mMarkedSent;
+
// Back pointer to the MDC...not a ref!
LLMediaDataClient *mMDC;
};
@@ -184,18 +207,23 @@ protected:
};
protected:
-
- void enqueue(const Request*);
-
+
// Subclasses must override this factory method to return a new responder
virtual Responder *createResponder(const request_ptr_t &request) const = 0;
// Subclasses must override to return a cap name
virtual const char *getCapabilityName() const = 0;
-private:
+ virtual void sortQueue();
+ virtual void serviceQueue();
+private:
typedef std::list<request_ptr_t> request_queue_t;
+
+ void enqueue(const Request*);
+
+ // Return whether the given object is/was in the queue
+ static LLMediaDataClient::request_ptr_t findOrRemove(request_queue_t &queue, const LLMediaDataClientObject::ptr_t &obj, bool remove, Request::Type type);
// Comparator for sorting
static bool compareRequests(const request_ptr_t &o1, const request_ptr_t &o2);
@@ -215,34 +243,40 @@ private:
// back-pointer
LLPointer<LLMediaDataClient> mMDC;
};
-
- // Return whether the given object is in the queue
- bool find(const LLMediaDataClientObject::ptr_t &obj) const;
void startQueueTimer();
void stopQueueTimer();
void setIsRunning(bool val) { mQueueTimerIsRunning = val; }
-
+
+ void swapCurrentQueue();
+ request_queue_t *getCurrentQueue();
+
const F32 mQueueTimerDelay;
const F32 mRetryTimerDelay;
const U32 mMaxNumRetries;
+ const U32 mMaxSortedQueueSize;
+ const U32 mMaxRoundRobinQueueSize;
bool mQueueTimerIsRunning;
- request_queue_t *pRequestQueue;
+ request_queue_t mSortedQueue;
+ request_queue_t mRoundRobinQueue;
+ bool mCurrentQueueIsTheSortedQueue;
};
-// MediaDataResponder specific for the ObjectMedia cap
+// MediaDataClient specific for the ObjectMedia cap
class LLObjectMediaDataClient : public LLMediaDataClient
{
public:
LLObjectMediaDataClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY,
F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY,
- U32 max_retries = MAX_RETRIES)
+ U32 max_retries = MAX_RETRIES,
+ U32 max_sorted_queue_size = MAX_SORTED_QUEUE_SIZE,
+ U32 max_round_robin_queue_size = MAX_ROUND_ROBIN_QUEUE_SIZE)
: LLMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries)
{}
- ~LLObjectMediaDataClient() {}
+ virtual ~LLObjectMediaDataClient() {}
void fetchMedia(LLMediaDataClientObject *object);
void updateMedia(LLMediaDataClientObject *object);
@@ -264,7 +298,7 @@ protected:
};
-// MediaDataResponder specific for the ObjectMediaNavigate cap
+// MediaDataClient specific for the ObjectMediaNavigate cap
class LLObjectMediaNavigateClient : public LLMediaDataClient
{
public:
@@ -273,10 +307,12 @@ public:
LLObjectMediaNavigateClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY,
F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY,
- U32 max_retries = MAX_RETRIES)
+ U32 max_retries = MAX_RETRIES,
+ U32 max_sorted_queue_size = MAX_SORTED_QUEUE_SIZE,
+ U32 max_round_robin_queue_size = MAX_ROUND_ROBIN_QUEUE_SIZE)
: LLMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries)
{}
- ~LLObjectMediaNavigateClient() {}
+ virtual ~LLObjectMediaNavigateClient() {}
void navigate(LLMediaDataClientObject *object, U8 texture_index, const std::string &url);
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index a729b8c06f..a5bfa18851 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -73,6 +73,11 @@
#include "llfloatertos.h"
#include "lltrans.h"
#include "llglheaders.h"
+#include "llpanelloginlistener.h"
+
+#if LL_WINDOWS
+#pragma warning(disable: 4355) // 'this' used in initializer list
+#endif // LL_WINDOWS
#define USE_VIEWER_AUTH 0
@@ -166,7 +171,8 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
mLogoImage(),
mCallback(callback),
mCallbackData(cb_data),
- mHtmlAvailable( TRUE )
+ mHtmlAvailable( TRUE ),
+ mListener(new LLPanelLoginListener(this))
{
setFocusRoot(TRUE);
@@ -452,7 +458,7 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask)
if ( KEY_F1 == key )
{
LLViewerHelp* vhelp = LLViewerHelp::getInstance();
- vhelp->showTopic(vhelp->getTopicFromFocus());
+ vhelp->showTopic(vhelp->f1HelpTopic());
return TRUE;
}
@@ -972,7 +978,7 @@ void LLPanelLogin::onClickHelp(void*)
if (sInstance)
{
LLViewerHelp* vhelp = LLViewerHelp::getInstance();
- vhelp->showTopic(vhelp->getTopicFromFocus());
+ vhelp->showTopic(vhelp->preLoginTopic());
}
}
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index e3d30d7d0c..97350ce5c7 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -36,10 +36,11 @@
#include "llpanel.h"
#include "llpointer.h" // LLPointer<>
#include "llmediactrl.h" // LLMediaCtrlObserver
+#include <boost/scoped_ptr.hpp>
class LLLineEditor;
class LLUIImage;
-
+class LLPanelLoginListener;
class LLPanelLogin:
public LLPanel,
@@ -90,6 +91,7 @@ public:
/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
private:
+ friend class LLPanelLoginListener;
void reshapeBrowser();
static void onClickConnect(void*);
static void onClickNewAccount(void*);
@@ -103,6 +105,7 @@ private:
private:
LLPointer<LLUIImage> mLogoImage;
+ boost::scoped_ptr<LLPanelLoginListener> mListener;
void (*mCallback)(S32 option, void *userdata);
void* mCallbackData;
diff --git a/indra/newview/llpanelloginlistener.cpp b/indra/newview/llpanelloginlistener.cpp
new file mode 100644
index 0000000000..f7e59aaf54
--- /dev/null
+++ b/indra/newview/llpanelloginlistener.cpp
@@ -0,0 +1,34 @@
+/**
+ * @file llpanelloginlistener.cpp
+ * @author Nat Goodspeed
+ * @date 2009-12-10
+ * @brief Implementation for llpanelloginlistener.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "llviewerprecompiledheaders.h"
+// associated header
+#include "llpanelloginlistener.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "llpanellogin.h"
+
+LLPanelLoginListener::LLPanelLoginListener(LLPanelLogin* instance):
+ LLEventAPI("LLPanelLogin", "Access to LLPanelLogin methods"),
+ mPanel(instance)
+{
+ add("onClickConnect",
+ "Pretend user clicked the \"Log In\" button",
+ &LLPanelLoginListener::onClickConnect);
+}
+
+void LLPanelLoginListener::onClickConnect(const LLSD&) const
+{
+ mPanel->onClickConnect(NULL);
+}
diff --git a/indra/newview/llpanelloginlistener.h b/indra/newview/llpanelloginlistener.h
new file mode 100644
index 0000000000..0a56c75422
--- /dev/null
+++ b/indra/newview/llpanelloginlistener.h
@@ -0,0 +1,30 @@
+/**
+ * @file llpanelloginlistener.h
+ * @author Nat Goodspeed
+ * @date 2009-12-10
+ * @brief LLEventAPI for LLPanelLogin
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLPANELLOGINLISTENER_H)
+#define LL_LLPANELLOGINLISTENER_H
+
+#include "lleventapi.h"
+class LLPanelLogin;
+class LLSD;
+
+class LLPanelLoginListener: public LLEventAPI
+{
+public:
+ LLPanelLoginListener(LLPanelLogin* instance);
+
+private:
+ void onClickConnect(const LLSD&) const;
+
+ LLPanelLogin* mPanel;
+};
+
+#endif /* ! defined(LL_LLPANELLOGINLISTENER_H) */
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 21627e84ff..cef21e85d6 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -33,6 +33,7 @@
#include "llviewerprecompiledheaders.h"
#include "llpanelmaininventory.h"
+#include "llagent.h"
#include "lldndbutton.h"
#include "llfilepicker.h"
#include "llfloaterinventory.h"
@@ -863,7 +864,6 @@ void LLPanelMainInventory::initListCommandsHandlers()
mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-
}
void LLPanelMainInventory::updateListCommands()
@@ -909,6 +909,22 @@ void LLPanelMainInventory::onClipboardAction(const LLSD& userdata)
getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
}
+void LLPanelMainInventory::saveTexture(const LLSD& userdata)
+{
+ LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+ if (!current_item)
+ {
+ return;
+ }
+
+ const LLUUID& item_id = current_item->getListener()->getUUID();
+ LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item_id), TAKE_FOCUS_YES);
+ if (preview_texture)
+ {
+ preview_texture->openToSave();
+ }
+}
+
void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
{
if (!isActionEnabled(userdata))
@@ -953,18 +969,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
}
if (command_name == "save_texture")
{
- LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
- if (!current_item)
- {
- return;
- }
-
- const LLUUID& item_id = current_item->getListener()->getUUID();
- LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item_id), TAKE_FOCUS_YES);
- if (preview_texture)
- {
- preview_texture->openToSave();
- }
+ saveTexture(userdata);
}
// This doesn't currently work, since the viewer can't change an assetID an item.
if (command_name == "regenerate_link")
@@ -1008,6 +1013,22 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
}
}
+bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata)
+{
+ LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+ if (current_item)
+ {
+ LLViewerInventoryItem *inv_item = current_item->getInventoryItem();
+ if(inv_item)
+ {
+ bool can_save = inv_item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED);
+ LLInventoryType::EType curr_type = current_item->getListener()->getInventoryType();
+ return can_save && (curr_type == LLInventoryType::IT_TEXTURE || curr_type == LLInventoryType::IT_SNAPSHOT);
+ }
+ }
+ return false;
+}
+
BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
{
const std::string command_name = userdata.asString();
@@ -1035,12 +1056,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
}
if (command_name == "save_texture")
{
- LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
- if (current_item)
- {
- return (current_item->getListener()->getInventoryType() == LLInventoryType::IT_TEXTURE);
- }
- return FALSE;
+ return isSaveTextureEnabled(userdata);
}
if (command_name == "find_original")
{
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index ae78d3bec8..92443df369 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -110,6 +110,8 @@ protected:
void doCreate(const LLSD& userdata);
void resetFilters();
void setSortBy(const LLSD& userdata);
+ void saveTexture(const LLSD& userdata);
+ bool isSaveTextureEnabled(const LLSD& userdata);
private:
LLFloaterInventoryFinder* getFinder();
diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp
index 3fa0e7bf8f..88eba14553 100644
--- a/indra/newview/llpanelmediasettingsgeneral.cpp
+++ b/indra/newview/llpanelmediasettingsgeneral.cpp
@@ -94,7 +94,7 @@ BOOL LLPanelMediaSettingsGeneral::postBuild()
mAutoScale = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_SCALE_KEY );
mAutoZoom = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_ZOOM_KEY );
mControls = getChild< LLComboBox >( LLMediaEntry::CONTROLS_KEY );
- mCurrentURL = getChild< LLLineEditor >( LLMediaEntry::CURRENT_URL_KEY );
+ mCurrentURL = getChild< LLTextBox >( LLMediaEntry::CURRENT_URL_KEY );
mFirstClick = getChild< LLCheckBoxCtrl >( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
mHeightPixels = getChild< LLSpinCtrl >( LLMediaEntry::HEIGHT_PIXELS_KEY );
mHomeURL = getChild< LLLineEditor >( LLMediaEntry::HOME_URL_KEY );
@@ -284,7 +284,7 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_
{ LLMediaEntry::AUTO_SCALE_KEY, self->mAutoScale, "LLCheckBoxCtrl" },
{ LLMediaEntry::AUTO_ZOOM_KEY, self->mAutoZoom, "LLCheckBoxCtrl" },
{ LLMediaEntry::CONTROLS_KEY, self->mControls, "LLComboBox" },
- { LLMediaEntry::CURRENT_URL_KEY, self->mCurrentURL, "LLLineEditor" },
+ { LLMediaEntry::CURRENT_URL_KEY, self->mCurrentURL, "LLTextBox" },
{ LLMediaEntry::HEIGHT_PIXELS_KEY, self->mHeightPixels, "LLSpinCtrl" },
{ LLMediaEntry::HOME_URL_KEY, self->mHomeURL, "LLLineEditor" },
{ LLMediaEntry::FIRST_CLICK_INTERACT_KEY, self->mFirstClick, "LLCheckBoxCtrl" },
@@ -518,4 +518,9 @@ void LLPanelMediaSettingsGeneral::updateCurrentUrl()
bool identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_current_url, value_str );
mCurrentURL->setText(value_str);
mCurrentURL->setTentative(identical);
+
+ if ( LLPanelMediaSettingsGeneral::isMultiple() )
+ {
+ mCurrentURL->setText(LLTrans::getString("Multiple Media"));
+ }
}
diff --git a/indra/newview/llpanelmediasettingsgeneral.h b/indra/newview/llpanelmediasettingsgeneral.h
index 7782b25d63..c6895b1dc9 100644
--- a/indra/newview/llpanelmediasettingsgeneral.h
+++ b/indra/newview/llpanelmediasettingsgeneral.h
@@ -99,7 +99,7 @@ private:
LLSpinCtrl* mWidthPixels;
LLSpinCtrl* mHeightPixels;
LLLineEditor* mHomeURL;
- LLLineEditor* mCurrentURL;
+ LLTextBox* mCurrentURL;
LLMediaCtrl* mPreviewMedia;
LLTextBox* mFailWhiteListText;
};
diff --git a/indra/newview/llpanelmediasettingssecurity.cpp b/indra/newview/llpanelmediasettingssecurity.cpp
index d87c7608d5..aea6b0aa3b 100644
--- a/indra/newview/llpanelmediasettingssecurity.cpp
+++ b/indra/newview/llpanelmediasettingssecurity.cpp
@@ -167,6 +167,9 @@ void LLPanelMediaSettingsSecurity::initValues( void* userdata, const LLSD& media
data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
};
};
+
+ // initial update - hides/shows status messages etc.
+ self->updateWhitelistEnableStatus();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index 59a68bc12d..7d21867efc 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -37,6 +37,7 @@
#include "llagent.h"
#include "llagentpicksinfo.h"
#include "llavatarconstants.h"
+#include "llcommandhandler.h"
#include "llflatlistview.h"
#include "llfloaterreg.h"
#include "llfloaterworldmap.h"
@@ -55,6 +56,8 @@
#include "llpanelprofile.h"
#include "llpanelpick.h"
#include "llpanelclassified.h"
+#include "llpanelprofileview.h"
+#include "llsidetray.h"
static const std::string XML_BTN_NEW = "new_btn";
static const std::string XML_BTN_DELETE = "trash_btn";
@@ -72,6 +75,83 @@ static const std::string CLASSIFIED_NAME("classified_name");
static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks("panel_picks");
+class LLClassifiedHandler :
+ public LLCommandHandler,
+ public LLAvatarPropertiesObserver
+{
+public:
+ // throttle calls from untrusted browsers
+ LLClassifiedHandler() : LLCommandHandler("classified", UNTRUSTED_THROTTLE) {}
+
+ std::set<LLUUID> mClassifiedIds;
+
+ bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
+ {
+ if (params.size() < 2)
+ {
+ return false;
+ }
+
+ // get the ID for the classified
+ LLUUID classified_id;
+ if (!classified_id.set(params[0], FALSE))
+ {
+ return false;
+ }
+
+ // show the classified in the side tray.
+ // need to ask the server for more info first though...
+ const std::string verb = params[1].asString();
+ if (verb == "about")
+ {
+ mClassifiedIds.insert(classified_id);
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
+ return true;
+ }
+
+ return false;
+ }
+
+ /*virtual*/ void processProperties(void* data, EAvatarProcessorType type)
+ {
+ if (APT_CLASSIFIED_INFO != type)
+ {
+ return;
+ }
+
+ // is this the classified that we asked for?
+ LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
+ if (!c_info || mClassifiedIds.find(c_info->classified_id) == mClassifiedIds.end())
+ {
+ return;
+ }
+
+ // open the people profile page for the classified's owner
+ LLSD params;
+ params["id"] = c_info->creator_id;
+ params["classified"] = c_info->classified_id;
+ params["open_tab_name"] = "panel_profile";
+ LLPanelProfileView *profile = dynamic_cast<LLPanelProfileView*>(LLSideTray::getInstance()->showPanel("panel_profile_view", params));
+
+ // then open the classified panel on this user's profile panel
+ if (profile)
+ {
+ LLPanelPicks* panel_picks = profile->getChild<LLPanelPicks>("panel_picks");
+ if (panel_picks)
+ {
+ panel_picks->openClassifiedInfo(c_info);
+ }
+ }
+
+ // remove our observer now that we're done
+ mClassifiedIds.erase(c_info->classified_id);
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
+ }
+
+};
+LLClassifiedHandler gClassifiedHandler;
+
//////////////////////////////////////////////////////////////////////////
/**
@@ -624,6 +704,25 @@ void LLPanelPicks::openClassifiedInfo()
getProfilePanel()->openPanel(mPanelClassifiedInfo, params);
}
+void LLPanelPicks::openClassifiedInfo(LLAvatarClassifiedInfo *c_info)
+{
+ if (! c_info)
+ {
+ return;
+ }
+
+ createClassifiedInfoPanel();
+
+ LLSD params;
+ params["classified_id"] = c_info->classified_id;
+ params["avatar_id"] = c_info->creator_id;
+ params["snapshot_id"] = c_info->snapshot_id;
+ params["name"] = c_info->name;
+ params["desc"] = c_info->description;
+
+ getProfilePanel()->openPanel(mPanelClassifiedInfo, params);
+}
+
void LLPanelPicks::showAccordion(const std::string& name, bool show)
{
LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(name);
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
index 21794d56b2..893a0c53a3 100644
--- a/indra/newview/llpanelpicks.h
+++ b/indra/newview/llpanelpicks.h
@@ -86,6 +86,9 @@ public:
// parent panels failed to work (picks related code was in my profile panel)
void setProfilePanel(LLPanelProfile* profile_panel);
+ // display the info panel for the given classified
+ void openClassifiedInfo(LLAvatarClassifiedInfo *c_info);
+
protected:
/*virtual*/void updateButtons();
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 4a554c1b2c..e21eb01da3 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -278,12 +278,20 @@ void LLPanelPlaces::onOpen(const LLSD& key)
}
else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
{
- mPosGlobal = LLVector3d(key["x"].asReal(),
- key["y"].asReal(),
- key["z"].asReal());
+ if (key.has("id"))
+ {
+ LLUUID parcel_id = key["id"].asUUID();
+ mPlaceProfile->setParcelID(parcel_id);
+ }
+ else
+ {
+ mPosGlobal = LLVector3d(key["x"].asReal(),
+ key["y"].asReal(),
+ key["z"].asReal());
+ mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
+ }
mPlaceProfile->setInfoType(LLPanelPlaceInfo::PLACE);
- mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
}
else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE)
{
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
index aa2b7d4554..3fe51106e4 100644
--- a/indra/newview/llpanelprimmediacontrols.cpp
+++ b/indra/newview/llpanelprimmediacontrols.cpp
@@ -150,7 +150,7 @@ BOOL LLPanelPrimMediaControls::postBuild()
mSkipFwdCtrl = getChild<LLUICtrl>("skip_forward");
mSkipBackCtrl = getChild<LLUICtrl>("skip_back");
mVolumeCtrl = getChild<LLUICtrl>("media_volume");
- mVolumeBtn = getChild<LLButton>("media_volume_button");
+ mMuteBtn = getChild<LLButton>("media_mute_button");
mVolumeUpCtrl = getChild<LLUICtrl>("volume_up");
mVolumeDownCtrl = getChild<LLUICtrl>("volume_down");
mVolumeSliderCtrl = getChild<LLSliderCtrl>("volume_slider");
@@ -200,7 +200,7 @@ BOOL LLPanelPrimMediaControls::postBuild()
mScrollDownCtrl->setHeldDownCallback(onScrollDownHeld, this);
mScrollDownCtrl->setMouseUpCallback(onScrollStop, this);
}
-
+
mMediaAddress->setFocusReceivedCallback(boost::bind(&LLPanelPrimMediaControls::onInputURL, _1, this ));
mInactiveTimeout = gSavedSettings.getF32("MediaControlTimeout");
mControlFadeTime = gSavedSettings.getF32("MediaControlFadeTime");
@@ -215,11 +215,15 @@ void LLPanelPrimMediaControls::setMediaFace(LLPointer<LLViewerObject> objectp, S
{
if (media_impl.notNull() && objectp.notNull())
{
+ LLUUID prev_id = mTargetImplID;
mTargetImplID = media_impl->getMediaTextureID();
mTargetObjectID = objectp->getID();
mTargetObjectFace = face;
mTargetObjectNormal = pick_normal;
mClearFaceOnFade = false;
+
+ if (prev_id != mTargetImplID)
+ mVolumeSliderCtrl->setValue(media_impl->getVolume());
}
else
{
@@ -308,13 +312,12 @@ void LLPanelPrimMediaControls::updateShape()
enabled = dynamic_cast<LLVOVolume*>(objectp)->hasMediaPermission(media_data, LLVOVolume::MEDIA_PERM_CONTROL);
mini_controls = (LLMediaEntry::MINI == media_data->getControls());
}
-
const bool is_hud = objectp->isHUDAttachment();
//
// Set the state of the buttons
//
-
+
// XXX RSP: TODO: FIXME: clean this up so that it is clearer what mode we are in,
// and that only the proper controls get made visible/enabled according to that mode.
mBackCtrl->setVisible(has_focus);
@@ -343,7 +346,7 @@ void LLPanelPrimMediaControls::updateShape()
mStopCtrl->setEnabled(has_focus && can_navigate);
mHomeCtrl->setEnabled(has_focus && can_navigate);
LLPluginClassMediaOwner::EMediaStatus result = ((media_impl != NULL) && media_impl->hasMedia()) ? media_plugin->getStatus() : LLPluginClassMediaOwner::MEDIA_NONE;
-
+
if(media_plugin && media_plugin->pluginSupportsMediaTime())
{
mReloadCtrl->setEnabled(false);
@@ -360,14 +363,14 @@ void LLPanelPrimMediaControls::updateShape()
mSkipFwdCtrl->setEnabled(has_focus && !mini_controls);
mSkipBackCtrl->setVisible(has_focus && !mini_controls);
mSkipBackCtrl->setEnabled(has_focus && !mini_controls);
-
+
mVolumeCtrl->setVisible(has_focus);
mVolumeUpCtrl->setVisible(has_focus);
mVolumeDownCtrl->setVisible(has_focus);
mVolumeCtrl->setEnabled(has_focus);
mVolumeSliderCtrl->setEnabled(has_focus && mVolumeSliderVisible);
mVolumeSliderCtrl->setVisible(has_focus && mVolumeSliderVisible);
-
+
mWhitelistIcon->setVisible(false);
mSecureLockIcon->setVisible(false);
if (mMediaPanelScroll)
@@ -378,7 +381,7 @@ void LLPanelPrimMediaControls::updateShape()
mScrollRightCtrl->setVisible(false);
mScrollDownCtrl->setVisible(false);
}
-
+
F32 volume = media_impl->getVolume();
// movie's url changed
if(mCurrentURL!=mPreviousURL)
@@ -386,7 +389,7 @@ void LLPanelPrimMediaControls::updateShape()
mMovieDuration = media_plugin->getDuration();
mPreviousURL = mCurrentURL;
}
-
+
if(mMovieDuration == 0)
{
mMovieDuration = media_plugin->getDuration();
@@ -394,7 +397,7 @@ void LLPanelPrimMediaControls::updateShape()
mMediaPlaySliderCtrl->setEnabled(false);
}
// TODO: What if it's not fully loaded
-
+
if(mUpdateSlider && mMovieDuration!= 0)
{
F64 current_time = media_plugin->getCurrentTime();
@@ -402,29 +405,27 @@ void LLPanelPrimMediaControls::updateShape()
mMediaPlaySliderCtrl->setValue(percent);
mMediaPlaySliderCtrl->setEnabled(true);
}
-
+
// video vloume
if(volume <= 0.0)
{
mVolumeUpCtrl->setEnabled(TRUE);
mVolumeDownCtrl->setEnabled(FALSE);
- media_impl->setVolume(0.0);
- mVolumeBtn->setToggleState(true);
+ mMuteBtn->setToggleState(true);
}
else if (volume >= 1.0)
{
mVolumeUpCtrl->setEnabled(FALSE);
mVolumeDownCtrl->setEnabled(TRUE);
- media_impl->setVolume(1.0);
- mVolumeBtn->setToggleState(false);
+ mMuteBtn->setToggleState(false);
}
else
{
+ mMuteBtn->setToggleState(false);
mVolumeUpCtrl->setEnabled(TRUE);
mVolumeDownCtrl->setEnabled(TRUE);
}
- mVolumeSliderCtrl->setValue(volume);
-
+
switch(result)
{
case LLPluginClassMediaOwner::MEDIA_PLAYING:
@@ -453,7 +454,7 @@ void LLPanelPrimMediaControls::updateShape()
{
mCurrentURL.clear();
}
-
+
mPlayCtrl->setVisible(FALSE);
mPauseCtrl->setVisible(FALSE);
mMediaStopCtrl->setVisible(FALSE);
@@ -465,7 +466,7 @@ void LLPanelPrimMediaControls::updateShape()
mSkipFwdCtrl->setEnabled(FALSE);
mSkipBackCtrl->setVisible(FALSE);
mSkipBackCtrl->setEnabled(FALSE);
-
+
mVolumeCtrl->setVisible(FALSE);
mVolumeUpCtrl->setVisible(FALSE);
mVolumeDownCtrl->setVisible(FALSE);
@@ -491,13 +492,13 @@ void LLPanelPrimMediaControls::updateShape()
{
mSecureLockIcon->setVisible(has_focus);
}
-
+
if(mCurrentURL!=mPreviousURL)
{
setCurrentURL();
mPreviousURL = mCurrentURL;
}
-
+
if(result == LLPluginClassMediaOwner::MEDIA_LOADING)
{
mReloadCtrl->setEnabled(FALSE);
@@ -513,7 +514,7 @@ void LLPanelPrimMediaControls::updateShape()
mStopCtrl->setVisible(FALSE);
}
}
-
+
if(media_plugin)
{
@@ -530,7 +531,7 @@ void LLPanelPrimMediaControls::updateShape()
mMediaProgressPanel->setVisible(false);
}
}
-
+
if(media_impl)
{
//
@@ -538,28 +539,28 @@ void LLPanelPrimMediaControls::updateShape()
//
switch (mScrollState)
{
- case SCROLL_UP:
- media_impl->scrollWheel(0, -1, MASK_NONE);
- break;
- case SCROLL_DOWN:
- media_impl->scrollWheel(0, 1, MASK_NONE);
- break;
- case SCROLL_LEFT:
- media_impl->scrollWheel(1, 0, MASK_NONE);
-// media_impl->handleKeyHere(KEY_LEFT, MASK_NONE);
- break;
- case SCROLL_RIGHT:
- media_impl->scrollWheel(-1, 0, MASK_NONE);
-// media_impl->handleKeyHere(KEY_RIGHT, MASK_NONE);
- break;
- case SCROLL_NONE:
- default:
- break;
+ case SCROLL_UP:
+ media_impl->scrollWheel(0, -1, MASK_NONE);
+ break;
+ case SCROLL_DOWN:
+ media_impl->scrollWheel(0, 1, MASK_NONE);
+ break;
+ case SCROLL_LEFT:
+ media_impl->scrollWheel(1, 0, MASK_NONE);
+ // media_impl->handleKeyHere(KEY_LEFT, MASK_NONE);
+ break;
+ case SCROLL_RIGHT:
+ media_impl->scrollWheel(-1, 0, MASK_NONE);
+ // media_impl->handleKeyHere(KEY_RIGHT, MASK_NONE);
+ break;
+ case SCROLL_NONE:
+ default:
+ break;
}
}
setVisible(enabled);
-
+
//
// Calculate position and shape of the controls
//
@@ -569,31 +570,31 @@ void LLPanelPrimMediaControls::updateShape()
std::vector<LLVector3>::iterator vert_it;
std::vector<LLVector3>::iterator vert_end;
std::vector<LLVector3> vect_face;
-
+
LLVolume* volume = objectp->getVolume();
-
+
if (volume)
{
const LLVolumeFace& vf = volume->getVolumeFace(mTargetObjectFace);
-
+
const LLVector3* ext = vf.mExtents;
-
+
LLVector3 center = (ext[0]+ext[1])*0.5f;
LLVector3 size = (ext[1]-ext[0])*0.5f;
LLVector3 vert[] =
- {
- center + size.scaledVec(LLVector3(1,1,1)),
- center + size.scaledVec(LLVector3(-1,1,1)),
- center + size.scaledVec(LLVector3(1,-1,1)),
- center + size.scaledVec(LLVector3(-1,-1,1)),
- center + size.scaledVec(LLVector3(1,1,-1)),
- center + size.scaledVec(LLVector3(-1,1,-1)),
- center + size.scaledVec(LLVector3(1,-1,-1)),
- center + size.scaledVec(LLVector3(-1,-1,-1)),
- };
-
+ {
+ center + size.scaledVec(LLVector3(1,1,1)),
+ center + size.scaledVec(LLVector3(-1,1,1)),
+ center + size.scaledVec(LLVector3(1,-1,1)),
+ center + size.scaledVec(LLVector3(-1,-1,1)),
+ center + size.scaledVec(LLVector3(1,1,-1)),
+ center + size.scaledVec(LLVector3(-1,1,-1)),
+ center + size.scaledVec(LLVector3(1,-1,-1)),
+ center + size.scaledVec(LLVector3(-1,-1,-1)),
+ };
+
LLVOVolume* vo = (LLVOVolume*) objectp;
-
+
for (U32 i = 0; i < 8; i++)
{
vect_face.push_back(vo->volumePositionToAgent(vert[i]));
@@ -601,7 +602,7 @@ void LLPanelPrimMediaControls::updateShape()
}
vert_it = vect_face.begin();
vert_end = vect_face.end();
-
+
min = LLVector3(1,1,1);
max = LLVector3(-1,-1,-1);
for(; vert_it != vert_end; ++vert_it)
@@ -609,19 +610,19 @@ void LLPanelPrimMediaControls::updateShape()
// project silhouette vertices into screen space
glh::vec3f screen_vert = glh::vec3f(vert_it->mV);
mat.mult_matrix_vec(screen_vert);
-
+
// add to screenspace bounding box
update_min_max(min, max, LLVector3(screen_vert.v));
}
-
+
LLCoordGL screen_min;
screen_min.mX = llround((F32)gViewerWindow->getWorldViewWidthScaled() * (min.mV[VX] + 1.f) * 0.5f);
screen_min.mY = llround((F32)gViewerWindow->getWorldViewHeightScaled() * (min.mV[VY] + 1.f) * 0.5f);
-
+
LLCoordGL screen_max;
screen_max.mX = llround((F32)gViewerWindow->getWorldViewWidthScaled() * (max.mV[VX] + 1.f) * 0.5f);
screen_max.mY = llround((F32)gViewerWindow->getWorldViewHeightScaled() * (max.mV[VY] + 1.f) * 0.5f);
-
+
// grow panel so that screenspace bounding box fits inside "media_region" element of HUD
LLRect media_controls_rect;
S32 volume_slider_height = mVolumeSliderCtrl->getRect().getHeight() - /*fudge*/ 2;
@@ -636,19 +637,19 @@ void LLPanelPrimMediaControls::updateShape()
// clamp to minimum size, keeping centered
media_controls_rect.setCenterAndSize(media_controls_rect.getCenterX(), media_controls_rect.getCenterY(),
- llmax(mMinWidth, media_controls_rect.getWidth()), llmax(mMinHeight, media_controls_rect.getHeight()));
-
+ llmax(mMinWidth, media_controls_rect.getWidth()), llmax(mMinHeight, media_controls_rect.getHeight()));
+
setShape(media_controls_rect, true);
-
+
// Test mouse position to see if the cursor is stationary
LLCoordWindow cursor_pos_window;
getWindow()->getCursorPosition(&cursor_pos_window);
-
+
// If last pos is not equal to current pos, the mouse has moved
// We need to reset the timer, and make sure the panel is visible
if(cursor_pos_window.mX != mLastCursorPos.mX ||
- cursor_pos_window.mY != mLastCursorPos.mY ||
- mScrollState != SCROLL_NONE)
+ cursor_pos_window.mY != mLastCursorPos.mY ||
+ mScrollState != SCROLL_NONE)
{
mInactivityTimer.start();
mLastCursorPos = cursor_pos_window;
@@ -673,7 +674,7 @@ void LLPanelPrimMediaControls::updateShape()
else
{
// I don't think this is correct anymore. This is done in draw() after the fade has completed.
-// setVisible(FALSE);
+ // setVisible(FALSE);
}
}
}
@@ -1193,7 +1194,7 @@ void LLPanelPrimMediaControls::onCommitVolumeUp()
}
media_impl->setVolume(volume);
- mVolumeBtn->setToggleState(false);
+ mMuteBtn->setToggleState(false);
}
}
@@ -1213,7 +1214,7 @@ void LLPanelPrimMediaControls::onCommitVolumeDown()
}
media_impl->setVolume(volume);
- mVolumeBtn->setToggleState(false);
+ mMuteBtn->setToggleState(false);
}
}
@@ -1243,7 +1244,7 @@ void LLPanelPrimMediaControls::onToggleMute()
}
else
{
- media_impl->setVolume(0.5);
+ media_impl->setVolume(mVolumeSliderCtrl->getValueF32());
}
}
}
diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h
index 06163051a5..17e65b8b0c 100644
--- a/indra/newview/llpanelprimmediacontrols.h
+++ b/indra/newview/llpanelprimmediacontrols.h
@@ -153,7 +153,7 @@ private:
LLUICtrl *mMediaPlaySliderPanel;
LLUICtrl *mMediaPlaySliderCtrl;
LLUICtrl *mVolumeCtrl;
- LLButton *mVolumeBtn;
+ LLButton *mMuteBtn;
LLUICtrl *mVolumeUpCtrl;
LLUICtrl *mVolumeDownCtrl;
LLSliderCtrl *mVolumeSliderCtrl;
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 698f6152b4..26694ac433 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -76,29 +76,12 @@ LLPreviewTexture::LLPreviewTexture(const LLSD& key)
mAspectRatio(0.f),
mPreviewToSave(FALSE)
{
- const LLInventoryItem *item = getItem();
+ const LLViewerInventoryItem *item = static_cast<const LLViewerInventoryItem*>(getItem());
if(item)
{
mShowKeepDiscard = item->getPermissions().getCreator() != gAgent.getID();
mImageID = item->getAssetUUID();
- const LLPermissions& perm = item->getPermissions();
- U32 mask = PERM_NONE;
- if(perm.getOwner() == gAgent.getID())
- {
- mask = perm.getMaskBase();
- }
- else if(gAgent.isInGroup(perm.getGroup()))
- {
- mask = perm.getMaskGroup();
- }
- else
- {
- mask = perm.getMaskEveryone();
- }
- if((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
- {
- mIsCopyable = TRUE;
- }
+ mIsCopyable = item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED);
}
else // not an item, assume it's an asset id
{
@@ -145,6 +128,9 @@ BOOL LLPreviewTexture::postBuild()
childSetVisible("Discard", false);
}
+ childSetAction("save_tex_btn", LLPreviewTexture::onSaveAsBtn, this);
+ childSetVisible("save_tex_btn", canSaveAs());
+
if (!mCopyToInv)
{
const LLInventoryItem* item = getItem();
@@ -164,6 +150,13 @@ BOOL LLPreviewTexture::postBuild()
return LLPreview::postBuild();
}
+// static
+void LLPreviewTexture::onSaveAsBtn(void* data)
+{
+ LLPreviewTexture* self = (LLPreviewTexture*)data;
+ self->saveAs();
+}
+
void LLPreviewTexture::draw()
{
if (mUpdateDimensions)
@@ -576,6 +569,7 @@ void LLPreviewTexture::loadAsset()
mImage->forceToSaveRawImage(0) ;
mAssetStatus = PREVIEW_ASSET_LOADING;
updateDimensions();
+ childSetVisible("save_tex_btn", canSaveAs());
}
LLPreview::EAssetStatus LLPreviewTexture::getAssetStatus()
diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h
index 9b3c91d831..980aecee6d 100644
--- a/indra/newview/llpreviewtexture.h
+++ b/indra/newview/llpreviewtexture.h
@@ -58,7 +58,6 @@ public:
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
virtual void onFocusReceived();
- static void saveToFile(void* userdata);
static void onFileLoadedForSave(
BOOL success,
LLViewerFetchedTexture *src_vi,
@@ -68,6 +67,8 @@ public:
BOOL final,
void* userdata );
void openToSave();
+
+ static void onSaveAsBtn(void* data);
protected:
void init();
/* virtual */ BOOL postBuild();
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index ca7a3b663a..5383158cd3 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -235,8 +235,10 @@ void LLSidepanelInventory::updateVerbs()
if (!item)
return;
- mInfoBtn->setEnabled(TRUE);
- mShareBtn->setEnabled(TRUE);
+ bool is_single_selection = getSelectedCount() == 1;
+
+ mInfoBtn->setEnabled(is_single_selection);
+ mShareBtn->setEnabled(is_single_selection);
switch(item->getInventoryType())
{
@@ -274,6 +276,14 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()
return item;
}
+U32 LLSidepanelInventory::getSelectedCount()
+{
+ LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");
+ std::set<LLUUID> selection_list;
+ panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList(selection_list);
+ return selection_list.size();
+}
+
LLInventoryPanel *LLSidepanelInventory::getActivePanel()
{
if (!getVisible())
diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h
index 231cdac9e1..ee11fb6b54 100644
--- a/indra/newview/llsidepanelinventory.h
+++ b/indra/newview/llsidepanelinventory.h
@@ -56,6 +56,7 @@ public:
protected:
// Tracks highlighted (selected) item in inventory panel.
LLInventoryItem *getSelectedItem();
+ U32 getSelectedCount();
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
// "wear", "teleport", etc.
void performActionOnSelection(const std::string &action);
diff --git a/indra/newview/llsidepanelinventorysubpanel.cpp b/indra/newview/llsidepanelinventorysubpanel.cpp
index 23931defdd..793904faa8 100644
--- a/indra/newview/llsidepanelinventorysubpanel.cpp
+++ b/indra/newview/llsidepanelinventorysubpanel.cpp
@@ -57,7 +57,6 @@ LLSidepanelInventorySubpanel::LLSidepanelInventorySubpanel()
: LLPanel(),
mIsDirty(TRUE),
mIsEditing(FALSE),
- mEditBtn(NULL),
mCancelBtn(NULL),
mSaveBtn(NULL)
{
@@ -71,9 +70,6 @@ LLSidepanelInventorySubpanel::~LLSidepanelInventorySubpanel()
// virtual
BOOL LLSidepanelInventorySubpanel::postBuild()
{
- mEditBtn = getChild<LLButton>("edit_btn");
- mEditBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onEditButtonClicked, this));
-
mSaveBtn = getChild<LLButton>("save_btn");
mSaveBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onSaveButtonClicked, this));
@@ -111,9 +107,9 @@ void LLSidepanelInventorySubpanel::draw()
{
if (mIsDirty)
{
- mIsDirty = FALSE;
refresh();
updateVerbs();
+ mIsDirty = FALSE;
}
LLPanel::draw();
@@ -127,7 +123,6 @@ void LLSidepanelInventorySubpanel::dirty()
void LLSidepanelInventorySubpanel::updateVerbs()
{
- mEditBtn->setVisible(!mIsEditing);
mSaveBtn->setVisible(mIsEditing);
mCancelBtn->setVisible(mIsEditing);
}
diff --git a/indra/newview/llsidepanelinventorysubpanel.h b/indra/newview/llsidepanelinventorysubpanel.h
index a74f4fdee6..b7bee6809f 100644
--- a/indra/newview/llsidepanelinventorysubpanel.h
+++ b/indra/newview/llsidepanelinventorysubpanel.h
@@ -70,7 +70,6 @@ protected:
void onEditButtonClicked();
void onSaveButtonClicked();
void onCancelButtonClicked();
- LLButton* mEditBtn;
LLButton* mSaveBtn;
LLButton* mCancelBtn;
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index ad6428e515..449bdefb8f 100644
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -159,7 +159,6 @@ void LLSidepanelItemInfo::refresh()
setIsEditing(FALSE);
return;
}
- mEditBtn->setEnabled(FALSE);
}
if (!getIsEditing())
@@ -251,6 +250,18 @@ void LLSidepanelItemInfo::refreshFromItem(LLInventoryItem* item)
GP_OBJECT_MANIPULATE)
&& is_obj_modify && is_complete;
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ bool item_in_trash = item->getUUID() == trash_id || gInventory.isObjectDescendentOf(item->getUUID(), trash_id);
+
+ if (is_modifiable && !item_in_trash)
+ {
+ setIsEditing(TRUE);
+ }
+ else
+ {
+ setIsEditing(FALSE);
+ }
+
childSetEnabled("LabelItemNameTitle",TRUE);
childSetEnabled("LabelItemName",is_modifiable && !is_calling_card); // for now, don't allow rename of calling cards
childSetText("LabelItemName",item->getName());
@@ -859,25 +870,6 @@ LLInventoryItem* LLSidepanelItemInfo::findItem() const
}
// virtual
-void LLSidepanelItemInfo::updateVerbs()
-{
- LLSidepanelInventorySubpanel::updateVerbs();
-
- const LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem();
- if (item)
- {
- const LLPermissions& perm = item->getPermissions();
- BOOL is_modifiable = gAgent.allowOperation(PERM_MODIFY, perm,
- GP_OBJECT_MANIPULATE);
-
- const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- bool item_in_trash = item->getUUID() == trash_id || gInventory.isObjectDescendentOf(item->getUUID(), trash_id);
- mEditBtn->setEnabled(is_modifiable && !item_in_trash);
-
- }
-}
-
-// virtual
void LLSidepanelItemInfo::save()
{
onCommitName();
diff --git a/indra/newview/llsidepaneliteminfo.h b/indra/newview/llsidepaneliteminfo.h
index 4bfbd56ea7..21002327bc 100644
--- a/indra/newview/llsidepaneliteminfo.h
+++ b/indra/newview/llsidepaneliteminfo.h
@@ -62,7 +62,6 @@ public:
protected:
/*virtual*/ void refresh();
/*virtual*/ void save();
- /*virtual*/ void updateVerbs();
LLInventoryItem* findItem() const;
LLViewerObject* findObject() const;
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index 464546cc77..2c40e948de 100644
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -1047,8 +1047,8 @@ void LLSidepanelTaskInfo::updateVerbs()
mBuyBtn->setVisible(!getIsEditing());
mOpenBtn->setEnabled(enable_object_open());
- const LLViewerObject *obj = getFirstSelectedObject();
- mEditBtn->setEnabled(obj && obj->permModify());
+ //const LLViewerObject *obj = getFirstSelectedObject();
+ //mEditBtn->setEnabled(obj && obj->permModify());
}
void LLSidepanelTaskInfo::onOpenButtonClicked()
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index d8d1760c38..93655eb1f1 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2695,12 +2695,15 @@ std::string LLStartUp::startupStateToString(EStartupState state)
#define RTNENUM(E) case E: return #E
switch(state){
RTNENUM( STATE_FIRST );
+ RTNENUM( STATE_BROWSER_INIT );
RTNENUM( STATE_LOGIN_SHOW );
RTNENUM( STATE_LOGIN_WAIT );
RTNENUM( STATE_LOGIN_CLEANUP );
RTNENUM( STATE_LOGIN_AUTH_INIT );
RTNENUM( STATE_LOGIN_PROCESS_RESPONSE );
RTNENUM( STATE_WORLD_INIT );
+ RTNENUM( STATE_MULTIMEDIA_INIT );
+ RTNENUM( STATE_FONT_INIT );
RTNENUM( STATE_SEED_GRANTED_WAIT );
RTNENUM( STATE_SEED_CAP_GRANTED );
RTNENUM( STATE_WORLD_WAIT );
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 67007629c0..e29c96bec4 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -311,10 +311,10 @@ public:
{
bool success = false;
bool partial = false;
- if (200 <= status && status < 300)
+ if (HTTP_OK <= status && status < HTTP_MULTIPLE_CHOICES)
{
success = true;
- if (203 == status) // partial information (i.e. last block)
+ if (HTTP_PARTIAL_CONTENT == status) // partial information (i.e. last block)
{
partial = true;
}
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 46618d4026..f8c82f8b22 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -47,11 +47,14 @@
#include "llurlsimstring.h"
#include "llweb.h"
#include "llworldmapmessage.h"
+#include "llurldispatcherlistener.h"
// library includes
#include "llnotificationsutil.h"
#include "llsd.h"
+static LLURLDispatcherListener sURLDispatcherListener;
+
class LLURLDispatcherImpl
{
public:
diff --git a/indra/newview/llurldispatcherlistener.cpp b/indra/newview/llurldispatcherlistener.cpp
new file mode 100644
index 0000000000..fea6a769c5
--- /dev/null
+++ b/indra/newview/llurldispatcherlistener.cpp
@@ -0,0 +1,58 @@
+/**
+ * @file llurldispatcherlistener.cpp
+ * @author Nat Goodspeed
+ * @date 2009-12-10
+ * @brief Implementation for llurldispatcherlistener.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "llviewerprecompiledheaders.h"
+// associated header
+#include "llurldispatcherlistener.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "llurldispatcher.h"
+
+LLURLDispatcherListener::LLURLDispatcherListener(/* LLURLDispatcher* instance */):
+ LLEventAPI("LLURLDispatcher", "Internal URL handling") /* ,
+ mDispatcher(instance) */
+{
+ add("dispatch",
+ "At startup time or on clicks in internal web browsers,\n"
+ "teleport, open map, or run requested command.\n"
+ "[\"url\"] string url to dispatch\n"
+ "[\"trusted\"] boolean indicating trusted browser [default true]",
+ &LLURLDispatcherListener::dispatch);
+ add("dispatchRightClick", "Dispatch [\"url\"] as if from a right-click on a hot link.",
+ &LLURLDispatcherListener::dispatchRightClick);
+ add("dispatchFromTextEditor", "Dispatch [\"url\"] as if from an edit field.",
+ &LLURLDispatcherListener::dispatchFromTextEditor);
+}
+
+void LLURLDispatcherListener::dispatch(const LLSD& params) const
+{
+ // For most purposes, we expect callers to want to be trusted.
+ bool trusted_browser = true;
+ if (params.has("trusted"))
+ {
+ // But for testing, allow a caller to specify untrusted.
+ trusted_browser = params["trusted"].asBoolean();
+ }
+ LLURLDispatcher::dispatch(params["url"], NULL, trusted_browser);
+}
+
+void LLURLDispatcherListener::dispatchRightClick(const LLSD& params) const
+{
+ LLURLDispatcher::dispatchRightClick(params["url"]);
+}
+
+void LLURLDispatcherListener::dispatchFromTextEditor(const LLSD& params) const
+{
+ LLURLDispatcher::dispatchFromTextEditor(params["url"]);
+}
diff --git a/indra/newview/llurldispatcherlistener.h b/indra/newview/llurldispatcherlistener.h
new file mode 100644
index 0000000000..894afcbb51
--- /dev/null
+++ b/indra/newview/llurldispatcherlistener.h
@@ -0,0 +1,32 @@
+/**
+ * @file llurldispatcherlistener.h
+ * @author Nat Goodspeed
+ * @date 2009-12-10
+ * @brief LLEventAPI for LLURLDispatcher
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLURLDISPATCHERLISTENER_H)
+#define LL_LLURLDISPATCHERLISTENER_H
+
+#include "lleventapi.h"
+class LLURLDispatcher;
+class LLSD;
+
+class LLURLDispatcherListener: public LLEventAPI
+{
+public:
+ LLURLDispatcherListener(/* LLURLDispatcher* instance */); // all static members
+
+private:
+ void dispatch(const LLSD& params) const;
+ void dispatchRightClick(const LLSD& params) const;
+ void dispatchFromTextEditor(const LLSD& params) const;
+
+ //LLURLDispatcher* mDispatcher;
+};
+
+#endif /* ! defined(LL_LLURLDISPATCHERLISTENER_H) */
diff --git a/indra/newview/llviewerhelp.cpp b/indra/newview/llviewerhelp.cpp
index 297c0cc111..b8f91697e5 100644
--- a/indra/newview/llviewerhelp.cpp
+++ b/indra/newview/llviewerhelp.cpp
@@ -49,24 +49,38 @@
void LLViewerHelp::showTopic(const std::string &topic)
{
- showHelp();
-
// allow overriding the help server with a local help file
if( gSavedSettings.getBOOL("HelpUseLocal") )
{
+ showHelp();
LLFloaterHelpBrowser* helpbrowser = dynamic_cast<LLFloaterHelpBrowser*>(LLFloaterReg::getInstance("help_browser"));
helpbrowser->navigateToLocalPage( "help-offline" , "index.html" );
return;
}
- // use a special login topic before the user logs in
+ // if the help topic is empty, use the default topic
std::string help_topic = topic;
- if (! LLLoginInstance::getInstance()->authSuccess())
+ if (help_topic.empty())
{
- help_topic = preLoginTopic();
+ help_topic = defaultTopic();
+ }
+
+ // f1 help topic means: if user not logged in yet, show the
+ // pre-login topic, otherwise show help for the focused item
+ if (help_topic == f1HelpTopic())
+ {
+ if (! LLLoginInstance::getInstance()->authSuccess())
+ {
+ help_topic = preLoginTopic();
+ }
+ else
+ {
+ help_topic = getTopicFromFocus();
+ }
}
// work out the URL for this topic and display it
+ showHelp();
const LLOSInfo& osinfo = LLAppViewer::instance()->getOSInfo();
std::string helpURL = LLViewerHelpUtil::buildHelpURL( help_topic, gSavedSettings, osinfo );
setRawURL( helpURL );
@@ -84,6 +98,12 @@ std::string LLViewerHelp::preLoginTopic()
return "pre_login_help";
}
+std::string LLViewerHelp::f1HelpTopic()
+{
+ // *hack: to be done properly
+ return "f1_help";
+}
+
//////////////////////////////
// our own interfaces
diff --git a/indra/newview/llviewerhelp.h b/indra/newview/llviewerhelp.h
index dcb5ae32c9..07971a593e 100644
--- a/indra/newview/llviewerhelp.h
+++ b/indra/newview/llviewerhelp.h
@@ -51,14 +51,17 @@ class LLViewerHelp : public LLHelp, public LLSingleton<LLViewerHelp>
/// display the specified help topic in the help viewer
/*virtual*/ void showTopic(const std::string &topic);
- /// return default (fallback) topic name suitable for showTopic()
- /*virtual*/ std::string defaultTopic();
-
// return topic derived from viewer UI focus, else default topic
std::string getTopicFromFocus();
+ /// return default (fallback) topic name suitable for showTopic()
+ /*virtual*/ std::string defaultTopic();
+
// return topic to use before the user logs in
- std::string preLoginTopic();
+ /*virtual*/ std::string preLoginTopic();
+
+ // return topic to use for the top-level help, invoked by F1
+ /*virtual*/ std::string f1HelpTopic();
private:
static void showHelp(); // make sure help UI is visible & raised
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 5417929dbb..8dcd1b8f93 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1379,6 +1379,25 @@ LLViewerInventoryCategory *LLViewerInventoryItem::getLinkedCategory() const
return NULL;
}
+bool LLViewerInventoryItem::checkPermissionsSet(PermissionMask mask) const
+{
+ const LLPermissions& perm = getPermissions();
+ PermissionMask curr_mask = PERM_NONE;
+ if(perm.getOwner() == gAgent.getID())
+ {
+ curr_mask = perm.getMaskBase();
+ }
+ else if(gAgent.isInGroup(perm.getGroup()))
+ {
+ curr_mask = perm.getMaskGroup();
+ }
+ else
+ {
+ curr_mask = perm.getMaskEveryone();
+ }
+ return ((curr_mask & mask) == mask);
+}
+
//----------
void LLViewerInventoryItem::onCallingCardNameLookup(const LLUUID& id, const std::string& first_name, const std::string& last_name)
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 0156e7dab1..412a2c66e6 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -158,6 +158,9 @@ public:
bool getIsBrokenLink() const; // true if the baseitem this points to doesn't exist in memory.
LLViewerInventoryItem *getLinkedItem() const;
LLViewerInventoryCategory *getLinkedCategory() const;
+
+ // Checks the items permissions (for owner, group, or everyone) and returns true if all mask bits are set.
+ bool checkPermissionsSet(PermissionMask mask) const;
// callback
void onCallingCardNameLookup(const LLUUID& id, const std::string& first_name, const std::string& last_name);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index ef8f63484e..57e4ed0c1e 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -172,6 +172,11 @@ public:
completeAny(status, "text/html");
}
else
+ if(status == 403)
+ {
+ completeAny(status, "text/html");
+ }
+ else
if(status == 404)
{
// 404 is content not found - sites often have bespoke 404 pages so
@@ -240,6 +245,7 @@ public:
bool mInitialized;
};
static LLViewerMedia::impl_list sViewerMediaImplList;
+static LLViewerMedia::impl_id_map sViewerMediaTextureIDMap;
static LLTimer sMediaCreateTimer;
static const F32 LLVIEWERMEDIA_CREATE_DELAY = 1.0f;
static F32 sGlobalVolume = 1.0f;
@@ -297,7 +303,7 @@ viewer_media_t LLViewerMedia::newMediaImpl(
else
{
media_impl->unload();
- media_impl->mTextureId = texture_id;
+ media_impl->setTextureID(texture_id);
media_impl->mMediaWidth = media_width;
media_impl->mMediaHeight = media_height;
media_impl->mMediaAutoScale = media_auto_scale;
@@ -412,18 +418,16 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s
// static
LLViewerMediaImpl* LLViewerMedia::getMediaImplFromTextureID(const LLUUID& texture_id)
{
- impl_list::iterator iter = sViewerMediaImplList.begin();
- impl_list::iterator end = sViewerMediaImplList.end();
-
- for(; iter != end; iter++)
+ LLViewerMediaImpl* result = NULL;
+
+ // Look up the texture ID in the texture id->impl map.
+ impl_id_map::iterator iter = sViewerMediaTextureIDMap.find(texture_id);
+ if(iter != sViewerMediaTextureIDMap.end())
{
- LLViewerMediaImpl* media_impl = *iter;
- if(media_impl->getMediaTextureID() == texture_id)
- {
- return media_impl;
- }
+ result = iter->second;
}
- return NULL;
+
+ return result;
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -626,7 +630,22 @@ bool LLViewerMedia::priorityComparitor(const LLViewerMediaImpl* i1, const LLView
static bool proximity_comparitor(const LLViewerMediaImpl* i1, const LLViewerMediaImpl* i2)
{
- return (i1->getProximityDistance() < i2->getProximityDistance());
+ if(i1->getProximityDistance() < i2->getProximityDistance())
+ {
+ return true;
+ }
+ else if(i1->getProximityDistance() > i2->getProximityDistance())
+ {
+ return false;
+ }
+ else
+ {
+ // Both objects have the same distance. This most likely means they're two faces of the same object.
+ // They may also be faces on different objects with exactly the same distance (like HUD objects).
+ // We don't actually care what the sort order is for this case, as long as it's stable and doesn't change when you enable/disable media.
+ // Comparing the impl pointers gives a completely arbitrary ordering, but it will be stable.
+ return (i1 < i2);
+ }
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -827,7 +846,6 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
:
mMediaSource( NULL ),
mMovieImageHasMips(false),
- mTextureId(texture_id),
mMediaWidth(media_width),
mMediaHeight(media_height),
mMediaAutoScale(media_auto_scale),
@@ -857,6 +875,7 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
mProximityDistance(0.0f),
mMimeTypeProbe(NULL),
mMediaAutoPlay(false),
+ mInNearbyMediaList(false),
mIsUpdated(false)
{
@@ -868,6 +887,8 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
}
add_media_impl(this);
+
+ setTextureID(texture_id);
// connect this media_impl to the media texture, creating it if it doesn't exist.0
// This is necessary because we need to be able to use getMaxVirtualSize() even if the media plugin is not loaded.
@@ -891,6 +912,7 @@ LLViewerMediaImpl::~LLViewerMediaImpl()
LLViewerMediaTexture::removeMediaImplFromTexture(mTextureId) ;
+ setTextureID();
remove_media_impl(this);
}
@@ -2421,6 +2443,26 @@ LLVOVolume *LLViewerMediaImpl::getSomeObject()
return result;
}
+void LLViewerMediaImpl::setTextureID(LLUUID id)
+{
+ if(id != mTextureId)
+ {
+ if(mTextureId.notNull())
+ {
+ // Remove this item's entry from the map
+ sViewerMediaTextureIDMap.erase(mTextureId);
+ }
+
+ if(id.notNull())
+ {
+ sViewerMediaTextureIDMap.insert(LLViewerMedia::impl_id_map::value_type(id, this));
+ }
+
+ mTextureId = id;
+ }
+}
+
+
//////////////////////////////////////////////////////////////////////////////////////////
//static
void LLViewerMedia::toggleMusicPlay(void*)
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 713eb2710b..349a66867a 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -79,6 +79,8 @@ class LLViewerMedia
typedef std::vector<LLViewerMediaImpl*> impl_list;
+ typedef std::map<LLUUID, LLViewerMediaImpl*> impl_id_map;
+
// Special case early init for just web browser component
// so we can show login screen. See .cpp file for details. JC
@@ -287,6 +289,8 @@ public:
LLPluginClassMedia::EPriority getPriority() { return mPriority; };
void setLowPrioritySizeLimit(int size);
+
+ void setTextureID(LLUUID id = LLUUID::null);
typedef enum
{
@@ -348,6 +352,7 @@ public:
LLMimeDiscoveryResponder *mMimeTypeProbe;
bool mMediaAutoPlay;
std::string mMediaEntryURL;
+ bool mInNearbyMediaList; // used by LLFloaterNearbyMedia::refreshList() for performance reasons
private:
BOOL mIsUpdated ;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 9def699708..36d9e7935f 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -5575,17 +5575,8 @@ class LLShowHelp : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
std::string help_topic = userdata.asString();
-
LLViewerHelp* vhelp = LLViewerHelp::getInstance();
- if (help_topic.empty())
- {
- vhelp->showTopic(vhelp->getTopicFromFocus());
- }
- else
- {
- vhelp->showTopic(help_topic);
- }
-
+ vhelp->showTopic(help_topic);
return true;
}
};
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 4b0dc8f668..a1c3806b27 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -71,15 +71,6 @@
// system libraries
#include <boost/tokenizer.hpp>
-class LLFileEnableSaveAs : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gFloaterView->getFrontmost() && gFloaterView->getFrontmost()->canSaveAs();
- return new_value;
- }
-};
-
class LLFileEnableUpload : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -386,19 +377,6 @@ class LLFileCloseAllWindows : public view_listener_t
}
};
-class LLFileSaveTexture : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- LLFloater* top = gFloaterView->getFrontmost();
- if (top)
- {
- top->saveAs();
- }
- return true;
- }
-};
-
class LLFileTakeSnapshotToDisk : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -1050,10 +1028,10 @@ void init_menu_file()
view_listener_t::addCommit(new LLFileCloseAllWindows(), "File.CloseAllWindows");
view_listener_t::addEnable(new LLFileEnableCloseWindow(), "File.EnableCloseWindow");
view_listener_t::addEnable(new LLFileEnableCloseAllWindows(), "File.EnableCloseAllWindows");
- view_listener_t::addCommit(new LLFileSaveTexture(), "File.SaveTexture");
view_listener_t::addCommit(new LLFileTakeSnapshotToDisk(), "File.TakeSnapshotToDisk");
view_listener_t::addCommit(new LLFileQuit(), "File.Quit");
view_listener_t::addEnable(new LLFileEnableUpload(), "File.EnableUpload");
- view_listener_t::addEnable(new LLFileEnableSaveAs(), "File.EnableSaveAs");
+
+ // "File.SaveTexture" moved to llpanelmaininventory so that it can be properly handled.
}
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 0d29efaedf..a5a40e9c2c 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -2879,7 +2879,8 @@ BOOL LLViewerMediaTexture::findFaces()
}
S32 face_id = -1 ;
- while((face_id = obj->getFaceIndexWithMediaImpl(mMediaImplp, face_id)) > -1)
+ S32 num_faces = obj->mDrawable->getNumFaces() ;
+ while((face_id = obj->getFaceIndexWithMediaImpl(mMediaImplp, face_id)) > -1 && face_id < num_faces)
{
LLFace* facep = obj->mDrawable->getFace(face_id) ;
if(facep)
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 93b0ad4a5b..226d85ec99 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -5994,7 +5994,7 @@ void LLVOAvatar::updateMeshTextures()
else
{
mBakedTextureDatas[i].mIsLoaded = FALSE;
- if ( (i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER) )
+ if ( (baked_img->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
{
baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));
}
@@ -6464,7 +6464,7 @@ void LLVOAvatar::onFirstTEMessageReceived()
LLViewerFetchedTexture* image = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;
mBakedTextureDatas[i].mLastTextureIndex = image->getID();
// If we have more than one texture for the other baked layers, we'll want to call this for them too.
- if ( (i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER) )
+ if ( (image->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
{
image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));
}
@@ -7651,6 +7651,9 @@ void LLVOAvatar::getImpostorValues(LLVector3* extents, LLVector3& angle, F32& di
void LLVOAvatar::idleUpdateRenderCost()
{
+ static const U32 ARC_BODY_PART_COST = 20;
+ static const U32 ARC_LIMIT = 2048;
+
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME))
{
return;
@@ -7667,7 +7670,7 @@ void LLVOAvatar::idleUpdateRenderCost()
{
if (isTextureVisible(tex_index))
{
- cost +=20;
+ cost +=ARC_BODY_PART_COST;
}
}
}
@@ -7687,7 +7690,6 @@ void LLVOAvatar::idleUpdateRenderCost()
const LLDrawable* drawable = attached_object->mDrawable;
if (drawable)
{
- cost += 10;
const LLVOVolume* volume = drawable->getVOVolume();
if (volume)
{
@@ -7698,11 +7700,11 @@ void LLVOAvatar::idleUpdateRenderCost()
}
}
- cost += textures.size() * 5;
+ cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST;
setDebugText(llformat("%d", cost));
- F32 green = 1.f-llclamp(((F32) cost-1024.f)/1024.f, 0.f, 1.f);
- F32 red = llmin((F32) cost/1024.f, 1.f);
+ F32 green = 1.f-llclamp(((F32) cost-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f);
+ F32 red = llmin((F32) cost/(F32)ARC_LIMIT, 1.f);
mText->setColor(LLColor4(red,green,0,1));
}
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 63acba50e7..aa69b46857 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -128,16 +128,8 @@ static int scale_mic_volume(float volume)
static int scale_speaker_volume(float volume)
{
// incoming volume has the range [0.0 ... 1.0], with 0.5 as the default.
- // Map it as follows: 0.0 -> 0, 0.5 -> 62, 1.0 -> 75
-
- volume -= 0.5f; // offset volume to the range [-0.5 ... 0.5], with 0 at the default.
- int scaled_volume = 62; // offset scaled_volume by its default level
- if(volume < 0.0f)
- scaled_volume += ((int)(volume * 124.0f)); // (62 - 0) * 2
- else
- scaled_volume += ((int)(volume * 26.0f)); // (75 - 62) * 2
-
- return scaled_volume;
+ // Map it as follows: 0.0 -> 0, 0.5 -> 50, 1.0 -> 100
+ return (int)(volume * 100.0f);
}
class LLViewerVoiceAccountProvisionResponder :
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index edfe0173f8..92e79a004d 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -125,7 +125,7 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient>
void tuningCaptureStartSendMessage(int duration);
void tuningCaptureStopSendMessage();
- void tuningSetMicVolume(float volume);
+ void tuningSetMicVolume(float volume=0.5f);
void tuningSetSpeakerVolume(float volume);
float tuningGetEnergy(void);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index cf61994fea..08e12f4ad9 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -92,7 +92,7 @@ static LLFastTimer::DeclareTimer FTM_GEN_VOLUME("Generate Volumes");
class LLMediaDataClientObjectImpl : public LLMediaDataClientObject
{
public:
- LLMediaDataClientObjectImpl(LLVOVolume *obj) : mObject(obj) {}
+ LLMediaDataClientObjectImpl(LLVOVolume *obj, bool isNew) : mObject(obj), mNew(isNew) {}
LLMediaDataClientObjectImpl() { mObject = NULL; }
virtual U8 getMediaDataCount() const
@@ -128,14 +128,19 @@ public:
virtual bool hasMedia() const
{ return mObject->hasMedia(); }
- virtual void updateObjectMediaData(LLSD const &data)
- { mObject->updateObjectMediaData(data); }
-
- virtual F64 getDistanceFromAvatar() const
- { return mObject->getRenderPosition().length(); }
+ virtual void updateObjectMediaData(LLSD const &data, const std::string &version_string)
+ { mObject->updateObjectMediaData(data, version_string); }
- virtual F64 getTotalMediaInterest() const
- { return mObject->getTotalMediaInterest(); }
+ virtual F64 getMediaInterest() const
+ {
+ F64 tmp = mObject->getTotalMediaInterest();
+ return (tmp < 0.0) ? mObject->getPixelArea() : tmp;
+ }
+ virtual bool isInterestingEnough() const
+ {
+ // TODO: use performance manager to control this
+ return true;
+ }
virtual std::string getCapabilityUrl(const std::string &name) const
{ return mObject->getRegion()->getCapability(name); }
@@ -143,8 +148,15 @@ public:
virtual bool isDead() const
{ return mObject->isDead(); }
+ virtual U32 getMediaVersion() const
+ { return LLTextureEntry::getVersionFromMediaVersionString(mObject->getMediaURL()); }
+
+ virtual bool isNew() const
+ { return mNew; }
+
private:
LLPointer<LLVOVolume> mObject;
+ bool mNew;
};
@@ -165,6 +177,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
mSpotLightPriority = 0.f;
mMediaImplList.resize(getNumTEs());
+ mLastFetchedMediaVersion = -1;
}
LLVOVolume::~LLVOVolume()
@@ -190,7 +203,9 @@ void LLVOVolume::markDead()
{
if (!mDead)
{
- // TODO: tell LLMediaDataClient to remove this object from its queue
+ LLMediaDataClientObject::ptr_t obj = new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this), false);
+ sObjectMediaClient->removeFromQueue(obj);
+ sObjectMediaNavigateClient->removeFromQueue(obj);
// Detach all media impls from this object
for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
@@ -210,8 +225,12 @@ void LLVOVolume::initClass()
const F32 queue_timer_delay = gSavedSettings.getF32("PrimMediaRequestQueueDelay");
const F32 retry_timer_delay = gSavedSettings.getF32("PrimMediaRetryTimerDelay");
const U32 max_retries = gSavedSettings.getU32("PrimMediaMaxRetries");
- sObjectMediaClient = new LLObjectMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries);
- sObjectMediaNavigateClient = new LLObjectMediaNavigateClient(queue_timer_delay, retry_timer_delay, max_retries);
+ const U32 max_sorted_queue_size = gSavedSettings.getU32("PrimMediaMaxSortedQueueSize");
+ const U32 max_round_robin_queue_size = gSavedSettings.getU32("PrimMediaMaxRoundRobinQueueSize");
+ sObjectMediaClient = new LLObjectMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries,
+ max_sorted_queue_size, max_round_robin_queue_size);
+ sObjectMediaNavigateClient = new LLObjectMediaNavigateClient(queue_timer_delay, retry_timer_delay,
+ max_retries, max_sorted_queue_size, max_round_robin_queue_size);
}
// static
@@ -406,7 +425,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
// If the media changed at all, request new media data
LL_DEBUGS("MediaOnAPrim") << "Media update: " << getID() << ": retval=" << retval << " Media URL: " <<
((mMedia) ? mMedia->mMediaURL : std::string("")) << LL_ENDL;
- requestMediaDataUpdate();
+ requestMediaDataUpdate(retval & MEDIA_FLAGS_CHANGED);
}
else {
LL_INFOS("MediaOnAPrim") << "Ignoring media update for: " << getID() << " Media URL: " <<
@@ -1698,16 +1717,16 @@ LLVector3 LLVOVolume::getApproximateFaceNormal(U8 face_id)
return result;
}
-void LLVOVolume::requestMediaDataUpdate()
+void LLVOVolume::requestMediaDataUpdate(bool isNew)
{
- sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this));
+ sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this, isNew));
}
bool LLVOVolume::isMediaDataBeingFetched() const
{
// I know what I'm doing by const_casting this away: this is just
// a wrapper class that is only going to do a lookup.
- return sObjectMediaClient->isInQueue(new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this)));
+ return sObjectMediaClient->isInQueue(new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this), false));
}
void LLVOVolume::cleanUpMediaImpls()
@@ -1725,18 +1744,25 @@ void LLVOVolume::cleanUpMediaImpls()
}
}
-void LLVOVolume::updateObjectMediaData(const LLSD &media_data_array)
+void LLVOVolume::updateObjectMediaData(const LLSD &media_data_array, const std::string &media_version)
{
// media_data_array is an array of media entry maps
+ // media_version is the version string in the response.
+ U32 fetched_version = LLTextureEntry::getVersionFromMediaVersionString(media_version);
- //llinfos << "updating:" << this->getID() << " " << ll_pretty_print_sd(media_data_array) << llendl;
-
- LLSD::array_const_iterator iter = media_data_array.beginArray();
- LLSD::array_const_iterator end = media_data_array.endArray();
- U8 texture_index = 0;
- for (; iter != end; ++iter, ++texture_index)
+ // Only update it if it is newer!
+ if ( (S32)fetched_version > mLastFetchedMediaVersion)
{
- syncMediaData(texture_index, *iter, false/*merge*/, false/*ignore_agent*/);
+ mLastFetchedMediaVersion = fetched_version;
+ //llinfos << "updating:" << this->getID() << " " << ll_pretty_print_sd(media_data_array) << llendl;
+
+ LLSD::array_const_iterator iter = media_data_array.beginArray();
+ LLSD::array_const_iterator end = media_data_array.endArray();
+ U8 texture_index = 0;
+ for (; iter != end; ++iter, ++texture_index)
+ {
+ syncMediaData(texture_index, *iter, false/*merge*/, false/*ignore_agent*/);
+ }
}
}
@@ -1904,7 +1930,7 @@ void LLVOVolume::mediaNavigated(LLViewerMediaImpl *impl, LLPluginClassMedia* plu
llinfos << "broadcasting navigate with URI " << new_location << llendl;
- sObjectMediaNavigateClient->navigate(new LLMediaDataClientObjectImpl(this), face_index, new_location);
+ sObjectMediaNavigateClient->navigate(new LLMediaDataClientObjectImpl(this, false), face_index, new_location);
}
}
@@ -1968,7 +1994,7 @@ void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin,
void LLVOVolume::sendMediaDataUpdate()
{
- sObjectMediaClient->updateMedia(new LLMediaDataClientObjectImpl(this));
+ sObjectMediaClient->updateMedia(new LLMediaDataClientObjectImpl(this, false));
}
void LLVOVolume::removeMediaImpl(S32 texture_index)
@@ -2063,7 +2089,7 @@ viewer_media_t LLVOVolume::getMediaImpl(U8 face_id) const
F64 LLVOVolume::getTotalMediaInterest() const
{
- F64 interest = (F64)0.0;
+ F64 interest = (F64)-1.0; // means not interested;
int i = 0;
const int end = getNumTEs();
for ( ; i < end; ++i)
@@ -2071,6 +2097,7 @@ F64 LLVOVolume::getTotalMediaInterest() const
const viewer_media_t &impl = getMediaImpl(i);
if (!impl.isNull())
{
+ if (interest == (F64)-1.0) interest = (F64)0.0;
interest += impl->getInterest();
}
}
@@ -2587,7 +2614,22 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const
// children, and cost should only be increased for unique textures -Nyx
U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const
{
- U32 shame = 0;
+ // base cost of each prim should be 10 points
+ static const U32 ARC_PRIM_COST = 10;
+ // per-prim costs
+ static const U32 ARC_INVISI_COST = 1;
+ static const U32 ARC_SHINY_COST = 1;
+ static const U32 ARC_GLOW_COST = 1;
+ static const U32 ARC_FLEXI_COST = 8;
+ static const U32 ARC_PARTICLE_COST = 16;
+ static const U32 ARC_BUMP_COST = 4;
+
+ // per-face costs
+ static const U32 ARC_PLANAR_COST = 1;
+ static const U32 ARC_ANIM_TEX_COST = 4;
+ static const U32 ARC_ALPHA_COST = 4;
+
+ U32 shame = ARC_PRIM_COST;
U32 invisi = 0;
U32 shiny = 0;
@@ -2663,7 +2705,17 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const
}
}
- shame += invisi + shiny + glow + alpha*4 + flexi*8 + animtex*4 + particles*16+bump*4+scale+planar;
+
+ shame += invisi * ARC_INVISI_COST;
+ shame += shiny * ARC_SHINY_COST;
+ shame += glow * ARC_GLOW_COST;
+ shame += alpha * ARC_ALPHA_COST;
+ shame += flexi * ARC_FLEXI_COST;
+ shame += animtex * ARC_ANIM_TEX_COST;
+ shame += particles * ARC_PARTICLE_COST;
+ shame += bump * ARC_BUMP_COST;
+ shame += planar * ARC_PLANAR_COST;
+ shame += scale;
LLViewerObject::const_child_list_t& child_list = getChildren();
for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 06e214b41e..7433404942 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -238,7 +238,7 @@ public:
// Update this object's media data with the given media data array
// (typically this is only called upon a response from a server request)
- void updateObjectMediaData(const LLSD &media_data_array);
+ void updateObjectMediaData(const LLSD &media_data_array, const std::string &media_version);
// Bounce back media at the given index to its current URL (or home URL, if current URL is empty)
void mediaNavigateBounceBack(U8 texture_index);
@@ -270,13 +270,16 @@ public:
// Returns 'true' iff the media data for this object is in flight
bool isMediaDataBeingFetched() const;
+ // Returns the "last fetched" media version, or -1 if not fetched yet
+ S32 getLastFetchedMediaVersion() const { return mLastFetchedMediaVersion; }
+
protected:
S32 computeLODDetail(F32 distance, F32 radius);
BOOL calcLOD();
LLFace* addFace(S32 face_index);
void updateTEData();
- void requestMediaDataUpdate();
+ void requestMediaDataUpdate(bool isNew);
void cleanUpMediaImpls();
void addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) ;
void removeMediaImpl(S32 texture_index) ;
@@ -300,6 +303,7 @@ private:
LLPointer<LLViewerFetchedTexture> mSculptTexture;
LLPointer<LLViewerFetchedTexture> mLightTexture;
media_list_t mMediaImplList;
+ S32 mLastFetchedMediaVersion; // as fetched from the server, starts as -1
// statics
public:
@@ -310,6 +314,8 @@ public:
static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;
static LLPointer<LLObjectMediaNavigateClient> sObjectMediaNavigateClient;
+ static const U32 ARC_TEXTURE_COST = 5;
+
protected:
static S32 sNumLODChanges;
diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp
index c8cc6a3d8e..697fefee3a 100644
--- a/indra/newview/llwaterparammanager.cpp
+++ b/indra/newview/llwaterparammanager.cpp
@@ -91,7 +91,7 @@ LLWaterParamManager::~LLWaterParamManager()
void LLWaterParamManager::loadAllPresets(const std::string& file_name)
{
std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", ""));
- LL_INFOS2("AppInit", "Shaders") << "Loading Default water settings from " << path_name << LL_ENDL;
+ LL_DEBUGS2("AppInit", "Shaders") << "Loading Default water settings from " << path_name << LL_ENDL;
bool found = true;
while(found)
@@ -117,7 +117,7 @@ void LLWaterParamManager::loadAllPresets(const std::string& file_name)
// And repeat for user presets, note the user presets will modify any system presets already loaded
std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", ""));
- LL_INFOS2("AppInit", "Shaders") << "Loading User water settings from " << path_name2 << LL_ENDL;
+ LL_DEBUGS2("AppInit", "Shaders") << "Loading User water settings from " << path_name2 << LL_ENDL;
found = true;
while(found)
@@ -152,7 +152,7 @@ void LLWaterParamManager::loadPreset(const std::string & name,bool propagate)
escaped_filename += ".xml";
std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", escaped_filename));
- llinfos << "Loading water settings from " << pathName << llendl;
+ LL_DEBUGS2("AppInit", "Shaders") << "Loading water settings from " << pathName << LL_ENDL;
llifstream presetsXML;
presetsXML.open(pathName.c_str());
@@ -161,7 +161,7 @@ void LLWaterParamManager::loadPreset(const std::string & name,bool propagate)
if(!presetsXML)
{
pathName=gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", escaped_filename);
- llinfos << "Loading User water setting from " << pathName << llendl;
+ LL_DEBUGS2("AppInit", "Shaders") << "Loading User water setting from " << pathName << LL_ENDL;
presetsXML.clear();
presetsXML.open(pathName.c_str());
}
diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp
index c6fd35c142..c3a70705cf 100644
--- a/indra/newview/llwlparammanager.cpp
+++ b/indra/newview/llwlparammanager.cpp
@@ -109,7 +109,7 @@ LLWLParamManager::~LLWLParamManager()
void LLWLParamManager::loadPresets(const std::string& file_name)
{
std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", ""));
- LL_INFOS2("AppInit", "Shaders") << "Loading Default WindLight settings from " << path_name << LL_ENDL;
+ LL_DEBUGS2("AppInit", "Shaders") << "Loading Default WindLight settings from " << path_name << LL_ENDL;
bool found = true;
while(found)
@@ -135,7 +135,7 @@ void LLWLParamManager::loadPresets(const std::string& file_name)
// And repeat for user presets, note the user presets will modify any system presets already loaded
std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", ""));
- LL_INFOS2("AppInit", "Shaders") << "Loading User WindLight settings from " << path_name2 << LL_ENDL;
+ LL_DEBUGS2("AppInit", "Shaders") << "Loading User WindLight settings from " << path_name2 << LL_ENDL;
found = true;
while(found)
@@ -196,7 +196,7 @@ void LLWLParamManager::loadPreset(const std::string & name,bool propagate)
escaped_filename += ".xml";
std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", escaped_filename));
- //llinfos << "Loading WindLight sky setting from " << pathName << llendl;
+ LL_DEBUGS2("AppInit", "Shaders") << "Loading WindLight sky setting from " << pathName << LL_ENDL;
llifstream presetsXML;
presetsXML.open(pathName.c_str());
@@ -205,7 +205,7 @@ void LLWLParamManager::loadPreset(const std::string & name,bool propagate)
if(!presetsXML)
{
pathName=gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", escaped_filename);
- llinfos << "Loading User WindLight sky setting from " << pathName << llendl;
+ LL_DEBUGS2("AppInit", "Shaders") << "Loading User WindLight sky setting from " << pathName << LL_ENDL;
presetsXML.clear();
presetsXML.open(pathName.c_str());
}
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index d1fd42bdd9..10b72144e7 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -4,7 +4,6 @@
height="420"
layout="topleft"
name="floaterland"
- help_topic="floaterland"
save_rect="true"
title="ABOUT LAND"
width="490">
@@ -1857,6 +1856,10 @@ Select the thumbnail to choose a different texture.
top="0"
help_topic="land_access_tab"
name="land_access_panel">
+ <panel.string
+ name="access_estate_defined">
+ (Defined by the Estate)
+ </panel.string>
<panel.string
name="estate_override">
One or more of these options is set at the estate level
@@ -1877,7 +1880,7 @@ Select the thumbnail to choose a different texture.
<check_box
follows="top|left"
height="16"
- label="Allow Public Access"
+ label="Allow Public Access [MATURITY]"
layout="topleft"
left_delta="0"
name="public_access"
@@ -1893,12 +1896,12 @@ Select the thumbnail to choose a different texture.
name="Only Allow"
top="49"
width="278">
- Block Access By:
+ Restrict Access to Residents verified by:
</text>
<check_box
follows="top|left"
height="16"
- label="Residents who have not given payment info to Linden Lab"
+ label="Payment Information on File [ESTATE_PAYMENT_LIMIT]"
layout="topleft"
left_delta="0"
name="limit_payment"
@@ -1908,7 +1911,7 @@ Select the thumbnail to choose a different texture.
<check_box
follows="top|left"
height="16"
- label="Residents who are not age verified adults"
+ label="Age Verification [ESTATE_AGE_LIMIT]"
layout="topleft"
left_delta="0"
name="limit_age_verified"
diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
index 75711cdf89..26b003cafe 100644
--- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
@@ -222,7 +222,7 @@
width="300"
height="30"
name="currency_links">
- [http://www.secondlife.com/ payment method] | [http://www.secondlife.com/ currency] | [http://www.secondlife.com exchange rate]
+ [http://www.secondlife.com/ payment method] | [http://www.secondlife.com/ currency] | [http://www.secondlife.com/my/account/exchange_rates.php exchange rate]
</text>
<text
type="string"
diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml
index 15655a920e..2f26e5d0c1 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences.xml
@@ -7,7 +7,6 @@
height="460"
layout="topleft"
name="Preferences"
- help_topic="preferences"
single_instance="true"
title="PREFERENCES"
width="620">
diff --git a/indra/newview/skins/default/xui/en/floater_preview_texture.xml b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
index 52a19ac6b3..602a18ea56 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
@@ -61,7 +61,16 @@
name="Discard"
top_delta="0"
width="100" />
- <text
+ <button
+ follows="left|bottom"
+ height="22"
+ label="Save As"
+ layout="topleft"
+ left_pad="5"
+ name="save_tex_btn"
+ top_delta="0"
+ width="100" />
+ <text
type="string"
length="1"
follows="left|bottom"
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index e3851de8e7..5e68850e30 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -2669,16 +2669,15 @@ even though the user gets a free copy.
top_pad="5"
name="media_tex"
width="260">
- Media URL
+ Media
</text>
- <line_editor
+ <text
follows="left|top|right"
height="18"
layout="topleft"
left="10"
read_only="true"
name="media_info"
- select_on_focus="true"
width="180" />
<button
follows="top|left"
diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
index 1ebc51f504..c1a211967c 100644
--- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
@@ -106,26 +106,6 @@
width="24" />
</layout_panel>
<layout_panel
- layout="topleft"
- name="volume_slider_panel"
- top="0"
- user_resize="false"
- width="138">
- <slider_bar
- control_name="AudioLevelMic"
- follows="left|right|top"
- height="24"
- increment="0.05"
- layout="topleft"
- left="0"
- max_val="2"
- name="volume_slider_bar"
- tool_tip="Master Volume"
- top="0"
- value="0.75"
- width="138" />
- </layout_panel>
- <layout_panel
auto_resize="false"
layout="topleft"
min_width="100"
diff --git a/indra/newview/skins/default/xui/en/floater_water.xml b/indra/newview/skins/default/xui/en/floater_water.xml
index 89492d8abc..439d68282f 100644
--- a/indra/newview/skins/default/xui/en/floater_water.xml
+++ b/indra/newview/skins/default/xui/en/floater_water.xml
@@ -4,7 +4,6 @@
height="240"
layout="topleft"
name="Water Floater"
- help_topic="water_floater"
save_rect="true"
title="ADVANCED WATER EDITOR"
width="700">
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index a36bfb8ec1..660e3858ac 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -451,6 +451,14 @@
<menu_item_separator
layout="topleft" />
<menu_item_call
+ label="Remove Link"
+ layout="topleft"
+ name="Remove Link">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="delete" />
+ </menu_item_call>
+ <menu_item_call
label="Delete"
layout="topleft"
name="Delete">
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index 9b439c16e0..53be40d7fd 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -45,7 +45,8 @@
name="Second Life Help"
shortcut="F1">
<menu_item_call.on_click
- function="ShowHelp" />
+ function="ShowHelp"
+ parameter="f1_help" />
</menu_item_call>
<menu_item_separator />
<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 861b0de2cf..0891afaf76 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1064,7 +1064,8 @@
name="Second Life Help"
shortcut="F1">
<menu_item_call.on_click
- function="ShowHelp" />
+ function="ShowHelp"
+ parameter="f1_help" />
</menu_item_call>
<menu_item_call
label="Tutorial"
@@ -1200,15 +1201,6 @@
function="ToggleControl"
parameter="CompressSnapshotsToDisk" />
</menu_item_check>
- <menu_item_call
- label="Save Texture As"
- layout="topleft"
- name="Save Texture As">
- <menu_item_call.on_click
- function="File.SaveTexture" />
- <menu_item_call.on_enable
- function="File.EnableSaveAs" />
- </menu_item_call>
<menu_item_separator
layout="topleft" />
<menu
diff --git a/indra/newview/skins/default/xui/en/mime_types_linux.xml b/indra/newview/skins/default/xui/en/mime_types_linux.xml
new file mode 100644
index 0000000000..05cd850725
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/mime_types_linux.xml
@@ -0,0 +1,442 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<mimetypes name="default">
+ <defaultlabel>
+ (Unknown)
+ </defaultlabel>
+ <defaultwidget>
+ none
+ </defaultwidget>
+ <defaultimpl>
+ media_plugin_webkit
+ </defaultimpl>
+ <widgetset name="web">
+ <label name="web_label">
+ Web Content
+ </label>
+ <icon>
+ icn_media_web.tga
+ </icon>
+ <default_type>
+ text/html
+ </default_type>
+ <tooltip name="web_tooltip">
+ This location has Web content
+ </tooltip>
+ <playtip name="web_playtip">
+ Show Web content
+ </playtip>
+ <allow_resize>
+ true
+ </allow_resize>
+ <allow_looping>
+ false
+ </allow_looping>
+ </widgetset>
+ <widgetset name="movie">
+ <label name="movie_label">
+ Movie
+ </label>
+ <default_type>
+ video/*
+ </default_type>
+ <icon>
+ icn_media_movie.tga
+ </icon>
+ <tooltip name="movie_tooltip">
+ There is a movie to play here
+ </tooltip>
+ <playtip name="movie_playtip">
+ Play movie
+ </playtip>
+ <allow_resize>
+ false
+ </allow_resize>
+ <allow_looping>
+ true
+ </allow_looping>
+ </widgetset>
+ <widgetset name="image">
+ <label name="image_label">
+ Image
+ </label>
+ <icon>
+ icn_media_web.tga
+ </icon>
+ <default_type>
+ image/*
+ </default_type>
+ <tooltip name="image_tooltip">
+ There is an image at this location
+ </tooltip>
+ <playtip name="image_playtip">
+ View this location&apos;s image
+ </playtip>
+ <allow_resize>
+ false
+ </allow_resize>
+ <allow_looping>
+ false
+ </allow_looping>
+ </widgetset>
+ <widgetset name="audio">
+ <label name="audio_label">
+ Audio
+ </label>
+ <icon>
+ icn_media_web.tga
+ </icon>
+ <default_type>
+ audio/*
+ </default_type>
+ <tooltip name="audio_tooltip">
+ There is audio at this location
+ </tooltip>
+ <playtip name="audio_playtip">
+ Play this location&apos;s audio
+ </playtip>
+ <allow_resize>
+ false
+ </allow_resize>
+ <allow_looping>
+ true
+ </allow_looping>
+ </widgetset>
+ <scheme name="rtsp">
+ <label name="rtsp_label">
+ Real Time Streaming
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_gstreamer
+ </impl>
+ </scheme>
+ <mimetype name="blank">
+ <label name="blank_label">
+ - None -
+ </label>
+ <widgettype>
+ none
+ </widgettype>
+ <impl>
+ media_plugin_gstreamer
+ </impl>
+ </mimetype>
+ <mimetype name="none/none">
+ <label name="none/none_label">
+ - None -
+ </label>
+ <widgettype>
+ none
+ </widgettype>
+ </mimetype>
+ <mimetype name="audio/*">
+ <label name="audio2_label">
+ Audio
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ </mimetype>
+ <mimetype name="video/*">
+ <label name="video2_label">
+ Video
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ </mimetype>
+ <mimetype name="image/*">
+ <label name="image2_label">
+ Image
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ </mimetype>
+ <mimetype menu="1" name="video/vnd.secondlife.qt.legacy">
+ <label name="vnd.secondlife.qt.legacy_label">
+ Movie (QuickTime)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_gstreamer
+ </impl>
+ </mimetype>
+ <mimetype name="application/javascript">
+ <label name="application/javascript_label">
+ Javascript
+ </label>
+ <widgettype>
+ web
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/ogg">
+ <label name="application/ogg_label">
+ Ogg Audio/Video
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/pdf">
+ <label name="application/pdf_label">
+ PDF Document
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/postscript">
+ <label name="application/postscript_label">
+ Postscript Document
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/rtf">
+ <label name="application/rtf_label">
+ Rich Text (RTF)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/smil">
+ <label name="application/smil_label">
+ Synchronized Multimedia Integration Language (SMIL)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/xhtml+xml">
+ <label name="application/xhtml+xml_label">
+ Web Page (XHTML)
+ </label>
+ <widgettype>
+ web
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/x-director">
+ <label name="application/x-director_label">
+ Macromedia Director
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ </mimetype>
+ <mimetype name="audio/mid">
+ <label name="audio/mid_label">
+ Audio (MIDI)
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ <impl>
+ media_plugin_gstreamer
+ </impl>
+ </mimetype>
+ <mimetype name="audio/mpeg">
+ <label name="audio/mpeg_label">
+ Audio (MP3)
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ <impl>
+ media_plugin_gstreamer
+ </impl>
+ </mimetype>
+ <mimetype name="audio/x-aiff">
+ <label name="audio/x-aiff_label">
+ Audio (AIFF)
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ <impl>
+ media_plugin_gstreamer
+ </impl>
+ </mimetype>
+ <mimetype name="audio/x-wav">
+ <label name="audio/x-wav_label">
+ Audio (WAV)
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ <impl>
+ media_plugin_gstreamer
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="image/bmp">
+ <label name="image/bmp_label">
+ Image (BMP)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="image/gif">
+ <label name="image/gif_label">
+ Image (GIF)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="image/jpeg">
+ <label name="image/jpeg_label">
+ Image (JPEG)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="image/png">
+ <label name="image/png_label">
+ Image (PNG)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype name="image/svg+xml">
+ <label name="image/svg+xml_label">
+ Image (SVG)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="image/tiff">
+ <label name="image/tiff_label">
+ Image (TIFF)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="text/html">
+ <label name="text/html_label">
+ Web Page
+ </label>
+ <widgettype>
+ web
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="text/plain">
+ <label name="text/plain_label">
+ Text
+ </label>
+ <widgettype>
+ text
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype name="text/xml">
+ <label name="text/xml_label">
+ XML
+ </label>
+ <widgettype>
+ text
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="video/mpeg">
+ <label name="video/mpeg_label">
+ Movie (MPEG)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_gstreamer
+ </impl>
+ </mimetype>
+ <mimetype name="video/mp4">
+ <label name="video/mp4_label">
+ Movie (MP4)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_gstreamer
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="video/quicktime">
+ <label name="video/quicktime_label">
+ Movie (QuickTime)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_gstreamer
+ </impl>
+ </mimetype>
+ <mimetype name="video/x-ms-asf">
+ <label name="video/x-ms-asf_label">
+ Movie (Windows Media ASF)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_gstreamer
+ </impl>
+ </mimetype>
+ <mimetype name="video/x-ms-wmv">
+ <label name="video/x-ms-wmv_label">
+ Movie (Windows Media WMV)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_gstreamer
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="video/x-msvideo">
+ <label name="video/x-msvideo_label">
+ Movie (AVI)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_gstreamer
+ </impl>
+ </mimetype>
+</mimetypes>
diff --git a/indra/newview/skins/default/xui/en/mime_types_mac.xml b/indra/newview/skins/default/xui/en/mime_types_mac.xml
new file mode 100644
index 0000000000..76c0d027f3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/mime_types_mac.xml
@@ -0,0 +1,442 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<mimetypes name="default">
+ <defaultlabel>
+ (Unknown)
+ </defaultlabel>
+ <defaultwidget>
+ none
+ </defaultwidget>
+ <defaultimpl>
+ media_plugin_webkit
+ </defaultimpl>
+ <widgetset name="web">
+ <label name="web_label">
+ Web Content
+ </label>
+ <icon>
+ icn_media_web.tga
+ </icon>
+ <default_type>
+ text/html
+ </default_type>
+ <tooltip name="web_tooltip">
+ This location has Web content
+ </tooltip>
+ <playtip name="web_playtip">
+ Show Web content
+ </playtip>
+ <allow_resize>
+ true
+ </allow_resize>
+ <allow_looping>
+ false
+ </allow_looping>
+ </widgetset>
+ <widgetset name="movie">
+ <label name="movie_label">
+ Movie
+ </label>
+ <default_type>
+ video/*
+ </default_type>
+ <icon>
+ icn_media_movie.tga
+ </icon>
+ <tooltip name="movie_tooltip">
+ There is a movie to play here
+ </tooltip>
+ <playtip name="movie_playtip">
+ Play movie
+ </playtip>
+ <allow_resize>
+ false
+ </allow_resize>
+ <allow_looping>
+ true
+ </allow_looping>
+ </widgetset>
+ <widgetset name="image">
+ <label name="image_label">
+ Image
+ </label>
+ <icon>
+ icn_media_web.tga
+ </icon>
+ <default_type>
+ image/*
+ </default_type>
+ <tooltip name="image_tooltip">
+ There is an image at this location
+ </tooltip>
+ <playtip name="image_playtip">
+ View this location&apos;s image
+ </playtip>
+ <allow_resize>
+ false
+ </allow_resize>
+ <allow_looping>
+ false
+ </allow_looping>
+ </widgetset>
+ <widgetset name="audio">
+ <label name="audio_label">
+ Audio
+ </label>
+ <icon>
+ icn_media_web.tga
+ </icon>
+ <default_type>
+ audio/*
+ </default_type>
+ <tooltip name="audio_tooltip">
+ There is audio at this location
+ </tooltip>
+ <playtip name="audio_playtip">
+ Play this location&apos;s audio
+ </playtip>
+ <allow_resize>
+ false
+ </allow_resize>
+ <allow_looping>
+ true
+ </allow_looping>
+ </widgetset>
+ <scheme name="rtsp">
+ <label name="rtsp_label">
+ Real Time Streaming
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </scheme>
+ <mimetype name="blank">
+ <label name="blank_label">
+ - None -
+ </label>
+ <widgettype>
+ none
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="none/none">
+ <label name="none/none_label">
+ - None -
+ </label>
+ <widgettype>
+ none
+ </widgettype>
+ </mimetype>
+ <mimetype name="audio/*">
+ <label name="audio2_label">
+ Audio
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ </mimetype>
+ <mimetype name="video/*">
+ <label name="video2_label">
+ Video
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ </mimetype>
+ <mimetype name="image/*">
+ <label name="image2_label">
+ Image
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ </mimetype>
+ <mimetype menu="1" name="video/vnd.secondlife.qt.legacy">
+ <label name="vnd.secondlife.qt.legacy_label">
+ Movie (QuickTime)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="application/javascript">
+ <label name="application/javascript_label">
+ Javascript
+ </label>
+ <widgettype>
+ web
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/ogg">
+ <label name="application/ogg_label">
+ Ogg Audio/Video
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/pdf">
+ <label name="application/pdf_label">
+ PDF Document
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/postscript">
+ <label name="application/postscript_label">
+ Postscript Document
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/rtf">
+ <label name="application/rtf_label">
+ Rich Text (RTF)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/smil">
+ <label name="application/smil_label">
+ Synchronized Multimedia Integration Language (SMIL)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/xhtml+xml">
+ <label name="application/xhtml+xml_label">
+ Web Page (XHTML)
+ </label>
+ <widgettype>
+ web
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/x-director">
+ <label name="application/x-director_label">
+ Macromedia Director
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ </mimetype>
+ <mimetype name="audio/mid">
+ <label name="audio/mid_label">
+ Audio (MIDI)
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="audio/mpeg">
+ <label name="audio/mpeg_label">
+ Audio (MP3)
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="audio/x-aiff">
+ <label name="audio/x-aiff_label">
+ Audio (AIFF)
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="audio/x-wav">
+ <label name="audio/x-wav_label">
+ Audio (WAV)
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="image/bmp">
+ <label name="image/bmp_label">
+ Image (BMP)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="image/gif">
+ <label name="image/gif_label">
+ Image (GIF)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="image/jpeg">
+ <label name="image/jpeg_label">
+ Image (JPEG)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="image/png">
+ <label name="image/png_label">
+ Image (PNG)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype name="image/svg+xml">
+ <label name="image/svg+xml_label">
+ Image (SVG)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="image/tiff">
+ <label name="image/tiff_label">
+ Image (TIFF)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="text/html">
+ <label name="text/html_label">
+ Web Page
+ </label>
+ <widgettype>
+ web
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="text/plain">
+ <label name="text/plain_label">
+ Text
+ </label>
+ <widgettype>
+ text
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype name="text/xml">
+ <label name="text/xml_label">
+ XML
+ </label>
+ <widgettype>
+ text
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="video/mpeg">
+ <label name="video/mpeg_label">
+ Movie (MPEG)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="video/mp4">
+ <label name="video/mp4_label">
+ Movie (MP4)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="video/quicktime">
+ <label name="video/quicktime_label">
+ Movie (QuickTime)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="video/x-ms-asf">
+ <label name="video/x-ms-asf_label">
+ Movie (Windows Media ASF)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="video/x-ms-wmv">
+ <label name="video/x-ms-wmv_label">
+ Movie (Windows Media WMV)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="video/x-msvideo">
+ <label name="video/x-msvideo_label">
+ Movie (AVI)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+</mimetypes>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 22896d59c3..4645bfea74 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -579,7 +579,7 @@ Scripts must be allowed to run for weapons to work.
type="alertmodal">
Multiple faces are currently selected.
If you continue this action, separate instances of media will be set on multiple faces of the object.
-To place the media on only one face, choose Select Texture and click on the desired face of that object then click Add.
+To place the media on only one face, choose Select Face and click on the desired face of that object then click Add.
<usetemplate
ignoretext="Media will be set on multiple selected faces"
name="okcancelignore"
@@ -3539,6 +3539,8 @@ Type a short announcement which will be sent to everyone in this region.
type="alertmodal">
The maturity rating for this region has been updated.
It may take some time for the change to be reflected on the map.
+
+To enter Adult regions, residents must be Account Verified, either by age-verification or payment-verification.
</notification>
<notification
@@ -3799,21 +3801,6 @@ All reported abuses are investigated and resolved. You can view the resolution b
<notification
icon="alertmodal.tga"
- name="HelpReportAbuseEmailEO"
- type="alertmodal">
-IMPORTANT: This report will go to the owner of the region you are currently in and not to Linden Lab.
-
-As a service to residents and visitors, the owner of the region you are in has elected to receive and resolve all reports originating in this region. Linden Lab will not investigate reports you file from this location.
-
-The region owner will resolve reports based on the local rules of this region as outlined in the estate Covenant.
-(View covenants by going to the World menu and selecting About Land.)
-
-The resolution of this report applies only to this Region. Residents&apos; access to other areas of [SECOND_LIFE] will not be affected by the outcome of this report. Only Linden Lab can restrict access to the entirety of [SECOND_LIFE].
- <unique/>
- </notification>
-
- <notification
- icon="alertmodal.tga"
name="HelpReportAbuseSelectCategory"
type="alertmodal">
Please select a category for this abuse report.
diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
index b82a435b41..24c40b32fb 100644
--- a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
@@ -71,7 +71,7 @@
name="current_url_label">
Current URL:
</text>
- <line_editor
+ <text
bottom_delta="-20"
enabled="false"
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
index 8aba8b9dd1..b5c6b637e5 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
@@ -92,11 +92,7 @@
name="(Japanese)"
value="ja" />
- <combo_box.item
- enabled="true"
- label="Test Language"
- name="TestLanguage"
- value="test" />
+
</combo_box>
<text
type="string"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
index 102a53ad90..5332007baf 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
@@ -399,31 +399,6 @@
name="voice_input_device"
top_pad="0"
width="200" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- left="165"
- name="My volume label"
- top_pad="10"
- width="200">
- My volume:
- </text>
- <slider_bar
- control_name="AudioLevelMic"
- follows="left|top"
- height="17"
- increment="0.05"
- initial_value="1.0"
- layout="topleft"
- left="160"
- max_val="2"
- name="mic_volume_slider"
- tool_tip="Change the volume using this slider"
- top_pad="0"
- width="220" />
<text
type="string"
text_color="EmphasisColor"
@@ -433,7 +408,7 @@
layout="topleft"
left_pad="5"
name="wait_text"
- top_delta="0"
+ top_delta="5"
width="110">
Please wait
</text>
@@ -442,7 +417,7 @@
layout="topleft"
left_delta="0"
name="bar0"
- top_delta="5"
+ top_delta="-5"
width="20" />
<locate
height="20"
@@ -472,23 +447,13 @@
name="bar4"
top_delta="0"
width="20" />
- <!-- <text
- type="string"
- height="37"
- left="30"
- name="voice_intro_text1"
- top_pad="-4"
- width="410"
- word_wrap="true">
- Adjust the slider to control how loud you sound to other people. To test your volume, simply speak into your microphone
- </text>-->
<icon
height="18"
image_name="Parcel_Voice_Light"
left="80"
name="speaker_icon"
mouse_opaque="false"
- top_pad="-8"
+ top_pad="4"
visible="true"
width="22" />
<text
diff --git a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml
index e21de31498..b4f72a48bc 100644
--- a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml
@@ -380,7 +380,7 @@
image_selected="AudioMute_Off"
image_unselected="Audio_Off"
hover_glow_amount="0.15"
- name="media_volume_button"
+ name="media_mute_button"
height="22"
is_toggle="true"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_region_covenant.xml b/indra/newview/skins/default/xui/en/panel_region_covenant.xml
index 75d7d85505..ff55090f16 100644
--- a/indra/newview/skins/default/xui/en/panel_region_covenant.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_covenant.xml
@@ -3,6 +3,7 @@
border="true"
follows="top|left"
height="320"
+ help_topic="panel_region_covenant_tab"
label="Covenant"
layout="topleft"
left="0"
diff --git a/indra/newview/skins/default/xui/en/panel_region_debug.xml b/indra/newview/skins/default/xui/en/panel_region_debug.xml
index e07585d285..a6b4ddd01e 100644
--- a/indra/newview/skins/default/xui/en/panel_region_debug.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_debug.xml
@@ -3,6 +3,7 @@
border="true"
follows="top|left"
height="320"
+ help_topic="panel_region_debug_tab"
label="Debug"
layout="topleft"
left="0"
diff --git a/indra/newview/skins/default/xui/en/panel_region_estate.xml b/indra/newview/skins/default/xui/en/panel_region_estate.xml
index e25ff0d548..ba39e88024 100644
--- a/indra/newview/skins/default/xui/en/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_estate.xml
@@ -3,16 +3,13 @@
border="false"
follows="top|left"
height="320"
+ help_topic="panel_region_estate_tab"
label="Estate"
layout="topleft"
left="0"
name="Estate"
top="320"
width="480">
- <panel.string
- name="email_unsupported">
- Feature unsupported
- </panel.string>
<text
type="string"
length="1"
@@ -81,7 +78,7 @@ regions in the estate.
<view_border
bevel_style="in"
follows="top|left"
- height="310"
+ height="270"
layout="topleft"
left_delta="-4"
top_pad="5"
@@ -141,12 +138,12 @@ regions in the estate.
name="Only Allow"
top="250"
width="278">
- Restrict Access To:
+ Restrict Access to Accounts Verified by:
</text>
<check_box
follows="top|left"
height="16"
- label="Residents with payment info on file"
+ label="Payment Information on File"
layout="topleft"
left_delta="0"
name="limit_payment"
@@ -156,7 +153,7 @@ regions in the estate.
<check_box
follows="top|left"
height="16"
- label="Age-verified adults"
+ label="Age Verification"
layout="topleft"
left_delta="0"
name="limit_age_verified"
@@ -179,26 +176,6 @@ regions in the estate.
name="allow_direct_teleport"
top_pad="4"
width="80" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="20"
- layout="topleft"
- left="15"
- name="abuse_email_text"
- top_pad="10"
- width="180">
- Abuse email address:
- </text>
- <line_editor
- follows="top|left"
- height="23"
- layout="topleft"
- left="15"
- name="abuse_email_address"
- top_pad="-5"
- width="230" />
<button
enabled="false"
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_region_general.xml b/indra/newview/skins/default/xui/en/panel_region_general.xml
index 79d8f3a0ee..26568c2a28 100644
--- a/indra/newview/skins/default/xui/en/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_general.xml
@@ -3,6 +3,7 @@
border="true"
follows="top|left"
height="320"
+ help_topic="panel_region_general_tab"
label="Region"
layout="topleft"
left="0"
diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
index ffd51bf510..5093c52129 100644
--- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
@@ -3,6 +3,7 @@
border="true"
follows="top|left"
height="320"
+ help_topic="panel_region_terrain_tab"
label="Terrain"
layout="topleft"
left="0"
diff --git a/indra/newview/skins/default/xui/en/panel_region_texture.xml b/indra/newview/skins/default/xui/en/panel_region_texture.xml
index 5089064c07..a4d24cb0fc 100644
--- a/indra/newview/skins/default/xui/en/panel_region_texture.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_texture.xml
@@ -3,6 +3,7 @@
border="true"
follows="top|left"
height="320"
+ help_topic="panel_region_texture_tab"
label="Ground Textures"
layout="topleft"
left="0"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
index db8a844eb0..d006fd0700 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -489,15 +489,6 @@
bottom="5"
width="313">
<button
- follows="bottom|left"
- height="25"
- label="Edit"
- layout="topleft"
- left="0"
- name="edit_btn"
- top="0"
- width="50" />
- <button
follows="bottom|right"
height="25"
label="Cancel"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
index 348f0dfc09..eff2ca1fcd 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
@@ -482,16 +482,7 @@
left="5"
bottom="5"
width="313">
- <button
- follows="bottom|left"
- height="25"
- label="Edit"
- layout="topleft"
- left="0"
- name="edit_btn"
- top="0"
- width="50" />
- <button
+ <button
follows="bottom|left"
height="25"
label="Open"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index c3650c71c3..3044f10573 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -460,7 +460,7 @@ Returns the rotation of detected object number (returns &lt;0,0,0,1&gt; if numbe
</string>
<string name="LSLTipText_llDetectedGroup" translate="false">
integer llDetectedGroup(integer number)
-Returns TRUE if detected object is part of same group as owner
+Returns an integer that is a boolean representing if the detected object or avatar is in the same group that the prim containing the script is set to
</string>
<string name="LSLTipText_llDetectedLinkNumber" translate="false">
integer llDetectedLinkNumber(integer number)
@@ -812,7 +812,7 @@ Preloads a sound on viewers within range
</string>
<string name="LSLTipText_llRotLookAt" translate="false">
llRotLookAt(rotation target, float strength, float damping)
-Causes object name to point its forward axis towards target
+Causes object to point its forward axis towards target
</string>
<string name="LSLTipText_llStringLength" translate="false">
integer llStringLength(string str)
@@ -1471,7 +1471,7 @@ Returns the requested permission mask for the root object the task is attached t
</string>
<string name="LSLTipText_llSetObjectPermMask" translate="false">
llSetObjectPermMask(integer mask, integer value)
-Sets the given permission mask to the new value on the root object the task is attached to
+Sets the given permission mask to the new value on the root object the task is attached to (requires God Mode)
</string>
<string name="LSLTipText_llGetInventoryPermMask" translate="false">
integer llGetInventoryPermMask(string item, integer mask)
@@ -1479,7 +1479,7 @@ Returns the requested permission mask for the inventory item
</string>
<string name="LSLTipText_llSetInventoryPermMask" translate="false">
llSetInventoryPermMask(string item, integer mask, integer value)
-Sets the given permission mask to the new value on the inventory item
+Sets the given permission mask to the new value on the inventory item (requires God Mode)
</string>
<string name="LSLTipText_llGetInventoryCreator" translate="false">
key llGetInventoryCreator(string item)
diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp
index 6ff2c9446e..33d413bd21 100644
--- a/indra/newview/tests/llmediadataclient_test.cpp
+++ b/indra/newview/tests/llmediadataclient_test.cpp
@@ -75,15 +75,13 @@
<string>baz</string> \
</array>"
-#define _DATA_URLS(ID,DIST,INT,URL1,URL2) " \
+#define _DATA_URLS(ID,INTEREST,NEW,URL1,URL2) " \
<llsd> \
<map> \
<key>uuid</key> \
<string>" ID "</string> \
- <key>distance</key> \
- <real>" DIST "</real> \
<key>interest</key> \
- <real>" INT "</real> \
+ <real>" INTEREST "</real> \
<key>cap_urls</key> \
<map> \
<key>ObjectMedia</key> \
@@ -93,21 +91,26 @@
</map> \
<key>media_data</key> \
" MEDIA_DATA " \
+ <key>is_dead</key> \
+ <boolean>false</boolean> \
+ <key>is_new</key> \
+ <boolean>" NEW "</boolean> \
</map> \
</llsd>"
-#define _DATA(ID,DIST,INT) _DATA_URLS(ID,DIST,INT,FAKE_OBJECT_MEDIA_CAP_URL,FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL)
+#define _DATA(ID,INTEREST,NEW) _DATA_URLS(ID,INTEREST,NEW,FAKE_OBJECT_MEDIA_CAP_URL,FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL)
-const char *DATA = _DATA(VALID_OBJECT_ID,"1.0","1.0");
+const char *DATA = _DATA(VALID_OBJECT_ID,"1.0","true");
#define STR(I) boost::lexical_cast<std::string>(I)
#define LOG_TEST(N) LL_DEBUGS("LLMediaDataClient") << "\n" << \
"================================================================================\n" << \
-"===================================== TEST " #N " ===================================\n" << \
+"==================================== TEST " #N " ===================================\n" << \
"================================================================================\n" << LL_ENDL;
LLSD *gPostRecords = NULL;
+F64 gMinimumInterestLevel = (F64)0.0;
// stubs:
void LLHTTPClient::post(
@@ -125,21 +128,20 @@ void LLHTTPClient::post(
gPostRecords->append(record);
// Magic URL that triggers a 503:
+ LLSD result;
+ result[LLTextureEntry::OBJECT_ID_KEY] = body[LLTextureEntry::OBJECT_ID_KEY];
if ( url == FAKE_OBJECT_MEDIA_CAP_URL_503 )
{
responder->error(HTTP_SERVICE_UNAVAILABLE, "fake reason");
+ return;
}
else if (url == FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR)
{
- LLSD result;
LLSD error;
error["code"] = LLObjectMediaNavigateClient::ERROR_PERMISSION_DENIED_CODE;
result["error"] = error;
- responder->result(result);
- }
- else {
- responder->result(LLSD());
- }
+ }
+ responder->result(result);
}
const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
@@ -152,13 +154,12 @@ public:
std::istringstream d(data);
LLSDSerialize::fromXML(mRep, d);
mNumBounceBacks = 0;
- mDead = false;
// std::cout << ll_pretty_print_sd(mRep) << std::endl;
// std::cout << "ID: " << getID() << std::endl;
}
LLMediaDataClientObjectTest(const LLSD &rep)
- : mRep(rep), mNumBounceBacks(0), mDead(false) {}
+ : mRep(rep), mNumBounceBacks(0) {}
~LLMediaDataClientObjectTest()
{ LL_DEBUGS("LLMediaDataClient") << "~LLMediaDataClientObjectTest" << LL_ENDL; }
@@ -169,43 +170,47 @@ public:
virtual LLUUID getID() const
{ return mRep["uuid"]; }
virtual void mediaNavigateBounceBack(U8 index)
- {
- mNumBounceBacks++;
- }
+ { mNumBounceBacks++; }
virtual bool hasMedia() const
{ return mRep.has("media_data"); }
- virtual void updateObjectMediaData(LLSD const &media_data_array)
- { mRep["media_data"] = media_data_array; }
+ virtual void updateObjectMediaData(LLSD const &media_data_array, const std::string &media_version)
+ { mRep["media_data"] = media_data_array; mRep["media_version"] = media_version; }
+
+ virtual F64 getMediaInterest() const
+ { return (LLSD::Real)mRep["interest"]; }
- virtual F64 getDistanceFromAvatar() const
- { return (LLSD::Real)mRep["distance"]; }
+ virtual bool isInterestingEnough() const
+ { return getMediaInterest() > gMinimumInterestLevel; }
- virtual F64 getTotalMediaInterest() const
- { return (LLSD::Real)mRep["interest"]; }
-
virtual std::string getCapabilityUrl(const std::string &name) const
{ return mRep["cap_urls"][name]; }
virtual bool isDead() const
- { return mDead; }
-
- void setDistanceFromAvatar(F64 val)
- { mRep["distance"] = val; }
+ { return mRep["is_dead"]; }
+
+ virtual U32 getMediaVersion() const
+ { return (LLSD::Integer)mRep["media_version"]; }
+
+ virtual bool isNew() const
+ { return mRep["is_new"]; }
- void setTotalMediaInterest(F64 val)
+ void setMediaInterest(F64 val)
{ mRep["interest"] = val; }
int getNumBounceBacks() const
{ return mNumBounceBacks; }
void markDead()
- { mDead = true; }
+ { mRep["is_dead"] = true; }
+
+ void markOld()
+ { mRep["is_new"] = false; }
+
private:
LLSD mRep;
int mNumBounceBacks;
- bool mDead;
};
// This special timer delay should ensure that the timer will fire on the very
@@ -224,10 +229,11 @@ namespace tut
{
mediadataclient() {
gPostRecords = &mLLSD;
+ gMinimumInterestLevel = (F64)0.0;
- //LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
- //LLError::setClassLevel("LLMediaDataClient", LLError::LEVEL_DEBUG);
- //LLError::setTagLevel("MediaOnAPrim", LLError::LEVEL_DEBUG);
+// LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
+// LLError::setClassLevel("LLMediaDataClient", LLError::LEVEL_DEBUG);
+// LLError::setTagLevel("MediaOnAPrim", LLError::LEVEL_DEBUG);
}
LLSD mLLSD;
};
@@ -378,11 +384,11 @@ namespace tut
LOG_TEST(4);
LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(
- _DATA(VALID_OBJECT_ID_1,"3.0","1.0"));
+ _DATA(VALID_OBJECT_ID_1,"1.0","true"));
LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(
- _DATA(VALID_OBJECT_ID_2,"1.0","1.0"));
+ _DATA(VALID_OBJECT_ID_2,"3.0","true"));
LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(
- _DATA(VALID_OBJECT_ID_3,"2.0","1.0"));
+ _DATA(VALID_OBJECT_ID_3,"2.0","true"));
{
LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
const char *ORDERED_OBJECT_IDS[] = { VALID_OBJECT_ID_2, VALID_OBJECT_ID_3, VALID_OBJECT_ID_1 };
@@ -428,8 +434,7 @@ namespace tut
LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(
_DATA_URLS(VALID_OBJECT_ID,
- "1.0",
- "1.0",
+ "1.0","true",
FAKE_OBJECT_MEDIA_CAP_URL_503,
FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL));
int num_refs_start = o->getNumRefs();
@@ -484,8 +489,7 @@ namespace tut
LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(
_DATA_URLS(VALID_OBJECT_ID,
- "1.0",
- "1.0",
+ "1.0","true",
FAKE_OBJECT_MEDIA_CAP_URL,
FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR));
{
@@ -517,9 +521,9 @@ namespace tut
LOG_TEST(7);
LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(
- _DATA(VALID_OBJECT_ID_1,"3.0","1.0"));
+ _DATA(VALID_OBJECT_ID_1,"3.0","true"));
LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(
- _DATA(VALID_OBJECT_ID_2,"1.0","1.0"));
+ _DATA(VALID_OBJECT_ID_2,"1.0","true"));
int num_refs_start = o1->getNumRefs();
{
LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
@@ -551,10 +555,10 @@ namespace tut
// Test queue handling of objects that are marked dead.
LOG_TEST(8);
- LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"1.0","1.0"));
- LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"2.0","1.0"));
- LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"3.0","1.0"));
- LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"4.0","1.0"));
+ LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"4.0","true"));
+ LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"3.0","true"));
+ LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"2.0","true"));
+ LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"1.0","true"));
{
LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
@@ -616,10 +620,11 @@ namespace tut
//
LOG_TEST(9);
- LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"10.0","1.0"));
- LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"20.0","1.0"));
- LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"30.0","1.0"));
- LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"40.0","1.0"));
+ LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"40.0","true"));
+ LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"30.0","true"));
+ LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"20.0","true"));
+ LLMediaDataClientObjectTest *object4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"10.0","true"));
+ LLMediaDataClientObject::ptr_t o4 = object4;
{
LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
@@ -630,53 +635,52 @@ namespace tut
mdc->fetchMedia(o3);
mdc->fetchMedia(o4);
- int test_num = 0;
+ int tick_num = 0;
- ensure(STR(test_num) + ". is in queue 1", mdc->isInQueue(o1));
- ensure(STR(test_num) + ". is in queue 2", mdc->isInQueue(o2));
- ensure(STR(test_num) + ". is in queue 3", mdc->isInQueue(o3));
- ensure(STR(test_num) + ". is in queue 4", mdc->isInQueue(o4));
- ensure(STR(test_num) + ". post records", gPostRecords->size(), 0);
+ ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
+ ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 0);
::pump_timers();
- ++test_num;
+ ++tick_num;
// The first tick should remove the first one
- ensure(STR(test_num) + ". is not in queue 1", !mdc->isInQueue(o1));
- ensure(STR(test_num) + ". is in queue 2", mdc->isInQueue(o2));
- ensure(STR(test_num) + ". is in queue 3", mdc->isInQueue(o3));
- ensure(STR(test_num) + ". is in queue 4", mdc->isInQueue(o4));
- ensure(STR(test_num) + ". post records", gPostRecords->size(), 1);
+ ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
+ ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 1);
// Now, pretend that object 4 moved relative to the avatar such
// that it is now closest
- static_cast<LLMediaDataClientObjectTest*>(
- static_cast<LLMediaDataClientObject*>(o4))->setDistanceFromAvatar(5.0);
+ object4->setMediaInterest(50.0);
::pump_timers();
- ++test_num;
+ ++tick_num;
// The second tick should still pick off item 2, but then re-sort
// have picked off object 4
- ensure(STR(test_num) + ". is in queue 2", mdc->isInQueue(o2));
- ensure(STR(test_num) + ". is in queue 3", mdc->isInQueue(o3));
- ensure(STR(test_num) + ". is not in queue 4", !mdc->isInQueue(o4));
- ensure(STR(test_num) + ". post records", gPostRecords->size(), 2);
+ ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
::pump_timers();
- ++test_num;
+ ++tick_num;
// The third tick should pick off object 2
- ensure(STR(test_num) + ". is not in queue 2", !mdc->isInQueue(o2));
- ensure(STR(test_num) + ". is in queue 3", mdc->isInQueue(o3));
- ensure(STR(test_num) + ". post records", gPostRecords->size(), 3);
+ ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);
// The fourth tick should pick off object 3
::pump_timers();
- ++test_num;
+ ++tick_num;
- ensure(STR(test_num) + ". is not in queue 3", !mdc->isInQueue(o3));
- ensure(STR(test_num) + ". post records", gPostRecords->size(), 4);
+ ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 4);
ensure("queue empty", mdc->isEmpty());
}
@@ -686,4 +690,249 @@ namespace tut
ensure("refcount of o4", o4->getNumRefs(), 1);
}
+
+ template<> template<>
+ void mediadataclient_object_t::test<10>()
+ {
+ //
+ // Test using the "round-robin" queue
+ //
+ LOG_TEST(10);
+
+ LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"1.0","true"));
+ LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"2.0","true"));
+ LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"3.0","false"));
+ LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"4.0","false"));
+ {
+ LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
+
+ // queue up all 4 objects. The first two should be in the sorted
+ // queue [2 1], the second in the round-robin queue. The queues
+ // are serviced interleaved, so we should expect:
+ // 2, 4, 1, 3
+ mdc->fetchMedia(o1);
+ mdc->fetchMedia(o2);
+ mdc->fetchMedia(o3);
+ mdc->fetchMedia(o4);
+
+ int tick_num = 0;
+
+ // 0
+ ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
+ ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 0);
+
+ ::pump_timers();
+ ++tick_num;
+
+ // 1 The first tick should remove object 2
+ ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
+ ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 1);
+ ensure(STR(tick_num) + ". post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_2));
+
+ ::pump_timers();
+ ++tick_num;
+
+ // 2 The second tick should send object 4, but it will still be
+ // "in the queue"
+ ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
+ ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
+ ensure(STR(tick_num) + ". post object id", (*gPostRecords)[1]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_4));
+
+ ::pump_timers();
+ ++tick_num;
+
+ // 3 The third tick should remove object 1
+ ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
+ ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);
+ ensure(STR(tick_num) + ". post object id", (*gPostRecords)[2]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_1));
+
+ ::pump_timers();
+ ++tick_num;
+
+ // 4 The fourth tick should send object 3, but it will still be
+ // "in the queue"
+ ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
+ ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 4);
+ ensure(STR(tick_num) + ". post object id", (*gPostRecords)[3]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_3));
+
+ ::pump_timers();
+ ++tick_num;
+
+ // 5 The fifth tick should now identify objects 3 and 4 as no longer
+ // needing "updating", and remove them from the queue
+ ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
+ ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 4);
+
+ ::pump_timers();
+
+ // Whew....better be empty
+ ensure("queue empty", mdc->isEmpty());
+ }
+ ensure("refcount of o1", o1->getNumRefs(), 1);
+ ensure("refcount of o2", o2->getNumRefs(), 1);
+ ensure("refcount of o3", o3->getNumRefs(), 1);
+ ensure("refcount of o4", o4->getNumRefs(), 1);
+ }
+
+
+ template<> template<>
+ void mediadataclient_object_t::test<11>()
+ {
+ //
+ // Test LLMediaDataClient's destructor
+ //
+ LOG_TEST(11);
+
+ LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA);
+ int num_refs_start = o->getNumRefs();
+ {
+ LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
+ mdc->fetchMedia(o);
+ // must tick enough times to clear refcount of mdc
+ ::pump_timers();
+ }
+ // Make sure everyone's destroyed properly
+ ensure("REF COUNT", o->getNumRefs(), num_refs_start);
+ }
+
+ template<> template<>
+ void mediadataclient_object_t::test<12>()
+ {
+ //
+ // Test the "not interesting enough" call
+ //
+ LOG_TEST(12);
+
+ LLMediaDataClientObjectTest *object1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"1.0","true"));
+ LLMediaDataClientObject::ptr_t o1 = object1;
+ LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"2.0","true"));
+ LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"3.0","true"));
+ LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"4.0","true"));
+ {
+ LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
+
+ // queue up all 4 objects. The first two are "interesting enough".
+ // Firing the timer 4 times should therefore leave them.
+ // Note that they should be sorted 4,3,2,1
+ // Then, we'll make one "interesting enough", fire the timer a few
+ // times, and make sure only it gets pulled off the queue
+ gMinimumInterestLevel = 2.5;
+ mdc->fetchMedia(o1);
+ mdc->fetchMedia(o2);
+ mdc->fetchMedia(o3);
+ mdc->fetchMedia(o4);
+
+ int tick_num = 0;
+
+ // 0
+ ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
+ ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 0);
+
+ ::pump_timers();
+ ++tick_num;
+
+ // 1 The first tick should remove object 4
+ ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
+ ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 1);
+ ensure(STR(tick_num) + ". post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_4));
+
+ ::pump_timers();
+ ++tick_num;
+
+ // 2 The second tick should send object 3
+ ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
+ ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
+ ensure(STR(tick_num) + ". post object id", (*gPostRecords)[1]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_3));
+
+ ::pump_timers();
+ ++tick_num;
+
+ // 3 The third tick should not pull off anything
+ ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
+ ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
+
+ ::pump_timers();
+ ++tick_num;
+
+ // 4 The fourth tick (for good measure) should not pull off anything
+ ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1));
+ ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2);
+
+ // Okay, now futz with object 1's interest, such that it is now
+ // "interesting enough"
+ object1->setMediaInterest((F64)5.0);
+
+ // This should sort so that the queue is now [1 2]
+ ::pump_timers();
+ ++tick_num;
+
+ // 5 The fifth tick should now identify objects 3 and 4 as no longer
+ // needing "updating", and remove them from the queue
+ ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
+ ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);
+ ensure(STR(tick_num) + ". post object id", (*gPostRecords)[2]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_1));
+
+ ::pump_timers();
+ ++tick_num;
+
+ // 6 The sixth tick should not pull off anything
+ ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1));
+ ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2));
+ ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3));
+ ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4));
+ ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3);
+
+ ::pump_timers();
+ ++tick_num;
+
+ // Whew....better NOT be empty ... o2 should still be there
+ ensure("queue not empty", !mdc->isEmpty());
+
+ // But, we need to clear the queue, or else we won't destroy MDC...
+ // this is a strange interplay between the queue timer and the MDC
+ ensure("o2 couldn't be removed from queue", mdc->removeFromQueue(o2));
+ // tick
+ ::pump_timers();
+ }
+ ensure("refcount of o1", o1->getNumRefs(), 1);
+ ensure("refcount of o2", o2->getNumRefs(), 1);
+ ensure("refcount of o3", o3->getNumRefs(), 1);
+ ensure("refcount of o4", o4->getNumRefs(), 1);
+ }
}
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 4133315480..32fdd41be2 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -803,7 +803,7 @@ class Linux_i686Manifest(LinuxManifest):
# plugins
if self.prefix(src="", dst="bin/llplugin"):
self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so")
- self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_quicktime.so")
+ self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so")
self.end_prefix("bin/llplugin")
self.path("featuretable_linux.txt")
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp
index 30d338292e..d183aac208 100644
--- a/indra/test_apps/llplugintest/llmediaplugintest.cpp
+++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp
@@ -1537,7 +1537,7 @@ void LLMediaPluginTest::addMediaPanel( std::string url )
char cwd[ FILENAME_MAX ];
if (NULL == getcwd( cwd, FILENAME_MAX - 1 ))
{
- std::cerr << "Couldn't get cwd - probably too long - failing to init." << llendl;
+ std::cerr << "Couldn't get cwd - probably too long - failing to init." << std::endl;
return;
}
std::string user_data_path = std::string( cwd ) + "/";
@@ -1774,7 +1774,7 @@ void LLMediaPluginTest::replaceMediaPanel( mediaPanel* panel, std::string url )
char cwd[ FILENAME_MAX ];
if (NULL == getcwd( cwd, FILENAME_MAX - 1 ))
{
- std::cerr << "Couldn't get cwd - probably too long - failing to init." << llendl;
+ std::cerr << "Couldn't get cwd - probably too long - failing to init." << std::endl;
return;
}
std::string user_data_path = std::string( cwd ) + "/";