summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeslie Linden <leslie@lindenlab.com>2011-09-20 15:18:49 -0700
committerLeslie Linden <leslie@lindenlab.com>2011-09-20 15:18:49 -0700
commiteb3a643f3bcddb159622e2d38ef65f661b204653 (patch)
treec33e9db5e102f3099091a0e90fdfc26ad1e8db42
parent3df9545017a4835e162801d3e8a13d68c8bc44ad (diff)
parent938f1b4f41683e1a3aaa424d3d7bac5b0772d09c (diff)
Merge from viewer-experience
-rw-r--r--doc/contributions.txt3
-rw-r--r--indra/llcommon/CMakeLists.txt1
-rw-r--r--indra/llcommon/llfasttimer_class.cpp19
-rw-r--r--indra/llcommon/llfasttimer_class.h2
-rw-r--r--indra/llcommon/llinstancetracker.cpp19
-rw-r--r--indra/llcommon/llinstancetracker.h105
-rw-r--r--indra/llcommon/llsingleton.h24
-rw-r--r--indra/llcommon/tests/llinstancetracker_test.cpp64
-rw-r--r--indra/llcommon/tests/llsingleton_test.cpp76
-rw-r--r--indra/llmessage/llcurl.cpp12
-rw-r--r--indra/llmessage/llcurl.h8
-rw-r--r--indra/llmessage/llpacketring.cpp16
-rw-r--r--indra/llmessage/llpacketring.h3
-rw-r--r--indra/llmessage/llproxy.cpp102
-rw-r--r--indra/llmessage/llproxy.h107
-rw-r--r--indra/llui/llnotifications.cpp1
-rw-r--r--indra/llui/llnotificationtemplate.h4
-rw-r--r--indra/llui/llscrollcontainer.cpp9
-rw-r--r--indra/llui/llscrollcontainer.h1
-rw-r--r--indra/llui/llsdparam.cpp2
-rw-r--r--indra/llui/lluictrlfactory.h6
-rw-r--r--indra/llxuixml/llinitparam.h113
-rw-r--r--indra/llxuixml/llxuiparser.cpp3
-rw-r--r--indra/newview/app_settings/settings.xml4
-rw-r--r--indra/newview/app_settings/settings_per_account.xml14
-rw-r--r--indra/newview/llappviewer.cpp12
-rw-r--r--indra/newview/llbottomtray.cpp35
-rw-r--r--indra/newview/llbottomtray.h2
-rw-r--r--indra/newview/lldebugview.cpp8
-rw-r--r--indra/newview/llfasttimerview.cpp154
-rw-r--r--indra/newview/llfasttimerview.h7
-rw-r--r--indra/newview/llfloatersearch.cpp65
-rw-r--r--indra/newview/llfolderview.cpp2
-rw-r--r--indra/newview/llfolderviewitem.cpp4
-rw-r--r--indra/newview/llinventoryfilter.cpp24
-rw-r--r--indra/newview/llinventorypanel.cpp26
-rw-r--r--indra/newview/llinventorypanel.h5
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp5
-rw-r--r--indra/newview/llpanelmarketplaceinbox.cpp3
-rw-r--r--indra/newview/llpanelmarketplaceinboxinventory.cpp15
-rw-r--r--indra/newview/llpanelmarketplaceoutbox.cpp5
-rw-r--r--indra/newview/llsidepanelinventory.cpp4
-rw-r--r--indra/newview/llsidetray.cpp255
-rw-r--r--indra/newview/llviewerfloaterreg.cpp2
-rw-r--r--indra/newview/llviewermenu.cpp4
-rw-r--r--indra/newview/llviewermessage.cpp50
-rw-r--r--indra/newview/llvoicevivox.cpp31
-rw-r--r--indra/newview/skins/default/xui/en/floater_fast_timers.xml28
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml190
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_main_inventory.xml5
-rw-r--r--indra/newview/skins/default/xui/en/widgets/inventory_panel.xml11
-rw-r--r--indra/newview/viewer_manifest.py8
-rw-r--r--scripts/templates/template-cpp.cpp30
-rw-r--r--scripts/templates/template-h.h31
55 files changed, 1074 insertions, 671 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 5930bab04f..bcdc5a63d2 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -177,6 +177,8 @@ Ardy Lay
VWR-24917
Argent Stonecutter
VWR-68
+ArminWeatherHax
+ STORM-1532
Armin Weatherwax
VWR-8436
ArminasX Saiman
@@ -568,6 +570,7 @@ Jonathan Yap
STORM-1276
STORM-1462
STORM-1459
+ STORM-1297
STORM-1522
STORM-1567
STORM-1572
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index cc6bddc4da..60d4cfe6d3 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -322,6 +322,7 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}"
"${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/setpython.py")
+ LL_ADD_INTEGRATION_TEST(llsingleton "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")
diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer_class.cpp
index ebb5961c91..463f558c2c 100644
--- a/indra/llcommon/llfasttimer_class.cpp
+++ b/indra/llcommon/llfasttimer_class.cpp
@@ -303,14 +303,15 @@ LLFastTimer::NamedTimer::~NamedTimer()
std::string LLFastTimer::NamedTimer::getToolTip(S32 history_idx)
{
+ F64 ms_multiplier = 1000.0 / (F64)LLFastTimer::countsPerSecond();
if (history_idx < 0)
{
- // by default, show average number of calls
- return llformat("%s (%d calls)", getName().c_str(), (S32)getCallAverage());
+ // by default, show average number of call
+ return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getCountAverage() * ms_multiplier), (S32)getCallAverage());
}
else
{
- return llformat("%s (%d calls)", getName().c_str(), (S32)getHistoricalCalls(history_idx));
+ return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getHistoricalCount(history_idx) * ms_multiplier), (S32)getHistoricalCalls(history_idx));
}
}
@@ -693,17 +694,7 @@ void LLFastTimer::nextFrame()
llinfos << "Slow frame, fast timers inaccurate" << llendl;
}
- if (sPauseHistory)
- {
- sResetHistory = true;
- }
- else if (sResetHistory)
- {
- sLastFrameIndex = 0;
- sCurFrameIndex = 0;
- sResetHistory = false;
- }
- else // not paused
+ if (!sPauseHistory)
{
NamedTimer::processTimes();
sLastFrameIndex = sCurFrameIndex++;
diff --git a/indra/llcommon/llfasttimer_class.h b/indra/llcommon/llfasttimer_class.h
index 827747f0c6..f481e968a6 100644
--- a/indra/llcommon/llfasttimer_class.h
+++ b/indra/llcommon/llfasttimer_class.h
@@ -66,7 +66,7 @@ public:
public:
~NamedTimer();
- enum { HISTORY_NUM = 60 };
+ enum { HISTORY_NUM = 300 };
const std::string& getName() const { return mName; }
NamedTimer* getParent() const { return mParent; }
diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp
index f576204511..5dc3ea5d7b 100644
--- a/indra/llcommon/llinstancetracker.cpp
+++ b/indra/llcommon/llinstancetracker.cpp
@@ -35,14 +35,15 @@
//static
void * & LLInstanceTrackerBase::getInstances(std::type_info const & info)
{
- static std::map<std::string, void *> instances;
+ typedef std::map<std::string, void *> InstancesMap;
+ static InstancesMap instances;
- std::string k = info.name();
- if(instances.find(k) == instances.end())
- {
- instances[k] = NULL;
- }
-
- return instances[k];
+ // std::map::insert() is just what we want here. You attempt to insert a
+ // (key, value) pair. If the specified key doesn't yet exist, it inserts
+ // the pair and returns a std::pair of (iterator, true). If the specified
+ // key DOES exist, insert() simply returns (iterator, false). One lookup
+ // handles both cases.
+ return instances.insert(InstancesMap::value_type(info.name(),
+ InstancesMap::mapped_type()))
+ .first->second;
}
-
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index afb714c71c..5a3990a8df 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -29,6 +29,7 @@
#define LL_LLINSTANCETRACKER_H
#include <map>
+#include <typeinfo>
#include "string_table.h"
#include <boost/utility.hpp>
@@ -37,10 +38,40 @@
#include <boost/iterator/transform_iterator.hpp>
#include <boost/iterator/indirect_iterator.hpp>
+/**
+ * Base class manages "class-static" data that must actually have singleton
+ * semantics: one instance per process, rather than one instance per module as
+ * sometimes happens with data simply declared static.
+ */
class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
{
- protected:
- static void * & getInstances(std::type_info const & info);
+protected:
+ /// Get a process-unique void* pointer slot for the specified type_info
+ static void * & getInstances(std::type_info const & info);
+
+ /// Find or create a STATICDATA instance for the specified TRACKED class.
+ /// STATICDATA must be default-constructible.
+ template<typename STATICDATA, class TRACKED>
+ static STATICDATA& getStatic()
+ {
+ void *& instances = getInstances(typeid(TRACKED));
+ if (! instances)
+ {
+ instances = new STATICDATA;
+ }
+ return *static_cast<STATICDATA*>(instances);
+ }
+
+ /// It's not essential to derive your STATICDATA (for use with
+ /// getStatic()) from StaticBase; it's just that both known
+ /// implementations do.
+ struct StaticBase
+ {
+ StaticBase():
+ sIterationNestDepth(0)
+ {}
+ S32 sIterationNestDepth;
+ };
};
/// This mix-in class adds support for tracking all instances of the specified class parameter T
@@ -50,8 +81,15 @@ class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
template<typename T, typename KEY = T*>
class LLInstanceTracker : public LLInstanceTrackerBase
{
- typedef typename std::map<KEY, T*> InstanceMap;
typedef LLInstanceTracker<T, KEY> MyT;
+ typedef typename std::map<KEY, T*> InstanceMap;
+ struct StaticData: public StaticBase
+ {
+ InstanceMap sMap;
+ };
+ static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
+ static InstanceMap& getMap_() { return getStatic().sMap; }
+
public:
class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
{
@@ -61,12 +99,12 @@ public:
instance_iter(const typename InstanceMap::iterator& it)
: mIterator(it)
{
- ++sIterationNestDepth;
+ ++getStatic().sIterationNestDepth;
}
~instance_iter()
{
- --sIterationNestDepth;
+ --getStatic().sIterationNestDepth;
}
@@ -95,18 +133,18 @@ public:
key_iter(typename InstanceMap::iterator it)
: mIterator(it)
{
- ++sIterationNestDepth;
+ ++getStatic().sIterationNestDepth;
}
key_iter(const key_iter& other)
: mIterator(other.mIterator)
{
- ++sIterationNestDepth;
+ ++getStatic().sIterationNestDepth;
}
~key_iter()
{
- --sIterationNestDepth;
+ --getStatic().sIterationNestDepth;
}
@@ -159,8 +197,8 @@ protected:
virtual ~LLInstanceTracker()
{
// it's unsafe to delete instances of this type while all instances are being iterated over.
- llassert(sIterationNestDepth == 0);
- remove_();
+ llassert_always(getStatic().sIterationNestDepth == 0);
+ remove_();
}
virtual void setKey(KEY key) { remove_(); add_(key); }
virtual const KEY& getKey() const { return mInstanceKey; }
@@ -176,31 +214,24 @@ private:
getMap_().erase(mInstanceKey);
}
- static InstanceMap& getMap_()
- {
- void * & instances = getInstances(typeid(MyT));
- if (! instances)
- {
- instances = new InstanceMap;
- }
- return * static_cast<InstanceMap*>(instances);
- }
-
private:
-
KEY mInstanceKey;
- static S32 sIterationNestDepth;
};
-template <typename T, typename KEY> S32 LLInstanceTracker<T, KEY>::sIterationNestDepth = 0;
-
/// explicit specialization for default case where KEY is T*
/// use a simple std::set<T*>
template<typename T>
class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
{
- typedef typename std::set<T*> InstanceSet;
typedef LLInstanceTracker<T, T*> MyT;
+ typedef typename std::set<T*> InstanceSet;
+ struct StaticData: public StaticBase
+ {
+ InstanceSet sSet;
+ };
+ static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
+ static InstanceSet& getSet_() { return getStatic().sSet; }
+
public:
/// for completeness of analogy with the generic implementation
@@ -213,18 +244,18 @@ public:
instance_iter(const typename InstanceSet::iterator& it)
: mIterator(it)
{
- ++sIterationNestDepth;
+ ++getStatic().sIterationNestDepth;
}
instance_iter(const instance_iter& other)
: mIterator(other.mIterator)
{
- ++sIterationNestDepth;
+ ++getStatic().sIterationNestDepth;
}
~instance_iter()
{
- --sIterationNestDepth;
+ --getStatic().sIterationNestDepth;
}
private:
@@ -250,13 +281,13 @@ public:
protected:
LLInstanceTracker()
{
- // it's safe but unpredictable to create instances of this type while all instances are being iterated over. I hate unpredictable. This assert will probably be turned on early in the next development cycle.
+ // it's safe but unpredictable to create instances of this type while all instances are being iterated over. I hate unpredictable. This assert will probably be turned on early in the next development cycle.
getSet_().insert(static_cast<T*>(this));
}
virtual ~LLInstanceTracker()
{
// it's unsafe to delete instances of this type while all instances are being iterated over.
- llassert(sIterationNestDepth == 0);
+ llassert_always(getStatic().sIterationNestDepth == 0);
getSet_().erase(static_cast<T*>(this));
}
@@ -264,20 +295,6 @@ protected:
{
getSet_().insert(static_cast<T*>(this));
}
-
- static InstanceSet& getSet_()
- {
- void * & instances = getInstances(typeid(MyT));
- if (! instances)
- {
- instances = new InstanceSet;
- }
- return * static_cast<InstanceSet *>(instances);
- }
-
- static S32 sIterationNestDepth;
};
-template <typename T> S32 LLInstanceTracker<T, T*>::sIterationNestDepth = 0;
-
#endif
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 00757be277..49d99f2cd0 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -114,8 +114,7 @@ private:
~SingletonInstanceData()
{
- SingletonInstanceData& data = getData();
- if (data.mInitState != DELETED)
+ if (mInitState != DELETED)
{
deleteSingleton();
}
@@ -130,7 +129,26 @@ public:
data.mInitState = DELETED;
}
- // Can be used to control when the singleton is deleted. Not normally needed.
+ /**
+ * @brief Immediately delete the singleton.
+ *
+ * A subsequent call to LLProxy::getInstance() will construct a new
+ * instance of the class.
+ *
+ * LLSingletons are normally destroyed after main() has exited and the C++
+ * runtime is cleaning up statically-constructed objects. Some classes
+ * derived from LLSingleton have objects that are part of a runtime system
+ * that is terminated before main() exits. Calling the destructor of those
+ * objects after the termination of their respective systems can cause
+ * crashes and other problems during termination of the project. Using this
+ * method to destroy the singleton early can prevent these crashes.
+ *
+ * An example where this is needed is for a LLSingleton that has an APR
+ * object as a member that makes APR calls on destruction. The APR system is
+ * shut down explicitly before main() exits. This causes a crash on exit.
+ * Using this method before the call to apr_terminate() and NOT calling
+ * getInstance() again will prevent the crash.
+ */
static void deleteSingleton()
{
delete getData().mSingletonInstance;
diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp
index 80b35bbdc3..b34d1c5fd3 100644
--- a/indra/llcommon/tests/llinstancetracker_test.cpp
+++ b/indra/llcommon/tests/llinstancetracker_test.cpp
@@ -40,6 +40,7 @@
#include <boost/scoped_ptr.hpp>
// other Linden headers
#include "../test/lltut.h"
+#include "wrapllerrs.h"
struct Keyed: public LLInstanceTracker<Keyed, std::string>
{
@@ -165,4 +166,67 @@ namespace tut
ensure_equals("unreported instance", instances.size(), 0);
}
+
+ template<> template<>
+ void object::test<5>()
+ {
+ set_test_name("delete Keyed with outstanding instance_iter");
+ std::string what;
+ Keyed* keyed = new Keyed("one");
+ {
+ WrapLL_ERRS wrapper;
+ Keyed::instance_iter i(Keyed::beginInstances());
+ try
+ {
+ delete keyed;
+ }
+ catch (const WrapLL_ERRS::FatalException& e)
+ {
+ what = e.what();
+ }
+ }
+ ensure(! what.empty());
+ }
+
+ template<> template<>
+ void object::test<6>()
+ {
+ set_test_name("delete Keyed with outstanding key_iter");
+ std::string what;
+ Keyed* keyed = new Keyed("one");
+ {
+ WrapLL_ERRS wrapper;
+ Keyed::key_iter i(Keyed::beginKeys());
+ try
+ {
+ delete keyed;
+ }
+ catch (const WrapLL_ERRS::FatalException& e)
+ {
+ what = e.what();
+ }
+ }
+ ensure(! what.empty());
+ }
+
+ template<> template<>
+ void object::test<7>()
+ {
+ set_test_name("delete Unkeyed with outstanding instance_iter");
+ std::string what;
+ Unkeyed* unkeyed = new Unkeyed;
+ {
+ WrapLL_ERRS wrapper;
+ Unkeyed::instance_iter i(Unkeyed::beginInstances());
+ try
+ {
+ delete unkeyed;
+ }
+ catch (const WrapLL_ERRS::FatalException& e)
+ {
+ what = e.what();
+ }
+ }
+ ensure(! what.empty());
+ }
} // namespace tut
diff --git a/indra/llcommon/tests/llsingleton_test.cpp b/indra/llcommon/tests/llsingleton_test.cpp
new file mode 100644
index 0000000000..385289aefe
--- /dev/null
+++ b/indra/llcommon/tests/llsingleton_test.cpp
@@ -0,0 +1,76 @@
+/**
+ * @file llsingleton_test.cpp
+ * @date 2011-08-11
+ * @brief Unit test for the LLSingleton class
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llsingleton.h"
+#include "../test/lltut.h"
+
+namespace tut
+{
+ struct singleton
+ {
+ // We need a class created with the LLSingleton template to test with.
+ class LLSingletonTest: public LLSingleton<LLSingletonTest>
+ {
+
+ };
+ };
+
+ typedef test_group<singleton> singleton_t;
+ typedef singleton_t::object singleton_object_t;
+ tut::singleton_t tut_singleton("LLSingleton");
+
+ template<> template<>
+ void singleton_object_t::test<1>()
+ {
+
+ }
+ template<> template<>
+ void singleton_object_t::test<2>()
+ {
+ LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
+ ensure(singleton_test);
+ }
+ template<> template<>
+ void singleton_object_t::test<3>()
+ {
+ //Construct the instance
+ LLSingletonTest::getInstance();
+ ensure(LLSingletonTest::instanceExists());
+
+ //Delete the instance
+ LLSingletonTest::deleteSingleton();
+ ensure(LLSingletonTest::destroyed());
+ ensure(!LLSingletonTest::instanceExists());
+
+ //Construct it again.
+ LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
+ ensure(singleton_test);
+ ensure(LLSingletonTest::instanceExists());
+ }
+}
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index a3de178d78..14e169c6b1 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -499,7 +499,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
//don't verify host name so urls with scrubbed host names will work (improves DNS performance)
setopt(CURLOPT_SSL_VERIFYHOST, 0);
- setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT);
+ setopt(CURLOPT_TIMEOUT, llmax(time_out, CURL_REQUEST_TIMEOUT));
setoptString(CURLOPT_URL, url);
@@ -1213,3 +1213,13 @@ void LLCurl::cleanupClass()
}
const unsigned int LLCurl::MAX_REDIRECTS = 5;
+
+// Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace.
+void LLCurlFF::check_easy_code(CURLcode code)
+{
+ check_curl_code(code);
+}
+void LLCurlFF::check_multi_code(CURLMcode code)
+{
+ check_curl_multi_code(code);
+}
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 5ab4dc35b9..213b281e72 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -371,7 +371,11 @@ private:
bool mResultReturned;
};
-void check_curl_code(CURLcode code);
-void check_curl_multi_code(CURLMcode code);
+// Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace.
+namespace LLCurlFF
+{
+ void check_easy_code(CURLcode code);
+ void check_multi_code(CURLMcode code);
+}
#endif // LL_LLCURL_H
diff --git a/indra/llmessage/llpacketring.cpp b/indra/llmessage/llpacketring.cpp
index 7628984de4..fc6e9c5193 100644
--- a/indra/llmessage/llpacketring.cpp
+++ b/indra/llmessage/llpacketring.cpp
@@ -228,13 +228,13 @@ S32 LLPacketRing::receivePacket (S32 socket, char *datap)
if (LLProxy::isSOCKSProxyEnabled())
{
U8 buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
- packet_size = receive_packet(socket, reinterpret_cast<char *>(buffer));
+ packet_size = receive_packet(socket, static_cast<char*>(static_cast<void*>(buffer)));
if (packet_size > SOCKS_HEADER_SIZE)
{
// *FIX We are assuming ATYP is 0x01 (IPv4), not 0x03 (hostname) or 0x04 (IPv6)
memcpy(datap, buffer + SOCKS_HEADER_SIZE, packet_size - SOCKS_HEADER_SIZE);
- proxywrap_t * header = reinterpret_cast<proxywrap_t *>(buffer);
+ proxywrap_t * header = static_cast<proxywrap_t*>(static_cast<void*>(buffer));
mLastSender.setAddress(header->addr);
mLastSender.setPort(ntohs(header->port));
@@ -353,14 +353,20 @@ BOOL LLPacketRing::sendPacketImpl(int h_socket, const char * send_buffer, S32 bu
return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort());
}
- proxywrap_t *socks_header = reinterpret_cast<proxywrap_t *>(&mProxyWrappedSendBuffer);
+ char headered_send_buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
+
+ proxywrap_t *socks_header = static_cast<proxywrap_t*>(static_cast<void*>(&headered_send_buffer));
socks_header->rsv = 0;
socks_header->addr = host.getAddress();
socks_header->port = htons(host.getPort());
socks_header->atype = ADDRESS_IPV4;
socks_header->frag = 0;
- memcpy(mProxyWrappedSendBuffer + SOCKS_HEADER_SIZE, send_buffer, buf_size);
+ memcpy(headered_send_buffer + SOCKS_HEADER_SIZE, send_buffer, buf_size);
- return send_packet(h_socket, (const char*) mProxyWrappedSendBuffer, buf_size + 10, LLProxy::getInstance()->getUDPProxy().getAddress(), LLProxy::getInstance()->getUDPProxy().getPort());
+ return send_packet( h_socket,
+ headered_send_buffer,
+ buf_size + SOCKS_HEADER_SIZE,
+ LLProxy::getInstance()->getUDPProxy().getAddress(),
+ LLProxy::getInstance()->getUDPProxy().getPort());
}
diff --git a/indra/llmessage/llpacketring.h b/indra/llmessage/llpacketring.h
index 7edcc834db..b214271e78 100644
--- a/indra/llmessage/llpacketring.h
+++ b/indra/llmessage/llpacketring.h
@@ -83,9 +83,6 @@ protected:
LLHost mLastSender;
LLHost mLastReceivingIF;
-
- U8 mProxyWrappedSendBuffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
-
private:
BOOL sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host);
};
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index 19f1fc6545..4a7d326c0e 100644
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -43,7 +43,7 @@
bool LLProxy::sUDPProxyEnabled = false;
// Some helpful TCP static functions.
-static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
+static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
static LLSocket::ptr_t tcp_open_channel(LLHost host); // Open a TCP channel to a given host
static void tcp_close_channel(LLSocket::ptr_t* handle_ptr); // Close an open TCP channel
@@ -63,14 +63,13 @@ LLProxy::LLProxy():
LLProxy::~LLProxy()
{
stopSOCKSProxy();
- sUDPProxyEnabled = false;
- mHTTPProxyEnabled = false;
+ disableHTTPProxy();
}
/**
* @brief Open the SOCKS 5 TCP control channel.
*
- * Perform a SOCKS 5 authentication and UDP association to the proxy server.
+ * Perform a SOCKS 5 authentication and UDP association with the proxy server.
*
* @param proxy The SOCKS 5 server to connect to.
* @return SOCKS_OK if successful, otherwise a socks error code from llproxy.h.
@@ -83,11 +82,15 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
socks_auth_request_t socks_auth_request;
socks_auth_response_t socks_auth_response;
- socks_auth_request.version = SOCKS_VERSION; // SOCKS version 5
- socks_auth_request.num_methods = 1; // Sending 1 method.
- socks_auth_request.methods = getSelectedAuthMethod(); // Send only the selected method.
+ socks_auth_request.version = SOCKS_VERSION; // SOCKS version 5
+ socks_auth_request.num_methods = 1; // Sending 1 method.
+ socks_auth_request.methods = getSelectedAuthMethod(); // Send only the selected method.
- result = tcp_handshake(mProxyControlChannel, (char*)&socks_auth_request, sizeof(socks_auth_request), (char*)&socks_auth_response, sizeof(socks_auth_response));
+ result = tcp_blocking_handshake(mProxyControlChannel,
+ static_cast<char*>(static_cast<void*>(&socks_auth_request)),
+ sizeof(socks_auth_request),
+ static_cast<char*>(static_cast<void*>(&socks_auth_response)),
+ sizeof(socks_auth_response));
if (result != APR_SUCCESS)
{
LL_WARNS("Proxy") << "SOCKS authentication request failed, error on TCP control channel : " << result << LL_ENDL;
@@ -97,12 +100,12 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
if (socks_auth_response.method == AUTH_NOT_ACCEPTABLE)
{
- LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods" << LL_ENDL;
+ LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods." << LL_ENDL;
stopSOCKSProxy();
return SOCKS_NOT_ACCEPTABLE;
}
- // SOCKS 5 USERNAME/PASSWORD authentication
+ /* SOCKS 5 USERNAME/PASSWORD authentication */
if (socks_auth_response.method == METHOD_PASSWORD)
{
// The server has requested a username/password combination
@@ -114,11 +117,15 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
password_auth[1] = socks_username.size();
memcpy(&password_auth[2], socks_username.c_str(), socks_username.size());
password_auth[socks_username.size() + 2] = socks_password.size();
- memcpy(&password_auth[socks_username.size()+3], socks_password.c_str(), socks_password.size());
+ memcpy(&password_auth[socks_username.size() + 3], socks_password.c_str(), socks_password.size());
authmethod_password_reply_t password_reply;
- result = tcp_handshake(mProxyControlChannel, password_auth, request_size, (char*)&password_reply, sizeof(password_reply));
+ result = tcp_blocking_handshake(mProxyControlChannel,
+ password_auth,
+ request_size,
+ static_cast<char*>(static_cast<void*>(&password_reply)),
+ sizeof(password_reply));
delete[] password_auth;
if (result != APR_SUCCESS)
@@ -150,7 +157,11 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
// "If the client is not in possession of the information at the time of the UDP ASSOCIATE,
// the client MUST use a port number and address of all zeros. RFC 1928"
- result = tcp_handshake(mProxyControlChannel, (char*)&connect_request, sizeof(connect_request), (char*)&connect_reply, sizeof(connect_reply));
+ result = tcp_blocking_handshake(mProxyControlChannel,
+ static_cast<char*>(static_cast<void*>(&connect_request)),
+ sizeof(connect_request),
+ static_cast<char*>(static_cast<void*>(&connect_reply)),
+ sizeof(connect_reply));
if (result != APR_SUCCESS)
{
LL_WARNS("Proxy") << "SOCKS connect request failed, error on TCP control channel : " << result << LL_ENDL;
@@ -169,6 +180,7 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
mUDPProxy.setAddress(proxy.getAddress());
// The connection was successful. We now have the UDP port to send requests that need forwarding to.
LL_INFOS("Proxy") << "SOCKS 5 UDP proxy connected on " << mUDPProxy << LL_ENDL;
+
return SOCKS_OK;
}
@@ -176,7 +188,8 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
* @brief Initiates a SOCKS 5 proxy session.
*
* Performs basic checks on host to verify that it is a valid address. Opens the control channel
- * and then negotiates the proxy connection with the server.
+ * and then negotiates the proxy connection with the server. Closes any existing SOCKS
+ * connection before proceeding. Also disables an HTTP proxy if it is using SOCKS as the proxy.
*
*
* @param host Socks server to connect to.
@@ -184,43 +197,37 @@ S32 LLProxy::proxyHandshake(LLHost proxy)
*/
S32 LLProxy::startSOCKSProxy(LLHost host)
{
- S32 status = SOCKS_OK;
-
if (host.isOk())
{
mTCPProxy = host;
}
else
{
- status = SOCKS_INVALID_HOST;
+ return SOCKS_INVALID_HOST;
}
- if (mProxyControlChannel && status == SOCKS_OK)
- {
- tcp_close_channel(&mProxyControlChannel);
- }
+ // Close any running SOCKS connection.
+ stopSOCKSProxy();
- if (status == SOCKS_OK)
+ mProxyControlChannel = tcp_open_channel(mTCPProxy);
+ if (!mProxyControlChannel)
{
- mProxyControlChannel = tcp_open_channel(mTCPProxy);
- if (!mProxyControlChannel)
- {
- status = SOCKS_HOST_CONNECT_FAILED;
- }
+ return SOCKS_HOST_CONNECT_FAILED;
}
- if (status == SOCKS_OK)
- {
- status = proxyHandshake(mTCPProxy);
- }
- if (status == SOCKS_OK)
+ S32 status = proxyHandshake(mTCPProxy);
+
+ if (status != SOCKS_OK)
{
- sUDPProxyEnabled = true;
+ // Shut down the proxy if any of the above steps failed.
+ stopSOCKSProxy();
}
else
{
- stopSOCKSProxy();
+ // Connection was successful.
+ sUDPProxyEnabled = true;
}
+
return status;
}
@@ -241,7 +248,7 @@ void LLProxy::stopSOCKSProxy()
if (LLPROXY_SOCKS == getHTTPProxyType())
{
- void disableHTTPProxy();
+ disableHTTPProxy();
}
if (mProxyControlChannel)
@@ -350,16 +357,6 @@ void LLProxy::disableHTTPProxy()
}
/**
- * @brief Get the HTTP proxy address and port
- */
-//
-LLHost LLProxy::getHTTPProxy() const
-{
- LLMutexLock lock(&mProxyMutex);
- return mHTTPProxy;
-}
-
-/**
* @brief Get the currently selected HTTP proxy type
*/
LLHttpProxyType LLProxy::getHTTPProxyType() const
@@ -440,21 +437,21 @@ void LLProxy::applyProxySettings(CURL* handle)
// Now test again to verify that the proxy wasn't disabled between the first check and the lock.
if (mHTTPProxyEnabled)
{
- check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()));
- check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()));
+ LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()));
+ LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()));
if (mProxyType == LLPROXY_SOCKS)
{
- check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5));
+ LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5));
if (mAuthMethodSelected == METHOD_PASSWORD)
{
std::string auth_string = mSocksUsername + ":" + mSocksPassword;
- check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()));
+ LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()));
}
}
else
{
- check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP));
+ LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP));
}
}
}
@@ -473,7 +470,7 @@ void LLProxy::applyProxySettings(CURL* handle)
* @param maxinlen Maximum possible length of received data. Short reads are allowed.
* @return Indicates APR status code of exchange. APR_SUCCESS if exchange was successful, -1 if invalid data length was received.
*/
-static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen)
+static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen)
{
apr_socket_t* apr_socket = handle->getSocket();
apr_status_t rv = APR_SUCCESS;
@@ -522,7 +519,6 @@ static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outl
*
* Checks for a successful connection, and makes sure the connection is closed if it fails.
*
- * @param pool APR pool to pass into the LLSocket.
* @param host The host to open the connection to.
* @return The created socket. Will evaluate as NULL if the connection is unsuccessful.
*/
@@ -541,7 +537,7 @@ static LLSocket::ptr_t tcp_open_channel(LLHost host)
/**
* @brief Close the socket.
*
- * @param handle_ptr A pointer-to-pointer to avoid increasing the use count.
+ * @param handle_ptr The handle of the socket being closed. A pointer-to-pointer to avoid increasing the use count.
*/
static void tcp_close_channel(LLSocket::ptr_t* handle_ptr)
{
diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h
index 621debb61d..a919370540 100644
--- a/indra/llmessage/llproxy.h
+++ b/indra/llmessage/llproxy.h
@@ -36,7 +36,6 @@
#include <string>
// SOCKS error codes returned from the StartProxy method
-
#define SOCKS_OK 0
#define SOCKS_CONNECT_ERROR (-1)
#define SOCKS_NOT_PERMITTED (-2)
@@ -46,7 +45,6 @@
#define SOCKS_HOST_CONNECT_FAILED (-6)
#define SOCKS_INVALID_HOST (-7)
-
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN (255 + 1) /* socks5: 255, +1 for len. */
#endif
@@ -225,62 +223,71 @@ class LLProxy: public LLSingleton<LLProxy>
{
LOG_CLASS(LLProxy);
public:
- // METHODS THAT DO NOT LOCK mProxyMutex!
-
+ /*###########################################################################################
+ METHODS THAT DO NOT LOCK mProxyMutex!
+ ###########################################################################################*/
+ // Constructor, cannot have parameters due to LLSingleton parent class. Call from main thread only.
LLProxy();
- // static check for enabled status for UDP packets
+ // Static check for enabled status for UDP packets. Call from main thread only.
static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; }
- // check for enabled status for HTTP packets
- // mHTTPProxyEnabled is atomic, so no locking is required for thread safety.
- bool isHTTPProxyEnabled() const { return mHTTPProxyEnabled; }
-
- // Get the UDP proxy address and port
+ // Get the UDP proxy address and port. Call from main thread only.
LLHost getUDPProxy() const { return mUDPProxy; }
- // Get the SOCKS 5 TCP control channel address and port
- LLHost getTCPProxy() const { return mTCPProxy; }
+ /*###########################################################################################
+ END OF NON-LOCKING METHODS
+ ###########################################################################################*/
- // END OF NON-LOCKING METHODS
+ /*###########################################################################################
+ METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!
+ ###########################################################################################*/
+ // Destructor, closes open connections. Do not call directly, use cleanupClass().
+ ~LLProxy();
- // METHODS THAT DO LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!
+ // Delete LLProxy singleton. Allows the apr_socket used in the SOCKS 5 control channel to be
+ // destroyed before the call to apr_terminate. Call from main thread only.
+ static void cleanupClass();
- ~LLProxy();
+ // Apply the current proxy settings to a curl request. Doesn't do anything if mHTTPProxyEnabled is false.
+ // Safe to call from any thread.
+ void applyProxySettings(CURL* handle);
+ void applyProxySettings(LLCurl::Easy* handle);
+ void applyProxySettings(LLCurlEasyRequest* handle);
- // Start a connection to the SOCKS 5 proxy
+ // Start a connection to the SOCKS 5 proxy. Call from main thread only.
S32 startSOCKSProxy(LLHost host);
- // Disconnect and clean up any connection to the SOCKS 5 proxy
+ // Disconnect and clean up any connection to the SOCKS 5 proxy. Call from main thread only.
void stopSOCKSProxy();
- // Delete LLProxy singleton, destroying the APR pool used by the control channel.
- static void cleanupClass();
-
- // Set up to use Password auth when connecting to the SOCKS proxy
+ // Use Password auth when connecting to the SOCKS proxy. Call from main thread only.
bool setAuthPassword(const std::string &username, const std::string &password);
- // Set up to use No Auth when connecting to the SOCKS proxy
+ // Disable authentication when connecting to the SOCKS proxy. Call from main thread only.
void setAuthNone();
- // Get the currently selected auth method.
- LLSocks5AuthType getSelectedAuthMethod() const;
-
- // Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy
- // as specified in type
+ // Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy.
+ // as specified in type. Call from main thread only.
bool enableHTTPProxy(LLHost httpHost, LLHttpProxyType type);
bool enableHTTPProxy();
- // Stop proxying HTTP packets
+ // Stop proxying HTTP packets. Call from main thread only.
void disableHTTPProxy();
- // Apply the current proxy settings to a curl request. Doesn't do anything if mHTTPProxyEnabled is false.
- void applyProxySettings(CURL* handle);
- void applyProxySettings(LLCurl::Easy* handle);
- void applyProxySettings(LLCurlEasyRequest* handle);
+ /*###########################################################################################
+ END OF LOCKING METHODS
+ ###########################################################################################*/
+private:
+ /*###########################################################################################
+ METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!
+ ###########################################################################################*/
- // Get the HTTP proxy address and port
- LLHost getHTTPProxy() const;
+ // Perform a SOCKS 5 authentication and UDP association with the proxy server.
+ S32 proxyHandshake(LLHost proxy);
+
+ // Get the currently selected auth method.
+ LLSocks5AuthType getSelectedAuthMethod() const;
// Get the currently selected HTTP proxy type
LLHttpProxyType getHTTPProxyType() const;
@@ -288,21 +295,21 @@ public:
std::string getSocksPwd() const;
std::string getSocksUser() const;
- // END OF LOCKING METHODS
-private:
- // Open a communication channel to the SOCKS 5 proxy proxy, at port messagePort
- S32 proxyHandshake(LLHost proxy);
+ /*###########################################################################################
+ END OF LOCKING METHODS
+ ###########################################################################################*/
private:
- // Is the HTTP proxy enabled?
- // Safe to read in any thread, do not write directly,
- // use enableHTTPProxy() and disableHTTPProxy() instead.
+ // Is the HTTP proxy enabled? Safe to read in any thread, but do not write directly.
+ // Instead use enableHTTPProxy() and disableHTTPProxy() instead.
mutable LLAtomic32<bool> mHTTPProxyEnabled;
- // Mutex to protect shared members in non-main thread calls to applyProxySettings()
+ // Mutex to protect shared members in non-main thread calls to applyProxySettings().
mutable LLMutex mProxyMutex;
- // MEMBERS READ AND WRITTEN ONLY IN THE MAIN THREAD. DO NOT SHARE!
+ /*###########################################################################################
+ MEMBERS READ AND WRITTEN ONLY IN THE MAIN THREAD. DO NOT SHARE!
+ ###########################################################################################*/
// Is the UDP proxy enabled?
static bool sUDPProxyEnabled;
@@ -315,9 +322,13 @@ private:
// socket handle to proxy TCP control channel
LLSocket::ptr_t mProxyControlChannel;
- // END OF UNSHARED MEMBERS
+ /*###########################################################################################
+ END OF UNSHARED MEMBERS
+ ###########################################################################################*/
- // MEMBERS WRITTEN IN MAIN THREAD AND READ IN ANY THREAD. ONLY READ OR WRITE AFTER LOCKING mProxyMutex!
+ /*###########################################################################################
+ MEMBERS WRITTEN IN MAIN THREAD AND READ IN ANY THREAD. ONLY READ OR WRITE AFTER LOCKING mProxyMutex!
+ ###########################################################################################*/
// HTTP proxy address and port
LLHost mHTTPProxy;
@@ -325,7 +336,7 @@ private:
// Currently selected HTTP proxy type. Can be web or socks.
LLHttpProxyType mProxyType;
- // SOCKS 5 auth method selected
+ // SOCKS 5 selected authentication method.
LLSocks5AuthType mAuthMethodSelected;
// SOCKS 5 username
@@ -333,7 +344,9 @@ private:
// SOCKS 5 password
std::string mSocksPassword;
- // END OF SHARED MEMBERS
+ /*###########################################################################################
+ END OF SHARED MEMBERS
+ ###########################################################################################*/
};
#endif
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 6085c61f9a..ffe5908a9d 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -245,7 +245,6 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica
LLParamSDParser parser;
parser.writeSD(mFormData, p.form_elements);
- mFormData = mFormData[""];
if (!mFormData.isArray())
{
// change existing contents to a one element array
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index eff572b553..ab777d37a5 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -88,10 +88,10 @@ struct LLNotificationTemplate
{
private:
// this idiom allows
- // <notification unique="true">
+ // <notification> <unique/> </notification>
// as well as
// <notification> <unique> <context></context> </unique>...
- Optional<bool> dummy_val;
+ Flag dummy_val;
public:
Multiple<UniquenessContext> contexts;
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index b44b4c36b6..fe3f688fc5 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -223,6 +223,15 @@ BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask)
return FALSE;
}
+BOOL LLScrollContainer::handleUnicodeCharHere(llwchar uni_char)
+{
+ if (mScrolledView && mScrolledView->handleUnicodeCharHere(uni_char))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks )
{
// Give event to my child views - they may have scroll bars
diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h
index 46a71a7e30..3aa79cc255 100644
--- a/indra/llui/llscrollcontainer.h
+++ b/indra/llui/llscrollcontainer.h
@@ -103,6 +103,7 @@ public:
// LLView functionality
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
virtual BOOL handleKeyHere(KEY key, MASK mask);
+ virtual BOOL handleUnicodeCharHere(llwchar uni_char);
virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
index 9ad13054cb..04919e6991 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llui/llsdparam.cpp
@@ -183,7 +183,7 @@ LLSD* LLParamSDParser::getSDWriteNode(const parser_t::name_stack_t& name_stack)
}
}
- LLSD* child_sd = &(*sd_to_write)[it->first];
+ LLSD* child_sd = it->first.empty() ? sd_to_write : &(*sd_to_write)[it->first];
if (child_sd->isArray())
{
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index f0ba7fc7d7..d345ad4cd0 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -125,12 +125,12 @@ private:
// base case for recursion, there are NO base classes of LLInitParam::BaseBlock
template<int DUMMY>
- class ParamDefaults<LLInitParam::BaseBlock, DUMMY> : public LLSingleton<ParamDefaults<LLInitParam::BaseBlock, DUMMY> >
+ class ParamDefaults<LLInitParam::BaseBlockWithFlags, DUMMY> : public LLSingleton<ParamDefaults<LLInitParam::BaseBlockWithFlags, DUMMY> >
{
public:
- const LLInitParam::BaseBlock& get() { return mBaseBlock; }
+ const LLInitParam::BaseBlockWithFlags& get() { return mBaseBlock; }
private:
- LLInitParam::BaseBlock mBaseBlock;
+ LLInitParam::BaseBlockWithFlags mBaseBlock;
};
public:
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 9d0fe781ce..69dcd474f7 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -289,15 +289,15 @@ namespace LLInitParam
protected:
bool anyProvided() const { return mIsProvided; }
- Param(class BaseBlock* enclosing_block);
+ Param(BaseBlock* enclosing_block);
// store pointer to enclosing block as offset to reduce space and allow for quick copying
- class BaseBlock& enclosingBlock() const
+ BaseBlock& enclosingBlock() const
{
const U8* my_addr = reinterpret_cast<const U8*>(this);
// get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class
- return *const_cast<class BaseBlock*>
- (reinterpret_cast<const class BaseBlock*>
+ return *const_cast<BaseBlock*>
+ (reinterpret_cast<const BaseBlock*>
(my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));
}
@@ -367,18 +367,16 @@ namespace LLInitParam
typedef boost::unordered_map<const std::string, ParamDescriptorPtr> param_map_t;
typedef std::vector<ParamDescriptorPtr> param_list_t;
- typedef std::list<ParamDescriptorPtr> all_params_list_t;
+ typedef std::list<ParamDescriptorPtr> all_params_list_t;
typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t;
param_map_t mNamedParams; // parameters with associated names
param_list_t mUnnamedParams; // parameters with_out_ associated names
param_validation_list_t mValidationList; // parameters that must be validated
all_params_list_t mAllParams; // all parameters, owns descriptors
-
- size_t mMaxParamOffset;
-
- EInitializationState mInitializationState; // whether or not static block data has been initialized
- class BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
+ size_t mMaxParamOffset;
+ EInitializationState mInitializationState; // whether or not static block data has been initialized
+ BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
};
class BaseBlock
@@ -499,6 +497,92 @@ namespace LLInitParam
const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
};
+ class BaseBlockWithFlags : public BaseBlock
+ {
+ public:
+ class FlagBase : public Param
+ {
+ public:
+ typedef FlagBase self_t;
+
+ FlagBase(const char* name, BaseBlock* enclosing_block) : Param(enclosing_block)
+ {
+ if (LL_UNLIKELY(enclosing_block->mostDerivedBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
+ {
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ enclosing_block->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ NULL,
+ &inspectParam,
+ 0, 1));
+ BaseBlock::addParam(enclosing_block->mostDerivedBlockDescriptor(), param_descriptor, name);
+ }
+ }
+
+ bool isProvided() const { return anyProvided(); }
+
+ private:
+ static bool mergeWith(Param& dst, const Param& src, bool overwrite)
+ {
+ const self_t& src_typed_param = static_cast<const self_t&>(src);
+ self_t& dst_typed_param = static_cast<self_t&>(dst);
+
+ if (src_typed_param.isProvided()
+ && (overwrite || !dst_typed_param.isProvided()))
+ {
+ dst.setProvided(true);
+ return true;
+ }
+ return false;
+ }
+
+ static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
+ {
+ self_t& typed_param = static_cast<self_t&>(param);
+
+ // no further names in stack, parse value now
+ if (name_stack.first == name_stack.second)
+ {
+ typed_param.setProvided(true);
+ typed_param.enclosingBlock().paramChanged(param, true);
+ return true;
+ }
+
+ return false;
+ }
+
+ static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ {
+ const self_t& typed_param = static_cast<const self_t&>(param);
+ const self_t* typed_diff_param = static_cast<const self_t*>(diff_param);
+
+ if (!typed_param.isProvided()) return;
+
+ if (!name_stack.empty())
+ {
+ name_stack.back().second = parser.newParseGeneration();
+ }
+
+ // then try to serialize value directly
+ if (!typed_diff_param || !typed_diff_param->isProvided())
+ {
+ if (!parser.writeValue(NoParamValue(), name_stack))
+ {
+ return;
+ }
+ }
+ }
+
+ static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
+ {
+ // tell parser about our actual type
+ parser.inspectValue<NoParamValue>(name_stack, min_count, max_count, NULL);
+ }
+ };
+ };
+
// these templates allow us to distinguish between template parameters
// that derive from BaseBlock and those that don't
template<typename T, typename Void = void>
@@ -1424,7 +1508,7 @@ namespace LLInitParam
}
};
- template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
+ template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlockWithFlags>
class Block
: public BASE_BLOCK
{
@@ -1520,6 +1604,13 @@ namespace LLInitParam
};
+ class Flag : public BaseBlockWithFlags::FlagBase
+ {
+ public:
+ Flag(const char* name) : FlagBase(name, DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr)
+ {}
+ };
+
template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >
class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
{
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index 72a7bb7af5..4af077b22c 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -440,12 +440,11 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block)
&& nodep->mAttributes.empty()
&& nodep->getSanitizedValue().empty())
{
- // empty node, just parse as NoValue
+ // empty node, just parse as flag
mCurReadNode = DUMMY_NODE;
return block.submitValue(mNameStack, *this, silent);
}
-
// submit attributes for current node
values_parsed |= readAttributes(nodep, block);
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 7ab9f36b87..60025707a4 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1858,7 +1858,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>Cursor3D</key>
<map>
@@ -4059,7 +4059,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>http://search.secondlife.com/viewer/[CATEGORY]/?q=[QUERY]</string>
+ <string>http://search.secondlife.com/viewer/[CATEGORY]/?q=[QUERY]&amp;p=[AUTH_TOKEN]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
</map>
<key>WebProfileURL</key>
<map>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index c7140283f1..d8295ddb87 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -34,15 +34,15 @@
<string />
</map>
<key>LastInventoryInboxActivity</key>
- <map>
- <key>Comment</key>
+ <map>
+ <key>Comment</key>
<string>The last time the received items inbox was poked by the user.</string>
- <key>Persist</key>
+ <key>Persist</key>
<integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string />
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>0</integer>
</map>
<key>LastLogoff</key>
<map>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 7e597fe5dc..4e1ef59765 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -786,6 +786,12 @@ bool LLAppViewer::init()
&LLUI::sGLScaleFactor);
LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ;
+ // Setup paths and LLTrans after LLUI::initClass has been called.
+ LLUI::setupPaths();
+ LLTransUtil::parseStrings("strings.xml", default_trans_args);
+ LLTransUtil::parseLanguageStrings("language_settings.xml");
+
+ // Setup notifications after LLUI::setupPaths() has been called.
LLNotifications::instance();
LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ;
@@ -831,12 +837,6 @@ bool LLAppViewer::init()
LLError::setPrintLocation(true);
}
-
- // Setup paths and LLTrans after LLUI::initClass has been called
- LLUI::setupPaths();
- LLTransUtil::parseStrings("strings.xml", default_trans_args);
- LLTransUtil::parseLanguageStrings("language_settings.xml");
-
// LLKeyboard relies on LLUI to know what some accelerator keys are called.
LLKeyboard::setStringTranslatorFunc( LLTrans::getKeyboardString );
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 79e6c7b66b..c8cfe5b51e 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -201,7 +201,8 @@ public:
};
LLBottomTray::LLBottomTray(const LLSD&)
-: mChicletPanel(NULL),
+: mDesiredNearbyChatWidth(0),
+ mChicletPanel(NULL),
mSpeakPanel(NULL),
mSpeakBtn(NULL),
mNearbyChatBar(NULL),
@@ -1095,33 +1096,35 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width)
if (still_should_be_processed)
{
processShrinkButtons(delta_width, buttons_freed_width);
+ still_should_be_processed = delta_width < 0;
}
+
// 3. Decreasing width of nearby chat.
const S32 chatbar_panel_min_width = get_panel_min_width(mToolbarStack, mChatBarContainer);
const S32 chatbar_panel_width = mChatBarContainer->getRect().getWidth();
if (still_should_be_processed && chatbar_panel_width > chatbar_panel_min_width)
{
// we have some space to decrease chatbar panel
- S32 panel_delta_min = chatbar_panel_width - chatbar_panel_min_width;
+ S32 chatbar_shrink_headroom = chatbar_panel_width - chatbar_panel_min_width;
- S32 delta_panel = llmin(-delta_width, panel_delta_min);
+ S32 shrink_by = llmin(-delta_width, chatbar_shrink_headroom);
// is chatbar panel wide enough to process resizing?
- delta_width += panel_delta_min;
+ delta_width += chatbar_shrink_headroom;
still_should_be_processed = delta_width < 0;
// chatbar should only be shrunk here, not stretched
- if(delta_panel > 0)
+ if (shrink_by > 0)
{
- lldebugs << "Shrinking nearby chat bar by " << delta_panel << " px " << llendl;
- mChatBarContainer->reshape(mNearbyChatBar->getRect().getWidth() - delta_panel, mChatBarContainer->getRect().getHeight());
+ lldebugs << "Shrinking nearby chat bar by " << shrink_by << " px " << llendl;
+ mChatBarContainer->reshape(mNearbyChatBar->getRect().getWidth() - shrink_by, mChatBarContainer->getRect().getHeight());
}
log(mNearbyChatBar, "after processing panel decreasing via nearby chatbar panel");
lldebugs << "RS_CHATBAR_INPUT"
- << ", delta_panel: " << delta_panel
+ << ", shrink_by: " << shrink_by
<< ", delta_width: " << delta_width
<< llendl;
}
@@ -1200,16 +1203,16 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
<< ", mDesiredNearbyChatWidth = " << mDesiredNearbyChatWidth << llendl;
if (delta_width > 0 && chatbar_panel_width < mDesiredNearbyChatWidth)
{
- S32 delta_panel_max = mDesiredNearbyChatWidth - chatbar_panel_width;
- S32 delta_panel = llmin(delta_width, delta_panel_max);
- lldebugs << "Unprocesed delta width: " << delta_width
- << ", can be applied to chatbar: " << delta_panel_max
- << ", will be applied: " << delta_panel
+ S32 extend_by_max = mDesiredNearbyChatWidth - chatbar_panel_width;
+ S32 extend_by = llmin(delta_width, extend_by_max);
+ lldebugs << "Unprocessed delta width: " << delta_width
+ << " px, chatbar can be extended by " << extend_by_max
+ << " px, extending it by " << extend_by << " px"
<< llendl;
- delta_width -= delta_panel_max;
- lldebugs << "Extending nearby chat bar by " << delta_panel << " px " << llendl;
- mChatBarContainer->reshape(chatbar_panel_width + delta_panel, mChatBarContainer->getRect().getHeight());
+ delta_width -= extend_by_max;
+ lldebugs << "Extending nearby chat bar by " << extend_by << " px " << llendl;
+ mChatBarContainer->reshape(chatbar_panel_width + extend_by, mChatBarContainer->getRect().getHeight());
log(mNearbyChatBar, "applied unprocessed delta width");
}
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index 62718531ef..e26b0792e9 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -323,7 +323,7 @@ private:
void processExtendButtons(S32& available_width);
/**
- * Extends the Speak button if there is anough headroom.
+ * Extends the Speak button if there is enough headroom.
*
* Unlike other buttons, the Speak buttons has only two possible widths:
* the minimal one (without label) and the maximal (default) one.
diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp
index 216cc66ef8..cc6ba05e7e 100644
--- a/indra/newview/lldebugview.cpp
+++ b/indra/newview/lldebugview.cpp
@@ -41,6 +41,7 @@
#include "llmemoryview.h"
#include "llsceneview.h"
#include "llviewertexture.h"
+#include "llfloaterreg.h"
//
// Globals
@@ -79,12 +80,7 @@ void LLDebugView::init()
r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f),
(S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f));
- mFastTimerView = new LLFastTimerView(r);
- mFastTimerView->setFollowsTop();
- mFastTimerView->setFollowsLeft();
- mFastTimerView->setVisible(FALSE); // start invisible
- addChild(mFastTimerView);
- mFastTimerView->setRect(rect);
+ mFastTimerView = dynamic_cast<LLFastTimerView*>(LLFloaterReg::getInstance("fast_timers"));
gSceneView = new LLSceneView(r);
gSceneView->setFollowsTop();
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 366154302c..a161428c2b 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -80,12 +80,10 @@ static timer_tree_iterator_t end_timer_tree()
return timer_tree_iterator_t();
}
-LLFastTimerView::LLFastTimerView(const LLRect& rect)
-: LLFloater(LLSD()),
+LLFastTimerView::LLFastTimerView(const LLSD& key)
+: LLFloater(key),
mHoverTimer(NULL)
{
- setRect(rect);
- setVisible(FALSE);
mDisplayMode = 0;
mAvgCountTotal = 0;
mMaxCountTotal = 0;
@@ -98,10 +96,30 @@ LLFastTimerView::LLFastTimerView(const LLRect& rect)
FTV_NUM_TIMERS = LLFastTimer::NamedTimer::instanceCount();
mPrintStats = -1;
mAverageCyclesPerTimer = 0;
- setCanMinimize(false);
- setCanClose(true);
}
+void LLFastTimerView::onPause()
+{
+ LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory;
+ // reset scroll to bottom when unpausing
+ if (!LLFastTimer::sPauseHistory)
+ {
+ mScrollIndex = 0;
+ getChild<LLButton>("pause_btn")->setLabel(getString("pause"));
+ }
+ else
+ {
+ getChild<LLButton>("pause_btn")->setLabel(getString("run"));
+ }
+}
+
+BOOL LLFastTimerView::postBuild()
+{
+ LLButton& pause_btn = getChildRef<LLButton>("pause_btn");
+
+ pause_btn.setCommitCallback(boost::bind(&LLFastTimerView::onPause, this));
+ return TRUE;
+}
BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
@@ -116,14 +134,16 @@ BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
mHoverTimer->getParent()->setCollapsed(true);
}
+ return TRUE;
}
else if (mBarRect.pointInRect(x, y))
{
S32 bar_idx = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight());
bar_idx = llclamp(bar_idx, 0, MAX_VISIBLE_HISTORY);
mPrintStats = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - bar_idx;
+ return TRUE;
}
- return FALSE;
+ return LLFloater::handleRightMouseDown(x, y, mask);
}
LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y)
@@ -151,18 +171,6 @@ BOOL LLFastTimerView::handleDoubleClick(S32 x, S32 y, MASK mask)
BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
{
-
- {
- S32 local_x = x - mButtons[BUTTON_CLOSE]->getRect().mLeft;
- S32 local_y = y - mButtons[BUTTON_CLOSE]->getRect().mBottom;
- if(mButtons[BUTTON_CLOSE]->getVisible()
- && mButtons[BUTTON_CLOSE]->pointInView(local_x, local_y) )
- {
- return LLFloater::handleMouseDown(x, y, mask);;
- }
- }
-
-
if (x < mBarRect.mLeft)
{
LLFastTimer::NamedTimer* idp = getLegendID(y);
@@ -196,36 +204,42 @@ BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
{
mDisplayCenter = (ChildAlignment)((mDisplayCenter + 1) % ALIGN_COUNT);
}
- else
+ else if (mGraphRect.pointInRect(x, y))
{
- // pause/unpause
- LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory;
- // reset scroll to bottom when unpausing
- if (!LLFastTimer::sPauseHistory)
- {
- mScrollIndex = 0;
- }
+ gFocusMgr.setMouseCapture(this);
+ return TRUE;
}
- // SJB: Don't pass mouse clicks through the display
- return TRUE;
+ //else
+ //{
+ // // pause/unpause
+ // LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory;
+ // // reset scroll to bottom when unpausing
+ // if (!LLFastTimer::sPauseHistory)
+ // {
+ // mScrollIndex = 0;
+ // }
+ //}
+ return LLFloater::handleMouseDown(x, y, mask);
}
BOOL LLFastTimerView::handleMouseUp(S32 x, S32 y, MASK mask)
{
+ if (hasMouseCapture())
{
- S32 local_x = x - mButtons[BUTTON_CLOSE]->getRect().mLeft;
- S32 local_y = y - mButtons[BUTTON_CLOSE]->getRect().mBottom;
- if(mButtons[BUTTON_CLOSE]->getVisible()
- && mButtons[BUTTON_CLOSE]->pointInView(local_x, local_y) )
- {
- return LLFloater::handleMouseUp(x, y, mask);;
- }
+ gFocusMgr.setMouseCapture(NULL);
}
- return FALSE;
+ return LLFloater::handleMouseUp(x, y, mask);;
}
BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
{
+ if (hasMouseCapture())
+ {
+ F32 lerp = llclamp(1.f - (F32) (x - mGraphRect.mLeft) / (F32) mGraphRect.getWidth(), 0.f, 1.f);
+ mScrollIndex = llround( lerp * (F32)(LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY));
+ mScrollIndex = llclamp( mScrollIndex, 0, LLFastTimer::getLastFrameIndex());
+ return TRUE;
+ }
mHoverTimer = NULL;
mHoverID = NULL;
@@ -282,7 +296,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
}
}
- return FALSE;
+ return LLFloater::handleHover(x, y, mask);
}
@@ -318,15 +332,15 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)
}
}
}
-
- return FALSE;
+
+ return LLFloater::handleToolTip(x, y, mask);
}
BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
LLFastTimer::sPauseHistory = TRUE;
- mScrollIndex = llclamp(mScrollIndex - clicks,
- 0,
+ mScrollIndex = llclamp( mScrollIndex + clicks,
+ 0,
llmin(LLFastTimer::getLastFrameIndex(), (S32)LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY));
return TRUE;
}
@@ -345,8 +359,8 @@ void LLFastTimerView::draw()
F64 iclock_freq = 1000.0 / clock_freq;
S32 margin = 10;
- S32 height = (S32) (gViewerWindow->getWindowRectScaled().getHeight()*0.75f);
- S32 width = (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f);
+ S32 height = getRect().getHeight();
+ S32 width = getRect().getWidth();
LLRect new_rect;
new_rect.setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height);
@@ -630,7 +644,6 @@ void LLFastTimerView::draw()
LLFontGL::LEFT, LLFontGL::TOP);
}
- LLRect graph_rect;
// Draw borders
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -663,9 +676,9 @@ void LLFastTimerView::draw()
by = LINE_GRAPH_HEIGHT-barh-dy-7;
//line graph
- graph_rect = LLRect(xleft-5, by, getRect().getWidth()-5, 5);
+ mGraphRect = LLRect(xleft-5, by, getRect().getWidth()-5, 5);
- gl_rect_2d(graph_rect, FALSE);
+ gl_rect_2d(mGraphRect, FALSE);
}
mBarStart.clear();
@@ -813,7 +826,7 @@ void LLFastTimerView::draw()
//draw line graph history
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLLocalClipRect clip(graph_rect);
+ LLLocalClipRect clip(mGraphRect);
//normalize based on last frame's maximum
static U64 last_max = 0;
@@ -830,8 +843,8 @@ void LLFastTimerView::draw()
else
tdesc = llformat("%4.2f ms", ms);
- x = graph_rect.mRight - LLFontGL::getFontMonospace()->getWidth(tdesc)-5;
- y = graph_rect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight());
+ x = mGraphRect.mRight - LLFontGL::getFontMonospace()->getWidth(tdesc)-5;
+ y = mGraphRect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight());
LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white,
LLFontGL::LEFT, LLFontGL::TOP);
@@ -841,24 +854,24 @@ void LLFastTimerView::draw()
S32 first_frame = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex;
S32 last_frame = first_frame - MAX_VISIBLE_HISTORY;
- F32 frame_delta = ((F32) (graph_rect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1);
+ F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1);
- F32 right = (F32) graph_rect.mLeft + frame_delta*first_frame;
- F32 left = (F32) graph_rect.mLeft + frame_delta*last_frame;
+ F32 right = (F32) mGraphRect.mLeft + frame_delta*first_frame;
+ F32 left = (F32) mGraphRect.mLeft + frame_delta*last_frame;
gGL.color4f(0.5f,0.5f,0.5f,0.3f);
- gl_rect_2d((S32) left, graph_rect.mTop, (S32) right, graph_rect.mBottom);
+ gl_rect_2d((S32) left, mGraphRect.mTop, (S32) right, mGraphRect.mBottom);
if (mHoverBarIndex >= 0)
{
S32 bar_frame = first_frame - mHoverBarIndex;
- F32 bar = (F32) graph_rect.mLeft + frame_delta*bar_frame;
+ F32 bar = (F32) mGraphRect.mLeft + frame_delta*bar_frame;
gGL.color4f(0.5f,0.5f,0.5f,1);
gGL.begin(LLRender::LINES);
- gGL.vertex2i((S32)bar, graph_rect.mBottom);
- gGL.vertex2i((S32)bar, graph_rect.mTop);
+ gGL.vertex2i((S32)bar, mGraphRect.mBottom);
+ gGL.vertex2i((S32)bar, mGraphRect.mTop);
gGL.end();
}
}
@@ -883,7 +896,7 @@ void LLFastTimerView::draw()
if (mHoverID != NULL &&
idp != mHoverID)
- { //fade out non-hihglighted timers
+ { //fade out non-highlighted timers
if (idp->getParent() != mHoverID)
{
alpha = alpha_interp;
@@ -891,8 +904,10 @@ void LLFastTimerView::draw()
}
gGL.color4f(col[0], col[1], col[2], alpha);
- gGL.begin(LLRender::LINE_STRIP);
- for (U32 j = 0; j < LLFastTimer::NamedTimer::HISTORY_NUM; j++)
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ for (U32 j = llmax(0, LLFastTimer::NamedTimer::HISTORY_NUM - LLFastTimer::getLastFrameIndex());
+ j < LLFastTimer::NamedTimer::HISTORY_NUM;
+ j++)
{
U64 ticks = idp->getHistoricalCount(j);
@@ -912,9 +927,10 @@ void LLFastTimerView::draw()
//normalize to highlighted timer
cur_max = llmax(cur_max, ticks);
}
- F32 x = graph_rect.mLeft + ((F32) (graph_rect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1)*j;
- F32 y = graph_rect.mBottom + (F32) graph_rect.getHeight()/max_ticks*ticks;
+ F32 x = mGraphRect.mLeft + ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1)*j;
+ F32 y = mGraphRect.mBottom + (F32) mGraphRect.getHeight()/max_ticks*ticks;
gGL.vertex2f(x,y);
+ gGL.vertex2f(x,mGraphRect.mBottom);
}
gGL.end();
@@ -932,18 +948,20 @@ void LLFastTimerView::draw()
}
//interpolate towards new maximum
- F32 dt = gFrameIntervalSeconds*3.f;
- last_max = (U64) ((F32) last_max + ((F32) cur_max- (F32) last_max) * dt);
+ last_max = (U64) lerp((F32)last_max, (F32) cur_max, LLCriticalDamp::getInterpolant(0.1f));
+ if (last_max - cur_max <= 1 || cur_max - last_max <= 1)
+ {
+ last_max = cur_max;
+ }
F32 alpha_target = last_max > cur_max ?
llmin((F32) last_max/ (F32) cur_max - 1.f,1.f) :
llmin((F32) cur_max/ (F32) last_max - 1.f,1.f);
-
- alpha_interp = alpha_interp + (alpha_target-alpha_interp) * dt;
+ alpha_interp = lerp(alpha_interp, alpha_target, LLCriticalDamp::getInterpolant(0.1f));
if (mHoverID != NULL)
{
- x = (graph_rect.mRight + graph_rect.mLeft)/2;
- y = graph_rect.mBottom + 8;
+ x = (mGraphRect.mRight + mGraphRect.mLeft)/2;
+ y = mGraphRect.mBottom + 8;
LLFontGL::getFontMonospace()->renderUTF8(
mHoverID->getName(),
diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h
index ea8251191b..a349e7ad4c 100644
--- a/indra/newview/llfasttimerview.h
+++ b/indra/newview/llfasttimerview.h
@@ -33,8 +33,9 @@
class LLFastTimerView : public LLFloater
{
public:
- LLFastTimerView(const LLRect& rect);
-
+ LLFastTimerView(const LLSD&);
+ BOOL postBuild();
+
static BOOL sAnalyzePerformance;
static void outputAllMetrics();
@@ -44,6 +45,7 @@ private:
static void doAnalysisDefault(std::string baseline, std::string target, std::string output) ;
static LLSD analyzePerformanceLogDefault(std::istream& is) ;
static void exportCharts(const std::string& base, const std::string& target);
+ void onPause();
public:
@@ -89,6 +91,7 @@ private:
LLFrameTimer mHighlightTimer;
S32 mPrintStats;
S32 mAverageCyclesPerTimer;
+ LLRect mGraphRect;
};
#endif
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index 23cc23376f..2a946b1edf 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -27,26 +27,16 @@
#include "llviewerprecompiledheaders.h"
-#include "llappviewer.h"
-#include "llbase64.h"
#include "llcommandhandler.h"
#include "llfloaterreg.h"
#include "llfloatersearch.h"
#include "llmediactrl.h"
#include "llnotificationsutil.h"
-#include "llparcel.h"
-#include "llplugincookiestore.h"
#include "lllogininstance.h"
#include "lluri.h"
#include "llagent.h"
-#include "llsdserialize.h"
#include "llui.h"
#include "llviewercontrol.h"
-#include "llviewerregion.h"
-#include "llversioninfo.h"
-#include "llviewermedia.h"
-#include "llviewernetwork.h"
-#include "llviewerparcelmgr.h"
#include "llweb.h"
// support secondlife:///app/search/{CATEGORY}/{QUERY} SLapps
@@ -178,14 +168,12 @@ void LLFloaterSearch::search(const SearchQuery &p)
// add the permissions token that login.cgi gave us
// We use "search_token", and fallback to "auth_token" if not present.
- LLSD search_cookie;
-
LLSD search_token = LLLoginInstance::getInstance()->getResponse("search_token");
if (search_token.asString().empty())
{
search_token = LLLoginInstance::getInstance()->getResponse("auth_token");
}
- search_cookie["AUTH_TOKEN"] = search_token.asString();
+ subs["AUTH_TOKEN"] = search_token.asString();
// add the user's preferred maturity (can be changed via prefs)
std::string maturity;
@@ -201,57 +189,10 @@ void LLFloaterSearch::search(const SearchQuery &p)
{
maturity = "13"; // PG
}
- search_cookie["MATURITY"] = maturity;
+ subs["MATURITY"] = maturity;
// add the user's god status
- search_cookie["GODLIKE"] = gAgent.isGodlike() ? "1" : "0";
- search_cookie["VERSION"] = LLVersionInfo::getVersion();
- search_cookie["VERSION_MAJOR"] = LLVersionInfo::getMajor();
- search_cookie["VERSION_MINOR"] = LLVersionInfo::getMinor();
- search_cookie["VERSION_PATCH"] = LLVersionInfo::getPatch();
- search_cookie["VERSION_BUILD"] = LLVersionInfo::getBuild();
- search_cookie["CHANNEL"] = LLVersionInfo::getChannel();
- search_cookie["GRID"] = LLGridManager::getInstance()->getGridLabel();
- search_cookie["OS"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
- search_cookie["SESSION_ID"] = gAgent.getSessionID();
- search_cookie["FIRST_LOGIN"] = gAgent.isFirstLogin();
-
- std::string lang = LLUI::getLanguage();
- if (lang == "en-us")
- {
- lang = "en";
- }
- search_cookie["LANGUAGE"] = lang;
-
- // find the region ID
- LLUUID region_id;
- LLViewerRegion *region = gAgent.getRegion();
- if (region)
- {
- region_id = region->getRegionID();
- }
- search_cookie["REGION_ID"] = region_id;
-
- // find the parcel local ID
- S32 parcel_id = 0;
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (parcel)
- {
- parcel_id = parcel->getLocalID();
- }
- search_cookie["PARCEL_ID"] = llformat("%d", parcel_id);
-
- std::stringstream cookie_string_stream;
- LLSDSerialize::toXML(search_cookie, cookie_string_stream);
- std::string cookie_string = cookie_string_stream.str();
-
- U8* cookie_string_buffer = (U8*)cookie_string.c_str();
- std::string cookie_value = LLBase64::encode(cookie_string_buffer, cookie_string.size());
-
- // for staging services
- LLViewerMedia::getCookieStore()->setCookiesFromHost(std::string("viewer_session_info=") + cookie_value, ".lindenlab.com");
- // for live services
- LLViewerMedia::getCookieStore()->setCookiesFromHost(std::string("viewer_session_info=") + cookie_value, ".secondlife.com");
+ subs["GODLIKE"] = gAgent.isGodlike() ? "1" : "0";
// get the search URL and expand all of the substitutions
// (also adds things like [LANGUAGE], [VERSION], [OS], etc.)
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 8b72d83830..9ba5f827e2 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -1723,7 +1723,7 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char)
}
BOOL handled = FALSE;
- if (gFocusMgr.childHasKeyboardFocus(getRoot()))
+ if (mParentPanel->hasFocus())
{
// SL-51858: Key presses are not being passed to the Popup menu.
// A proper fix is non-trivial so instead just close the menu.
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 2888f779f4..622dcfe8dd 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -282,9 +282,9 @@ void LLFolderViewItem::refreshFromListener()
setToolTip(mLabel);
setIcon(mListener->getIcon());
time_t creation_date = mListener->getCreationDate();
- if (mCreationDate != creation_date)
+ if ((creation_date > 0) && (mCreationDate != creation_date))
{
- setCreationDate(mListener->getCreationDate());
+ setCreationDate(creation_date);
dirtyFilter();
}
if (mRoot->useLabelSuffix())
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index d6278a5fda..516b47e616 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -256,16 +256,20 @@ std::string::size_type LLInventoryFilter::getStringMatchOffset() const
// has user modified default filter params?
BOOL LLInventoryFilter::isNotDefault() const
{
- return mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes
- || mFilterOps.mFilterCategoryTypes != mDefaultFilterOps.mFilterCategoryTypes
- || mFilterOps.mFilterWearableTypes != mDefaultFilterOps.mFilterWearableTypes
- || mFilterOps.mFilterTypes != FILTERTYPE_OBJECT
- || mFilterOps.mFilterLinks != FILTERLINK_INCLUDE_LINKS
- || mFilterSubString.size()
- || mFilterOps.mPermissions != mDefaultFilterOps.mPermissions
- || mFilterOps.mMinDate != mDefaultFilterOps.mMinDate
- || mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate
- || mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo;
+ BOOL not_default = FALSE;
+
+ not_default |= (mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes);
+ not_default |= (mFilterOps.mFilterCategoryTypes != mDefaultFilterOps.mFilterCategoryTypes);
+ not_default |= (mFilterOps.mFilterWearableTypes != mDefaultFilterOps.mFilterWearableTypes);
+ not_default |= (mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes);
+ not_default |= (mFilterOps.mFilterLinks != mDefaultFilterOps.mFilterLinks);
+ not_default |= (mFilterSubString.size());
+ not_default |= (mFilterOps.mPermissions != mDefaultFilterOps.mPermissions);
+ not_default |= (mFilterOps.mMinDate != mDefaultFilterOps.mMinDate);
+ not_default |= (mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate);
+ not_default |= (mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo);
+
+ return not_default;
}
BOOL LLInventoryFilter::isActive() const
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 173e5c6ae6..615d3aefde 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -129,6 +129,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mScroller(NULL),
mSortOrderSetting(p.sort_order_setting),
mInventory(p.inventory),
+ mAcceptsDragAndDrop(p.accepts_drag_and_drop),
mAllowMultiSelect(p.allow_multi_select),
mShowItemLinkOverlays(p.show_item_link_overlays),
mShowLoadStatus(p.show_load_status),
@@ -824,19 +825,24 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EAcceptance* accept,
std::string& tooltip_msg)
{
- BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+ BOOL handled = FALSE;
- // If folder view is empty the (x, y) point won't be in its rect
- // so the handler must be called explicitly.
- // but only if was not handled before. See EXT-6746.
- if (!handled && !mFolderRoot->hasVisibleChildren())
+ if (mAcceptsDragAndDrop)
{
- handled = mFolderRoot->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
- }
+ handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
- if (handled)
- {
- mFolderRoot->setDragAndDropThisFrame();
+ // If folder view is empty the (x, y) point won't be in its rect
+ // so the handler must be called explicitly.
+ // but only if was not handled before. See EXT-6746.
+ if (!handled && !mFolderRoot->hasVisibleChildren())
+ {
+ handled = mFolderRoot->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+ }
+
+ if (handled)
+ {
+ mFolderRoot->setDragAndDropThisFrame();
+ }
}
return handled;
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index cfb84bf4b7..8635ebc5c8 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -86,6 +86,7 @@ public:
Optional<bool> use_label_suffix;
Optional<bool> show_load_status;
Optional<LLScrollContainer::Params> scroll;
+ Optional<bool> accepts_drag_and_drop;
Params()
: sort_order_setting("sort_order_setting"),
@@ -96,7 +97,8 @@ public:
start_folder("start_folder"),
use_label_suffix("use_label_suffix", true),
show_load_status("show_load_status"),
- scroll("scroll")
+ scroll("scroll"),
+ accepts_drag_and_drop("accepts_drag_and_drop")
{}
};
@@ -181,6 +183,7 @@ protected:
LLInventoryModel* mInventory;
LLInventoryObserver* mInventoryObserver;
LLInvPanelComplObserver* mCompletionObserver;
+ BOOL mAcceptsDragAndDrop;
BOOL mAllowMultiSelect;
BOOL mShowItemLinkOverlays; // Shows link graphic over inventory item icons
BOOL mShowLoadStatus;
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 1576ccccdf..bc594b5517 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -579,6 +579,11 @@ void LLPanelGroupGeneral::update(LLGroupChange gc)
}
+ // After role member data was changed in Roles->Members
+ // need to update role titles. See STORM-918.
+ if (gc == GC_ROLE_MEMBER_DATA)
+ LLGroupMgr::getInstance()->sendGroupTitlesRequest(mGroupID);
+
// If this was just a titles update, we are done.
if (gc == GC_TITLES) return;
diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp
index 2cb91f771f..0579ecbb90 100644
--- a/indra/newview/llpanelmarketplaceinbox.cpp
+++ b/indra/newview/llpanelmarketplaceinbox.cpp
@@ -97,6 +97,7 @@ LLInventoryPanel * LLPanelMarketplaceInbox::setupInventoryPanel()
// Set the sort order newest to oldest
mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);
+ mInventoryPanel->getFilter()->markDefault();
// Set selection callback for proper update of inventory status buttons
mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceInbox::onSelectionChange, this));
@@ -116,7 +117,7 @@ void LLPanelMarketplaceInbox::onFocusReceived()
sidepanel_inventory->clearSelections(true, false, true);
- gSavedPerAccountSettings.setString("LastInventoryInboxActivity", LLDate::now().asString());
+ gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
}
BOOL LLPanelMarketplaceInbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg)
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index d51aa73c93..faba6dc0cf 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -192,20 +192,19 @@ void LLInboxFolderViewFolder::draw()
void LLInboxFolderViewFolder::computeFreshness()
{
- const std::string& last_expansion = gSavedPerAccountSettings.getString("LastInventoryInboxActivity");
+ const U32 last_expansion_utc = gSavedPerAccountSettings.getU32("LastInventoryInboxActivity");
- if (!last_expansion.empty())
+ if (last_expansion_utc > 0)
{
- // Inventory DB timezone is hardcoded to PDT or GMT-7, which is 7 hours behind GMT
- const F64 SEVEN_HOURS_IN_SECONDS = 7 * 60 * 60;
- const F64 saved_freshness_inventory_db_timezone = LLDate(last_expansion).secondsSinceEpoch() - SEVEN_HOURS_IN_SECONDS;
+ const U32 time_offset_for_pdt = 7 * 60 * 60;
+ const U32 last_expansion = last_expansion_utc - time_offset_for_pdt;
- mFresh = (mCreationDate > saved_freshness_inventory_db_timezone);
+ mFresh = (mCreationDate > last_expansion);
#if DEBUGGING_FRESHNESS
if (mFresh)
{
- llinfos << "Item is fresh! -- creation " << mCreationDate << ", saved_freshness_date " << saved_freshness_inventory_db_timezone << llendl;
+ llinfos << "Item is fresh! -- creation " << mCreationDate << ", saved_freshness_date " << last_expansion << llendl;
}
#endif
}
@@ -219,7 +218,7 @@ void LLInboxFolderViewFolder::deFreshify()
{
mFresh = false;
- gSavedPerAccountSettings.setString("LastInventoryInboxActivity", LLDate::now().asString());
+ gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
}
void LLInboxFolderViewFolder::selectItem()
diff --git a/indra/newview/llpanelmarketplaceoutbox.cpp b/indra/newview/llpanelmarketplaceoutbox.cpp
index 839369bffe..73fb92ff72 100644
--- a/indra/newview/llpanelmarketplaceoutbox.cpp
+++ b/indra/newview/llpanelmarketplaceoutbox.cpp
@@ -117,8 +117,11 @@ LLInventoryPanel * LLPanelMarketplaceOutbox::setupInventoryPanel()
LLRect inventory_placeholder_rect = outbox_inventory_placeholder->getRect();
mInventoryPanel->setShape(inventory_placeholder_rect);
- // Set the sort order newest to oldest, and a selection change callback
+ // Set the sort order newest to oldest
mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);
+ mInventoryPanel->getFilter()->markDefault();
+
+ // Set selection callback for proper update of inventory status buttons
mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceOutbox::onSelectionChange, this));
// Set up the note to display when the outbox is empty
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 9814e5b81a..bd62b5c101 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -539,7 +539,7 @@ void LLSidepanelInventory::onToggleInboxBtn()
if (inbox_expanded && inboxPanel->isInVisibleChain())
{
- gSavedPerAccountSettings.setString("LastInventoryInboxActivity", LLDate::now().asString());
+ gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
}
}
@@ -568,7 +568,7 @@ void LLSidepanelInventory::onOpen(const LLSD& key)
#else
if (mInboxEnabled && getChild<LLButton>(INBOX_BUTTON_NAME)->getToggleState())
{
- gSavedPerAccountSettings.setString("LastInventoryInboxActivity", LLDate::now().asString());
+ gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
}
#endif
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index f53b08a4bc..55d6378ad8 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -62,6 +62,8 @@
using namespace std;
using namespace LLNotificationsUI;
+class LLSideTrayButton;
+
static LLRootViewRegistry::Register<LLSideTray> t1("side_tray");
static LLDefaultChildRegistry::Register<LLSideTrayTab> t2("sidetray_tab");
@@ -168,8 +170,131 @@ private:
bool mHasBadge;
LLBadge::Params mBadgeParams;
+ LLSideTrayButton* mSideTrayButton;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// LLSideTrayButton
+// Side Tray tab button with "tear off" handling.
+//////////////////////////////////////////////////////////////////////////////
+
+class LLSideTrayButton : public LLButton
+{
+public:
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask)
+ {
+ // Route future Mouse messages here preemptively. (Release on mouse up.)
+ // No handler needed for focus lost since this class has no state that depends on it.
+ gFocusMgr.setMouseCapture(this);
+
+ localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY);
+
+ // Note: don't pass on to children
+ return TRUE;
+ }
+
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask)
+ {
+ // We only handle the click if the click both started and ended within us
+ if( !hasMouseCapture() ) return FALSE;
+
+ S32 screen_x;
+ S32 screen_y;
+ localPointToScreen(x, y, &screen_x, &screen_y);
+
+ S32 delta_x = screen_x - mDragLastScreenX;
+ S32 delta_y = screen_y - mDragLastScreenY;
+
+ LLSideTray* side_tray = LLSideTray::getInstance();
+
+ // Check if the tab we are dragging is docked.
+ if (!side_tray->isTabAttached(mTabName)) return FALSE;
+
+ // Same value is hardcoded in LLDragHandle::handleHover().
+ const S32 undock_threshold = 12;
+
+ // Detach a tab if it has been pulled further than undock_threshold.
+ if (delta_x <= -undock_threshold || delta_x >= undock_threshold ||
+ delta_y <= -undock_threshold || delta_y >= undock_threshold)
+ {
+ LLSideTrayTab* tab = side_tray->getTab(mTabName);
+ if (!tab) return FALSE;
+
+ tab->setDocked(false);
+
+ LLFloater* floater_tab = LLFloaterReg::getInstance("side_bar_tab", tab->getName());
+ if (!floater_tab) return FALSE;
+
+ LLRect original_rect = floater_tab->getRect();
+ S32 header_snap_y = floater_tab->getHeaderHeight() / 2;
+ S32 snap_x = screen_x - original_rect.mLeft - original_rect.getWidth() / 2;
+ S32 snap_y = screen_y - original_rect.mTop + header_snap_y;
+
+ // Move the floater to appear "under" the mouse pointer.
+ floater_tab->setRect(original_rect.translate(snap_x, snap_y));
+
+ // Snap the mouse pointer to the center of the floater header
+ // and call 'mouse down' event handler to begin dragging.
+ floater_tab->handleMouseDown(original_rect.getWidth() / 2,
+ original_rect.getHeight() - header_snap_y,
+ mask);
+
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+ void setBadgeDriver(LLSideTrayTabBadgeDriver* driver)
+ {
+ mBadgeDriver = driver;
+ }
+
+ void setVisible(BOOL visible)
+ {
+ setBadgeVisibility(visible);
+
+ LLButton::setVisible(visible);
+ }
+
+protected:
+ LLSideTrayButton(const LLButton::Params& p)
+ : LLButton(p)
+ , mDragLastScreenX(0)
+ , mDragLastScreenY(0)
+ , mBadgeDriver(NULL)
+ {
+ // Find out the tab name to use in handleHover().
+ size_t pos = getName().find("_button");
+ llassert(pos != std::string::npos);
+ mTabName = getName().substr(0, pos);
+ }
+
+ friend class LLUICtrlFactory;
+
+ void draw()
+ {
+ if (mBadgeDriver)
+ {
+ setBadgeLabel(mBadgeDriver->getBadgeString());
+ }
+
+ LLButton::draw();
+ }
+
+private:
+ S32 mDragLastScreenX;
+ S32 mDragLastScreenY;
+
+ std::string mTabName;
+ LLSideTrayTabBadgeDriver* mBadgeDriver;
};
+
+////////////////////////////////////////////////////
+// LLSideTrayTab implementation
+////////////////////////////////////////////////////
+
LLSideTrayTab::LLSideTrayTab(const Params& p)
: LLPanel(),
mTabTitle(p.tab_title),
@@ -177,7 +302,8 @@ LLSideTrayTab::LLSideTrayTab(const Params& p)
mImageSelected(p.image_selected),
mDescription(p.description),
mMainPanel(NULL),
- mBadgeParams(p.badge)
+ mBadgeParams(p.badge),
+ mSideTrayButton(NULL)
{
mHasBadge = p.badge.isProvided();
}
@@ -271,6 +397,11 @@ void LLSideTrayTab::toggleTabDocked(bool toggle_floater /* = true */)
bool docking = !isDocked();
+ if (mSideTrayButton)
+ {
+ mSideTrayButton->setVisible(docking);
+ }
+
// Hide the "Tear Off" button when a tab gets undocked
// and show "Dock" button instead.
getChild<LLButton>("undock")->setVisible(docking);
@@ -462,116 +593,6 @@ template <>
LLPanel* tab_cast<LLPanel*>(LLSideTrayTab* tab) { return tab; }
//////////////////////////////////////////////////////////////////////////////
-// LLSideTrayButton
-// Side Tray tab button with "tear off" handling.
-//////////////////////////////////////////////////////////////////////////////
-
-class LLSideTrayButton : public LLButton
-{
-public:
- /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask)
- {
- // Route future Mouse messages here preemptively. (Release on mouse up.)
- // No handler needed for focus lost since this class has no state that depends on it.
- gFocusMgr.setMouseCapture(this);
-
- localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY);
-
- // Note: don't pass on to children
- return TRUE;
- }
-
- /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask)
- {
- // We only handle the click if the click both started and ended within us
- if( !hasMouseCapture() ) return FALSE;
-
- S32 screen_x;
- S32 screen_y;
- localPointToScreen(x, y, &screen_x, &screen_y);
-
- S32 delta_x = screen_x - mDragLastScreenX;
- S32 delta_y = screen_y - mDragLastScreenY;
-
- LLSideTray* side_tray = LLSideTray::getInstance();
-
- // Check if the tab we are dragging is docked.
- if (!side_tray->isTabAttached(mTabName)) return FALSE;
-
- // Same value is hardcoded in LLDragHandle::handleHover().
- const S32 undock_threshold = 12;
-
- // Detach a tab if it has been pulled further than undock_threshold.
- if (delta_x <= -undock_threshold || delta_x >= undock_threshold ||
- delta_y <= -undock_threshold || delta_y >= undock_threshold)
- {
- LLSideTrayTab* tab = side_tray->getTab(mTabName);
- if (!tab) return FALSE;
-
- tab->setDocked(false);
-
- LLFloater* floater_tab = LLFloaterReg::getInstance("side_bar_tab", tab->getName());
- if (!floater_tab) return FALSE;
-
- LLRect original_rect = floater_tab->getRect();
- S32 header_snap_y = floater_tab->getHeaderHeight() / 2;
- S32 snap_x = screen_x - original_rect.mLeft - original_rect.getWidth() / 2;
- S32 snap_y = screen_y - original_rect.mTop + header_snap_y;
-
- // Move the floater to appear "under" the mouse pointer.
- floater_tab->setRect(original_rect.translate(snap_x, snap_y));
-
- // Snap the mouse pointer to the center of the floater header
- // and call 'mouse down' event handler to begin dragging.
- floater_tab->handleMouseDown(original_rect.getWidth() / 2,
- original_rect.getHeight() - header_snap_y,
- mask);
-
- return TRUE;
- }
-
- return FALSE;
- }
-
- void setBadgeDriver(LLSideTrayTabBadgeDriver* driver)
- {
- mBadgeDriver = driver;
- }
-
-protected:
- LLSideTrayButton(const LLButton::Params& p)
- : LLButton(p)
- , mDragLastScreenX(0)
- , mDragLastScreenY(0)
- , mBadgeDriver(NULL)
- {
- // Find out the tab name to use in handleHover().
- size_t pos = getName().find("_button");
- llassert(pos != std::string::npos);
- mTabName = getName().substr(0, pos);
- }
-
- friend class LLUICtrlFactory;
-
- void draw()
- {
- if (mBadgeDriver)
- {
- setBadgeLabel(mBadgeDriver->getBadgeString());
- }
-
- LLButton::draw();
- }
-
-private:
- S32 mDragLastScreenX;
- S32 mDragLastScreenY;
-
- std::string mTabName;
- LLSideTrayTabBadgeDriver* mBadgeDriver;
-};
-
-//////////////////////////////////////////////////////////////////////////////
// LLSideTray
//////////////////////////////////////////////////////////////////////////////
@@ -786,7 +807,7 @@ bool LLSideTray::selectTabByName(const std::string& name, bool keep_prev_visible
{
// Keep previously active tab visible if requested.
if (keep_prev_visible) tab_to_keep_visible = mActiveTab;
- toggleTabButton(mActiveTab);
+ toggleTabButton(mActiveTab);
}
//select new tab
@@ -794,9 +815,9 @@ bool LLSideTray::selectTabByName(const std::string& name, bool keep_prev_visible
if (mActiveTab)
{
- toggleTabButton(mActiveTab);
- LLSD key;//empty
- mActiveTab->onOpen(key);
+ toggleTabButton(mActiveTab);
+ LLSD key;//empty
+ mActiveTab->onOpen(key);
}
//arrange();
@@ -976,7 +997,9 @@ LLButton* LLSideTrayTab::createButton(bool allowTearOff, LLUICtrl::commit_callba
LLButton* button;
if (allowTearOff)
{
- button = LLUICtrlFactory::create<LLSideTrayButton>(bparams);
+ mSideTrayButton = LLUICtrlFactory::create<LLSideTrayButton>(bparams);
+
+ button = mSideTrayButton;
}
else
{
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index fecc6d91bd..4af5fdd9f3 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -33,6 +33,7 @@
#include "llcompilequeue.h"
#include "llcallfloater.h"
+#include "llfasttimerview.h"
#include "llfloaterabout.h"
#include "llfloateranimpreview.h"
#include "llfloaterauction.h"
@@ -159,6 +160,7 @@ void LLViewerFloaterReg::registerFloaters()
// *NOTE: Please keep these alphabetized for easier merges
LLFloaterAboutUtil::registerFloater();
+ LLFloaterReg::add("fast_timers", "floater_fast_timers.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFastTimerView>);
LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLand>);
LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>);
LLFloaterReg::add("avatar_picker", "floater_avatar_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarPicker>);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 26599f557e..754731b290 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -523,7 +523,7 @@ class LLAdvancedToggleConsole : public view_listener_t
}
else if ("fast timers" == console_type)
{
- toggle_visibility( (void*)gDebugView->mFastTimerView );
+ LLFloaterReg::toggleInstance("fast_timers");
}
else if ("scene view" == console_type)
{
@@ -563,7 +563,7 @@ class LLAdvancedCheckConsole : public view_listener_t
}
else if ("fast timers" == console_type)
{
- new_value = get_visibility( (void*)gDebugView->mFastTimerView );
+ new_value = LLFloaterReg::instanceVisible("fast_timers");
}
else if ("scene view" == console_type)
{
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 68745d5aeb..6435904fee 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1299,29 +1299,12 @@ bool highlight_offered_object(const LLUUID& obj_id)
void inventory_offer_mute_callback(const LLUUID& blocked_id,
const std::string& full_name,
- bool is_group,
- boost::shared_ptr<LLNotificationResponderInterface> offer_ptr)
+ bool is_group)
{
- LLOfferInfo* offer = dynamic_cast<LLOfferInfo*>(offer_ptr.get());
-
- std::string from_name = full_name;
- LLMute::EType type;
- if (is_group)
- {
- type = LLMute::GROUP;
- }
- else if(offer && offer->mFromObject)
- {
- //we have to block object by name because blocked_id is an id of owner
- type = LLMute::BY_NAME;
- }
- else
- {
- type = LLMute::AGENT;
- }
+ // *NOTE: blocks owner if the offer came from an object
+ LLMute::EType mute_type = is_group ? LLMute::GROUP : LLMute::AGENT;
- // id should be null for BY_NAME mute, see LLMuteList::add for details
- LLMute mute(type == LLMute::BY_NAME ? LLUUID::null : blocked_id, from_name, type);
+ LLMute mute(blocked_id, full_name, mute_type);
if (LLMuteList::getInstance()->add(mute))
{
LLPanelBlockedList::showPanelAndSelect(blocked_id);
@@ -1335,6 +1318,7 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
bool matches(const LLNotificationPtr notification) const
{
if(notification->getName() == "ObjectGiveItem"
+ || notification->getName() == "OwnObjectGiveItem"
|| notification->getName() == "UserGiveItem")
{
return (notification->getPayload()["from_id"].asUUID() == blocked_id);
@@ -1495,7 +1479,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
llassert(notification_ptr != NULL);
if (notification_ptr != NULL)
{
- gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,notification_ptr->getResponderPtr()));
+ gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
}
}
@@ -1640,7 +1624,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
llassert(notification_ptr != NULL);
if (notification_ptr != NULL)
{
- gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,notification_ptr->getResponderPtr()));
+ gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
}
}
@@ -1818,6 +1802,7 @@ void LLOfferInfo::initRespondFunctionMap()
if(mRespondFunctions.empty())
{
mRespondFunctions["ObjectGiveItem"] = boost::bind(&LLOfferInfo::inventory_task_offer_callback, this, _1, _2);
+ mRespondFunctions["OwnObjectGiveItem"] = boost::bind(&LLOfferInfo::inventory_task_offer_callback, this, _1, _2);
mRespondFunctions["UserGiveItem"] = boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2);
}
}
@@ -1905,7 +1890,7 @@ void inventory_offer_handler(LLOfferInfo* info)
std::string verb = "select?name=" + LLURI::escape(msg);
args["ITEM_SLURL"] = LLSLURL("inventory", info->mObjectID, verb.c_str()).getSLURLString();
- LLNotification::Params p("ObjectGiveItem");
+ LLNotification::Params p;
// Object -> Agent Inventory Offer
if (info->mFromObject)
@@ -1915,7 +1900,10 @@ void inventory_offer_handler(LLOfferInfo* info)
// Note: sets inventory_task_offer_callback as the callback
p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
info->mPersist = true;
- p.name = "ObjectGiveItem";
+
+ // Offers from your own objects need a special notification template.
+ p.name = info->mFromID == gAgentID ? "OwnObjectGiveItem" : "ObjectGiveItem";
+
// Pop up inv offer chiclet and let the user accept (keep), or reject (and silently delete) the inventory.
LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, info->mFromGroup == TRUE);
}
@@ -2594,8 +2582,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0];
info->mType = (LLAssetType::EType) bucketp->asset_type;
info->mObjectID = bucketp->object_id;
+ info->mFromObject = FALSE;
}
- else
+ else // IM_TASK_INVENTORY_OFFERED
{
if (sizeof(S8) != binary_bucket_size)
{
@@ -2605,6 +2594,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
}
info->mType = (LLAssetType::EType) binary_bucket[0];
info->mObjectID = LLUUID::null;
+ info->mFromObject = TRUE;
}
info->mIM = dialog;
@@ -2613,14 +2603,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
info->mTransactionID = session_id;
info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
- if (dialog == IM_TASK_INVENTORY_OFFERED)
- {
- info->mFromObject = TRUE;
- }
- else
- {
- info->mFromObject = FALSE;
- }
info->mFromName = name;
info->mDesc = message;
info->mHost = msg->getSender();
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 8b942fbc6a..90a05cd9e5 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -4498,17 +4498,25 @@ bool LLVivoxVoiceClient::parcelVoiceInfoReceived(state requesting_state)
bool LLVivoxVoiceClient::requestParcelVoiceInfo()
{
- LL_DEBUGS("Voice") << "sending ParcelVoiceInfoRequest (" << mCurrentRegionName << ", " << mCurrentParcelLocalID << ")" << LL_ENDL;
-
- // grab the cap for parcel voice info from the region.
LLViewerRegion * region = gAgent.getRegion();
- if (region == NULL)
+ if (region == NULL || !region->capabilitiesReceived())
{
+ // we don't have the cap yet, so return false so the caller can try again later.
+
+ LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest capability not yet available, deferring" << LL_ENDL;
return false;
}
+
// grab the cap.
std::string url = gAgent.getRegion()->getCapability("ParcelVoiceInfoRequest");
- if (!url.empty())
+ if (url.empty())
+ {
+ // Region dosn't have the cap. Stop probing.
+ LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest capability not available in this region" << LL_ENDL;
+ setState(stateDisableCleanup);
+ return false;
+ }
+ else
{
// if we've already retrieved the cap from the region, go ahead and make the request,
// and return true so we can go into the state that waits for the response.
@@ -4517,18 +4525,11 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo()
LL_DEBUGS("Voice") << "sending ParcelVoiceInfoRequest (" << mCurrentRegionName << ", " << mCurrentParcelLocalID << ")" << LL_ENDL;
LLHTTPClient::post(
- url,
- data,
- new LLVivoxVoiceClientCapResponder(getState()));
+ url,
+ data,
+ new LLVivoxVoiceClientCapResponder(getState()));
return true;
}
- else
- {
-
- // we don't have the cap yet, so return false so the caller can try again later.
- LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest cap not yet available, deferring" << LL_ENDL;
- return false;
- }
}
void LLVivoxVoiceClient::switchChannel(
diff --git a/indra/newview/skins/default/xui/en/floater_fast_timers.xml b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
new file mode 100644
index 0000000000..49aa8f3840
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_minimize="false"
+ can_tear_off="false"
+ can_resize="true"
+ can_drag_on_left="false"
+ can_close="true"
+ height="500"
+ layout="topleft"
+ name="fast_timers"
+ save_rect="true"
+ save_visibility="false"
+ single_instance="true"
+ min_width="400"
+ width="700">
+ <string name="pause" >Pause</string>
+ <string name="run">Run</string>
+ <button follows="top|right"
+ name="pause_btn"
+ left="-200"
+ top="5"
+ width="180"
+ height="40"
+ pad_bottom="-5"
+ label="Pause"
+ font="SansSerifHuge"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index a9ae4475b6..41a90f5984 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -2297,8 +2297,8 @@ Would you be my friend?
icon="alertmodal.tga"
label="Save Outfit"
name="SaveOutfitAs"
- type="alertmodal"
- unique="true">
+ type="alertmodal">
+ <unique/>
Save what I'm wearing as a new Outfit:
<tag>confirm</tag>
<form name="form">
@@ -4611,8 +4611,8 @@ Go to your [http://secondlife.com/account/ Dashboard] to see your account histor
<notification
icon="alertmodal.tga"
name="ConfirmQuit"
- type="alertmodal"
- unique="true">
+ type="alertmodal">
+ <unique/>
Are you sure you want to quit?
<tag>confirm</tag>
<usetemplate
@@ -4625,8 +4625,8 @@ Are you sure you want to quit?
<notification
icon="alertmodal.tga"
name="DeleteItems"
- type="alertmodal"
- unique="true">
+ type="alertmodal">
+ <unique/>
[QUESTION]
<tag>confirm</tag>
<usetemplate
@@ -4639,8 +4639,9 @@ Are you sure you want to quit?
<notification
icon="alertmodal.tga"
name="HelpReportAbuseEmailLL"
- type="alert"
- unique="true">
+ type="alert">
+ <unique/>
+
Use this tool to report violations of the [http://secondlife.com/corporate/tos.php Terms of Service] and [http://secondlife.com/corporate/cs.php Community Standards].
All reported abuses are investigated and resolved.
@@ -5615,8 +5616,8 @@ Message from [NAME]:
icon="notify.tga"
name="NotSafe"
persist="true"
- type="notify"
- unique="true">
+ type="notify">
+ <unique/>
This land has damage enabled.
You can be hurt here. If you die, you will be teleported to your home location.
</notification>
@@ -5625,8 +5626,8 @@ You can be hurt here. If you die, you will be teleported to your home location.
icon="notify.tga"
name="NoFly"
persist="true"
- type="notify"
- unique="true">
+ type="notify">
+ <unique/>
<tag>fail</tag>
This area has flying disabled.
You can&apos;t fly here.
@@ -5636,8 +5637,8 @@ You can&apos;t fly here.
icon="notify.tga"
name="PushRestricted"
persist="true"
- type="notify"
- unique="true">
+ type="notify">
+ <unique/>
This area does not allow pushing. You can&apos;t push others here unless you own the land.
</notification>
@@ -5645,8 +5646,8 @@ This area does not allow pushing. You can&apos;t push others here unless you own
icon="notify.tga"
name="NoVoice"
persist="true"
- type="notify"
- unique="true">
+ type="notify">
+ <unique/>
This area has voice chat disabled. You won&apos;t be able to hear anyone talking.
<tag>voice</tag>
</notification>
@@ -5655,8 +5656,8 @@ This area has voice chat disabled. You won&apos;t be able to hear anyone talking
icon="notify.tga"
name="NoBuild"
persist="true"
- type="notify"
- unique="true">
+ type="notify">
+ <unique/>
This area has building disabled. You can&apos;t build or rez objects here.
</notification>
@@ -5664,8 +5665,8 @@ This area has building disabled. You can&apos;t build or rez objects here.
icon="notify.tga"
name="SeeAvatars"
persist="true"
- type="notify"
- unique="true">
+ type="notify">
+ <unique/>
This parcel hides avatars and text chat from another parcel. You can&apos;t see other residents outside the parcel, and those outside are not able to see you. Regular text chat on channel 0 is also blocked.
</notification>
@@ -5950,7 +5951,25 @@ An object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; owned by [NAME_SLU
<button
index="2"
name="Mute"
- text="Block"/>
+ text="Block Owner"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="OwnObjectGiveItem"
+ type="offer">
+Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you this [OBJECTTYPE]:
+&lt;nolink&gt;[ITEM_SLURL]&lt;/nolink&gt;
+ <form name="form">
+ <button
+ index="0"
+ name="Keep"
+ text="Keep"/>
+ <button
+ index="1"
+ name="Discard"
+ text="Discard"/>
</form>
</notification>
@@ -5962,7 +5981,7 @@ An object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; owned by [NAME_SLU
[ITEM_SLURL]
<form name="form">
<button
- index="4"
+ index="3"
name="Show"
text="Show"/>
<button
@@ -6535,8 +6554,8 @@ The voice call you are trying to join, [VOICE_CHANNEL_NAME], has reached maximum
<notification
icon="notifytip.tga"
name="ProximalVoiceChannelFull"
- type="notifytip"
- unique="true">
+ type="notifytip">
+ <unique/>
We&apos;re sorry. This area has reached maximum capacity for voice conversations. Please try to use voice in another area.
<tag>fail</tag>
<tag>voice</tag>
@@ -6604,8 +6623,8 @@ Failed to connect to [VOICE_CHANNEL_NAME], please try again later. You will now
duration="10"
icon="notifytip.tga"
name="VoiceLoginRetry"
- type="notifytip"
- unique="true">
+ type="notifytip">
+ <unique/>
We are creating a voice channel for you. This may take up to one minute.
<tag>status</tag>
<tag>voice</tag>
@@ -6616,8 +6635,8 @@ We are creating a voice channel for you. This may take up to one minute.
name="VoiceEffectsExpired"
sound="UISndAlert"
persist="true"
- type="notify"
- unique="true">
+ type="notify">
+ <unique/>
One or more of your subscribed Voice Morphs has expired.
[[URL] Click here] to renew your subscription.
<tag>fail</tag>
@@ -6629,8 +6648,8 @@ One or more of your subscribed Voice Morphs has expired.
name="VoiceEffectsExpiredInUse"
sound="UISndAlert"
persist="true"
- type="notify"
- unique="true">
+ type="notify">
+ <unique/>
The active Voice Morph has expired, your normal voice settings have been applied.
[[URL] Click here] to renew your subscription.
<tag>fail</tag>
@@ -6642,8 +6661,8 @@ The active Voice Morph has expired, your normal voice settings have been applied
name="VoiceEffectsWillExpire"
sound="UISndAlert"
persist="true"
- type="notify"
- unique="true">
+ type="notify">
+ <unique/>
One or more of your Voice Morphs will expire in less than [INTERVAL] days.
[[URL] Click here] to renew your subscription.
<tag>fail</tag>
@@ -6655,8 +6674,8 @@ One or more of your Voice Morphs will expire in less than [INTERVAL] days.
name="VoiceEffectsNew"
sound="UISndAlert"
persist="true"
- type="notify"
- unique="true">
+ type="notify">
+ <unique/>
New Voice Morphs are available!
<tag>voice</tag>
</notification>
@@ -7057,8 +7076,9 @@ Are you sure you want to leave this call?
ignoretext="Confirm before I leave call"
name="okcancelignore"
notext="No"
- yestext="Yes"
- unique="true"/>
+ yestext="Yes">
+ <unique/>
+ </usetemplate>
</notification>
<notification
@@ -7077,31 +7097,31 @@ Mute everyone?
ignoretext="Confirm before I mute all participants in a group call"
name="okcancelignore"
yestext="Ok"
- notext="Cancel"
- unique="true"/>
+ notext="Cancel">
+ <unique/>
+ </usetemplate>
</notification>
<notification
name="HintChat"
label="Chat"
- type="hint"
- unique="true">
+ type="hint">
+ <unique/>
To join the conversation, type into the chat field below.
</notification>
<notification
name="HintSit"
-
label="Stand"
- type="hint"
- unique="true">
+ type="hint">
+ <unique/>
To stand up and exit the sitting position, click the Stand button.
</notification>
<notification
name="HintSpeak"
label="Speak"
- type="hint"
- unique="true">
+ type="hint">
+ <unique/>
Click the Speak button to turn your microphone on and off.
Click on the up arrow to see the voice control panel.
@@ -7112,32 +7132,32 @@ Hiding the Speak button will disable the voice feature.
<notification
name="HintDestinationGuide"
label="Explore the World"
- type="hint"
- unique="true">
+ type="hint">
+ <unique/>
The Destination Guide contains thousands of new places to discover. Select a location and choose Teleport to start exploring.
</notification>
<notification
name="HintSidePanel"
label="Side Panel"
- type="hint"
- unique="true">
+ type="hint">
+ <unique/>
Get quick access to your inventory, outfits, profiles and more in the side panel.
</notification>
<notification
name="HintMove"
label="Move"
- type="hint"
- unique="true">
+ type="hint">
+ <unique/>
To walk or run, open the Move Panel and use the directional arrows to navigate. You can also use the directional keys on your keyboard.
</notification>
<notification
name="HintMoveClick"
label=""
- type="hint"
- unique="true">
+ type="hint">
+ <unique/>
1. Click to Walk
Click anywhere on the ground to walk to that spot.
@@ -7149,8 +7169,8 @@ Click and drag anywhere on the world to rotate your view
<notification
name="HintDisplayName"
label="Display Name"
- type="hint"
- unique="true">
+ type="hint">
+ <unique/>
Set your customizable display name here. This is in addition to your unique username, which can't be changed. You can change how you see other people's names in your preferences.
</notification>
@@ -7158,8 +7178,8 @@ Click and drag anywhere on the world to rotate your view
<notification
name="HintView"
label="View"
- type="hint"
- unique="true">
+ type="hint">
+ <unique/>
To change your camera view, use the Orbit and Pan controls. Reset your view by pressing Escape or walking.
<tag>custom_skin</tag>
</notification>
@@ -7167,16 +7187,16 @@ Click and drag anywhere on the world to rotate your view
<notification
name="HintInventory"
label="Inventory"
- type="hint"
- unique="true">
+ type="hint">
+ <unique/>
Check your inventory to find items. Newest items can be easily found in the Recent tab.
</notification>
<notification
name="HintLindenDollar"
label="You've got Linden Dollars!"
- type="hint"
- unique="true">
+ type="hint">
+ <unique/>
Here's your current balance of L$. Click Buy L$ to purchase more Linden Dollars.
<tag>funds</tag>
</notification>
@@ -7365,8 +7385,8 @@ The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;
<notification
name="ModeChange"
label=""
- type="alertmodal"
- unique="true">
+ type="alertmodal">
+ <unique/>
Changing modes requires you to quit and restart.
<tag>confirm</tag>
<usetemplate
@@ -7378,8 +7398,8 @@ The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;
<notification
name="NoClassifieds"
label=""
- type="alertmodal"
- unique="true">
+ type="alertmodal">
+ <unique/>
<tag>fail</tag>
<tag>confirm</tag>
Creation and editing of Classifieds is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen.
@@ -7392,8 +7412,8 @@ The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;
<notification
name="NoGroupInfo"
label=""
- type="alertmodal"
- unique="true">
+ type="alertmodal">
+ <unique/>
<tag>fail</tag>
<tag>confirm</tag>
Creation and editing of Groups is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen.
@@ -7406,8 +7426,8 @@ The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;
<notification
name="NoPlaceInfo"
label=""
- type="alertmodal"
- unique="true">
+ type="alertmodal">
+ <unique/>
<tag>fail</tag>
<tag>confirm</tag>
Viewing place profile is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen.
@@ -7420,8 +7440,8 @@ The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;
<notification
name="NoPicks"
label=""
- type="alertmodal"
- unique="true">
+ type="alertmodal">
+ <unique/>
<tag>fail</tag>
<tag>confirm</tag>
Creation and editing of Picks is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen.
@@ -7434,8 +7454,8 @@ The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;
<notification
name="NoWorldMap"
label=""
- type="alertmodal"
- unique="true">
+ type="alertmodal">
+ <unique/>
<tag>fail</tag>
<tag>confirm</tag>
Viewing of the world map is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen.
@@ -7448,8 +7468,8 @@ The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;
<notification
name="NoVoiceCall"
label=""
- type="alertmodal"
- unique="true">
+ type="alertmodal">
+ <unique/>
<tag>fail</tag>
<tag>confirm</tag>
Voice calls are only available in Advanced mode. Would you like to logout and change modes?
@@ -7462,8 +7482,8 @@ The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;
<notification
name="NoAvatarShare"
label=""
- type="alertmodal"
- unique="true">
+ type="alertmodal">
+ <unique/>
<tag>fail</tag>
<tag>confirm</tag>
Sharing is only available in Advanced mode. Would you like to logout and change modes?
@@ -7476,8 +7496,8 @@ The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;
<notification
name="NoAvatarPay"
label=""
- type="alertmodal"
- unique="true">
+ type="alertmodal">
+ <unique/>
<tag>fail</tag>
<tag>confirm</tag>
Paying other residents is only available in Advanced mode. Would you like to logout and change modes?
@@ -7490,8 +7510,8 @@ The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;
<notification
name="NoInventory"
label=""
- type="alertmodal"
- unique="true">
+ type="alertmodal">
+ <unique/>
<tag>fail</tag>
<tag>confirm</tag>
Viewing inventory is only available in Advanced mode. Would you like to logout and change modes?
@@ -7504,8 +7524,8 @@ The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;
<notification
name="NoAppearance"
label=""
- type="alertmodal"
- unique="true">
+ type="alertmodal">
+ <unique/>
<tag>fail</tag>
<tag>confirm</tag>
The appearance editor is only available in Advanced mode. Would you like to logout and change modes?
@@ -7518,8 +7538,8 @@ The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;
<notification
name="NoSearch"
label=""
- type="alertmodal"
- unique="true">
+ type="alertmodal">
+ <unique/>
<tag>fail</tag>
<tag>confirm</tag>
Search is only available in Advanced mode. Would you like to logout and change modes?
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index c8f8d07701..ec5853649e 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -47,13 +47,13 @@
mouse_opaque="false"
name="chat_bar_layout_panel"
user_resize="true"
- width="310" >
+ width="250" >
<panel
name="chat_bar"
filename="panel_nearby_chat_bar.xml"
left="0"
height="28"
- width="308"
+ width="248"
top="0"
mouse_opaque="false"
follows="left|right"
@@ -341,7 +341,7 @@ Disabled for now.
height="28"
layout="topleft"
min_height="28"
- min_width="52"
+ min_width="62"
mouse_opaque="false"
name="mini_map_btn_panel"
user_resize="false"
diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
index 888230a00e..e6c5110999 100644
--- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
@@ -82,10 +82,11 @@
left="0"
name="All Items"
sort_order_setting="InventorySortOrder"
- show_item_link_overlays="true"
+ show_item_link_overlays="true"
top="16"
width="288" />
<recent_inventory_panel
+ accepts_drag_and_drop="false"
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
@@ -99,7 +100,7 @@
layout="topleft"
left_delta="0"
name="Recent Items"
- show_item_link_overlays="true"
+ show_item_link_overlays="true"
width="290" />
</tab_container>
<layout_stack
diff --git a/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml
index 00f4c43915..eaf148c5e4 100644
--- a/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml
+++ b/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml
@@ -4,11 +4,12 @@
background_visible="true"
background_opaque="true"
show_load_status="true"
+ accepts_drag_and_drop="true"
>
<scroll
- name="Inventory Scroller"
- follows="all"
- reserve_scroll_corner="true"
- tab_stop="true"
- />
+ name="Inventory Scroller"
+ follows="all"
+ reserve_scroll_corner="true"
+ tab_stop="true"
+ />
</panel>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 0a21d8714c..f0bee2bfee 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -66,12 +66,14 @@ class ViewerManifest(LLManifest):
# include the extracted list of contributors
contributor_names = self.extract_names("../../doc/contributions.txt")
self.put_in_file(contributor_names, "contributors.txt")
+ self.file_list.append(["../../doc/contributions.txt",self.dst_path_of("contributors.txt")])
# include the extracted list of translators
translator_names = self.extract_names("../../doc/translations.txt")
self.put_in_file(translator_names, "translators.txt")
+ self.file_list.append(["../../doc/translations.txt",self.dst_path_of("translators.txt")])
# include the list of Lindens (if any)
# see https://wiki.lindenlab.com/wiki/Generated_Linden_Credits
- linden_names_path = os.getenv("linden_credits")
+ linden_names_path = os.getenv("LINDEN_CREDITS")
if linden_names_path :
try:
linden_file = open(linden_names_path,'r')
@@ -79,9 +81,13 @@ class ViewerManifest(LLManifest):
linden_names = ', '.join(linden_file.readlines())
self.put_in_file(linden_names, "lindens.txt")
linden_file.close()
+ print "Linden names extracted from '%s'" % linden_names_path
+ self.file_list.append([linden_names_path,self.dst_path_of("lindens.txt")])
except IOError:
print "No Linden names found at '%s', using built-in list" % linden_names_path
pass
+ else :
+ print "No 'LINDEN_CREDITS' specified in environment, using built-in list"
# ... and the entire windlight directory
self.path("windlight")
diff --git a/scripts/templates/template-cpp.cpp b/scripts/templates/template-cpp.cpp
new file mode 100644
index 0000000000..35d8441c87
--- /dev/null
+++ b/scripts/templates/template-cpp.cpp
@@ -0,0 +1,30 @@
+/**
+* @file #filename#.cpp
+* @brief Implementation of #filename#
+* @author #getpass.getuser()#@lindenlab.com
+*
+* $LicenseInfo:firstyear=#datetime.datetime.now().year#&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) #datetime.datetime.now().year#, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+
+#'' if ( skip_h ) else '%cinclude "%s.h"' % (35,filename)#
+
diff --git a/scripts/templates/template-h.h b/scripts/templates/template-h.h
new file mode 100644
index 0000000000..ce7b4ddc87
--- /dev/null
+++ b/scripts/templates/template-h.h
@@ -0,0 +1,31 @@
+/**
+* @file #filename#.h
+* @brief Header file for #filename#
+* @author #getpass.getuser()#@lindenlab.com
+*
+* $LicenseInfo:firstyear=#datetime.datetime.now().year#&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) #datetime.datetime.now().year#, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+#'%c'%35#ifndef LL_#filename.upper().replace('-','_')#_H
+#'%c'%35#define LL_#filename.upper().replace('-','_')#_H
+
+
+#'%c'%35#endif // LL_#filename.upper().replace('-','_')#_H