summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/cmake/run_build_test.py222
-rw-r--r--indra/llcommon/llallocator.h126
-rw-r--r--indra/llcommon/llcoros.h298
-rw-r--r--indra/llcommon/llfasttimer.h634
-rw-r--r--indra/llcommon/llmemory.h130
-rw-r--r--indra/llcommon/llmemtype.h496
-rw-r--r--indra/llcommon/llpreprocessor.h338
-rw-r--r--indra/llcommon/llstacktrace.cpp284
-rw-r--r--indra/llcommon/llstacktrace.h88
-rw-r--r--indra/llcommon/llstring.h2600
-rw-r--r--indra/llinventory/llinventory.h4
-rw-r--r--indra/media_plugins/quicktime/media_plugin_quicktime.cpp14
-rw-r--r--indra/newview/CMakeLists.txt10
-rw-r--r--indra/newview/app_settings/ignorable_dialogs.xml582
-rw-r--r--indra/newview/character/avatar_lad.xml2
-rw-r--r--indra/newview/installers/windows/FILES_ARE_UNICODE_UTF-16LE.txt12
-rw-r--r--indra/newview/llagent.cpp58
-rw-r--r--indra/newview/llagent.h9
-rw-r--r--indra/newview/llagentwearables.cpp18
-rw-r--r--indra/newview/llappearancemgr.cpp20
-rw-r--r--indra/newview/llappearancemgr.h41
-rw-r--r--indra/newview/llcallingcard.h1
-rw-r--r--indra/newview/llfolderviewitem.cpp16
-rw-r--r--indra/newview/llfolderviewitem.h8
-rw-r--r--indra/newview/llinventorybridge.cpp30
-rw-r--r--indra/newview/llinventorybridge.h16
-rw-r--r--indra/newview/llinventoryfilter.cpp17
-rw-r--r--indra/newview/llinventoryfunctions.h272
-rw-r--r--indra/newview/llinventorypanel.cpp207
-rw-r--r--indra/newview/llinventorypanel.h4
-rw-r--r--indra/newview/llpanellandmarks.cpp16
-rw-r--r--indra/newview/llpanellandmarks.h8
-rw-r--r--indra/newview/llpanelmaininventory.cpp48
-rw-r--r--indra/newview/llpanelmaininventory.h29
-rw-r--r--indra/newview/llpanelobjectinventory.h204
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp347
-rw-r--r--indra/newview/llpaneloutfitsinventory.h102
-rw-r--r--indra/newview/llscrollingpanelparam.cpp4
-rw-r--r--indra/newview/llsidepanelappearance.cpp372
-rw-r--r--indra/newview/llsidepanelappearance.h102
-rw-r--r--indra/newview/lltoolmorph.cpp8
-rw-r--r--indra/newview/llwearable.cpp20
-rw-r--r--indra/newview/skins/default/html/da/loading/loading.html20
-rw-r--r--indra/newview/skins/default/html/de/loading/loading.html20
-rw-r--r--indra/newview/skins/default/html/en-us/loading/loading.html18
-rw-r--r--indra/newview/skins/default/html/es/loading/loading.html20
-rw-r--r--indra/newview/skins/default/html/fr/loading/loading.html20
-rw-r--r--indra/newview/skins/default/html/hu/loading/loading.html20
-rw-r--r--indra/newview/skins/default/html/it/loading/loading.html20
-rw-r--r--indra/newview/skins/default/html/ja/loading/loading.html20
-rw-r--r--indra/newview/skins/default/html/nl/loading/loading.html20
-rw-r--r--indra/newview/skins/default/html/pl/loading/loading.html20
-rw-r--r--indra/newview/skins/default/html/pt/loading/loading.html20
-rw-r--r--indra/newview/skins/default/html/ru/loading/loading.html20
-rw-r--r--indra/newview/skins/default/html/tr/loading/loading.html20
-rw-r--r--indra/newview/skins/default/html/uk/loading/loading.html20
-rw-r--r--indra/newview/skins/default/html/zh/loading/loading.html20
-rw-r--r--indra/newview/skins/default/xui/da/panel_edit_profile.xml90
-rw-r--r--indra/newview/skins/default/xui/en/panel_landmarks.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfits_inventory.xml81
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfits_inventory_gear_default.xml42
-rw-r--r--indra/newview/skins/default/xui/en/panel_side_tray.xml6
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_appearance.xml104
-rw-r--r--indra/newview/skins/default/xui/es/panel_edit_profile.xml90
-rw-r--r--indra/newview/skins/default/xui/it/panel_edit_profile.xml90
-rw-r--r--indra/newview/skins/default/xui/nl/panel_edit_profile.xml90
-rw-r--r--indra/newview/skins/default/xui/pl/panel_edit_profile.xml90
-rw-r--r--indra/newview/skins/default/xui/pt/panel_edit_profile.xml90
-rw-r--r--indra/tools/vstool/README.txt18
-rw-r--r--indra/tools/vstool/VSTool.csproj188
-rw-r--r--indra/tools/vstool/VSTool.sln38
-rw-r--r--indra/tools/vstool/main.cs1422
72 files changed, 5881 insertions, 4675 deletions
diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py
index fff78ecbe3..17bce6f434 100644
--- a/indra/cmake/run_build_test.py
+++ b/indra/cmake/run_build_test.py
@@ -1,111 +1,111 @@
-#!/usr/bin/python
-"""\
-@file run_build_test.py
-@author Nat Goodspeed
-@date 2009-09-03
-@brief Helper script to allow CMake to run some command after setting
- environment variables.
-
-CMake has commands to run an external program. But remember that each CMake
-command must be backed by multiple build-system implementations. Unfortunately
-it seems CMake can't promise that every target build system can set specified
-environment variables before running the external program of interest.
-
-This helper script is a workaround. It simply sets the requested environment
-variables and then executes the program specified on the rest of its command
-line.
-
-Example:
-
-python run_build_test.py -DFOO=bar myprog somearg otherarg
-
-sets environment variable FOO=bar, then runs:
-myprog somearg otherarg
-
-$LicenseInfo:firstyear=2009&license=internal$
-Copyright (c) 2009, Linden Research, Inc.
-$/LicenseInfo$
-"""
-
-import os
-import sys
-import subprocess
-
-def main(command, libpath=[], vars={}):
- """Pass:
- command is a sequence (e.g. a list) of strings. The first item in the list
- must be the command name, the rest are its arguments.
-
- libpath is a sequence of directory pathnames. These will be appended to
- the platform-specific dynamic library search path environment variable.
-
- vars is a dict of arbitrary (var, value) pairs to be added to the
- environment before running 'command'.
-
- This function runs the specified command, waits for it to terminate and
- returns its return code. This will be negative if the command terminated
- with a signal, else it will be the process's specified exit code.
- """
- # Handle platform-dependent libpath first.
- if sys.platform == "win32":
- lpvars = ["PATH"]
- elif sys.platform == "darwin":
- lpvars = ["LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH"]
- elif sys.platform.startswith("linux"):
- lpvars = ["LD_LIBRARY_PATH"]
- else:
- # No idea what the right pathname might be! But only crump if this
- # feature is requested.
- if libpath:
- raise NotImplemented("run_build_test: unknown platform %s" % sys.platform)
- lpvars = []
- for var in lpvars:
- # Split the existing path. Bear in mind that the variable in question
- # might not exist; instead of KeyError, just use an empty string.
- dirs = os.environ.get(var, "").split(os.pathsep)
- # Append the sequence in libpath
-## print "%s += %r" % (var, libpath)
- dirs.extend(libpath)
- # Now rebuild the path string. This way we use a minimum of separators
- # -- and we avoid adding a pointless separator when libpath is empty.
- os.environ[var] = os.pathsep.join(dirs)
- # Now handle arbitrary environment variables. The tricky part is ensuring
- # that all the keys and values we try to pass are actually strings.
-## if vars:
-## print "Setting:"
-## for key, value in vars.iteritems():
-## print "%s=%s" % (key, value)
- os.environ.update(dict([(str(key), str(value)) for key, value in vars.iteritems()]))
- # Run the child process.
-## print "Running: %s" % " ".join(command)
- return subprocess.call(command)
-
-if __name__ == "__main__":
- from optparse import OptionParser
- parser = OptionParser(usage="usage: %prog [options] command args...")
- # We want optparse support for the options we ourselves handle -- but we
- # DO NOT want it looking at options for the executable we intend to run,
- # rejecting them as invalid because we don't define them. So configure the
- # parser to stop looking for options as soon as it sees the first
- # positional argument (traditional Unix syntax).
- parser.disable_interspersed_args()
- parser.add_option("-D", "--define", dest="vars", default=[], action="append",
- metavar="VAR=value",
- help="Add VAR=value to the env variables defined")
- parser.add_option("-l", "--libpath", dest="libpath", default=[], action="append",
- metavar="DIR",
- help="Add DIR to the platform-dependent DLL search path")
- opts, args = parser.parse_args()
- # What we have in opts.vars is a list of strings of the form "VAR=value"
- # or possibly just "VAR". What we want is a dict. We can build that dict by
- # constructing a list of ["VAR", "value"] pairs -- so split each
- # "VAR=value" string on the '=' sign (but only once, in case we have
- # "VAR=some=user=string"). To handle the case of just "VAR", append "" to
- # the list returned by split(), then slice off anything after the pair we
- # want.
- rc = main(command=args, libpath=opts.libpath,
- vars=dict([(pair.split('=', 1) + [""])[:2] for pair in opts.vars]))
- if rc not in (None, 0):
- print >>sys.stderr, "Failure running: %s" % " ".join(args)
- print >>sys.stderr, "Error: %s" % rc
- sys.exit((rc < 0) and 255 or rc)
+#!/usr/bin/python
+"""\
+@file run_build_test.py
+@author Nat Goodspeed
+@date 2009-09-03
+@brief Helper script to allow CMake to run some command after setting
+ environment variables.
+
+CMake has commands to run an external program. But remember that each CMake
+command must be backed by multiple build-system implementations. Unfortunately
+it seems CMake can't promise that every target build system can set specified
+environment variables before running the external program of interest.
+
+This helper script is a workaround. It simply sets the requested environment
+variables and then executes the program specified on the rest of its command
+line.
+
+Example:
+
+python run_build_test.py -DFOO=bar myprog somearg otherarg
+
+sets environment variable FOO=bar, then runs:
+myprog somearg otherarg
+
+$LicenseInfo:firstyear=2009&license=internal$
+Copyright (c) 2009, Linden Research, Inc.
+$/LicenseInfo$
+"""
+
+import os
+import sys
+import subprocess
+
+def main(command, libpath=[], vars={}):
+ """Pass:
+ command is a sequence (e.g. a list) of strings. The first item in the list
+ must be the command name, the rest are its arguments.
+
+ libpath is a sequence of directory pathnames. These will be appended to
+ the platform-specific dynamic library search path environment variable.
+
+ vars is a dict of arbitrary (var, value) pairs to be added to the
+ environment before running 'command'.
+
+ This function runs the specified command, waits for it to terminate and
+ returns its return code. This will be negative if the command terminated
+ with a signal, else it will be the process's specified exit code.
+ """
+ # Handle platform-dependent libpath first.
+ if sys.platform == "win32":
+ lpvars = ["PATH"]
+ elif sys.platform == "darwin":
+ lpvars = ["LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH"]
+ elif sys.platform.startswith("linux"):
+ lpvars = ["LD_LIBRARY_PATH"]
+ else:
+ # No idea what the right pathname might be! But only crump if this
+ # feature is requested.
+ if libpath:
+ raise NotImplemented("run_build_test: unknown platform %s" % sys.platform)
+ lpvars = []
+ for var in lpvars:
+ # Split the existing path. Bear in mind that the variable in question
+ # might not exist; instead of KeyError, just use an empty string.
+ dirs = os.environ.get(var, "").split(os.pathsep)
+ # Append the sequence in libpath
+## print "%s += %r" % (var, libpath)
+ dirs.extend(libpath)
+ # Now rebuild the path string. This way we use a minimum of separators
+ # -- and we avoid adding a pointless separator when libpath is empty.
+ os.environ[var] = os.pathsep.join(dirs)
+ # Now handle arbitrary environment variables. The tricky part is ensuring
+ # that all the keys and values we try to pass are actually strings.
+## if vars:
+## print "Setting:"
+## for key, value in vars.iteritems():
+## print "%s=%s" % (key, value)
+ os.environ.update(dict([(str(key), str(value)) for key, value in vars.iteritems()]))
+ # Run the child process.
+## print "Running: %s" % " ".join(command)
+ return subprocess.call(command)
+
+if __name__ == "__main__":
+ from optparse import OptionParser
+ parser = OptionParser(usage="usage: %prog [options] command args...")
+ # We want optparse support for the options we ourselves handle -- but we
+ # DO NOT want it looking at options for the executable we intend to run,
+ # rejecting them as invalid because we don't define them. So configure the
+ # parser to stop looking for options as soon as it sees the first
+ # positional argument (traditional Unix syntax).
+ parser.disable_interspersed_args()
+ parser.add_option("-D", "--define", dest="vars", default=[], action="append",
+ metavar="VAR=value",
+ help="Add VAR=value to the env variables defined")
+ parser.add_option("-l", "--libpath", dest="libpath", default=[], action="append",
+ metavar="DIR",
+ help="Add DIR to the platform-dependent DLL search path")
+ opts, args = parser.parse_args()
+ # What we have in opts.vars is a list of strings of the form "VAR=value"
+ # or possibly just "VAR". What we want is a dict. We can build that dict by
+ # constructing a list of ["VAR", "value"] pairs -- so split each
+ # "VAR=value" string on the '=' sign (but only once, in case we have
+ # "VAR=some=user=string"). To handle the case of just "VAR", append "" to
+ # the list returned by split(), then slice off anything after the pair we
+ # want.
+ rc = main(command=args, libpath=opts.libpath,
+ vars=dict([(pair.split('=', 1) + [""])[:2] for pair in opts.vars]))
+ if rc not in (None, 0):
+ print >>sys.stderr, "Failure running: %s" % " ".join(args)
+ print >>sys.stderr, "Error: %s" % rc
+ sys.exit((rc < 0) and 255 or rc)
diff --git a/indra/llcommon/llallocator.h b/indra/llcommon/llallocator.h
index 50129b4526..0d6f18c5d4 100644
--- a/indra/llcommon/llallocator.h
+++ b/indra/llcommon/llallocator.h
@@ -1,63 +1,63 @@
-/**
- * @file llallocator.h
- * @brief Declaration of the LLAllocator class.
- *
- * $LicenseInfo:firstyear=2009&license=viewergpl$
- *
- * Copyright (c) 2009-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLALLOCATOR_H
-#define LL_LLALLOCATOR_H
-
-#include <string>
-
-#include "llmemtype.h"
-#include "llallocator_heap_profile.h"
-
-class LL_COMMON_API LLAllocator {
- friend class LLMemoryView;
- friend class LLMemType;
-
-private:
- static void pushMemType(S32 type);
- static S32 popMemType();
-
-public:
- void setProfilingEnabled(bool should_enable);
-
- static bool isProfiling();
-
- LLAllocatorHeapProfile const & getProfile();
-
-private:
- std::string getRawProfile();
-
-private:
- LLAllocatorHeapProfile mProf;
-};
-
-#endif // LL_LLALLOCATOR_H
+/**
+ * @file llallocator.h
+ * @brief Declaration of the LLAllocator class.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLALLOCATOR_H
+#define LL_LLALLOCATOR_H
+
+#include <string>
+
+#include "llmemtype.h"
+#include "llallocator_heap_profile.h"
+
+class LL_COMMON_API LLAllocator {
+ friend class LLMemoryView;
+ friend class LLMemType;
+
+private:
+ static void pushMemType(S32 type);
+ static S32 popMemType();
+
+public:
+ void setProfilingEnabled(bool should_enable);
+
+ static bool isProfiling();
+
+ LLAllocatorHeapProfile const & getProfile();
+
+private:
+ std::string getRawProfile();
+
+private:
+ LLAllocatorHeapProfile mProf;
+};
+
+#endif // LL_LLALLOCATOR_H
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index 141b0df43c..6c5fa5af6d 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -1,149 +1,149 @@
-/**
- * @file llcoros.h
- * @author Nat Goodspeed
- * @date 2009-06-02
- * @brief Manage running boost::coroutine instances
- *
- * $LicenseInfo:firstyear=2009&license=viewergpl$
- * Copyright (c) 2009, Linden Research, Inc.
- * $/LicenseInfo$
- */
-
-#if ! defined(LL_LLCOROS_H)
-#define LL_LLCOROS_H
-
-#include <boost/coroutine/coroutine.hpp>
-#include "llsingleton.h"
-#include <boost/ptr_container/ptr_map.hpp>
-#include <string>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/iteration/local.hpp>
-#include <stdexcept>
-
-/**
- * Registry of named Boost.Coroutine instances
- *
- * The Boost.Coroutine library supports the general case of a coroutine
- * accepting arbitrary parameters and yielding multiple (sets of) results. For
- * such use cases, it's natural for the invoking code to retain the coroutine
- * instance: the consumer repeatedly calls into the coroutine, perhaps passing
- * new parameter values, prompting it to yield its next result.
- *
- * Our typical coroutine usage is different, though. For us, coroutines
- * provide an alternative to the @c Responder pattern. Our typical coroutine
- * has @c void return, invoked in fire-and-forget mode: the handler for some
- * user gesture launches the coroutine and promptly returns to the main loop.
- * The coroutine initiates some action that will take multiple frames (e.g. a
- * capability request), waits for its result, processes it and silently steals
- * away.
- *
- * This usage poses two (related) problems:
- *
- * # Who should own the coroutine instance? If it's simply local to the
- * handler code that launches it, return from the handler will destroy the
- * coroutine object, terminating the coroutine.
- * # Once the coroutine terminates, in whatever way, who's responsible for
- * cleaning up the coroutine object?
- *
- * LLCoros is a Singleton collection of currently-active coroutine instances.
- * Each has a name. You ask LLCoros to launch a new coroutine with a suggested
- * name prefix; from your prefix it generates a distinct name, registers the
- * new coroutine and returns the actual name.
- *
- * The name can be used to kill off the coroutine prematurely, if needed. It
- * can also provide diagnostic info: we can look up the name of the
- * currently-running coroutine.
- *
- * Finally, the next frame ("mainloop" event) after the coroutine terminates,
- * LLCoros will notice its demise and destroy it.
- */
-class LL_COMMON_API LLCoros: public LLSingleton<LLCoros>
-{
-public:
- /// Canonical boost::coroutines::coroutine signature we use
- typedef boost::coroutines::coroutine<void()> coro;
- /// Canonical 'self' type
- typedef coro::self self;
-
- /**
- * Create and start running a new coroutine with specified name. The name
- * string you pass is a suggestion; it will be tweaked for uniqueness. The
- * actual name is returned to you.
- *
- * Usage looks like this, for (e.g.) two coroutine parameters:
- * @code
- * class MyClass
- * {
- * public:
- * ...
- * // Do NOT NOT NOT accept reference params other than 'self'!
- * // Pass by value only!
- * void myCoroutineMethod(LLCoros::self& self, std::string, LLSD);
- * ...
- * };
- * ...
- * std::string name = LLCoros::instance().launch(
- * "mycoro", boost::bind(&MyClass::myCoroutineMethod, this, _1,
- * "somestring", LLSD(17));
- * @endcode
- *
- * Your function/method must accept LLCoros::self& as its first parameter.
- * It can accept any other parameters you want -- but ONLY BY VALUE!
- * Other reference parameters are a BAD IDEA! You Have Been Warned. See
- * DEV-32777 comments for an explanation.
- *
- * Pass a callable that accepts the single LLCoros::self& parameter. It
- * may work to pass a free function whose only parameter is 'self'; for
- * all other cases use boost::bind(). Of course, for a non-static class
- * method, the first parameter must be the class instance. Use the
- * placeholder _1 for the 'self' parameter. Any other parameters should be
- * passed via the bind() expression.
- *
- * launch() tweaks the suggested name so it won't collide with any
- * existing coroutine instance, creates the coroutine instance, registers
- * it with the tweaked name and runs it until its first wait. At that
- * point it returns the tweaked name.
- */
- template <typename CALLABLE>
- std::string launch(const std::string& prefix, const CALLABLE& callable)
- {
- return launchImpl(prefix, new coro(callable));
- }
-
- /**
- * Abort a running coroutine by name. Normally, when a coroutine either
- * runs to completion or terminates with an exception, LLCoros quietly
- * cleans it up. This is for use only when you must explicitly interrupt
- * one prematurely. Returns @c true if the specified name was found and
- * still running at the time.
- */
- bool kill(const std::string& name);
-
- /**
- * From within a coroutine, pass its @c self object to look up the
- * (tweaked) name string by which this coroutine is registered. Returns
- * the empty string if not found (e.g. if the coroutine was launched by
- * hand rather than using LLCoros::launch()).
- */
- template <typename COROUTINE_SELF>
- std::string getName(const COROUTINE_SELF& self) const
- {
- return getNameByID(self.get_id());
- }
-
- /// getName() by self.get_id()
- std::string getNameByID(const void* self_id) const;
-
-private:
- friend class LLSingleton<LLCoros>;
- LLCoros();
- std::string launchImpl(const std::string& prefix, coro* newCoro);
- std::string generateDistinctName(const std::string& prefix) const;
- bool cleanup(const LLSD&);
-
- typedef boost::ptr_map<std::string, coro> CoroMap;
- CoroMap mCoros;
-};
-
-#endif /* ! defined(LL_LLCOROS_H) */
+/**
+ * @file llcoros.h
+ * @author Nat Goodspeed
+ * @date 2009-06-02
+ * @brief Manage running boost::coroutine instances
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLCOROS_H)
+#define LL_LLCOROS_H
+
+#include <boost/coroutine/coroutine.hpp>
+#include "llsingleton.h"
+#include <boost/ptr_container/ptr_map.hpp>
+#include <string>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/iteration/local.hpp>
+#include <stdexcept>
+
+/**
+ * Registry of named Boost.Coroutine instances
+ *
+ * The Boost.Coroutine library supports the general case of a coroutine
+ * accepting arbitrary parameters and yielding multiple (sets of) results. For
+ * such use cases, it's natural for the invoking code to retain the coroutine
+ * instance: the consumer repeatedly calls into the coroutine, perhaps passing
+ * new parameter values, prompting it to yield its next result.
+ *
+ * Our typical coroutine usage is different, though. For us, coroutines
+ * provide an alternative to the @c Responder pattern. Our typical coroutine
+ * has @c void return, invoked in fire-and-forget mode: the handler for some
+ * user gesture launches the coroutine and promptly returns to the main loop.
+ * The coroutine initiates some action that will take multiple frames (e.g. a
+ * capability request), waits for its result, processes it and silently steals
+ * away.
+ *
+ * This usage poses two (related) problems:
+ *
+ * # Who should own the coroutine instance? If it's simply local to the
+ * handler code that launches it, return from the handler will destroy the
+ * coroutine object, terminating the coroutine.
+ * # Once the coroutine terminates, in whatever way, who's responsible for
+ * cleaning up the coroutine object?
+ *
+ * LLCoros is a Singleton collection of currently-active coroutine instances.
+ * Each has a name. You ask LLCoros to launch a new coroutine with a suggested
+ * name prefix; from your prefix it generates a distinct name, registers the
+ * new coroutine and returns the actual name.
+ *
+ * The name can be used to kill off the coroutine prematurely, if needed. It
+ * can also provide diagnostic info: we can look up the name of the
+ * currently-running coroutine.
+ *
+ * Finally, the next frame ("mainloop" event) after the coroutine terminates,
+ * LLCoros will notice its demise and destroy it.
+ */
+class LL_COMMON_API LLCoros: public LLSingleton<LLCoros>
+{
+public:
+ /// Canonical boost::coroutines::coroutine signature we use
+ typedef boost::coroutines::coroutine<void()> coro;
+ /// Canonical 'self' type
+ typedef coro::self self;
+
+ /**
+ * Create and start running a new coroutine with specified name. The name
+ * string you pass is a suggestion; it will be tweaked for uniqueness. The
+ * actual name is returned to you.
+ *
+ * Usage looks like this, for (e.g.) two coroutine parameters:
+ * @code
+ * class MyClass
+ * {
+ * public:
+ * ...
+ * // Do NOT NOT NOT accept reference params other than 'self'!
+ * // Pass by value only!
+ * void myCoroutineMethod(LLCoros::self& self, std::string, LLSD);
+ * ...
+ * };
+ * ...
+ * std::string name = LLCoros::instance().launch(
+ * "mycoro", boost::bind(&MyClass::myCoroutineMethod, this, _1,
+ * "somestring", LLSD(17));
+ * @endcode
+ *
+ * Your function/method must accept LLCoros::self& as its first parameter.
+ * It can accept any other parameters you want -- but ONLY BY VALUE!
+ * Other reference parameters are a BAD IDEA! You Have Been Warned. See
+ * DEV-32777 comments for an explanation.
+ *
+ * Pass a callable that accepts the single LLCoros::self& parameter. It
+ * may work to pass a free function whose only parameter is 'self'; for
+ * all other cases use boost::bind(). Of course, for a non-static class
+ * method, the first parameter must be the class instance. Use the
+ * placeholder _1 for the 'self' parameter. Any other parameters should be
+ * passed via the bind() expression.
+ *
+ * launch() tweaks the suggested name so it won't collide with any
+ * existing coroutine instance, creates the coroutine instance, registers
+ * it with the tweaked name and runs it until its first wait. At that
+ * point it returns the tweaked name.
+ */
+ template <typename CALLABLE>
+ std::string launch(const std::string& prefix, const CALLABLE& callable)
+ {
+ return launchImpl(prefix, new coro(callable));
+ }
+
+ /**
+ * Abort a running coroutine by name. Normally, when a coroutine either
+ * runs to completion or terminates with an exception, LLCoros quietly
+ * cleans it up. This is for use only when you must explicitly interrupt
+ * one prematurely. Returns @c true if the specified name was found and
+ * still running at the time.
+ */
+ bool kill(const std::string& name);
+
+ /**
+ * From within a coroutine, pass its @c self object to look up the
+ * (tweaked) name string by which this coroutine is registered. Returns
+ * the empty string if not found (e.g. if the coroutine was launched by
+ * hand rather than using LLCoros::launch()).
+ */
+ template <typename COROUTINE_SELF>
+ std::string getName(const COROUTINE_SELF& self) const
+ {
+ return getNameByID(self.get_id());
+ }
+
+ /// getName() by self.get_id()
+ std::string getNameByID(const void* self_id) const;
+
+private:
+ friend class LLSingleton<LLCoros>;
+ LLCoros();
+ std::string launchImpl(const std::string& prefix, coro* newCoro);
+ std::string generateDistinctName(const std::string& prefix) const;
+ bool cleanup(const LLSD&);
+
+ typedef boost::ptr_map<std::string, coro> CoroMap;
+ CoroMap mCoros;
+};
+
+#endif /* ! defined(LL_LLCOROS_H) */
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 45b84ea3ea..905d736d62 100644
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -1,317 +1,317 @@
-/**
- * @file llfasttimer.h
- * @brief Declaration of a fast timer.
- *
- * $LicenseInfo:firstyear=2004&license=viewergpl$
- *
- * Copyright (c) 2004-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#ifndef LL_FASTTIMER_H
-#define LL_FASTTIMER_H
-
-#include "llinstancetracker.h"
-
-#define FAST_TIMER_ON 1
-
-#if LL_WINDOWS
-
-// shift off lower 8 bits for lower resolution but longer term timing
-// on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing
-inline U32 get_cpu_clock_count_32()
-{
- U32 ret_val;
- __asm
- {
- _emit 0x0f
- _emit 0x31
- shr eax,8
- shl edx,24
- or eax, edx
- mov dword ptr [ret_val], eax
- }
- return ret_val;
-}
-
-// return full timer value, still shifted by 8 bits
-inline U64 get_cpu_clock_count_64()
-{
- U64 ret_val;
- __asm
- {
- _emit 0x0f
- _emit 0x31
- mov eax,eax
- mov edx,edx
- mov dword ptr [ret_val+4], edx
- mov dword ptr [ret_val], eax
- }
- return ret_val >> 8;
-}
-
-#endif // LL_WINDOWS
-
-#if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__))
-inline U32 get_cpu_clock_count_32()
-{
- U64 x;
- __asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
- return (U32)x >> 8;
-}
-
-inline U32 get_cpu_clock_count_64()
-{
- U64 x;
- __asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
- return x >> 8;
-}
-#endif
-
-#if ( LL_DARWIN && !(defined(__i386__) || defined(__amd64__))) || (LL_SOLARIS && defined(__sparc__))
-//
-// Mac PPC (deprecated) & Solaris SPARC implementation of CPU clock
-//
-// Just use gettimeofday implementation for now
-
-inline U32 get_cpu_clock_count_32()
-{
- return (U32)get_clock_count();
-}
-
-inline U32 get_cpu_clock_count_64()
-{
- return get_clock_count();
-}
-#endif
-
-class LLMutex;
-
-#include <queue>
-#include "llsd.h"
-
-
-class LL_COMMON_API LLFastTimer
-{
-public:
- // stores a "named" timer instance to be reused via multiple LLFastTimer stack instances
- class LL_COMMON_API NamedTimer
- : public LLInstanceTracker<NamedTimer>
- {
- friend class DeclareTimer;
- public:
- ~NamedTimer();
-
- enum { HISTORY_NUM = 60 };
-
- const std::string& getName() const { return mName; }
- NamedTimer* getParent() const { return mParent; }
- void setParent(NamedTimer* parent);
- S32 getDepth();
- std::string getToolTip(S32 history_index = -1);
-
- typedef std::vector<NamedTimer*>::const_iterator child_const_iter;
- child_const_iter beginChildren();
- child_const_iter endChildren();
- std::vector<NamedTimer*>& getChildren();
-
- void setCollapsed(bool collapsed) { mCollapsed = collapsed; }
- bool getCollapsed() const { return mCollapsed; }
-
- U32 getCountAverage() const { return mCountAverage; }
- U32 getCallAverage() const { return mCallAverage; }
-
- U32 getHistoricalCount(S32 history_index = 0) const;
- U32 getHistoricalCalls(S32 history_index = 0) const;
-
- static NamedTimer& getRootNamedTimer();
-
- struct FrameState
- {
- FrameState(NamedTimer* timerp);
-
- U32 mSelfTimeCounter;
- U32 mCalls;
- FrameState* mParent; // info for caller timer
- FrameState* mLastCaller; // used to bootstrap tree construction
- NamedTimer* mTimer;
- U16 mActiveCount; // number of timers with this ID active on stack
- bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame
- };
-
- S32 getFrameStateIndex() const { return mFrameStateIndex; }
-
- FrameState& getFrameState() const;
-
-
- private:
- friend class LLFastTimer;
- friend class NamedTimerFactory;
-
- //
- // methods
- //
- NamedTimer(const std::string& name);
- // recursive call to gather total time from children
- static void accumulateTimings();
-
- // updates cumulative times and hierarchy,
- // can be called multiple times in a frame, at any point
- static void processTimes();
-
- static void buildHierarchy();
- static void resetFrame();
- static void reset();
-
-
- //
- // members
- //
- S32 mFrameStateIndex;
-
- std::string mName;
-
- U32 mTotalTimeCounter;
-
- U32 mCountAverage;
- U32 mCallAverage;
-
- U32* mCountHistory;
- U32* mCallHistory;
-
- // tree structure
- NamedTimer* mParent; // NamedTimer of caller(parent)
- std::vector<NamedTimer*> mChildren;
- bool mCollapsed; // don't show children
- bool mNeedsSorting; // sort children whenever child added
-
- };
-
- // used to statically declare a new named timer
- class LL_COMMON_API DeclareTimer
- : public LLInstanceTracker<DeclareTimer>
- {
- public:
- DeclareTimer(const std::string& name, bool open);
- DeclareTimer(const std::string& name);
-
- static void updateCachedPointers();
-
- // convertable to NamedTimer::FrameState for convenient usage of LLFastTimer(declared_timer)
- operator NamedTimer::FrameState&() { return *mFrameState; }
- private:
- NamedTimer& mTimer;
- NamedTimer::FrameState* mFrameState;
- };
-
-
-public:
- static LLMutex* sLogLock;
- static std::queue<LLSD> sLogQueue;
- static BOOL sLog;
- static BOOL sMetricLog;
-
- typedef std::vector<NamedTimer::FrameState> info_list_t;
- static info_list_t& getFrameStateList();
-
- enum RootTimerMarker { ROOT };
- LLFastTimer(RootTimerMarker);
-
- LLFastTimer(NamedTimer::FrameState& timer)
- : mFrameState(&timer)
- {
-#if FAST_TIMER_ON
- NamedTimer::FrameState* frame_state = &timer;
- U32 cur_time = get_cpu_clock_count_32();
- mStartSelfTime = cur_time;
- mStartTotalTime = cur_time;
-
- frame_state->mActiveCount++;
- frame_state->mCalls++;
- // keep current parent as long as it is active when we are
- frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0);
-
- mLastTimer = sCurTimer;
- sCurTimer = this;
-#endif
- }
-
- ~LLFastTimer()
- {
-#if FAST_TIMER_ON
- NamedTimer::FrameState* frame_state = mFrameState;
- U32 cur_time = get_cpu_clock_count_32();
- frame_state->mSelfTimeCounter += cur_time - mStartSelfTime;
-
- frame_state->mActiveCount--;
- LLFastTimer* last_timer = mLastTimer;
- sCurTimer = last_timer;
-
- // store last caller to bootstrap tree creation
- frame_state->mLastCaller = last_timer->mFrameState;
-
- // we are only tracking self time, so subtract our total time delta from parents
- U32 total_time = cur_time - mStartTotalTime;
- last_timer->mStartSelfTime += total_time;
-#endif
- }
-
-
- // call this once a frame to reset timers
- static void nextFrame();
-
- // dumps current cumulative frame stats to log
- // call nextFrame() to reset timers
- static void dumpCurTimes();
-
- // call this to reset timer hierarchy, averages, etc.
- static void reset();
-
- static U64 countsPerSecond();
- static S32 getLastFrameIndex() { return sLastFrameIndex; }
- static S32 getCurFrameIndex() { return sCurFrameIndex; }
-
- static void writeLog(std::ostream& os);
- static const NamedTimer* getTimerByName(const std::string& name);
-
-public:
- static bool sPauseHistory;
- static bool sResetHistory;
-
-private:
- typedef std::vector<LLFastTimer*> timer_stack_t;
- static LLFastTimer* sCurTimer;
- static S32 sCurFrameIndex;
- static S32 sLastFrameIndex;
- static U64 sLastFrameTime;
- static info_list_t* sTimerInfos;
-
- U32 mStartSelfTime; // start time + time of all child timers
- U32 mStartTotalTime; // start time + time of all child timers
- NamedTimer::FrameState* mFrameState;
- LLFastTimer* mLastTimer;
-};
-
-#endif // LL_LLFASTTIMER_H
+/**
+ * @file llfasttimer.h
+ * @brief Declaration of a fast timer.
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_FASTTIMER_H
+#define LL_FASTTIMER_H
+
+#include "llinstancetracker.h"
+
+#define FAST_TIMER_ON 1
+
+#if LL_WINDOWS
+
+// shift off lower 8 bits for lower resolution but longer term timing
+// on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing
+inline U32 get_cpu_clock_count_32()
+{
+ U32 ret_val;
+ __asm
+ {
+ _emit 0x0f
+ _emit 0x31
+ shr eax,8
+ shl edx,24
+ or eax, edx
+ mov dword ptr [ret_val], eax
+ }
+ return ret_val;
+}
+
+// return full timer value, still shifted by 8 bits
+inline U64 get_cpu_clock_count_64()
+{
+ U64 ret_val;
+ __asm
+ {
+ _emit 0x0f
+ _emit 0x31
+ mov eax,eax
+ mov edx,edx
+ mov dword ptr [ret_val+4], edx
+ mov dword ptr [ret_val], eax
+ }
+ return ret_val >> 8;
+}
+
+#endif // LL_WINDOWS
+
+#if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__))
+inline U32 get_cpu_clock_count_32()
+{
+ U64 x;
+ __asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
+ return (U32)x >> 8;
+}
+
+inline U32 get_cpu_clock_count_64()
+{
+ U64 x;
+ __asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
+ return x >> 8;
+}
+#endif
+
+#if ( LL_DARWIN && !(defined(__i386__) || defined(__amd64__))) || (LL_SOLARIS && defined(__sparc__))
+//
+// Mac PPC (deprecated) & Solaris SPARC implementation of CPU clock
+//
+// Just use gettimeofday implementation for now
+
+inline U32 get_cpu_clock_count_32()
+{
+ return (U32)get_clock_count();
+}
+
+inline U32 get_cpu_clock_count_64()
+{
+ return get_clock_count();
+}
+#endif
+
+class LLMutex;
+
+#include <queue>
+#include "llsd.h"
+
+
+class LL_COMMON_API LLFastTimer
+{
+public:
+ // stores a "named" timer instance to be reused via multiple LLFastTimer stack instances
+ class LL_COMMON_API NamedTimer
+ : public LLInstanceTracker<NamedTimer>
+ {
+ friend class DeclareTimer;
+ public:
+ ~NamedTimer();
+
+ enum { HISTORY_NUM = 60 };
+
+ const std::string& getName() const { return mName; }
+ NamedTimer* getParent() const { return mParent; }
+ void setParent(NamedTimer* parent);
+ S32 getDepth();
+ std::string getToolTip(S32 history_index = -1);
+
+ typedef std::vector<NamedTimer*>::const_iterator child_const_iter;
+ child_const_iter beginChildren();
+ child_const_iter endChildren();
+ std::vector<NamedTimer*>& getChildren();
+
+ void setCollapsed(bool collapsed) { mCollapsed = collapsed; }
+ bool getCollapsed() const { return mCollapsed; }
+
+ U32 getCountAverage() const { return mCountAverage; }
+ U32 getCallAverage() const { return mCallAverage; }
+
+ U32 getHistoricalCount(S32 history_index = 0) const;
+ U32 getHistoricalCalls(S32 history_index = 0) const;
+
+ static NamedTimer& getRootNamedTimer();
+
+ struct FrameState
+ {
+ FrameState(NamedTimer* timerp);
+
+ U32 mSelfTimeCounter;
+ U32 mCalls;
+ FrameState* mParent; // info for caller timer
+ FrameState* mLastCaller; // used to bootstrap tree construction
+ NamedTimer* mTimer;
+ U16 mActiveCount; // number of timers with this ID active on stack
+ bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame
+ };
+
+ S32 getFrameStateIndex() const { return mFrameStateIndex; }
+
+ FrameState& getFrameState() const;
+
+
+ private:
+ friend class LLFastTimer;
+ friend class NamedTimerFactory;
+
+ //
+ // methods
+ //
+ NamedTimer(const std::string& name);
+ // recursive call to gather total time from children
+ static void accumulateTimings();
+
+ // updates cumulative times and hierarchy,
+ // can be called multiple times in a frame, at any point
+ static void processTimes();
+
+ static void buildHierarchy();
+ static void resetFrame();
+ static void reset();
+
+
+ //
+ // members
+ //
+ S32 mFrameStateIndex;
+
+ std::string mName;
+
+ U32 mTotalTimeCounter;
+
+ U32 mCountAverage;
+ U32 mCallAverage;
+
+ U32* mCountHistory;
+ U32* mCallHistory;
+
+ // tree structure
+ NamedTimer* mParent; // NamedTimer of caller(parent)
+ std::vector<NamedTimer*> mChildren;
+ bool mCollapsed; // don't show children
+ bool mNeedsSorting; // sort children whenever child added
+
+ };
+
+ // used to statically declare a new named timer
+ class LL_COMMON_API DeclareTimer
+ : public LLInstanceTracker<DeclareTimer>
+ {
+ public:
+ DeclareTimer(const std::string& name, bool open);
+ DeclareTimer(const std::string& name);
+
+ static void updateCachedPointers();
+
+ // convertable to NamedTimer::FrameState for convenient usage of LLFastTimer(declared_timer)
+ operator NamedTimer::FrameState&() { return *mFrameState; }
+ private:
+ NamedTimer& mTimer;
+ NamedTimer::FrameState* mFrameState;
+ };
+
+
+public:
+ static LLMutex* sLogLock;
+ static std::queue<LLSD> sLogQueue;
+ static BOOL sLog;
+ static BOOL sMetricLog;
+
+ typedef std::vector<NamedTimer::FrameState> info_list_t;
+ static info_list_t& getFrameStateList();
+
+ enum RootTimerMarker { ROOT };
+ LLFastTimer(RootTimerMarker);
+
+ LLFastTimer(NamedTimer::FrameState& timer)
+ : mFrameState(&timer)
+ {
+#if FAST_TIMER_ON
+ NamedTimer::FrameState* frame_state = &timer;
+ U32 cur_time = get_cpu_clock_count_32();
+ mStartSelfTime = cur_time;
+ mStartTotalTime = cur_time;
+
+ frame_state->mActiveCount++;
+ frame_state->mCalls++;
+ // keep current parent as long as it is active when we are
+ frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0);
+
+ mLastTimer = sCurTimer;
+ sCurTimer = this;
+#endif
+ }
+
+ ~LLFastTimer()
+ {
+#if FAST_TIMER_ON
+ NamedTimer::FrameState* frame_state = mFrameState;
+ U32 cur_time = get_cpu_clock_count_32();
+ frame_state->mSelfTimeCounter += cur_time - mStartSelfTime;
+
+ frame_state->mActiveCount--;
+ LLFastTimer* last_timer = mLastTimer;
+ sCurTimer = last_timer;
+
+ // store last caller to bootstrap tree creation
+ frame_state->mLastCaller = last_timer->mFrameState;
+
+ // we are only tracking self time, so subtract our total time delta from parents
+ U32 total_time = cur_time - mStartTotalTime;
+ last_timer->mStartSelfTime += total_time;
+#endif
+ }
+
+
+ // call this once a frame to reset timers
+ static void nextFrame();
+
+ // dumps current cumulative frame stats to log
+ // call nextFrame() to reset timers
+ static void dumpCurTimes();
+
+ // call this to reset timer hierarchy, averages, etc.
+ static void reset();
+
+ static U64 countsPerSecond();
+ static S32 getLastFrameIndex() { return sLastFrameIndex; }
+ static S32 getCurFrameIndex() { return sCurFrameIndex; }
+
+ static void writeLog(std::ostream& os);
+ static const NamedTimer* getTimerByName(const std::string& name);
+
+public:
+ static bool sPauseHistory;
+ static bool sResetHistory;
+
+private:
+ typedef std::vector<LLFastTimer*> timer_stack_t;
+ static LLFastTimer* sCurTimer;
+ static S32 sCurFrameIndex;
+ static S32 sLastFrameIndex;
+ static U64 sLastFrameTime;
+ static info_list_t* sTimerInfos;
+
+ U32 mStartSelfTime; // start time + time of all child timers
+ U32 mStartTotalTime; // start time + time of all child timers
+ NamedTimer::FrameState* mFrameState;
+ LLFastTimer* mLastTimer;
+};
+
+#endif // LL_LLFASTTIMER_H
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index 1c6f64dd8b..09f19532b7 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -1,65 +1,65 @@
-/**
- * @file llmemory.h
- * @brief Memory allocation/deallocation header-stuff goes here.
- *
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-#ifndef LLMEMORY_H
-#define LLMEMORY_H
-
-
-
-extern S32 gTotalDAlloc;
-extern S32 gTotalDAUse;
-extern S32 gDACount;
-
-extern void* ll_allocate (size_t size);
-extern void ll_release (void *p);
-
-class LL_COMMON_API LLMemory
-{
-public:
- static void initClass();
- static void cleanupClass();
- static void freeReserve();
- // Return the resident set size of the current process, in bytes.
- // Return value is zero if not known.
- static U64 getCurrentRSS();
-private:
- static char* reserveMem;
-};
-
-// LLRefCount moved to llrefcount.h
-
-// LLPointer moved to llpointer.h
-
-// LLSafeHandle moved to llsafehandle.h
-
-// LLSingleton moved to llsingleton.h
-
-#endif
+/**
+ * @file llmemory.h
+ * @brief Memory allocation/deallocation header-stuff goes here.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLMEMORY_H
+#define LLMEMORY_H
+
+
+
+extern S32 gTotalDAlloc;
+extern S32 gTotalDAUse;
+extern S32 gDACount;
+
+extern void* ll_allocate (size_t size);
+extern void ll_release (void *p);
+
+class LL_COMMON_API LLMemory
+{
+public:
+ static void initClass();
+ static void cleanupClass();
+ static void freeReserve();
+ // Return the resident set size of the current process, in bytes.
+ // Return value is zero if not known.
+ static U64 getCurrentRSS();
+private:
+ static char* reserveMem;
+};
+
+// LLRefCount moved to llrefcount.h
+
+// LLPointer moved to llpointer.h
+
+// LLSafeHandle moved to llsafehandle.h
+
+// LLSingleton moved to llsingleton.h
+
+#endif
diff --git a/indra/llcommon/llmemtype.h b/indra/llcommon/llmemtype.h
index 677fad3034..5952a3a7c5 100644
--- a/indra/llcommon/llmemtype.h
+++ b/indra/llcommon/llmemtype.h
@@ -1,248 +1,248 @@
-/**
- * @file llmemtype.h
- * @brief Runtime memory usage debugging utilities.
- *
- * $LicenseInfo:firstyear=2005&license=viewergpl$
- *
- * Copyright (c) 2005-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#ifndef LL_MEMTYPE_H
-#define LL_MEMTYPE_H
-
-//----------------------------------------------------------------------------
-//----------------------------------------------------------------------------
-
-//----------------------------------------------------------------------------
-
-#include "linden_common.h"
-//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-// WARNING: Never commit with MEM_TRACK_MEM == 1
-//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-#define MEM_TRACK_MEM (0 && LL_WINDOWS)
-
-#include <vector>
-
-#define MEM_TYPE_NEW(T)
-
-class LL_COMMON_API LLMemType
-{
-public:
-
- // class we'll initialize all instances of as
- // static members of MemType. Then use
- // to construct any new mem type.
- class LL_COMMON_API DeclareMemType
- {
- public:
- DeclareMemType(char const * st);
- ~DeclareMemType();
-
- S32 mID;
- char const * mName;
-
- // array so we can map an index ID to Name
- static std::vector<char const *> mNameList;
- };
-
- LLMemType(DeclareMemType& dt);
- ~LLMemType();
-
- static char const * getNameFromID(S32 id);
-
- static DeclareMemType MTYPE_INIT;
- static DeclareMemType MTYPE_STARTUP;
- static DeclareMemType MTYPE_MAIN;
- static DeclareMemType MTYPE_FRAME;
-
- static DeclareMemType MTYPE_GATHER_INPUT;
- static DeclareMemType MTYPE_JOY_KEY;
-
- static DeclareMemType MTYPE_IDLE;
- static DeclareMemType MTYPE_IDLE_PUMP;
- static DeclareMemType MTYPE_IDLE_NETWORK;
- static DeclareMemType MTYPE_IDLE_UPDATE_REGIONS;
- static DeclareMemType MTYPE_IDLE_UPDATE_VIEWER_REGION;
- static DeclareMemType MTYPE_IDLE_UPDATE_SURFACE;
- static DeclareMemType MTYPE_IDLE_UPDATE_PARCEL_OVERLAY;
- static DeclareMemType MTYPE_IDLE_AUDIO;
-
- static DeclareMemType MTYPE_CACHE_PROCESS_PENDING;
- static DeclareMemType MTYPE_CACHE_PROCESS_PENDING_ASKS;
- static DeclareMemType MTYPE_CACHE_PROCESS_PENDING_REPLIES;
-
- static DeclareMemType MTYPE_MESSAGE_CHECK_ALL;
- static DeclareMemType MTYPE_MESSAGE_PROCESS_ACKS;
-
- static DeclareMemType MTYPE_RENDER;
- static DeclareMemType MTYPE_SLEEP;
-
- static DeclareMemType MTYPE_NETWORK;
- static DeclareMemType MTYPE_PHYSICS;
- static DeclareMemType MTYPE_INTERESTLIST;
-
- static DeclareMemType MTYPE_IMAGEBASE;
- static DeclareMemType MTYPE_IMAGERAW;
- static DeclareMemType MTYPE_IMAGEFORMATTED;
-
- static DeclareMemType MTYPE_APPFMTIMAGE;
- static DeclareMemType MTYPE_APPRAWIMAGE;
- static DeclareMemType MTYPE_APPAUXRAWIMAGE;
-
- static DeclareMemType MTYPE_DRAWABLE;
-
- static DeclareMemType MTYPE_OBJECT;
- static DeclareMemType MTYPE_OBJECT_PROCESS_UPDATE;
- static DeclareMemType MTYPE_OBJECT_PROCESS_UPDATE_CORE;
-
- static DeclareMemType MTYPE_DISPLAY;
- static DeclareMemType MTYPE_DISPLAY_UPDATE;
- static DeclareMemType MTYPE_DISPLAY_UPDATE_CAMERA;
- static DeclareMemType MTYPE_DISPLAY_UPDATE_GEOM;
- static DeclareMemType MTYPE_DISPLAY_SWAP;
- static DeclareMemType MTYPE_DISPLAY_UPDATE_HUD;
- static DeclareMemType MTYPE_DISPLAY_GEN_REFLECTION;
- static DeclareMemType MTYPE_DISPLAY_IMAGE_UPDATE;
- static DeclareMemType MTYPE_DISPLAY_STATE_SORT;
- static DeclareMemType MTYPE_DISPLAY_SKY;
- static DeclareMemType MTYPE_DISPLAY_RENDER_GEOM;
- static DeclareMemType MTYPE_DISPLAY_RENDER_FLUSH;
- static DeclareMemType MTYPE_DISPLAY_RENDER_UI;
- static DeclareMemType MTYPE_DISPLAY_RENDER_ATTACHMENTS;
-
- static DeclareMemType MTYPE_VERTEX_DATA;
- static DeclareMemType MTYPE_VERTEX_CONSTRUCTOR;
- static DeclareMemType MTYPE_VERTEX_DESTRUCTOR;
- static DeclareMemType MTYPE_VERTEX_CREATE_VERTICES;
- static DeclareMemType MTYPE_VERTEX_CREATE_INDICES;
- static DeclareMemType MTYPE_VERTEX_DESTROY_BUFFER;
- static DeclareMemType MTYPE_VERTEX_DESTROY_INDICES;
- static DeclareMemType MTYPE_VERTEX_UPDATE_VERTS;
- static DeclareMemType MTYPE_VERTEX_UPDATE_INDICES;
- static DeclareMemType MTYPE_VERTEX_ALLOCATE_BUFFER;
- static DeclareMemType MTYPE_VERTEX_RESIZE_BUFFER;
- static DeclareMemType MTYPE_VERTEX_MAP_BUFFER;
- static DeclareMemType MTYPE_VERTEX_MAP_BUFFER_VERTICES;
- static DeclareMemType MTYPE_VERTEX_MAP_BUFFER_INDICES;
- static DeclareMemType MTYPE_VERTEX_UNMAP_BUFFER;
- static DeclareMemType MTYPE_VERTEX_SET_STRIDE;
- static DeclareMemType MTYPE_VERTEX_SET_BUFFER;
- static DeclareMemType MTYPE_VERTEX_SETUP_VERTEX_BUFFER;
- static DeclareMemType MTYPE_VERTEX_CLEANUP_CLASS;
-
- static DeclareMemType MTYPE_SPACE_PARTITION;
-
- static DeclareMemType MTYPE_PIPELINE;
- static DeclareMemType MTYPE_PIPELINE_INIT;
- static DeclareMemType MTYPE_PIPELINE_CREATE_BUFFERS;
- static DeclareMemType MTYPE_PIPELINE_RESTORE_GL;
- static DeclareMemType MTYPE_PIPELINE_UNLOAD_SHADERS;
- static DeclareMemType MTYPE_PIPELINE_LIGHTING_DETAIL;
- static DeclareMemType MTYPE_PIPELINE_GET_POOL_TYPE;
- static DeclareMemType MTYPE_PIPELINE_ADD_POOL;
- static DeclareMemType MTYPE_PIPELINE_ALLOCATE_DRAWABLE;
- static DeclareMemType MTYPE_PIPELINE_ADD_OBJECT;
- static DeclareMemType MTYPE_PIPELINE_CREATE_OBJECTS;
- static DeclareMemType MTYPE_PIPELINE_UPDATE_MOVE;
- static DeclareMemType MTYPE_PIPELINE_UPDATE_GEOM;
- static DeclareMemType MTYPE_PIPELINE_MARK_VISIBLE;
- static DeclareMemType MTYPE_PIPELINE_MARK_MOVED;
- static DeclareMemType MTYPE_PIPELINE_MARK_SHIFT;
- static DeclareMemType MTYPE_PIPELINE_SHIFT_OBJECTS;
- static DeclareMemType MTYPE_PIPELINE_MARK_TEXTURED;
- static DeclareMemType MTYPE_PIPELINE_MARK_REBUILD;
- static DeclareMemType MTYPE_PIPELINE_UPDATE_CULL;
- static DeclareMemType MTYPE_PIPELINE_STATE_SORT;
- static DeclareMemType MTYPE_PIPELINE_POST_SORT;
-
- static DeclareMemType MTYPE_PIPELINE_RENDER_HUD_ELS;
- static DeclareMemType MTYPE_PIPELINE_RENDER_HL;
- static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM;
- static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED;
- static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM_POST_DEF;
- static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM_SHADOW;
- static DeclareMemType MTYPE_PIPELINE_RENDER_SELECT;
- static DeclareMemType MTYPE_PIPELINE_REBUILD_POOLS;
- static DeclareMemType MTYPE_PIPELINE_QUICK_LOOKUP;
- static DeclareMemType MTYPE_PIPELINE_RENDER_OBJECTS;
- static DeclareMemType MTYPE_PIPELINE_GENERATE_IMPOSTOR;
- static DeclareMemType MTYPE_PIPELINE_RENDER_BLOOM;
-
- static DeclareMemType MTYPE_UPKEEP_POOLS;
-
- static DeclareMemType MTYPE_AVATAR;
- static DeclareMemType MTYPE_AVATAR_MESH;
- static DeclareMemType MTYPE_PARTICLES;
- static DeclareMemType MTYPE_REGIONS;
-
- static DeclareMemType MTYPE_INVENTORY;
- static DeclareMemType MTYPE_INVENTORY_DRAW;
- static DeclareMemType MTYPE_INVENTORY_BUILD_NEW_VIEWS;
- static DeclareMemType MTYPE_INVENTORY_DO_FOLDER;
- static DeclareMemType MTYPE_INVENTORY_POST_BUILD;
- static DeclareMemType MTYPE_INVENTORY_FROM_XML;
- static DeclareMemType MTYPE_INVENTORY_CREATE_NEW_ITEM;
- static DeclareMemType MTYPE_INVENTORY_VIEW_INIT;
- static DeclareMemType MTYPE_INVENTORY_VIEW_SHOW;
- static DeclareMemType MTYPE_INVENTORY_VIEW_TOGGLE;
-
- static DeclareMemType MTYPE_ANIMATION;
- static DeclareMemType MTYPE_VOLUME;
- static DeclareMemType MTYPE_PRIMITIVE;
-
- static DeclareMemType MTYPE_SCRIPT;
- static DeclareMemType MTYPE_SCRIPT_RUN;
- static DeclareMemType MTYPE_SCRIPT_BYTECODE;
-
- static DeclareMemType MTYPE_IO_PUMP;
- static DeclareMemType MTYPE_IO_TCP;
- static DeclareMemType MTYPE_IO_BUFFER;
- static DeclareMemType MTYPE_IO_HTTP_SERVER;
- static DeclareMemType MTYPE_IO_SD_SERVER;
- static DeclareMemType MTYPE_IO_SD_CLIENT;
- static DeclareMemType MTYPE_IO_URL_REQUEST;
-
- static DeclareMemType MTYPE_DIRECTX_INIT;
-
- static DeclareMemType MTYPE_TEMP1;
- static DeclareMemType MTYPE_TEMP2;
- static DeclareMemType MTYPE_TEMP3;
- static DeclareMemType MTYPE_TEMP4;
- static DeclareMemType MTYPE_TEMP5;
- static DeclareMemType MTYPE_TEMP6;
- static DeclareMemType MTYPE_TEMP7;
- static DeclareMemType MTYPE_TEMP8;
- static DeclareMemType MTYPE_TEMP9;
-
- static DeclareMemType MTYPE_OTHER; // Special; used by display code
-
- S32 mTypeIndex;
-};
-
-//----------------------------------------------------------------------------
-
-#endif
-
+/**
+ * @file llmemtype.h
+ * @brief Runtime memory usage debugging utilities.
+ *
+ * $LicenseInfo:firstyear=2005&license=viewergpl$
+ *
+ * Copyright (c) 2005-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_MEMTYPE_H
+#define LL_MEMTYPE_H
+
+//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+
+#include "linden_common.h"
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// WARNING: Never commit with MEM_TRACK_MEM == 1
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+#define MEM_TRACK_MEM (0 && LL_WINDOWS)
+
+#include <vector>
+
+#define MEM_TYPE_NEW(T)
+
+class LL_COMMON_API LLMemType
+{
+public:
+
+ // class we'll initialize all instances of as
+ // static members of MemType. Then use
+ // to construct any new mem type.
+ class LL_COMMON_API DeclareMemType
+ {
+ public:
+ DeclareMemType(char const * st);
+ ~DeclareMemType();
+
+ S32 mID;
+ char const * mName;
+
+ // array so we can map an index ID to Name
+ static std::vector<char const *> mNameList;
+ };
+
+ LLMemType(DeclareMemType& dt);
+ ~LLMemType();
+
+ static char const * getNameFromID(S32 id);
+
+ static DeclareMemType MTYPE_INIT;
+ static DeclareMemType MTYPE_STARTUP;
+ static DeclareMemType MTYPE_MAIN;
+ static DeclareMemType MTYPE_FRAME;
+
+ static DeclareMemType MTYPE_GATHER_INPUT;
+ static DeclareMemType MTYPE_JOY_KEY;
+
+ static DeclareMemType MTYPE_IDLE;
+ static DeclareMemType MTYPE_IDLE_PUMP;
+ static DeclareMemType MTYPE_IDLE_NETWORK;
+ static DeclareMemType MTYPE_IDLE_UPDATE_REGIONS;
+ static DeclareMemType MTYPE_IDLE_UPDATE_VIEWER_REGION;
+ static DeclareMemType MTYPE_IDLE_UPDATE_SURFACE;
+ static DeclareMemType MTYPE_IDLE_UPDATE_PARCEL_OVERLAY;
+ static DeclareMemType MTYPE_IDLE_AUDIO;
+
+ static DeclareMemType MTYPE_CACHE_PROCESS_PENDING;
+ static DeclareMemType MTYPE_CACHE_PROCESS_PENDING_ASKS;
+ static DeclareMemType MTYPE_CACHE_PROCESS_PENDING_REPLIES;
+
+ static DeclareMemType MTYPE_MESSAGE_CHECK_ALL;
+ static DeclareMemType MTYPE_MESSAGE_PROCESS_ACKS;
+
+ static DeclareMemType MTYPE_RENDER;
+ static DeclareMemType MTYPE_SLEEP;
+
+ static DeclareMemType MTYPE_NETWORK;
+ static DeclareMemType MTYPE_PHYSICS;
+ static DeclareMemType MTYPE_INTERESTLIST;
+
+ static DeclareMemType MTYPE_IMAGEBASE;
+ static DeclareMemType MTYPE_IMAGERAW;
+ static DeclareMemType MTYPE_IMAGEFORMATTED;
+
+ static DeclareMemType MTYPE_APPFMTIMAGE;
+ static DeclareMemType MTYPE_APPRAWIMAGE;
+ static DeclareMemType MTYPE_APPAUXRAWIMAGE;
+
+ static DeclareMemType MTYPE_DRAWABLE;
+
+ static DeclareMemType MTYPE_OBJECT;
+ static DeclareMemType MTYPE_OBJECT_PROCESS_UPDATE;
+ static DeclareMemType MTYPE_OBJECT_PROCESS_UPDATE_CORE;
+
+ static DeclareMemType MTYPE_DISPLAY;
+ static DeclareMemType MTYPE_DISPLAY_UPDATE;
+ static DeclareMemType MTYPE_DISPLAY_UPDATE_CAMERA;
+ static DeclareMemType MTYPE_DISPLAY_UPDATE_GEOM;
+ static DeclareMemType MTYPE_DISPLAY_SWAP;
+ static DeclareMemType MTYPE_DISPLAY_UPDATE_HUD;
+ static DeclareMemType MTYPE_DISPLAY_GEN_REFLECTION;
+ static DeclareMemType MTYPE_DISPLAY_IMAGE_UPDATE;
+ static DeclareMemType MTYPE_DISPLAY_STATE_SORT;
+ static DeclareMemType MTYPE_DISPLAY_SKY;
+ static DeclareMemType MTYPE_DISPLAY_RENDER_GEOM;
+ static DeclareMemType MTYPE_DISPLAY_RENDER_FLUSH;
+ static DeclareMemType MTYPE_DISPLAY_RENDER_UI;
+ static DeclareMemType MTYPE_DISPLAY_RENDER_ATTACHMENTS;
+
+ static DeclareMemType MTYPE_VERTEX_DATA;
+ static DeclareMemType MTYPE_VERTEX_CONSTRUCTOR;
+ static DeclareMemType MTYPE_VERTEX_DESTRUCTOR;
+ static DeclareMemType MTYPE_VERTEX_CREATE_VERTICES;
+ static DeclareMemType MTYPE_VERTEX_CREATE_INDICES;
+ static DeclareMemType MTYPE_VERTEX_DESTROY_BUFFER;
+ static DeclareMemType MTYPE_VERTEX_DESTROY_INDICES;
+ static DeclareMemType MTYPE_VERTEX_UPDATE_VERTS;
+ static DeclareMemType MTYPE_VERTEX_UPDATE_INDICES;
+ static DeclareMemType MTYPE_VERTEX_ALLOCATE_BUFFER;
+ static DeclareMemType MTYPE_VERTEX_RESIZE_BUFFER;
+ static DeclareMemType MTYPE_VERTEX_MAP_BUFFER;
+ static DeclareMemType MTYPE_VERTEX_MAP_BUFFER_VERTICES;
+ static DeclareMemType MTYPE_VERTEX_MAP_BUFFER_INDICES;
+ static DeclareMemType MTYPE_VERTEX_UNMAP_BUFFER;
+ static DeclareMemType MTYPE_VERTEX_SET_STRIDE;
+ static DeclareMemType MTYPE_VERTEX_SET_BUFFER;
+ static DeclareMemType MTYPE_VERTEX_SETUP_VERTEX_BUFFER;
+ static DeclareMemType MTYPE_VERTEX_CLEANUP_CLASS;
+
+ static DeclareMemType MTYPE_SPACE_PARTITION;
+
+ static DeclareMemType MTYPE_PIPELINE;
+ static DeclareMemType MTYPE_PIPELINE_INIT;
+ static DeclareMemType MTYPE_PIPELINE_CREATE_BUFFERS;
+ static DeclareMemType MTYPE_PIPELINE_RESTORE_GL;
+ static DeclareMemType MTYPE_PIPELINE_UNLOAD_SHADERS;
+ static DeclareMemType MTYPE_PIPELINE_LIGHTING_DETAIL;
+ static DeclareMemType MTYPE_PIPELINE_GET_POOL_TYPE;
+ static DeclareMemType MTYPE_PIPELINE_ADD_POOL;
+ static DeclareMemType MTYPE_PIPELINE_ALLOCATE_DRAWABLE;
+ static DeclareMemType MTYPE_PIPELINE_ADD_OBJECT;
+ static DeclareMemType MTYPE_PIPELINE_CREATE_OBJECTS;
+ static DeclareMemType MTYPE_PIPELINE_UPDATE_MOVE;
+ static DeclareMemType MTYPE_PIPELINE_UPDATE_GEOM;
+ static DeclareMemType MTYPE_PIPELINE_MARK_VISIBLE;
+ static DeclareMemType MTYPE_PIPELINE_MARK_MOVED;
+ static DeclareMemType MTYPE_PIPELINE_MARK_SHIFT;
+ static DeclareMemType MTYPE_PIPELINE_SHIFT_OBJECTS;
+ static DeclareMemType MTYPE_PIPELINE_MARK_TEXTURED;
+ static DeclareMemType MTYPE_PIPELINE_MARK_REBUILD;
+ static DeclareMemType MTYPE_PIPELINE_UPDATE_CULL;
+ static DeclareMemType MTYPE_PIPELINE_STATE_SORT;
+ static DeclareMemType MTYPE_PIPELINE_POST_SORT;
+
+ static DeclareMemType MTYPE_PIPELINE_RENDER_HUD_ELS;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_HL;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM_POST_DEF;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM_SHADOW;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_SELECT;
+ static DeclareMemType MTYPE_PIPELINE_REBUILD_POOLS;
+ static DeclareMemType MTYPE_PIPELINE_QUICK_LOOKUP;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_OBJECTS;
+ static DeclareMemType MTYPE_PIPELINE_GENERATE_IMPOSTOR;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_BLOOM;
+
+ static DeclareMemType MTYPE_UPKEEP_POOLS;
+
+ static DeclareMemType MTYPE_AVATAR;
+ static DeclareMemType MTYPE_AVATAR_MESH;
+ static DeclareMemType MTYPE_PARTICLES;
+ static DeclareMemType MTYPE_REGIONS;
+
+ static DeclareMemType MTYPE_INVENTORY;
+ static DeclareMemType MTYPE_INVENTORY_DRAW;
+ static DeclareMemType MTYPE_INVENTORY_BUILD_NEW_VIEWS;
+ static DeclareMemType MTYPE_INVENTORY_DO_FOLDER;
+ static DeclareMemType MTYPE_INVENTORY_POST_BUILD;
+ static DeclareMemType MTYPE_INVENTORY_FROM_XML;
+ static DeclareMemType MTYPE_INVENTORY_CREATE_NEW_ITEM;
+ static DeclareMemType MTYPE_INVENTORY_VIEW_INIT;
+ static DeclareMemType MTYPE_INVENTORY_VIEW_SHOW;
+ static DeclareMemType MTYPE_INVENTORY_VIEW_TOGGLE;
+
+ static DeclareMemType MTYPE_ANIMATION;
+ static DeclareMemType MTYPE_VOLUME;
+ static DeclareMemType MTYPE_PRIMITIVE;
+
+ static DeclareMemType MTYPE_SCRIPT;
+ static DeclareMemType MTYPE_SCRIPT_RUN;
+ static DeclareMemType MTYPE_SCRIPT_BYTECODE;
+
+ static DeclareMemType MTYPE_IO_PUMP;
+ static DeclareMemType MTYPE_IO_TCP;
+ static DeclareMemType MTYPE_IO_BUFFER;
+ static DeclareMemType MTYPE_IO_HTTP_SERVER;
+ static DeclareMemType MTYPE_IO_SD_SERVER;
+ static DeclareMemType MTYPE_IO_SD_CLIENT;
+ static DeclareMemType MTYPE_IO_URL_REQUEST;
+
+ static DeclareMemType MTYPE_DIRECTX_INIT;
+
+ static DeclareMemType MTYPE_TEMP1;
+ static DeclareMemType MTYPE_TEMP2;
+ static DeclareMemType MTYPE_TEMP3;
+ static DeclareMemType MTYPE_TEMP4;
+ static DeclareMemType MTYPE_TEMP5;
+ static DeclareMemType MTYPE_TEMP6;
+ static DeclareMemType MTYPE_TEMP7;
+ static DeclareMemType MTYPE_TEMP8;
+ static DeclareMemType MTYPE_TEMP9;
+
+ static DeclareMemType MTYPE_OTHER; // Special; used by display code
+
+ S32 mTypeIndex;
+};
+
+//----------------------------------------------------------------------------
+
+#endif
+
diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index bb3301df9f..dda9a95597 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -1,169 +1,169 @@
-/**
- * @file llpreprocessor.h
- * @brief This file should be included in all Linden Lab files and
- * should only contain special preprocessor directives
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#ifndef LLPREPROCESSOR_H
-#define LLPREPROCESSOR_H
-
-// Figure out endianness of platform
-#ifdef LL_LINUX
-#define __ENABLE_WSTRING
-#include <endian.h>
-#endif // LL_LINUX
-
-#if LL_SOLARIS
-# ifdef __sparc // Since we're talking Solaris 10 and up, only 64 bit is supported.
-# define LL_BIG_ENDIAN 1
-# define LL_SOLARIS_ALIGNED_CPU 1 // used to designate issues where SPARC alignment is addressed
-# define LL_SOLARIS_NON_MESA_GL 1 // The SPARC GL does not provide a MESA-based GL API
-# endif
-# include <sys/isa_defs.h> // ensure we know which end is up
-#endif // LL_SOLARIS
-
-#if (defined(LL_WINDOWS) || (defined(LL_LINUX) && (__BYTE_ORDER == __LITTLE_ENDIAN)) || (defined(LL_DARWIN) && defined(__LITTLE_ENDIAN__)) || (defined(LL_SOLARIS) && defined(__i386)))
-#define LL_LITTLE_ENDIAN 1
-#else
-#define LL_BIG_ENDIAN 1
-#endif
-
-// Per-compiler switches
-#ifdef __GNUC__
-#define LL_FORCE_INLINE inline __attribute__((always_inline))
-#else
-#define LL_FORCE_INLINE __forceinline
-#endif
-
-// Figure out differences between compilers
-#if defined(__GNUC__)
- #define GCC_VERSION (__GNUC__ * 10000 \
- + __GNUC_MINOR__ * 100 \
- + __GNUC_PATCHLEVEL__)
- #ifndef LL_GNUC
- #define LL_GNUC 1
- #endif
-#elif defined(__MSVC_VER__) || defined(_MSC_VER)
- #ifndef LL_MSVC
- #define LL_MSVC 1
- #endif
- #if _MSC_VER < 1400
- #define LL_MSVC7 //Visual C++ 2003 or earlier
- #endif
-#endif
-
-// Deal with minor differences on Unixy OSes.
-#if LL_DARWIN || LL_LINUX
- // Different name, same functionality.
- #define stricmp strcasecmp
- #define strnicmp strncasecmp
-
- // Not sure why this is different, but...
- #ifndef MAX_PATH
- #define MAX_PATH PATH_MAX
- #endif // not MAX_PATH
-
-#endif
-
-
-// Static linking with apr on windows needs to be declared.
-#if LL_WINDOWS && !LL_COMMON_LINK_SHARED
-#ifndef APR_DECLARE_STATIC
-#define APR_DECLARE_STATIC // For APR on Windows
-#endif
-#ifndef APU_DECLARE_STATIC
-#define APU_DECLARE_STATIC // For APR util on Windows
-#endif
-#endif
-
-#if defined(LL_WINDOWS)
-#define BOOST_REGEX_NO_LIB 1
-#define CURL_STATICLIB 1
-#ifndef XML_STATIC
-#define XML_STATIC
-#endif
-#endif // LL_WINDOWS
-
-
-// Deal with VC6 problems
-#if LL_MSVC
-#pragma warning( 3 : 4701 ) // "local variable used without being initialized" Treat this as level 3, not level 4.
-#pragma warning( 3 : 4702 ) // "unreachable code" Treat this as level 3, not level 4.
-#pragma warning( 3 : 4189 ) // "local variable initialized but not referenced" Treat this as level 3, not level 4.
-//#pragma warning( 3 : 4018 ) // "signed/unsigned mismatch" Treat this as level 3, not level 4.
-#pragma warning( 3 : 4263 ) // 'function' : member function does not override any base class virtual member function
-#pragma warning( 3 : 4264 ) // "'virtual_function' : no override available for virtual member function from base 'class'; function is hidden"
-#pragma warning( 3 : 4265 ) // "class has virtual functions, but destructor is not virtual"
-#pragma warning( 3 : 4266 ) // 'function' : no override available for virtual member function from base 'type'; function is hidden
-#pragma warning (disable : 4180) // qualifier applied to function type has no meaning; ignored
-#pragma warning( disable : 4284 ) // silly MS warning deep inside their <map> include file
-#pragma warning( disable : 4503 ) // 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation.
-#pragma warning( disable : 4800 ) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
-#pragma warning( disable : 4996 ) // warning: deprecated
-
-// level 4 warnings that we need to disable:
-#pragma warning (disable : 4100) // unreferenced formal parameter
-#pragma warning (disable : 4127) // conditional expression is constant (e.g. while(1) )
-#pragma warning (disable : 4244) // possible loss of data on conversions
-#pragma warning (disable : 4396) // the inline specifier cannot be used when a friend declaration refers to a specialization of a function template
-#pragma warning (disable : 4512) // assignment operator could not be generated
-#pragma warning (disable : 4706) // assignment within conditional (even if((x = y)) )
-
-#pragma warning (disable : 4251) // member needs to have dll-interface to be used by clients of class
-#pragma warning (disable : 4275) // non dll-interface class used as base for dll-interface class
-#endif // LL_MSVC
-
-#if LL_WINDOWS
-#define LL_DLLEXPORT __declspec(dllexport)
-#define LL_DLLIMPORT __declspec(dllimport)
-#elif LL_LINUX
-#define LL_DLLEXPORT __attribute__ ((visibility("default")))
-#define LL_DLLIMPORT
-#else
-#define LL_DLLEXPORT
-#define LL_DLLIMPORT
-#endif // LL_WINDOWS
-
-#if LL_COMMON_LINK_SHARED
-// CMake automagically defines llcommon_EXPORTS only when building llcommon
-// sources, and only when llcommon is a shared library (i.e. when
-// LL_COMMON_LINK_SHARED). We must still test LL_COMMON_LINK_SHARED because
-// otherwise we can't distinguish between (non-llcommon source) and (llcommon
-// not shared).
-# if defined(llcommon_EXPORTS)
-# define LL_COMMON_API LL_DLLEXPORT
-# else //llcommon_EXPORTS
-# define LL_COMMON_API LL_DLLIMPORT
-# endif //llcommon_EXPORTS
-#else // LL_COMMON_LINK_SHARED
-# define LL_COMMON_API
-#endif // LL_COMMON_LINK_SHARED
-
-#endif // not LL_LINDEN_PREPROCESSOR_H
+/**
+ * @file llpreprocessor.h
+ * @brief This file should be included in all Linden Lab files and
+ * should only contain special preprocessor directives
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLPREPROCESSOR_H
+#define LLPREPROCESSOR_H
+
+// Figure out endianness of platform
+#ifdef LL_LINUX
+#define __ENABLE_WSTRING
+#include <endian.h>
+#endif // LL_LINUX
+
+#if LL_SOLARIS
+# ifdef __sparc // Since we're talking Solaris 10 and up, only 64 bit is supported.
+# define LL_BIG_ENDIAN 1
+# define LL_SOLARIS_ALIGNED_CPU 1 // used to designate issues where SPARC alignment is addressed
+# define LL_SOLARIS_NON_MESA_GL 1 // The SPARC GL does not provide a MESA-based GL API
+# endif
+# include <sys/isa_defs.h> // ensure we know which end is up
+#endif // LL_SOLARIS
+
+#if (defined(LL_WINDOWS) || (defined(LL_LINUX) && (__BYTE_ORDER == __LITTLE_ENDIAN)) || (defined(LL_DARWIN) && defined(__LITTLE_ENDIAN__)) || (defined(LL_SOLARIS) && defined(__i386)))
+#define LL_LITTLE_ENDIAN 1
+#else
+#define LL_BIG_ENDIAN 1
+#endif
+
+// Per-compiler switches
+#ifdef __GNUC__
+#define LL_FORCE_INLINE inline __attribute__((always_inline))
+#else
+#define LL_FORCE_INLINE __forceinline
+#endif
+
+// Figure out differences between compilers
+#if defined(__GNUC__)
+ #define GCC_VERSION (__GNUC__ * 10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__)
+ #ifndef LL_GNUC
+ #define LL_GNUC 1
+ #endif
+#elif defined(__MSVC_VER__) || defined(_MSC_VER)
+ #ifndef LL_MSVC
+ #define LL_MSVC 1
+ #endif
+ #if _MSC_VER < 1400
+ #define LL_MSVC7 //Visual C++ 2003 or earlier
+ #endif
+#endif
+
+// Deal with minor differences on Unixy OSes.
+#if LL_DARWIN || LL_LINUX
+ // Different name, same functionality.
+ #define stricmp strcasecmp
+ #define strnicmp strncasecmp
+
+ // Not sure why this is different, but...
+ #ifndef MAX_PATH
+ #define MAX_PATH PATH_MAX
+ #endif // not MAX_PATH
+
+#endif
+
+
+// Static linking with apr on windows needs to be declared.
+#if LL_WINDOWS && !LL_COMMON_LINK_SHARED
+#ifndef APR_DECLARE_STATIC
+#define APR_DECLARE_STATIC // For APR on Windows
+#endif
+#ifndef APU_DECLARE_STATIC
+#define APU_DECLARE_STATIC // For APR util on Windows
+#endif
+#endif
+
+#if defined(LL_WINDOWS)
+#define BOOST_REGEX_NO_LIB 1
+#define CURL_STATICLIB 1
+#ifndef XML_STATIC
+#define XML_STATIC
+#endif
+#endif // LL_WINDOWS
+
+
+// Deal with VC6 problems
+#if LL_MSVC
+#pragma warning( 3 : 4701 ) // "local variable used without being initialized" Treat this as level 3, not level 4.
+#pragma warning( 3 : 4702 ) // "unreachable code" Treat this as level 3, not level 4.
+#pragma warning( 3 : 4189 ) // "local variable initialized but not referenced" Treat this as level 3, not level 4.
+//#pragma warning( 3 : 4018 ) // "signed/unsigned mismatch" Treat this as level 3, not level 4.
+#pragma warning( 3 : 4263 ) // 'function' : member function does not override any base class virtual member function
+#pragma warning( 3 : 4264 ) // "'virtual_function' : no override available for virtual member function from base 'class'; function is hidden"
+#pragma warning( 3 : 4265 ) // "class has virtual functions, but destructor is not virtual"
+#pragma warning( 3 : 4266 ) // 'function' : no override available for virtual member function from base 'type'; function is hidden
+#pragma warning (disable : 4180) // qualifier applied to function type has no meaning; ignored
+#pragma warning( disable : 4284 ) // silly MS warning deep inside their <map> include file
+#pragma warning( disable : 4503 ) // 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation.
+#pragma warning( disable : 4800 ) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
+#pragma warning( disable : 4996 ) // warning: deprecated
+
+// level 4 warnings that we need to disable:
+#pragma warning (disable : 4100) // unreferenced formal parameter
+#pragma warning (disable : 4127) // conditional expression is constant (e.g. while(1) )
+#pragma warning (disable : 4244) // possible loss of data on conversions
+#pragma warning (disable : 4396) // the inline specifier cannot be used when a friend declaration refers to a specialization of a function template
+#pragma warning (disable : 4512) // assignment operator could not be generated
+#pragma warning (disable : 4706) // assignment within conditional (even if((x = y)) )
+
+#pragma warning (disable : 4251) // member needs to have dll-interface to be used by clients of class
+#pragma warning (disable : 4275) // non dll-interface class used as base for dll-interface class
+#endif // LL_MSVC
+
+#if LL_WINDOWS
+#define LL_DLLEXPORT __declspec(dllexport)
+#define LL_DLLIMPORT __declspec(dllimport)
+#elif LL_LINUX
+#define LL_DLLEXPORT __attribute__ ((visibility("default")))
+#define LL_DLLIMPORT
+#else
+#define LL_DLLEXPORT
+#define LL_DLLIMPORT
+#endif // LL_WINDOWS
+
+#if LL_COMMON_LINK_SHARED
+// CMake automagically defines llcommon_EXPORTS only when building llcommon
+// sources, and only when llcommon is a shared library (i.e. when
+// LL_COMMON_LINK_SHARED). We must still test LL_COMMON_LINK_SHARED because
+// otherwise we can't distinguish between (non-llcommon source) and (llcommon
+// not shared).
+# if defined(llcommon_EXPORTS)
+# define LL_COMMON_API LL_DLLEXPORT
+# else //llcommon_EXPORTS
+# define LL_COMMON_API LL_DLLIMPORT
+# endif //llcommon_EXPORTS
+#else // LL_COMMON_LINK_SHARED
+# define LL_COMMON_API
+#endif // LL_COMMON_LINK_SHARED
+
+#endif // not LL_LINDEN_PREPROCESSOR_H
diff --git a/indra/llcommon/llstacktrace.cpp b/indra/llcommon/llstacktrace.cpp
index 6558df70a4..3cb074257b 100644
--- a/indra/llcommon/llstacktrace.cpp
+++ b/indra/llcommon/llstacktrace.cpp
@@ -1,142 +1,142 @@
-/**
- * @file llstacktrace.cpp
- * @brief stack tracing functionality
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-#include "llstacktrace.h"
-
-#ifdef LL_WINDOWS
-
-#include <iostream>
-#include <sstream>
-
-#include "windows.h"
-#include "Dbghelp.h"
-
-typedef USHORT NTAPI RtlCaptureStackBackTrace_Function(
- IN ULONG frames_to_skip,
- IN ULONG frames_to_capture,
- OUT PVOID *backtrace,
- OUT PULONG backtrace_hash);
-
-static RtlCaptureStackBackTrace_Function* const RtlCaptureStackBackTrace_fn =
- (RtlCaptureStackBackTrace_Function*)
- GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlCaptureStackBackTrace");
-
-bool ll_get_stack_trace(std::vector<std::string>& lines)
-{
- const S32 MAX_STACK_DEPTH = 32;
- const S32 STRING_NAME_LENGTH = 200;
- const S32 FRAME_SKIP = 2;
- static BOOL symbolsLoaded = false;
- static BOOL firstCall = true;
-
- HANDLE hProc = GetCurrentProcess();
-
- // load the symbols if they're not loaded
- if(!symbolsLoaded && firstCall)
- {
- symbolsLoaded = SymInitialize(hProc, NULL, true);
- firstCall = false;
- }
-
- // if loaded, get the call stack
- if(symbolsLoaded)
- {
- // create the frames to hold the addresses
- void* frames[MAX_STACK_DEPTH];
- memset(frames, 0, sizeof(void*)*MAX_STACK_DEPTH);
- S32 depth = 0;
-
- // get the addresses
- depth = RtlCaptureStackBackTrace_fn(FRAME_SKIP, MAX_STACK_DEPTH, frames, NULL);
-
- IMAGEHLP_LINE64 line;
- memset(&line, 0, sizeof(IMAGEHLP_LINE64));
- line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
-
- // create something to hold address info
- PIMAGEHLP_SYMBOL64 pSym;
- pSym = (PIMAGEHLP_SYMBOL64)malloc(sizeof(IMAGEHLP_SYMBOL64) + STRING_NAME_LENGTH);
- memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STRING_NAME_LENGTH);
- pSym->MaxNameLength = STRING_NAME_LENGTH;
- pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
-
- // get address info for each address frame
- // and store
- for(S32 i=0; i < depth; i++)
- {
- std::stringstream stack_line;
- BOOL ret;
-
- DWORD64 addr = (DWORD64)frames[i];
- ret = SymGetSymFromAddr64(hProc, addr, 0, pSym);
- if(ret)
- {
- stack_line << pSym->Name << " ";
- }
-
- DWORD dummy;
- ret = SymGetLineFromAddr64(hProc, addr, &dummy, &line);
- if(ret)
- {
- std::string file_name = line.FileName;
- std::string::size_type index = file_name.rfind("\\");
- stack_line << file_name.substr(index + 1, file_name.size()) << ":" << line.LineNumber;
- }
-
- lines.push_back(stack_line.str());
- }
-
- free(pSym);
-
- // TODO: figure out a way to cleanup symbol loading
- // Not hugely necessary, however.
- //SymCleanup(hProc);
- return true;
- }
- else
- {
- lines.push_back("Stack Trace Failed. PDB symbol info not loaded");
- }
-
- return false;
-}
-
-#else
-
-bool ll_get_stack_trace(std::vector<std::string>& lines)
-{
- return false;
-}
-
-#endif
-
+/**
+ * @file llstacktrace.cpp
+ * @brief stack tracing functionality
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llstacktrace.h"
+
+#ifdef LL_WINDOWS
+
+#include <iostream>
+#include <sstream>
+
+#include "windows.h"
+#include "Dbghelp.h"
+
+typedef USHORT NTAPI RtlCaptureStackBackTrace_Function(
+ IN ULONG frames_to_skip,
+ IN ULONG frames_to_capture,
+ OUT PVOID *backtrace,
+ OUT PULONG backtrace_hash);
+
+static RtlCaptureStackBackTrace_Function* const RtlCaptureStackBackTrace_fn =
+ (RtlCaptureStackBackTrace_Function*)
+ GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlCaptureStackBackTrace");
+
+bool ll_get_stack_trace(std::vector<std::string>& lines)
+{
+ const S32 MAX_STACK_DEPTH = 32;
+ const S32 STRING_NAME_LENGTH = 200;
+ const S32 FRAME_SKIP = 2;
+ static BOOL symbolsLoaded = false;
+ static BOOL firstCall = true;
+
+ HANDLE hProc = GetCurrentProcess();
+
+ // load the symbols if they're not loaded
+ if(!symbolsLoaded && firstCall)
+ {
+ symbolsLoaded = SymInitialize(hProc, NULL, true);
+ firstCall = false;
+ }
+
+ // if loaded, get the call stack
+ if(symbolsLoaded)
+ {
+ // create the frames to hold the addresses
+ void* frames[MAX_STACK_DEPTH];
+ memset(frames, 0, sizeof(void*)*MAX_STACK_DEPTH);
+ S32 depth = 0;
+
+ // get the addresses
+ depth = RtlCaptureStackBackTrace_fn(FRAME_SKIP, MAX_STACK_DEPTH, frames, NULL);
+
+ IMAGEHLP_LINE64 line;
+ memset(&line, 0, sizeof(IMAGEHLP_LINE64));
+ line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
+
+ // create something to hold address info
+ PIMAGEHLP_SYMBOL64 pSym;
+ pSym = (PIMAGEHLP_SYMBOL64)malloc(sizeof(IMAGEHLP_SYMBOL64) + STRING_NAME_LENGTH);
+ memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STRING_NAME_LENGTH);
+ pSym->MaxNameLength = STRING_NAME_LENGTH;
+ pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
+
+ // get address info for each address frame
+ // and store
+ for(S32 i=0; i < depth; i++)
+ {
+ std::stringstream stack_line;
+ BOOL ret;
+
+ DWORD64 addr = (DWORD64)frames[i];
+ ret = SymGetSymFromAddr64(hProc, addr, 0, pSym);
+ if(ret)
+ {
+ stack_line << pSym->Name << " ";
+ }
+
+ DWORD dummy;
+ ret = SymGetLineFromAddr64(hProc, addr, &dummy, &line);
+ if(ret)
+ {
+ std::string file_name = line.FileName;
+ std::string::size_type index = file_name.rfind("\\");
+ stack_line << file_name.substr(index + 1, file_name.size()) << ":" << line.LineNumber;
+ }
+
+ lines.push_back(stack_line.str());
+ }
+
+ free(pSym);
+
+ // TODO: figure out a way to cleanup symbol loading
+ // Not hugely necessary, however.
+ //SymCleanup(hProc);
+ return true;
+ }
+ else
+ {
+ lines.push_back("Stack Trace Failed. PDB symbol info not loaded");
+ }
+
+ return false;
+}
+
+#else
+
+bool ll_get_stack_trace(std::vector<std::string>& lines)
+{
+ return false;
+}
+
+#endif
+
diff --git a/indra/llcommon/llstacktrace.h b/indra/llcommon/llstacktrace.h
index 9f857f0fd3..b84b1aa6ad 100644
--- a/indra/llcommon/llstacktrace.h
+++ b/indra/llcommon/llstacktrace.h
@@ -1,44 +1,44 @@
-/**
- * @file llstacktrace.h
- * @brief stack trace functions
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-
-#ifndef LL_LLSTACKTRACE_H
-#define LL_LLSTACKTRACE_H
-
-#include "stdtypes.h"
-#include <vector>
-#include <string>
-
-LL_COMMON_API bool ll_get_stack_trace(std::vector<std::string>& lines);
-
-#endif
-
+/**
+ * @file llstacktrace.h
+ * @brief stack trace functions
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_LLSTACKTRACE_H
+#define LL_LLSTACKTRACE_H
+
+#include "stdtypes.h"
+#include <vector>
+#include <string>
+
+LL_COMMON_API bool ll_get_stack_trace(std::vector<std::string>& lines);
+
+#endif
+
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 31e70e0fe4..edbb007f61 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -1,1300 +1,1300 @@
-/**
- * @file llstring.h
- * @brief String utility functions and std::string class.
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLSTRING_H
-#define LL_LLSTRING_H
-
-#include <string>
-#include <cstdio>
-#include <locale>
-#include <iomanip>
-#include "llsd.h"
-#include "llfasttimer.h"
-
-#if LL_LINUX || LL_SOLARIS
-#include <wctype.h>
-#include <wchar.h>
-#endif
-
-#include <string.h>
-
-#if LL_SOLARIS
-// stricmp and strnicmp do not exist on Solaris:
-#define stricmp strcasecmp
-#define strnicmp strncasecmp
-#endif
-
-const char LL_UNKNOWN_CHAR = '?';
-
-#if LL_DARWIN || LL_LINUX || LL_SOLARIS
-// Template specialization of char_traits for U16s. Only necessary on Mac and Linux (exists on Windows already)
-#include <cstring>
-
-namespace std
-{
-template<>
-struct char_traits<U16>
-{
- typedef U16 char_type;
- typedef int int_type;
- typedef streampos pos_type;
- typedef streamoff off_type;
- typedef mbstate_t state_type;
-
- static void
- assign(char_type& __c1, const char_type& __c2)
- { __c1 = __c2; }
-
- static bool
- eq(const char_type& __c1, const char_type& __c2)
- { return __c1 == __c2; }
-
- static bool
- lt(const char_type& __c1, const char_type& __c2)
- { return __c1 < __c2; }
-
- static int
- compare(const char_type* __s1, const char_type* __s2, size_t __n)
- { return memcmp(__s1, __s2, __n * sizeof(char_type)); }
-
- static size_t
- length(const char_type* __s)
- {
- const char_type *cur_char = __s;
- while (*cur_char != 0)
- {
- ++cur_char;
- }
- return cur_char - __s;
- }
-
- static const char_type*
- find(const char_type* __s, size_t __n, const char_type& __a)
- { return static_cast<const char_type*>(memchr(__s, __a, __n * sizeof(char_type))); }
-
- static char_type*
- move(char_type* __s1, const char_type* __s2, size_t __n)
- { return static_cast<char_type*>(memmove(__s1, __s2, __n * sizeof(char_type))); }
-
- static char_type*
- copy(char_type* __s1, const char_type* __s2, size_t __n)
- { return static_cast<char_type*>(memcpy(__s1, __s2, __n * sizeof(char_type))); } /* Flawfinder: ignore */
-
- static char_type*
- assign(char_type* __s, size_t __n, char_type __a)
- {
- // This isn't right.
- //return static_cast<char_type*>(memset(__s, __a, __n * sizeof(char_type)));
-
- // I don't think there's a standard 'memset' for 16-bit values.
- // Do this the old-fashioned way.
-
- size_t __i;
- for(__i = 0; __i < __n; __i++)
- {
- __s[__i] = __a;
- }
- return __s;
- }
-
- static char_type
- to_char_type(const int_type& __c)
- { return static_cast<char_type>(__c); }
-
- static int_type
- to_int_type(const char_type& __c)
- { return static_cast<int_type>(__c); }
-
- static bool
- eq_int_type(const int_type& __c1, const int_type& __c2)
- { return __c1 == __c2; }
-
- static int_type
- eof() { return static_cast<int_type>(EOF); }
-
- static int_type
- not_eof(const int_type& __c)
- { return (__c == eof()) ? 0 : __c; }
- };
-};
-#endif
-
-class LL_COMMON_API LLStringOps
-{
-private:
- static long sPacificTimeOffset;
- static long sLocalTimeOffset;
- static bool sPacificDaylightTime;
- static std::map<std::string, std::string> datetimeToCodes;
-
-public:
- static char toUpper(char elem) { return toupper((unsigned char)elem); }
- static llwchar toUpper(llwchar elem) { return towupper(elem); }
-
- static char toLower(char elem) { return tolower((unsigned char)elem); }
- static llwchar toLower(llwchar elem) { return towlower(elem); }
-
- static bool isSpace(char elem) { return isspace((unsigned char)elem) != 0; }
- static bool isSpace(llwchar elem) { return iswspace(elem) != 0; }
-
- static bool isUpper(char elem) { return isupper((unsigned char)elem) != 0; }
- static bool isUpper(llwchar elem) { return iswupper(elem) != 0; }
-
- static bool isLower(char elem) { return islower((unsigned char)elem) != 0; }
- static bool isLower(llwchar elem) { return iswlower(elem) != 0; }
-
- static bool isDigit(char a) { return isdigit((unsigned char)a) != 0; }
- static bool isDigit(llwchar a) { return iswdigit(a) != 0; }
-
- static bool isPunct(char a) { return ispunct((unsigned char)a) != 0; }
- static bool isPunct(llwchar a) { return iswpunct(a) != 0; }
-
- static bool isAlnum(char a) { return isalnum((unsigned char)a) != 0; }
- static bool isAlnum(llwchar a) { return iswalnum(a) != 0; }
-
- static S32 collate(const char* a, const char* b) { return strcoll(a, b); }
- static S32 collate(const llwchar* a, const llwchar* b);
-
- static void setupDatetimeInfo(bool pacific_daylight_time);
- static long getPacificTimeOffset(void) { return sPacificTimeOffset;}
- static long getLocalTimeOffset(void) { return sLocalTimeOffset;}
- // Is the Pacific time zone (aka server time zone)
- // currently in daylight savings time?
- static bool getPacificDaylightTime(void) { return sPacificDaylightTime;}
-
- static std::string getDatetimeCode (std::string key);
-};
-
-/**
- * @brief Return a string constructed from in without crashing if the
- * pointer is NULL.
- */
-LL_COMMON_API std::string ll_safe_string(const char* in);
-LL_COMMON_API std::string ll_safe_string(const char* in, S32 maxlen);
-
-
-// Allowing assignments from non-strings into format_map_t is apparently
-// *really* error-prone, so subclass std::string with just basic c'tors.
-class LLFormatMapString
-{
-public:
- LLFormatMapString() {};
- LLFormatMapString(const char* s) : mString(ll_safe_string(s)) {};
- LLFormatMapString(const std::string& s) : mString(s) {};
- operator std::string() const { return mString; }
- bool operator<(const LLFormatMapString& rhs) const { return mString < rhs.mString; }
- std::size_t length() const { return mString.length(); }
-
-private:
- std::string mString;
-};
-
-template <class T>
-class LLStringUtilBase
-{
-private:
- static std::string sLocale;
-
-public:
- typedef typename std::basic_string<T>::size_type size_type;
-
-public:
- /////////////////////////////////////////////////////////////////////////////////////////
- // Static Utility functions that operate on std::strings
-
- static std::basic_string<T> null;
-
- typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t;
- LL_COMMON_API static void getTokens(const std::basic_string<T>& instr, std::vector<std::basic_string<T> >& tokens, const std::basic_string<T>& delims);
- LL_COMMON_API static void formatNumber(std::basic_string<T>& numStr, std::basic_string<T> decimals);
- LL_COMMON_API static bool formatDatetime(std::basic_string<T>& replacement, std::basic_string<T> token, std::basic_string<T> param, S32 secFromEpoch);
- LL_COMMON_API static S32 format(std::basic_string<T>& s, const format_map_t& substitutions);
- LL_COMMON_API static S32 format(std::basic_string<T>& s, const LLSD& substitutions);
- LL_COMMON_API static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const format_map_t& substitutions);
- LL_COMMON_API static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const LLSD& substitutions);
- static void setLocale (std::string inLocale) {sLocale = inLocale;};
- static std::string getLocale (void) {return sLocale;};
-
- static bool isValidIndex(const std::basic_string<T>& string, size_type i)
- {
- return !string.empty() && (0 <= i) && (i <= string.size());
- }
-
- static void trimHead(std::basic_string<T>& string);
- static void trimTail(std::basic_string<T>& string);
- static void trim(std::basic_string<T>& string) { trimHead(string); trimTail(string); }
- static void truncate(std::basic_string<T>& string, size_type count);
-
- static void toUpper(std::basic_string<T>& string);
- static void toLower(std::basic_string<T>& string);
-
- // True if this is the head of s.
- static BOOL isHead( const std::basic_string<T>& string, const T* s );
-
- /**
- * @brief Returns true if string starts with substr
- *
- * If etither string or substr are empty, this method returns false.
- */
- static bool startsWith(
- const std::basic_string<T>& string,
- const std::basic_string<T>& substr);
-
- /**
- * @brief Returns true if string ends in substr
- *
- * If etither string or substr are empty, this method returns false.
- */
- static bool endsWith(
- const std::basic_string<T>& string,
- const std::basic_string<T>& substr);
-
- static void addCRLF(std::basic_string<T>& string);
- static void removeCRLF(std::basic_string<T>& string);
-
- static void replaceTabsWithSpaces( std::basic_string<T>& string, size_type spaces_per_tab );
- static void replaceNonstandardASCII( std::basic_string<T>& string, T replacement );
- static void replaceChar( std::basic_string<T>& string, T target, T replacement );
- static void replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement );
-
- static BOOL containsNonprintable(const std::basic_string<T>& string);
- static void stripNonprintable(std::basic_string<T>& string);
-
- /**
- * @brief Unsafe way to make ascii characters. You should probably
- * only call this when interacting with the host operating system.
- * The 1 byte std::string does not work correctly.
- * The 2 and 4 byte std::string probably work, so LLWStringUtil::_makeASCII
- * should work.
- */
- static void _makeASCII(std::basic_string<T>& string);
-
- // Conversion to other data types
- static BOOL convertToBOOL(const std::basic_string<T>& string, BOOL& value);
- static BOOL convertToU8(const std::basic_string<T>& string, U8& value);
- static BOOL convertToS8(const std::basic_string<T>& string, S8& value);
- static BOOL convertToS16(const std::basic_string<T>& string, S16& value);
- static BOOL convertToU16(const std::basic_string<T>& string, U16& value);
- static BOOL convertToU32(const std::basic_string<T>& string, U32& value);
- static BOOL convertToS32(const std::basic_string<T>& string, S32& value);
- static BOOL convertToF32(const std::basic_string<T>& string, F32& value);
- static BOOL convertToF64(const std::basic_string<T>& string, F64& value);
-
- /////////////////////////////////////////////////////////////////////////////////////////
- // Utility functions for working with char*'s and strings
-
- // Like strcmp but also handles empty strings. Uses
- // current locale.
- static S32 compareStrings(const T* lhs, const T* rhs);
- static S32 compareStrings(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs);
-
- // case insensitive version of above. Uses current locale on
- // Win32, and falls back to a non-locale aware comparison on
- // Linux.
- static S32 compareInsensitive(const T* lhs, const T* rhs);
- static S32 compareInsensitive(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs);
-
- // Case sensitive comparison with good handling of numbers. Does not use current locale.
- // a.k.a. strdictcmp()
- static S32 compareDict(const std::basic_string<T>& a, const std::basic_string<T>& b);
-
- // Case *in*sensitive comparison with good handling of numbers. Does not use current locale.
- // a.k.a. strdictcmp()
- static S32 compareDictInsensitive(const std::basic_string<T>& a, const std::basic_string<T>& b);
-
- // Puts compareDict() in a form appropriate for LL container classes to use for sorting.
- static BOOL precedesDict( const std::basic_string<T>& a, const std::basic_string<T>& b );
-
- // A replacement for strncpy.
- // If the dst buffer is dst_size bytes long or more, ensures that dst is null terminated and holds
- // up to dst_size-1 characters of src.
- static void copy(T* dst, const T* src, size_type dst_size);
-
- // Copies src into dst at a given offset.
- static void copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset);
-
- static bool isPartOfWord(T c) { return (c == (T)'_') || LLStringOps::isAlnum(c); }
-
-
-#ifdef _DEBUG
- LL_COMMON_API static void testHarness();
-#endif
-
-private:
- LL_COMMON_API static size_type getSubstitution(const std::basic_string<T>& instr, size_type& start, std::vector<std::basic_string<T> >& tokens);
-};
-
-template<class T> std::basic_string<T> LLStringUtilBase<T>::null;
-template<class T> std::string LLStringUtilBase<T>::sLocale;
-
-typedef LLStringUtilBase<char> LLStringUtil;
-typedef LLStringUtilBase<llwchar> LLWStringUtil;
-typedef std::basic_string<llwchar> LLWString;
-
-//@ Use this where we want to disallow input in the form of "foo"
-// This is used to catch places where english text is embedded in the code
-// instead of in a translatable XUI file.
-class LLStringExplicit : public std::string
-{
-public:
- explicit LLStringExplicit(const char* s) : std::string(s) {}
- LLStringExplicit(const std::string& s) : std::string(s) {}
- LLStringExplicit(const std::string& s, size_type pos, size_type n = std::string::npos) : std::string(s, pos, n) {}
-};
-
-struct LLDictionaryLess
-{
-public:
- bool operator()(const std::string& a, const std::string& b)
- {
- return (LLStringUtil::precedesDict(a, b) ? true : false);
- }
-};
-
-
-/**
- * Simple support functions
- */
-
-/**
- * @brief chop off the trailing characters in a string.
- *
- * This function works on bytes rather than glyphs, so this will
- * incorrectly truncate non-single byte strings.
- * Use utf8str_truncate() for utf8 strings
- * @return a copy of in string minus the trailing count bytes.
- */
-inline std::string chop_tail_copy(
- const std::string& in,
- std::string::size_type count)
-{
- return std::string(in, 0, in.length() - count);
-}
-
-/**
- * @brief This translates a nybble stored as a hex value from 0-f back
- * to a nybble in the low order bits of the return byte.
- */
-LL_COMMON_API U8 hex_as_nybble(char hex);
-
-/**
- * @brief read the contents of a file into a string.
- *
- * Since this function has no concept of character encoding, most
- * anything you do with this method ill-advised. Please avoid.
- * @param str [out] The string which will have.
- * @param filename The full name of the file to read.
- * @return Returns true on success. If false, str is unmodified.
- */
-LL_COMMON_API bool _read_file_into_string(std::string& str, const std::string& filename);
-LL_COMMON_API bool iswindividual(llwchar elem);
-
-/**
- * Unicode support
- */
-
-// Make the incoming string a utf8 string. Replaces any unknown glyph
-// with the UNKOWN_CHARACTER. Once any unknown glph is found, the rest
-// of the data may not be recovered.
-LL_COMMON_API std::string rawstr_to_utf8(const std::string& raw);
-
-//
-// We should never use UTF16 except when communicating with Win32!
-//
-typedef std::basic_string<U16> llutf16string;
-
-LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len);
-LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str);
-
-LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len);
-LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str);
-
-LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len);
-LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str );
-
-LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str, S32 len);
-LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str);
-// Same function, better name. JC
-inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); }
-
-//
-LL_COMMON_API S32 wchar_to_utf8chars(llwchar inchar, char* outchars);
-
-LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str, S32 len);
-LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str);
-
-LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 len);
-LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str);
-
-// Length of this UTF32 string in bytes when transformed to UTF8
-LL_COMMON_API S32 wstring_utf8_length(const LLWString& wstr);
-
-// Length in bytes of this wide char in a UTF8 string
-LL_COMMON_API S32 wchar_utf8_length(const llwchar wc);
-
-LL_COMMON_API std::string utf8str_tolower(const std::string& utf8str);
-
-// Length in llwchar (UTF-32) of the first len units (16 bits) of the given UTF-16 string.
-LL_COMMON_API S32 utf16str_wstring_length(const llutf16string &utf16str, S32 len);
-
-// Length in utf16string (UTF-16) of wlen wchars beginning at woffset.
-LL_COMMON_API S32 wstring_utf16_length(const LLWString & wstr, S32 woffset, S32 wlen);
-
-// Length in wstring (i.e., llwchar count) of a part of a wstring specified by utf16 length (i.e., utf16 units.)
-LL_COMMON_API S32 wstring_wstring_length_from_utf16_length(const LLWString & wstr, S32 woffset, S32 utf16_length, BOOL *unaligned = NULL);
-
-/**
- * @brief Properly truncate a utf8 string to a maximum byte count.
- *
- * The returned string may be less than max_len if the truncation
- * happens in the middle of a glyph. If max_len is longer than the
- * string passed in, the return value == utf8str.
- * @param utf8str A valid utf8 string to truncate.
- * @param max_len The maximum number of bytes in the return value.
- * @return Returns a valid utf8 string with byte count <= max_len.
- */
-LL_COMMON_API std::string utf8str_truncate(const std::string& utf8str, const S32 max_len);
-
-LL_COMMON_API std::string utf8str_trim(const std::string& utf8str);
-
-LL_COMMON_API S32 utf8str_compare_insensitive(
- const std::string& lhs,
- const std::string& rhs);
-
-/**
- * @brief Replace all occurences of target_char with replace_char
- *
- * @param utf8str A utf8 string to process.
- * @param target_char The wchar to be replaced
- * @param replace_char The wchar which is written on replace
- */
-LL_COMMON_API std::string utf8str_substChar(
- const std::string& utf8str,
- const llwchar target_char,
- const llwchar replace_char);
-
-LL_COMMON_API std::string utf8str_makeASCII(const std::string& utf8str);
-
-// Hack - used for evil notecards.
-LL_COMMON_API std::string mbcsstring_makeASCII(const std::string& str);
-
-LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str);
-
-
-#if LL_WINDOWS
-/* @name Windows string helpers
- */
-//@{
-
-/**
- * @brief Implementation the expected snprintf interface.
- *
- * If the size of the passed in buffer is not large enough to hold the string,
- * two bad things happen:
- * 1. resulting formatted string is NOT null terminated
- * 2. Depending on the platform, the return value could be a) the required
- * size of the buffer to copy the entire formatted string or b) -1.
- * On Windows with VS.Net 2003, it returns -1 e.g.
- *
- * safe_snprintf always adds a NULL terminator so that the caller does not
- * need to check for return value or need to add the NULL terminator.
- * It does not, however change the return value - to let the caller know
- * that the passed in buffer size was not large enough to hold the
- * formatted string.
- *
- */
-
-// Deal with the differeneces on Windows
-namespace snprintf_hack
-{
- LL_COMMON_API int snprintf(char *str, size_t size, const char *format, ...);
-}
-
-using snprintf_hack::snprintf;
-
-/**
- * @brief Convert a wide string to std::string
- *
- * This replaces the unsafe W2A macro from ATL.
- */
-LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in);
-
-//@}
-#endif // LL_WINDOWS
-
-/**
- * Many of the 'strip' and 'replace' methods of LLStringUtilBase need
- * specialization to work with the signed char type.
- * Sadly, it is not possible (AFAIK) to specialize a single method of
- * a template class.
- * That stuff should go here.
- */
-namespace LLStringFn
-{
- /**
- * @brief Replace all non-printable characters with replacement in
- * string.
- * NOTE - this will zap non-ascii
- *
- * @param [in,out] string the to modify. out value is the string
- * with zero non-printable characters.
- * @param The replacement character. use LL_UNKNOWN_CHAR if unsure.
- */
- LL_COMMON_API void replace_nonprintable_in_ascii(
- std::basic_string<char>& string,
- char replacement);
-
-
- /**
- * @brief Replace all non-printable characters and pipe characters
- * with replacement in a string.
- * NOTE - this will zap non-ascii
- *
- * @param [in,out] the string to modify. out value is the string
- * with zero non-printable characters and zero pipe characters.
- * @param The replacement character. use LL_UNKNOWN_CHAR if unsure.
- */
- LL_COMMON_API void replace_nonprintable_and_pipe_in_ascii(std::basic_string<char>& str,
- char replacement);
-
-
- /**
- * @brief Remove all characters that are not allowed in XML 1.0.
- * Returns a copy of the string with those characters removed.
- * Works with US ASCII and UTF-8 encoded strings. JC
- */
- LL_COMMON_API std::string strip_invalid_xml(const std::string& input);
-
-
- /**
- * @brief Replace all control characters (0 <= c < 0x20) with replacement in
- * string. This is safe for utf-8
- *
- * @param [in,out] string the to modify. out value is the string
- * with zero non-printable characters.
- * @param The replacement character. use LL_UNKNOWN_CHAR if unsure.
- */
- LL_COMMON_API void replace_ascii_controlchars(
- std::basic_string<char>& string,
- char replacement);
-}
-
-////////////////////////////////////////////////////////////
-// NOTE: LLStringUtil::format, getTokens, and support functions moved to llstring.cpp.
-// There is no LLWStringUtil::format implementation currently.
-// Calling thse for anything other than LLStringUtil will produce link errors.
-
-////////////////////////////////////////////////////////////
-
-
-// static
-template<class T>
-S32 LLStringUtilBase<T>::compareStrings(const T* lhs, const T* rhs)
-{
- S32 result;
- if( lhs == rhs )
- {
- result = 0;
- }
- else
- if ( !lhs || !lhs[0] )
- {
- result = ((!rhs || !rhs[0]) ? 0 : 1);
- }
- else
- if ( !rhs || !rhs[0])
- {
- result = -1;
- }
- else
- {
- result = LLStringOps::collate(lhs, rhs);
- }
- return result;
-}
-
-//static
-template<class T>
-S32 LLStringUtilBase<T>::compareStrings(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs)
-{
- return LLStringOps::collate(lhs.c_str(), rhs.c_str());
-}
-
-// static
-template<class T>
-S32 LLStringUtilBase<T>::compareInsensitive(const T* lhs, const T* rhs )
-{
- S32 result;
- if( lhs == rhs )
- {
- result = 0;
- }
- else
- if ( !lhs || !lhs[0] )
- {
- result = ((!rhs || !rhs[0]) ? 0 : 1);
- }
- else
- if ( !rhs || !rhs[0] )
- {
- result = -1;
- }
- else
- {
- std::basic_string<T> lhs_string(lhs);
- std::basic_string<T> rhs_string(rhs);
- LLStringUtilBase<T>::toUpper(lhs_string);
- LLStringUtilBase<T>::toUpper(rhs_string);
- result = LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str());
- }
- return result;
-}
-
-//static
-template<class T>
-S32 LLStringUtilBase<T>::compareInsensitive(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs)
-{
- std::basic_string<T> lhs_string(lhs);
- std::basic_string<T> rhs_string(rhs);
- LLStringUtilBase<T>::toUpper(lhs_string);
- LLStringUtilBase<T>::toUpper(rhs_string);
- return LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str());
-}
-
-// Case sensitive comparison with good handling of numbers. Does not use current locale.
-// a.k.a. strdictcmp()
-
-//static
-template<class T>
-S32 LLStringUtilBase<T>::compareDict(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
-{
- const T* a = astr.c_str();
- const T* b = bstr.c_str();
- T ca, cb;
- S32 ai, bi, cnt = 0;
- S32 bias = 0;
-
- ca = *(a++);
- cb = *(b++);
- while( ca && cb ){
- if( bias==0 ){
- if( LLStringOps::isUpper(ca) ){ ca = LLStringOps::toLower(ca); bias--; }
- if( LLStringOps::isUpper(cb) ){ cb = LLStringOps::toLower(cb); bias++; }
- }else{
- if( LLStringOps::isUpper(ca) ){ ca = LLStringOps::toLower(ca); }
- if( LLStringOps::isUpper(cb) ){ cb = LLStringOps::toLower(cb); }
- }
- if( LLStringOps::isDigit(ca) ){
- if( cnt-->0 ){
- if( cb!=ca ) break;
- }else{
- if( !LLStringOps::isDigit(cb) ) break;
- for(ai=0; LLStringOps::isDigit(a[ai]); ai++);
- for(bi=0; LLStringOps::isDigit(b[bi]); bi++);
- if( ai<bi ){ ca=0; break; }
- if( bi<ai ){ cb=0; break; }
- if( ca!=cb ) break;
- cnt = ai;
- }
- }else if( ca!=cb ){ break;
- }
- ca = *(a++);
- cb = *(b++);
- }
- if( ca==cb ) ca += bias;
- return ca-cb;
-}
-
-// static
-template<class T>
-S32 LLStringUtilBase<T>::compareDictInsensitive(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
-{
- const T* a = astr.c_str();
- const T* b = bstr.c_str();
- T ca, cb;
- S32 ai, bi, cnt = 0;
-
- ca = *(a++);
- cb = *(b++);
- while( ca && cb ){
- if( LLStringOps::isUpper(ca) ){ ca = LLStringOps::toLower(ca); }
- if( LLStringOps::isUpper(cb) ){ cb = LLStringOps::toLower(cb); }
- if( LLStringOps::isDigit(ca) ){
- if( cnt-->0 ){
- if( cb!=ca ) break;
- }else{
- if( !LLStringOps::isDigit(cb) ) break;
- for(ai=0; LLStringOps::isDigit(a[ai]); ai++);
- for(bi=0; LLStringOps::isDigit(b[bi]); bi++);
- if( ai<bi ){ ca=0; break; }
- if( bi<ai ){ cb=0; break; }
- if( ca!=cb ) break;
- cnt = ai;
- }
- }else if( ca!=cb ){ break;
- }
- ca = *(a++);
- cb = *(b++);
- }
- return ca-cb;
-}
-
-// Puts compareDict() in a form appropriate for LL container classes to use for sorting.
-// static
-template<class T>
-BOOL LLStringUtilBase<T>::precedesDict( const std::basic_string<T>& a, const std::basic_string<T>& b )
-{
- if( a.size() && b.size() )
- {
- return (LLStringUtilBase<T>::compareDict(a.c_str(), b.c_str()) < 0);
- }
- else
- {
- return (!b.empty());
- }
-}
-
-//static
-template<class T>
-void LLStringUtilBase<T>::toUpper(std::basic_string<T>& string)
-{
- if( !string.empty() )
- {
- std::transform(
- string.begin(),
- string.end(),
- string.begin(),
- (T(*)(T)) &LLStringOps::toUpper);
- }
-}
-
-//static
-template<class T>
-void LLStringUtilBase<T>::toLower(std::basic_string<T>& string)
-{
- if( !string.empty() )
- {
- std::transform(
- string.begin(),
- string.end(),
- string.begin(),
- (T(*)(T)) &LLStringOps::toLower);
- }
-}
-
-//static
-template<class T>
-void LLStringUtilBase<T>::trimHead(std::basic_string<T>& string)
-{
- if( !string.empty() )
- {
- size_type i = 0;
- while( i < string.length() && LLStringOps::isSpace( string[i] ) )
- {
- i++;
- }
- string.erase(0, i);
- }
-}
-
-//static
-template<class T>
-void LLStringUtilBase<T>::trimTail(std::basic_string<T>& string)
-{
- if( string.size() )
- {
- size_type len = string.length();
- size_type i = len;
- while( i > 0 && LLStringOps::isSpace( string[i-1] ) )
- {
- i--;
- }
-
- string.erase( i, len - i );
- }
-}
-
-
-// Replace line feeds with carriage return-line feed pairs.
-//static
-template<class T>
-void LLStringUtilBase<T>::addCRLF(std::basic_string<T>& string)
-{
- const T LF = 10;
- const T CR = 13;
-
- // Count the number of line feeds
- size_type count = 0;
- size_type len = string.size();
- size_type i;
- for( i = 0; i < len; i++ )
- {
- if( string[i] == LF )
- {
- count++;
- }
- }
-
- // Insert a carriage return before each line feed
- if( count )
- {
- size_type size = len + count;
- T *t = new T[size];
- size_type j = 0;
- for( i = 0; i < len; ++i )
- {
- if( string[i] == LF )
- {
- t[j] = CR;
- ++j;
- }
- t[j] = string[i];
- ++j;
- }
-
- string.assign(t, size);
- }
-}
-
-// Remove all carriage returns
-//static
-template<class T>
-void LLStringUtilBase<T>::removeCRLF(std::basic_string<T>& string)
-{
- const T CR = 13;
-
- size_type cr_count = 0;
- size_type len = string.size();
- size_type i;
- for( i = 0; i < len - cr_count; i++ )
- {
- if( string[i+cr_count] == CR )
- {
- cr_count++;
- }
-
- string[i] = string[i+cr_count];
- }
- string.erase(i, cr_count);
-}
-
-//static
-template<class T>
-void LLStringUtilBase<T>::replaceChar( std::basic_string<T>& string, T target, T replacement )
-{
- size_type found_pos = 0;
- while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos )
- {
- string[found_pos] = replacement;
- found_pos++; // avoid infinite defeat if target == replacement
- }
-}
-
-//static
-template<class T>
-void LLStringUtilBase<T>::replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement )
-{
- size_type found_pos = 0;
- while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos )
- {
- string.replace( found_pos, target.length(), replacement );
- found_pos += replacement.length(); // avoid infinite defeat if replacement contains target
- }
-}
-
-//static
-template<class T>
-void LLStringUtilBase<T>::replaceNonstandardASCII( std::basic_string<T>& string, T replacement )
-{
- const char LF = 10;
- const S8 MIN = 32;
-// const S8 MAX = 127;
-
- size_type len = string.size();
- for( size_type i = 0; i < len; i++ )
- {
- // No need to test MAX < mText[i] because we treat mText[i] as a signed char,
- // which has a max value of 127.
- if( ( S8(string[i]) < MIN ) && (string[i] != LF) )
- {
- string[i] = replacement;
- }
- }
-}
-
-//static
-template<class T>
-void LLStringUtilBase<T>::replaceTabsWithSpaces( std::basic_string<T>& str, size_type spaces_per_tab )
-{
- const T TAB = '\t';
- const T SPACE = ' ';
-
- std::basic_string<T> out_str;
- // Replace tabs with spaces
- for (size_type i = 0; i < str.length(); i++)
- {
- if (str[i] == TAB)
- {
- for (size_type j = 0; j < spaces_per_tab; j++)
- out_str += SPACE;
- }
- else
- {
- out_str += str[i];
- }
- }
- str = out_str;
-}
-
-//static
-template<class T>
-BOOL LLStringUtilBase<T>::containsNonprintable(const std::basic_string<T>& string)
-{
- const char MIN = 32;
- BOOL rv = FALSE;
- for (size_type i = 0; i < string.size(); i++)
- {
- if(string[i] < MIN)
- {
- rv = TRUE;
- break;
- }
- }
- return rv;
-}
-
-//static
-template<class T>
-void LLStringUtilBase<T>::stripNonprintable(std::basic_string<T>& string)
-{
- const char MIN = 32;
- size_type j = 0;
- if (string.empty())
- {
- return;
- }
- size_t src_size = string.size();
- char* c_string = new char[src_size + 1];
- if(c_string == NULL)
- {
- return;
- }
- copy(c_string, string.c_str(), src_size+1);
- char* write_head = &c_string[0];
- for (size_type i = 0; i < src_size; i++)
- {
- char* read_head = &string[i];
- write_head = &c_string[j];
- if(!(*read_head < MIN))
- {
- *write_head = *read_head;
- ++j;
- }
- }
- c_string[j]= '\0';
- string = c_string;
- delete []c_string;
-}
-
-template<class T>
-void LLStringUtilBase<T>::_makeASCII(std::basic_string<T>& string)
-{
- // Replace non-ASCII chars with LL_UNKNOWN_CHAR
- for (size_type i = 0; i < string.length(); i++)
- {
- if (string[i] > 0x7f)
- {
- string[i] = LL_UNKNOWN_CHAR;
- }
- }
-}
-
-// static
-template<class T>
-void LLStringUtilBase<T>::copy( T* dst, const T* src, size_type dst_size )
-{
- if( dst_size > 0 )
- {
- size_type min_len = 0;
- if( src )
- {
- min_len = llmin( dst_size - 1, strlen( src ) ); /* Flawfinder: ignore */
- memcpy(dst, src, min_len * sizeof(T)); /* Flawfinder: ignore */
- }
- dst[min_len] = '\0';
- }
-}
-
-// static
-template<class T>
-void LLStringUtilBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset)
-{
- if ( offset == dst.length() )
- {
- // special case - append to end of string and avoid expensive
- // (when strings are large) string manipulations
- dst += src;
- }
- else
- {
- std::basic_string<T> tail = dst.substr(offset);
-
- dst = dst.substr(0, offset);
- dst += src;
- dst += tail;
- };
-}
-
-// True if this is the head of s.
-//static
-template<class T>
-BOOL LLStringUtilBase<T>::isHead( const std::basic_string<T>& string, const T* s )
-{
- if( string.empty() )
- {
- // Early exit
- return FALSE;
- }
- else
- {
- return (strncmp( s, string.c_str(), string.size() ) == 0);
- }
-}
-
-// static
-template<class T>
-bool LLStringUtilBase<T>::startsWith(
- const std::basic_string<T>& string,
- const std::basic_string<T>& substr)
-{
- if(string.empty() || (substr.empty())) return false;
- if(0 == string.find(substr)) return true;
- return false;
-}
-
-// static
-template<class T>
-bool LLStringUtilBase<T>::endsWith(
- const std::basic_string<T>& string,
- const std::basic_string<T>& substr)
-{
- if(string.empty() || (substr.empty())) return false;
- std::string::size_type idx = string.rfind(substr);
- if(std::string::npos == idx) return false;
- return (idx == (string.size() - substr.size()));
-}
-
-
-template<class T>
-BOOL LLStringUtilBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL& value)
-{
- if( string.empty() )
- {
- return FALSE;
- }
-
- std::basic_string<T> temp( string );
- trim(temp);
- if(
- (temp == "1") ||
- (temp == "T") ||
- (temp == "t") ||
- (temp == "TRUE") ||
- (temp == "true") ||
- (temp == "True") )
- {
- value = TRUE;
- return TRUE;
- }
- else
- if(
- (temp == "0") ||
- (temp == "F") ||
- (temp == "f") ||
- (temp == "FALSE") ||
- (temp == "false") ||
- (temp == "False") )
- {
- value = FALSE;
- return TRUE;
- }
-
- return FALSE;
-}
-
-template<class T>
-BOOL LLStringUtilBase<T>::convertToU8(const std::basic_string<T>& string, U8& value)
-{
- S32 value32 = 0;
- BOOL success = convertToS32(string, value32);
- if( success && (U8_MIN <= value32) && (value32 <= U8_MAX) )
- {
- value = (U8) value32;
- return TRUE;
- }
- return FALSE;
-}
-
-template<class T>
-BOOL LLStringUtilBase<T>::convertToS8(const std::basic_string<T>& string, S8& value)
-{
- S32 value32 = 0;
- BOOL success = convertToS32(string, value32);
- if( success && (S8_MIN <= value32) && (value32 <= S8_MAX) )
- {
- value = (S8) value32;
- return TRUE;
- }
- return FALSE;
-}
-
-template<class T>
-BOOL LLStringUtilBase<T>::convertToS16(const std::basic_string<T>& string, S16& value)
-{
- S32 value32 = 0;
- BOOL success = convertToS32(string, value32);
- if( success && (S16_MIN <= value32) && (value32 <= S16_MAX) )
- {
- value = (S16) value32;
- return TRUE;
- }
- return FALSE;
-}
-
-template<class T>
-BOOL LLStringUtilBase<T>::convertToU16(const std::basic_string<T>& string, U16& value)
-{
- S32 value32 = 0;
- BOOL success = convertToS32(string, value32);
- if( success && (U16_MIN <= value32) && (value32 <= U16_MAX) )
- {
- value = (U16) value32;
- return TRUE;
- }
- return FALSE;
-}
-
-template<class T>
-BOOL LLStringUtilBase<T>::convertToU32(const std::basic_string<T>& string, U32& value)
-{
- if( string.empty() )
- {
- return FALSE;
- }
-
- std::basic_string<T> temp( string );
- trim(temp);
- U32 v;
- std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
- if(i_stream >> v)
- {
- value = v;
- return TRUE;
- }
- return FALSE;
-}
-
-template<class T>
-BOOL LLStringUtilBase<T>::convertToS32(const std::basic_string<T>& string, S32& value)
-{
- if( string.empty() )
- {
- return FALSE;
- }
-
- std::basic_string<T> temp( string );
- trim(temp);
- S32 v;
- std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
- if(i_stream >> v)
- {
- //TODO: figure out overflow and underflow reporting here
- //if((LONG_MAX == v) || (LONG_MIN == v))
- //{
- // // Underflow or overflow
- // return FALSE;
- //}
-
- value = v;
- return TRUE;
- }
- return FALSE;
-}
-
-template<class T>
-BOOL LLStringUtilBase<T>::convertToF32(const std::basic_string<T>& string, F32& value)
-{
- F64 value64 = 0.0;
- BOOL success = convertToF64(string, value64);
- if( success && (-F32_MAX <= value64) && (value64 <= F32_MAX) )
- {
- value = (F32) value64;
- return TRUE;
- }
- return FALSE;
-}
-
-template<class T>
-BOOL LLStringUtilBase<T>::convertToF64(const std::basic_string<T>& string, F64& value)
-{
- if( string.empty() )
- {
- return FALSE;
- }
-
- std::basic_string<T> temp( string );
- trim(temp);
- F64 v;
- std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
- if(i_stream >> v)
- {
- //TODO: figure out overflow and underflow reporting here
- //if( ((-HUGE_VAL == v) || (HUGE_VAL == v))) )
- //{
- // // Underflow or overflow
- // return FALSE;
- //}
-
- value = v;
- return TRUE;
- }
- return FALSE;
-}
-
-template<class T>
-void LLStringUtilBase<T>::truncate(std::basic_string<T>& string, size_type count)
-{
- size_type cur_size = string.size();
- string.resize(count < cur_size ? count : cur_size);
-}
-
-#endif // LL_STRING_H
+/**
+ * @file llstring.h
+ * @brief String utility functions and std::string class.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSTRING_H
+#define LL_LLSTRING_H
+
+#include <string>
+#include <cstdio>
+#include <locale>
+#include <iomanip>
+#include "llsd.h"
+#include "llfasttimer.h"
+
+#if LL_LINUX || LL_SOLARIS
+#include <wctype.h>
+#include <wchar.h>
+#endif
+
+#include <string.h>
+
+#if LL_SOLARIS
+// stricmp and strnicmp do not exist on Solaris:
+#define stricmp strcasecmp
+#define strnicmp strncasecmp
+#endif
+
+const char LL_UNKNOWN_CHAR = '?';
+
+#if LL_DARWIN || LL_LINUX || LL_SOLARIS
+// Template specialization of char_traits for U16s. Only necessary on Mac and Linux (exists on Windows already)
+#include <cstring>
+
+namespace std
+{
+template<>
+struct char_traits<U16>
+{
+ typedef U16 char_type;
+ typedef int int_type;
+ typedef streampos pos_type;
+ typedef streamoff off_type;
+ typedef mbstate_t state_type;
+
+ static void
+ assign(char_type& __c1, const char_type& __c2)
+ { __c1 = __c2; }
+
+ static bool
+ eq(const char_type& __c1, const char_type& __c2)
+ { return __c1 == __c2; }
+
+ static bool
+ lt(const char_type& __c1, const char_type& __c2)
+ { return __c1 < __c2; }
+
+ static int
+ compare(const char_type* __s1, const char_type* __s2, size_t __n)
+ { return memcmp(__s1, __s2, __n * sizeof(char_type)); }
+
+ static size_t
+ length(const char_type* __s)
+ {
+ const char_type *cur_char = __s;
+ while (*cur_char != 0)
+ {
+ ++cur_char;
+ }
+ return cur_char - __s;
+ }
+
+ static const char_type*
+ find(const char_type* __s, size_t __n, const char_type& __a)
+ { return static_cast<const char_type*>(memchr(__s, __a, __n * sizeof(char_type))); }
+
+ static char_type*
+ move(char_type* __s1, const char_type* __s2, size_t __n)
+ { return static_cast<char_type*>(memmove(__s1, __s2, __n * sizeof(char_type))); }
+
+ static char_type*
+ copy(char_type* __s1, const char_type* __s2, size_t __n)
+ { return static_cast<char_type*>(memcpy(__s1, __s2, __n * sizeof(char_type))); } /* Flawfinder: ignore */
+
+ static char_type*
+ assign(char_type* __s, size_t __n, char_type __a)
+ {
+ // This isn't right.
+ //return static_cast<char_type*>(memset(__s, __a, __n * sizeof(char_type)));
+
+ // I don't think there's a standard 'memset' for 16-bit values.
+ // Do this the old-fashioned way.
+
+ size_t __i;
+ for(__i = 0; __i < __n; __i++)
+ {
+ __s[__i] = __a;
+ }
+ return __s;
+ }
+
+ static char_type
+ to_char_type(const int_type& __c)
+ { return static_cast<char_type>(__c); }
+
+ static int_type
+ to_int_type(const char_type& __c)
+ { return static_cast<int_type>(__c); }
+
+ static bool
+ eq_int_type(const int_type& __c1, const int_type& __c2)
+ { return __c1 == __c2; }
+
+ static int_type
+ eof() { return static_cast<int_type>(EOF); }
+
+ static int_type
+ not_eof(const int_type& __c)
+ { return (__c == eof()) ? 0 : __c; }
+ };
+};
+#endif
+
+class LL_COMMON_API LLStringOps
+{
+private:
+ static long sPacificTimeOffset;
+ static long sLocalTimeOffset;
+ static bool sPacificDaylightTime;
+ static std::map<std::string, std::string> datetimeToCodes;
+
+public:
+ static char toUpper(char elem) { return toupper((unsigned char)elem); }
+ static llwchar toUpper(llwchar elem) { return towupper(elem); }
+
+ static char toLower(char elem) { return tolower((unsigned char)elem); }
+ static llwchar toLower(llwchar elem) { return towlower(elem); }
+
+ static bool isSpace(char elem) { return isspace((unsigned char)elem) != 0; }
+ static bool isSpace(llwchar elem) { return iswspace(elem) != 0; }
+
+ static bool isUpper(char elem) { return isupper((unsigned char)elem) != 0; }
+ static bool isUpper(llwchar elem) { return iswupper(elem) != 0; }
+
+ static bool isLower(char elem) { return islower((unsigned char)elem) != 0; }
+ static bool isLower(llwchar elem) { return iswlower(elem) != 0; }
+
+ static bool isDigit(char a) { return isdigit((unsigned char)a) != 0; }
+ static bool isDigit(llwchar a) { return iswdigit(a) != 0; }
+
+ static bool isPunct(char a) { return ispunct((unsigned char)a) != 0; }
+ static bool isPunct(llwchar a) { return iswpunct(a) != 0; }
+
+ static bool isAlnum(char a) { return isalnum((unsigned char)a) != 0; }
+ static bool isAlnum(llwchar a) { return iswalnum(a) != 0; }
+
+ static S32 collate(const char* a, const char* b) { return strcoll(a, b); }
+ static S32 collate(const llwchar* a, const llwchar* b);
+
+ static void setupDatetimeInfo(bool pacific_daylight_time);
+ static long getPacificTimeOffset(void) { return sPacificTimeOffset;}
+ static long getLocalTimeOffset(void) { return sLocalTimeOffset;}
+ // Is the Pacific time zone (aka server time zone)
+ // currently in daylight savings time?
+ static bool getPacificDaylightTime(void) { return sPacificDaylightTime;}
+
+ static std::string getDatetimeCode (std::string key);
+};
+
+/**
+ * @brief Return a string constructed from in without crashing if the
+ * pointer is NULL.
+ */
+LL_COMMON_API std::string ll_safe_string(const char* in);
+LL_COMMON_API std::string ll_safe_string(const char* in, S32 maxlen);
+
+
+// Allowing assignments from non-strings into format_map_t is apparently
+// *really* error-prone, so subclass std::string with just basic c'tors.
+class LLFormatMapString
+{
+public:
+ LLFormatMapString() {};
+ LLFormatMapString(const char* s) : mString(ll_safe_string(s)) {};
+ LLFormatMapString(const std::string& s) : mString(s) {};
+ operator std::string() const { return mString; }
+ bool operator<(const LLFormatMapString& rhs) const { return mString < rhs.mString; }
+ std::size_t length() const { return mString.length(); }
+
+private:
+ std::string mString;
+};
+
+template <class T>
+class LLStringUtilBase
+{
+private:
+ static std::string sLocale;
+
+public:
+ typedef typename std::basic_string<T>::size_type size_type;
+
+public:
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // Static Utility functions that operate on std::strings
+
+ static std::basic_string<T> null;
+
+ typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t;
+ LL_COMMON_API static void getTokens(const std::basic_string<T>& instr, std::vector<std::basic_string<T> >& tokens, const std::basic_string<T>& delims);
+ LL_COMMON_API static void formatNumber(std::basic_string<T>& numStr, std::basic_string<T> decimals);
+ LL_COMMON_API static bool formatDatetime(std::basic_string<T>& replacement, std::basic_string<T> token, std::basic_string<T> param, S32 secFromEpoch);
+ LL_COMMON_API static S32 format(std::basic_string<T>& s, const format_map_t& substitutions);
+ LL_COMMON_API static S32 format(std::basic_string<T>& s, const LLSD& substitutions);
+ LL_COMMON_API static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const format_map_t& substitutions);
+ LL_COMMON_API static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const LLSD& substitutions);
+ static void setLocale (std::string inLocale) {sLocale = inLocale;};
+ static std::string getLocale (void) {return sLocale;};
+
+ static bool isValidIndex(const std::basic_string<T>& string, size_type i)
+ {
+ return !string.empty() && (0 <= i) && (i <= string.size());
+ }
+
+ static void trimHead(std::basic_string<T>& string);
+ static void trimTail(std::basic_string<T>& string);
+ static void trim(std::basic_string<T>& string) { trimHead(string); trimTail(string); }
+ static void truncate(std::basic_string<T>& string, size_type count);
+
+ static void toUpper(std::basic_string<T>& string);
+ static void toLower(std::basic_string<T>& string);
+
+ // True if this is the head of s.
+ static BOOL isHead( const std::basic_string<T>& string, const T* s );
+
+ /**
+ * @brief Returns true if string starts with substr
+ *
+ * If etither string or substr are empty, this method returns false.
+ */
+ static bool startsWith(
+ const std::basic_string<T>& string,
+ const std::basic_string<T>& substr);
+
+ /**
+ * @brief Returns true if string ends in substr
+ *
+ * If etither string or substr are empty, this method returns false.
+ */
+ static bool endsWith(
+ const std::basic_string<T>& string,
+ const std::basic_string<T>& substr);
+
+ static void addCRLF(std::basic_string<T>& string);
+ static void removeCRLF(std::basic_string<T>& string);
+
+ static void replaceTabsWithSpaces( std::basic_string<T>& string, size_type spaces_per_tab );
+ static void replaceNonstandardASCII( std::basic_string<T>& string, T replacement );
+ static void replaceChar( std::basic_string<T>& string, T target, T replacement );
+ static void replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement );
+
+ static BOOL containsNonprintable(const std::basic_string<T>& string);
+ static void stripNonprintable(std::basic_string<T>& string);
+
+ /**
+ * @brief Unsafe way to make ascii characters. You should probably
+ * only call this when interacting with the host operating system.
+ * The 1 byte std::string does not work correctly.
+ * The 2 and 4 byte std::string probably work, so LLWStringUtil::_makeASCII
+ * should work.
+ */
+ static void _makeASCII(std::basic_string<T>& string);
+
+ // Conversion to other data types
+ static BOOL convertToBOOL(const std::basic_string<T>& string, BOOL& value);
+ static BOOL convertToU8(const std::basic_string<T>& string, U8& value);
+ static BOOL convertToS8(const std::basic_string<T>& string, S8& value);
+ static BOOL convertToS16(const std::basic_string<T>& string, S16& value);
+ static BOOL convertToU16(const std::basic_string<T>& string, U16& value);
+ static BOOL convertToU32(const std::basic_string<T>& string, U32& value);
+ static BOOL convertToS32(const std::basic_string<T>& string, S32& value);
+ static BOOL convertToF32(const std::basic_string<T>& string, F32& value);
+ static BOOL convertToF64(const std::basic_string<T>& string, F64& value);
+
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // Utility functions for working with char*'s and strings
+
+ // Like strcmp but also handles empty strings. Uses
+ // current locale.
+ static S32 compareStrings(const T* lhs, const T* rhs);
+ static S32 compareStrings(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs);
+
+ // case insensitive version of above. Uses current locale on
+ // Win32, and falls back to a non-locale aware comparison on
+ // Linux.
+ static S32 compareInsensitive(const T* lhs, const T* rhs);
+ static S32 compareInsensitive(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs);
+
+ // Case sensitive comparison with good handling of numbers. Does not use current locale.
+ // a.k.a. strdictcmp()
+ static S32 compareDict(const std::basic_string<T>& a, const std::basic_string<T>& b);
+
+ // Case *in*sensitive comparison with good handling of numbers. Does not use current locale.
+ // a.k.a. strdictcmp()
+ static S32 compareDictInsensitive(const std::basic_string<T>& a, const std::basic_string<T>& b);
+
+ // Puts compareDict() in a form appropriate for LL container classes to use for sorting.
+ static BOOL precedesDict( const std::basic_string<T>& a, const std::basic_string<T>& b );
+
+ // A replacement for strncpy.
+ // If the dst buffer is dst_size bytes long or more, ensures that dst is null terminated and holds
+ // up to dst_size-1 characters of src.
+ static void copy(T* dst, const T* src, size_type dst_size);
+
+ // Copies src into dst at a given offset.
+ static void copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset);
+
+ static bool isPartOfWord(T c) { return (c == (T)'_') || LLStringOps::isAlnum(c); }
+
+
+#ifdef _DEBUG
+ LL_COMMON_API static void testHarness();
+#endif
+
+private:
+ LL_COMMON_API static size_type getSubstitution(const std::basic_string<T>& instr, size_type& start, std::vector<std::basic_string<T> >& tokens);
+};
+
+template<class T> std::basic_string<T> LLStringUtilBase<T>::null;
+template<class T> std::string LLStringUtilBase<T>::sLocale;
+
+typedef LLStringUtilBase<char> LLStringUtil;
+typedef LLStringUtilBase<llwchar> LLWStringUtil;
+typedef std::basic_string<llwchar> LLWString;
+
+//@ Use this where we want to disallow input in the form of "foo"
+// This is used to catch places where english text is embedded in the code
+// instead of in a translatable XUI file.
+class LLStringExplicit : public std::string
+{
+public:
+ explicit LLStringExplicit(const char* s) : std::string(s) {}
+ LLStringExplicit(const std::string& s) : std::string(s) {}
+ LLStringExplicit(const std::string& s, size_type pos, size_type n = std::string::npos) : std::string(s, pos, n) {}
+};
+
+struct LLDictionaryLess
+{
+public:
+ bool operator()(const std::string& a, const std::string& b)
+ {
+ return (LLStringUtil::precedesDict(a, b) ? true : false);
+ }
+};
+
+
+/**
+ * Simple support functions
+ */
+
+/**
+ * @brief chop off the trailing characters in a string.
+ *
+ * This function works on bytes rather than glyphs, so this will
+ * incorrectly truncate non-single byte strings.
+ * Use utf8str_truncate() for utf8 strings
+ * @return a copy of in string minus the trailing count bytes.
+ */
+inline std::string chop_tail_copy(
+ const std::string& in,
+ std::string::size_type count)
+{
+ return std::string(in, 0, in.length() - count);
+}
+
+/**
+ * @brief This translates a nybble stored as a hex value from 0-f back
+ * to a nybble in the low order bits of the return byte.
+ */
+LL_COMMON_API U8 hex_as_nybble(char hex);
+
+/**
+ * @brief read the contents of a file into a string.
+ *
+ * Since this function has no concept of character encoding, most
+ * anything you do with this method ill-advised. Please avoid.
+ * @param str [out] The string which will have.
+ * @param filename The full name of the file to read.
+ * @return Returns true on success. If false, str is unmodified.
+ */
+LL_COMMON_API bool _read_file_into_string(std::string& str, const std::string& filename);
+LL_COMMON_API bool iswindividual(llwchar elem);
+
+/**
+ * Unicode support
+ */
+
+// Make the incoming string a utf8 string. Replaces any unknown glyph
+// with the UNKOWN_CHARACTER. Once any unknown glph is found, the rest
+// of the data may not be recovered.
+LL_COMMON_API std::string rawstr_to_utf8(const std::string& raw);
+
+//
+// We should never use UTF16 except when communicating with Win32!
+//
+typedef std::basic_string<U16> llutf16string;
+
+LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len);
+LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str);
+
+LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len);
+LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str);
+
+LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len);
+LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str );
+
+LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str, S32 len);
+LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str);
+// Same function, better name. JC
+inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); }
+
+//
+LL_COMMON_API S32 wchar_to_utf8chars(llwchar inchar, char* outchars);
+
+LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str, S32 len);
+LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str);
+
+LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 len);
+LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str);
+
+// Length of this UTF32 string in bytes when transformed to UTF8
+LL_COMMON_API S32 wstring_utf8_length(const LLWString& wstr);
+
+// Length in bytes of this wide char in a UTF8 string
+LL_COMMON_API S32 wchar_utf8_length(const llwchar wc);
+
+LL_COMMON_API std::string utf8str_tolower(const std::string& utf8str);
+
+// Length in llwchar (UTF-32) of the first len units (16 bits) of the given UTF-16 string.
+LL_COMMON_API S32 utf16str_wstring_length(const llutf16string &utf16str, S32 len);
+
+// Length in utf16string (UTF-16) of wlen wchars beginning at woffset.
+LL_COMMON_API S32 wstring_utf16_length(const LLWString & wstr, S32 woffset, S32 wlen);
+
+// Length in wstring (i.e., llwchar count) of a part of a wstring specified by utf16 length (i.e., utf16 units.)
+LL_COMMON_API S32 wstring_wstring_length_from_utf16_length(const LLWString & wstr, S32 woffset, S32 utf16_length, BOOL *unaligned = NULL);
+
+/**
+ * @brief Properly truncate a utf8 string to a maximum byte count.
+ *
+ * The returned string may be less than max_len if the truncation
+ * happens in the middle of a glyph. If max_len is longer than the
+ * string passed in, the return value == utf8str.
+ * @param utf8str A valid utf8 string to truncate.
+ * @param max_len The maximum number of bytes in the return value.
+ * @return Returns a valid utf8 string with byte count <= max_len.
+ */
+LL_COMMON_API std::string utf8str_truncate(const std::string& utf8str, const S32 max_len);
+
+LL_COMMON_API std::string utf8str_trim(const std::string& utf8str);
+
+LL_COMMON_API S32 utf8str_compare_insensitive(
+ const std::string& lhs,
+ const std::string& rhs);
+
+/**
+ * @brief Replace all occurences of target_char with replace_char
+ *
+ * @param utf8str A utf8 string to process.
+ * @param target_char The wchar to be replaced
+ * @param replace_char The wchar which is written on replace
+ */
+LL_COMMON_API std::string utf8str_substChar(
+ const std::string& utf8str,
+ const llwchar target_char,
+ const llwchar replace_char);
+
+LL_COMMON_API std::string utf8str_makeASCII(const std::string& utf8str);
+
+// Hack - used for evil notecards.
+LL_COMMON_API std::string mbcsstring_makeASCII(const std::string& str);
+
+LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str);
+
+
+#if LL_WINDOWS
+/* @name Windows string helpers
+ */
+//@{
+
+/**
+ * @brief Implementation the expected snprintf interface.
+ *
+ * If the size of the passed in buffer is not large enough to hold the string,
+ * two bad things happen:
+ * 1. resulting formatted string is NOT null terminated
+ * 2. Depending on the platform, the return value could be a) the required
+ * size of the buffer to copy the entire formatted string or b) -1.
+ * On Windows with VS.Net 2003, it returns -1 e.g.
+ *
+ * safe_snprintf always adds a NULL terminator so that the caller does not
+ * need to check for return value or need to add the NULL terminator.
+ * It does not, however change the return value - to let the caller know
+ * that the passed in buffer size was not large enough to hold the
+ * formatted string.
+ *
+ */
+
+// Deal with the differeneces on Windows
+namespace snprintf_hack
+{
+ LL_COMMON_API int snprintf(char *str, size_t size, const char *format, ...);
+}
+
+using snprintf_hack::snprintf;
+
+/**
+ * @brief Convert a wide string to std::string
+ *
+ * This replaces the unsafe W2A macro from ATL.
+ */
+LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in);
+
+//@}
+#endif // LL_WINDOWS
+
+/**
+ * Many of the 'strip' and 'replace' methods of LLStringUtilBase need
+ * specialization to work with the signed char type.
+ * Sadly, it is not possible (AFAIK) to specialize a single method of
+ * a template class.
+ * That stuff should go here.
+ */
+namespace LLStringFn
+{
+ /**
+ * @brief Replace all non-printable characters with replacement in
+ * string.
+ * NOTE - this will zap non-ascii
+ *
+ * @param [in,out] string the to modify. out value is the string
+ * with zero non-printable characters.
+ * @param The replacement character. use LL_UNKNOWN_CHAR if unsure.
+ */
+ LL_COMMON_API void replace_nonprintable_in_ascii(
+ std::basic_string<char>& string,
+ char replacement);
+
+
+ /**
+ * @brief Replace all non-printable characters and pipe characters
+ * with replacement in a string.
+ * NOTE - this will zap non-ascii
+ *
+ * @param [in,out] the string to modify. out value is the string
+ * with zero non-printable characters and zero pipe characters.
+ * @param The replacement character. use LL_UNKNOWN_CHAR if unsure.
+ */
+ LL_COMMON_API void replace_nonprintable_and_pipe_in_ascii(std::basic_string<char>& str,
+ char replacement);
+
+
+ /**
+ * @brief Remove all characters that are not allowed in XML 1.0.
+ * Returns a copy of the string with those characters removed.
+ * Works with US ASCII and UTF-8 encoded strings. JC
+ */
+ LL_COMMON_API std::string strip_invalid_xml(const std::string& input);
+
+
+ /**
+ * @brief Replace all control characters (0 <= c < 0x20) with replacement in
+ * string. This is safe for utf-8
+ *
+ * @param [in,out] string the to modify. out value is the string
+ * with zero non-printable characters.
+ * @param The replacement character. use LL_UNKNOWN_CHAR if unsure.
+ */
+ LL_COMMON_API void replace_ascii_controlchars(
+ std::basic_string<char>& string,
+ char replacement);
+}
+
+////////////////////////////////////////////////////////////
+// NOTE: LLStringUtil::format, getTokens, and support functions moved to llstring.cpp.
+// There is no LLWStringUtil::format implementation currently.
+// Calling thse for anything other than LLStringUtil will produce link errors.
+
+////////////////////////////////////////////////////////////
+
+
+// static
+template<class T>
+S32 LLStringUtilBase<T>::compareStrings(const T* lhs, const T* rhs)
+{
+ S32 result;
+ if( lhs == rhs )
+ {
+ result = 0;
+ }
+ else
+ if ( !lhs || !lhs[0] )
+ {
+ result = ((!rhs || !rhs[0]) ? 0 : 1);
+ }
+ else
+ if ( !rhs || !rhs[0])
+ {
+ result = -1;
+ }
+ else
+ {
+ result = LLStringOps::collate(lhs, rhs);
+ }
+ return result;
+}
+
+//static
+template<class T>
+S32 LLStringUtilBase<T>::compareStrings(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs)
+{
+ return LLStringOps::collate(lhs.c_str(), rhs.c_str());
+}
+
+// static
+template<class T>
+S32 LLStringUtilBase<T>::compareInsensitive(const T* lhs, const T* rhs )
+{
+ S32 result;
+ if( lhs == rhs )
+ {
+ result = 0;
+ }
+ else
+ if ( !lhs || !lhs[0] )
+ {
+ result = ((!rhs || !rhs[0]) ? 0 : 1);
+ }
+ else
+ if ( !rhs || !rhs[0] )
+ {
+ result = -1;
+ }
+ else
+ {
+ std::basic_string<T> lhs_string(lhs);
+ std::basic_string<T> rhs_string(rhs);
+ LLStringUtilBase<T>::toUpper(lhs_string);
+ LLStringUtilBase<T>::toUpper(rhs_string);
+ result = LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str());
+ }
+ return result;
+}
+
+//static
+template<class T>
+S32 LLStringUtilBase<T>::compareInsensitive(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs)
+{
+ std::basic_string<T> lhs_string(lhs);
+ std::basic_string<T> rhs_string(rhs);
+ LLStringUtilBase<T>::toUpper(lhs_string);
+ LLStringUtilBase<T>::toUpper(rhs_string);
+ return LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str());
+}
+
+// Case sensitive comparison with good handling of numbers. Does not use current locale.
+// a.k.a. strdictcmp()
+
+//static
+template<class T>
+S32 LLStringUtilBase<T>::compareDict(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
+{
+ const T* a = astr.c_str();
+ const T* b = bstr.c_str();
+ T ca, cb;
+ S32 ai, bi, cnt = 0;
+ S32 bias = 0;
+
+ ca = *(a++);
+ cb = *(b++);
+ while( ca && cb ){
+ if( bias==0 ){
+ if( LLStringOps::isUpper(ca) ){ ca = LLStringOps::toLower(ca); bias--; }
+ if( LLStringOps::isUpper(cb) ){ cb = LLStringOps::toLower(cb); bias++; }
+ }else{
+ if( LLStringOps::isUpper(ca) ){ ca = LLStringOps::toLower(ca); }
+ if( LLStringOps::isUpper(cb) ){ cb = LLStringOps::toLower(cb); }
+ }
+ if( LLStringOps::isDigit(ca) ){
+ if( cnt-->0 ){
+ if( cb!=ca ) break;
+ }else{
+ if( !LLStringOps::isDigit(cb) ) break;
+ for(ai=0; LLStringOps::isDigit(a[ai]); ai++);
+ for(bi=0; LLStringOps::isDigit(b[bi]); bi++);
+ if( ai<bi ){ ca=0; break; }
+ if( bi<ai ){ cb=0; break; }
+ if( ca!=cb ) break;
+ cnt = ai;
+ }
+ }else if( ca!=cb ){ break;
+ }
+ ca = *(a++);
+ cb = *(b++);
+ }
+ if( ca==cb ) ca += bias;
+ return ca-cb;
+}
+
+// static
+template<class T>
+S32 LLStringUtilBase<T>::compareDictInsensitive(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
+{
+ const T* a = astr.c_str();
+ const T* b = bstr.c_str();
+ T ca, cb;
+ S32 ai, bi, cnt = 0;
+
+ ca = *(a++);
+ cb = *(b++);
+ while( ca && cb ){
+ if( LLStringOps::isUpper(ca) ){ ca = LLStringOps::toLower(ca); }
+ if( LLStringOps::isUpper(cb) ){ cb = LLStringOps::toLower(cb); }
+ if( LLStringOps::isDigit(ca) ){
+ if( cnt-->0 ){
+ if( cb!=ca ) break;
+ }else{
+ if( !LLStringOps::isDigit(cb) ) break;
+ for(ai=0; LLStringOps::isDigit(a[ai]); ai++);
+ for(bi=0; LLStringOps::isDigit(b[bi]); bi++);
+ if( ai<bi ){ ca=0; break; }
+ if( bi<ai ){ cb=0; break; }
+ if( ca!=cb ) break;
+ cnt = ai;
+ }
+ }else if( ca!=cb ){ break;
+ }
+ ca = *(a++);
+ cb = *(b++);
+ }
+ return ca-cb;
+}
+
+// Puts compareDict() in a form appropriate for LL container classes to use for sorting.
+// static
+template<class T>
+BOOL LLStringUtilBase<T>::precedesDict( const std::basic_string<T>& a, const std::basic_string<T>& b )
+{
+ if( a.size() && b.size() )
+ {
+ return (LLStringUtilBase<T>::compareDict(a.c_str(), b.c_str()) < 0);
+ }
+ else
+ {
+ return (!b.empty());
+ }
+}
+
+//static
+template<class T>
+void LLStringUtilBase<T>::toUpper(std::basic_string<T>& string)
+{
+ if( !string.empty() )
+ {
+ std::transform(
+ string.begin(),
+ string.end(),
+ string.begin(),
+ (T(*)(T)) &LLStringOps::toUpper);
+ }
+}
+
+//static
+template<class T>
+void LLStringUtilBase<T>::toLower(std::basic_string<T>& string)
+{
+ if( !string.empty() )
+ {
+ std::transform(
+ string.begin(),
+ string.end(),
+ string.begin(),
+ (T(*)(T)) &LLStringOps::toLower);
+ }
+}
+
+//static
+template<class T>
+void LLStringUtilBase<T>::trimHead(std::basic_string<T>& string)
+{
+ if( !string.empty() )
+ {
+ size_type i = 0;
+ while( i < string.length() && LLStringOps::isSpace( string[i] ) )
+ {
+ i++;
+ }
+ string.erase(0, i);
+ }
+}
+
+//static
+template<class T>
+void LLStringUtilBase<T>::trimTail(std::basic_string<T>& string)
+{
+ if( string.size() )
+ {
+ size_type len = string.length();
+ size_type i = len;
+ while( i > 0 && LLStringOps::isSpace( string[i-1] ) )
+ {
+ i--;
+ }
+
+ string.erase( i, len - i );
+ }
+}
+
+
+// Replace line feeds with carriage return-line feed pairs.
+//static
+template<class T>
+void LLStringUtilBase<T>::addCRLF(std::basic_string<T>& string)
+{
+ const T LF = 10;
+ const T CR = 13;
+
+ // Count the number of line feeds
+ size_type count = 0;
+ size_type len = string.size();
+ size_type i;
+ for( i = 0; i < len; i++ )
+ {
+ if( string[i] == LF )
+ {
+ count++;
+ }
+ }
+
+ // Insert a carriage return before each line feed
+ if( count )
+ {
+ size_type size = len + count;
+ T *t = new T[size];
+ size_type j = 0;
+ for( i = 0; i < len; ++i )
+ {
+ if( string[i] == LF )
+ {
+ t[j] = CR;
+ ++j;
+ }
+ t[j] = string[i];
+ ++j;
+ }
+
+ string.assign(t, size);
+ }
+}
+
+// Remove all carriage returns
+//static
+template<class T>
+void LLStringUtilBase<T>::removeCRLF(std::basic_string<T>& string)
+{
+ const T CR = 13;
+
+ size_type cr_count = 0;
+ size_type len = string.size();
+ size_type i;
+ for( i = 0; i < len - cr_count; i++ )
+ {
+ if( string[i+cr_count] == CR )
+ {
+ cr_count++;
+ }
+
+ string[i] = string[i+cr_count];
+ }
+ string.erase(i, cr_count);
+}
+
+//static
+template<class T>
+void LLStringUtilBase<T>::replaceChar( std::basic_string<T>& string, T target, T replacement )
+{
+ size_type found_pos = 0;
+ while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos )
+ {
+ string[found_pos] = replacement;
+ found_pos++; // avoid infinite defeat if target == replacement
+ }
+}
+
+//static
+template<class T>
+void LLStringUtilBase<T>::replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement )
+{
+ size_type found_pos = 0;
+ while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos )
+ {
+ string.replace( found_pos, target.length(), replacement );
+ found_pos += replacement.length(); // avoid infinite defeat if replacement contains target
+ }
+}
+
+//static
+template<class T>
+void LLStringUtilBase<T>::replaceNonstandardASCII( std::basic_string<T>& string, T replacement )
+{
+ const char LF = 10;
+ const S8 MIN = 32;
+// const S8 MAX = 127;
+
+ size_type len = string.size();
+ for( size_type i = 0; i < len; i++ )
+ {
+ // No need to test MAX < mText[i] because we treat mText[i] as a signed char,
+ // which has a max value of 127.
+ if( ( S8(string[i]) < MIN ) && (string[i] != LF) )
+ {
+ string[i] = replacement;
+ }
+ }
+}
+
+//static
+template<class T>
+void LLStringUtilBase<T>::replaceTabsWithSpaces( std::basic_string<T>& str, size_type spaces_per_tab )
+{
+ const T TAB = '\t';
+ const T SPACE = ' ';
+
+ std::basic_string<T> out_str;
+ // Replace tabs with spaces
+ for (size_type i = 0; i < str.length(); i++)
+ {
+ if (str[i] == TAB)
+ {
+ for (size_type j = 0; j < spaces_per_tab; j++)
+ out_str += SPACE;
+ }
+ else
+ {
+ out_str += str[i];
+ }
+ }
+ str = out_str;
+}
+
+//static
+template<class T>
+BOOL LLStringUtilBase<T>::containsNonprintable(const std::basic_string<T>& string)
+{
+ const char MIN = 32;
+ BOOL rv = FALSE;
+ for (size_type i = 0; i < string.size(); i++)
+ {
+ if(string[i] < MIN)
+ {
+ rv = TRUE;
+ break;
+ }
+ }
+ return rv;
+}
+
+//static
+template<class T>
+void LLStringUtilBase<T>::stripNonprintable(std::basic_string<T>& string)
+{
+ const char MIN = 32;
+ size_type j = 0;
+ if (string.empty())
+ {
+ return;
+ }
+ size_t src_size = string.size();
+ char* c_string = new char[src_size + 1];
+ if(c_string == NULL)
+ {
+ return;
+ }
+ copy(c_string, string.c_str(), src_size+1);
+ char* write_head = &c_string[0];
+ for (size_type i = 0; i < src_size; i++)
+ {
+ char* read_head = &string[i];
+ write_head = &c_string[j];
+ if(!(*read_head < MIN))
+ {
+ *write_head = *read_head;
+ ++j;
+ }
+ }
+ c_string[j]= '\0';
+ string = c_string;
+ delete []c_string;
+}
+
+template<class T>
+void LLStringUtilBase<T>::_makeASCII(std::basic_string<T>& string)
+{
+ // Replace non-ASCII chars with LL_UNKNOWN_CHAR
+ for (size_type i = 0; i < string.length(); i++)
+ {
+ if (string[i] > 0x7f)
+ {
+ string[i] = LL_UNKNOWN_CHAR;
+ }
+ }
+}
+
+// static
+template<class T>
+void LLStringUtilBase<T>::copy( T* dst, const T* src, size_type dst_size )
+{
+ if( dst_size > 0 )
+ {
+ size_type min_len = 0;
+ if( src )
+ {
+ min_len = llmin( dst_size - 1, strlen( src ) ); /* Flawfinder: ignore */
+ memcpy(dst, src, min_len * sizeof(T)); /* Flawfinder: ignore */
+ }
+ dst[min_len] = '\0';
+ }
+}
+
+// static
+template<class T>
+void LLStringUtilBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset)
+{
+ if ( offset == dst.length() )
+ {
+ // special case - append to end of string and avoid expensive
+ // (when strings are large) string manipulations
+ dst += src;
+ }
+ else
+ {
+ std::basic_string<T> tail = dst.substr(offset);
+
+ dst = dst.substr(0, offset);
+ dst += src;
+ dst += tail;
+ };
+}
+
+// True if this is the head of s.
+//static
+template<class T>
+BOOL LLStringUtilBase<T>::isHead( const std::basic_string<T>& string, const T* s )
+{
+ if( string.empty() )
+ {
+ // Early exit
+ return FALSE;
+ }
+ else
+ {
+ return (strncmp( s, string.c_str(), string.size() ) == 0);
+ }
+}
+
+// static
+template<class T>
+bool LLStringUtilBase<T>::startsWith(
+ const std::basic_string<T>& string,
+ const std::basic_string<T>& substr)
+{
+ if(string.empty() || (substr.empty())) return false;
+ if(0 == string.find(substr)) return true;
+ return false;
+}
+
+// static
+template<class T>
+bool LLStringUtilBase<T>::endsWith(
+ const std::basic_string<T>& string,
+ const std::basic_string<T>& substr)
+{
+ if(string.empty() || (substr.empty())) return false;
+ std::string::size_type idx = string.rfind(substr);
+ if(std::string::npos == idx) return false;
+ return (idx == (string.size() - substr.size()));
+}
+
+
+template<class T>
+BOOL LLStringUtilBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL& value)
+{
+ if( string.empty() )
+ {
+ return FALSE;
+ }
+
+ std::basic_string<T> temp( string );
+ trim(temp);
+ if(
+ (temp == "1") ||
+ (temp == "T") ||
+ (temp == "t") ||
+ (temp == "TRUE") ||
+ (temp == "true") ||
+ (temp == "True") )
+ {
+ value = TRUE;
+ return TRUE;
+ }
+ else
+ if(
+ (temp == "0") ||
+ (temp == "F") ||
+ (temp == "f") ||
+ (temp == "FALSE") ||
+ (temp == "false") ||
+ (temp == "False") )
+ {
+ value = FALSE;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+template<class T>
+BOOL LLStringUtilBase<T>::convertToU8(const std::basic_string<T>& string, U8& value)
+{
+ S32 value32 = 0;
+ BOOL success = convertToS32(string, value32);
+ if( success && (U8_MIN <= value32) && (value32 <= U8_MAX) )
+ {
+ value = (U8) value32;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+template<class T>
+BOOL LLStringUtilBase<T>::convertToS8(const std::basic_string<T>& string, S8& value)
+{
+ S32 value32 = 0;
+ BOOL success = convertToS32(string, value32);
+ if( success && (S8_MIN <= value32) && (value32 <= S8_MAX) )
+ {
+ value = (S8) value32;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+template<class T>
+BOOL LLStringUtilBase<T>::convertToS16(const std::basic_string<T>& string, S16& value)
+{
+ S32 value32 = 0;
+ BOOL success = convertToS32(string, value32);
+ if( success && (S16_MIN <= value32) && (value32 <= S16_MAX) )
+ {
+ value = (S16) value32;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+template<class T>
+BOOL LLStringUtilBase<T>::convertToU16(const std::basic_string<T>& string, U16& value)
+{
+ S32 value32 = 0;
+ BOOL success = convertToS32(string, value32);
+ if( success && (U16_MIN <= value32) && (value32 <= U16_MAX) )
+ {
+ value = (U16) value32;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+template<class T>
+BOOL LLStringUtilBase<T>::convertToU32(const std::basic_string<T>& string, U32& value)
+{
+ if( string.empty() )
+ {
+ return FALSE;
+ }
+
+ std::basic_string<T> temp( string );
+ trim(temp);
+ U32 v;
+ std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
+ if(i_stream >> v)
+ {
+ value = v;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+template<class T>
+BOOL LLStringUtilBase<T>::convertToS32(const std::basic_string<T>& string, S32& value)
+{
+ if( string.empty() )
+ {
+ return FALSE;
+ }
+
+ std::basic_string<T> temp( string );
+ trim(temp);
+ S32 v;
+ std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
+ if(i_stream >> v)
+ {
+ //TODO: figure out overflow and underflow reporting here
+ //if((LONG_MAX == v) || (LONG_MIN == v))
+ //{
+ // // Underflow or overflow
+ // return FALSE;
+ //}
+
+ value = v;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+template<class T>
+BOOL LLStringUtilBase<T>::convertToF32(const std::basic_string<T>& string, F32& value)
+{
+ F64 value64 = 0.0;
+ BOOL success = convertToF64(string, value64);
+ if( success && (-F32_MAX <= value64) && (value64 <= F32_MAX) )
+ {
+ value = (F32) value64;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+template<class T>
+BOOL LLStringUtilBase<T>::convertToF64(const std::basic_string<T>& string, F64& value)
+{
+ if( string.empty() )
+ {
+ return FALSE;
+ }
+
+ std::basic_string<T> temp( string );
+ trim(temp);
+ F64 v;
+ std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
+ if(i_stream >> v)
+ {
+ //TODO: figure out overflow and underflow reporting here
+ //if( ((-HUGE_VAL == v) || (HUGE_VAL == v))) )
+ //{
+ // // Underflow or overflow
+ // return FALSE;
+ //}
+
+ value = v;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+template<class T>
+void LLStringUtilBase<T>::truncate(std::basic_string<T>& string, size_type count)
+{
+ size_type cur_size = string.size();
+ string.resize(count < cur_size ? count : cur_size);
+}
+
+#endif // LL_STRING_H
diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h
index 3de9d14f54..9faecbea85 100644
--- a/indra/llinventory/llinventory.h
+++ b/indra/llinventory/llinventory.h
@@ -35,7 +35,6 @@
#include <functional>
-#include "llassetstorage.h"
#include "lldarray.h"
#include "llfoldertype.h"
#include "llinventorytype.h"
@@ -45,7 +44,6 @@
#include "llsaleinfo.h"
#include "llsd.h"
#include "lluuid.h"
-#include "llxmlnode.h"
// consts for Key field in the task inventory update message
extern const U8 TASK_INVENTORY_ITEM_KEY;
@@ -357,7 +355,7 @@ protected:
typedef std::list<LLPointer<LLInventoryObject> > InventoryObjectList;
-// These functions convert between structured data and an inventroy
+// These functions convert between structured data and an inventory
// item, appropriate for serialization.
LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item);
//LLPointer<LLInventoryItem> ll_create_item_from_sd(const LLSD& sd_item);
diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
index 236f79978d..20ba5768db 100644
--- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
+++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
@@ -531,13 +531,13 @@ private:
// this wasn't required in 1.xx viewer but we have to manually
// work the Windows message pump now
#if defined( LL_WINDOWS )
- MSG msg;
- while ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
- {
- GetMessage( &msg, NULL, 0, 0 );
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- };
+ MSG msg;
+ while ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
+ {
+ GetMessage( &msg, NULL, 0, 0 );
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ };
#endif
MCIdle( mMovieController );
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 4adef84cd3..e7458529be 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -297,8 +297,6 @@ set(viewer_SOURCE_FILES
llnotify.cpp
lloutputmonitorctrl.cpp
lloverlaybar.cpp
- llpanelappearance.cpp
- llpanelappearancetab.cpp
llpanelavatar.cpp
llpanelavatarrow.cpp
llpanelavatartag.cpp
@@ -322,7 +320,6 @@ set(viewer_SOURCE_FILES
llpanellandmedia.cpp
llpanellogin.cpp
llpanellookinfo.cpp
- llpanellooks.cpp
llpanelmaininventory.cpp
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
@@ -330,6 +327,7 @@ set(viewer_SOURCE_FILES
llpanelmeprofile.cpp
llpanelobject.cpp
llpanelobjectinventory.cpp
+ llpaneloutfitsinventory.cpp
llpanelpeople.cpp
llpanelpeoplemenus.cpp
llpanelpermissions.cpp
@@ -370,6 +368,7 @@ set(viewer_SOURCE_FILES
llsearchcombobox.cpp
llsearchhistory.cpp
llselectmgr.cpp
+ llsidepanelappearance.cpp
llsidepanelinventory.cpp
llsidepanelinventorysubpanel.cpp
llsidepaneliteminfo.cpp
@@ -792,8 +791,6 @@ set(viewer_HEADER_FILES
llnotify.h
lloutputmonitorctrl.h
lloverlaybar.h
- llpanelappearance.h
- llpanelappearancetab.h
llpanelavatar.h
llpanelavatarrow.h
llpanelavatartag.h
@@ -817,7 +814,6 @@ set(viewer_HEADER_FILES
llpanellandmedia.h
llpanellogin.h
llpanellookinfo.h
- llpanellooks.h
llpanelmaininventory.h
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
@@ -825,6 +821,7 @@ set(viewer_HEADER_FILES
llpanelmeprofile.h
llpanelobject.h
llpanelobjectinventory.h
+ llpaneloutfitsinventory.h
llpanelpeople.h
llpanelpeoplemenus.h
llpanelpermissions.h
@@ -867,6 +864,7 @@ set(viewer_HEADER_FILES
llsearchcombobox.h
llsearchhistory.h
llselectmgr.h
+ llsidepanelappearance.h
llsidepanelinventory.h
llsidepanelinventorysubpanel.h
llsidepaneliteminfo.h
diff --git a/indra/newview/app_settings/ignorable_dialogs.xml b/indra/newview/app_settings/ignorable_dialogs.xml
index ab18febccc..669235af1b 100644
--- a/indra/newview/app_settings/ignorable_dialogs.xml
+++ b/indra/newview/app_settings/ignorable_dialogs.xml
@@ -1,291 +1,291 @@
-<?xml version="1.0" ?>
-<llsd>
-<map>
- <key>FirstAppearance</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstAppearance warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstAttach</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstAttach warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstBalanceDecrease</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstBalanceDecrease warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstBalanceIncrease</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstBalanceIncrease warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstBuild</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstBuild warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstDebugMenus</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstDebugMenus warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstFlexible</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstFlexible warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstGoTo</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstGoTo warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstInventory</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstInventory warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstLeftClickNoHit</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstLeftClickNoHit warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstMap</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstMap warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstMedia</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstMedia warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstOverrideKeys</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstOverrideKeys warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstSandbox</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstSandbox warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstSculptedPrim</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstSculptedPrim warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstSit</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstSit warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstStreamingMusic</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstStreamingMusic warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstStreamingVideo</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstStreamingVideo warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstTeleport</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstTeleport warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FirstVoice</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstVoice warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>AboutDirectX9</key>
- <map>
- <key>Comment</key>
- <string>Enables AboutDirectX9 warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>BrowserLaunch</key>
- <map>
- <key>Comment</key>
- <string>Enables BrowserLaunch warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>DeedObject</key>
- <map>
- <key>Comment</key>
- <string>Enables DeedObject warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>NewClassified</key>
- <map>
- <key>Comment</key>
- <string>Enables NewClassified warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>QuickTimeInstalled</key>
- <map>
- <key>Comment</key>
- <string>Enables QuickTimeInstalled warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>ReturnToOwner</key>
- <map>
- <key>Comment</key>
- <string>Enables ReturnToOwner warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- </map>
-</llsd>
+<?xml version="1.0" ?>
+<llsd>
+<map>
+ <key>FirstAppearance</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstAppearance warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstAttach</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstAttach warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstBalanceDecrease</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstBalanceDecrease warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstBalanceIncrease</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstBalanceIncrease warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstBuild</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstBuild warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstDebugMenus</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstDebugMenus warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstFlexible</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstFlexible warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstGoTo</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstGoTo warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstInventory</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstInventory warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstLeftClickNoHit</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstLeftClickNoHit warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstMap</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstMap warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstMedia</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstMedia warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstOverrideKeys</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstOverrideKeys warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstSandbox</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstSandbox warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstSculptedPrim</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstSculptedPrim warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstSit</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstSit warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstStreamingMusic</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstStreamingMusic warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstStreamingVideo</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstStreamingVideo warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstTeleport</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstTeleport warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstVoice</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstVoice warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>AboutDirectX9</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables AboutDirectX9 warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>BrowserLaunch</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables BrowserLaunch warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>DeedObject</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables DeedObject warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>NewClassified</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables NewClassified warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>QuickTimeInstalled</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables QuickTimeInstalled warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>ReturnToOwner</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables ReturnToOwner warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ </map>
+</llsd>
diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml
index 10c197d09e..d7182dfaab 100644
--- a/indra/newview/character/avatar_lad.xml
+++ b/indra/newview/character/avatar_lad.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
<linden_avatar
- version="1.0" wearable_definition_version="24">
+ version="1.0" wearable_definition_version="22">
<!-- The wearable_definition_version is checked during asset upload. -->
<!-- If you increment it, check indra/lib/python/indra/assetutil.py. -->
<skeleton
diff --git a/indra/newview/installers/windows/FILES_ARE_UNICODE_UTF-16LE.txt b/indra/newview/installers/windows/FILES_ARE_UNICODE_UTF-16LE.txt
index 30f9349111..185c0180fb 100644
--- a/indra/newview/installers/windows/FILES_ARE_UNICODE_UTF-16LE.txt
+++ b/indra/newview/installers/windows/FILES_ARE_UNICODE_UTF-16LE.txt
@@ -1,6 +1,6 @@
-The language files in this directory are Unicode (Little-Endian) format, also known as UTF-16 LE.
-
-This is the format required for NSIS Unicode. See http://www.scratchpaper.com/ for details.
-
-James Cook
-September 2008
+The language files in this directory are Unicode (Little-Endian) format, also known as UTF-16 LE.
+
+This is the format required for NSIS Unicode. See http://www.scratchpaper.com/ for details.
+
+James Cook
+September 2008
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 1257cf9789..7a540a45c4 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -31,84 +31,54 @@
*/
#include "llviewerprecompiledheaders.h"
-
#include "llagent.h"
-#include "llagentwearables.h"
+
+#include "pipeline.h"
#include "llagentlistener.h"
+#include "llagentwearables.h"
+#include "llagentui.h"
+
#include "llanimationstates.h"
+#include "llbottomtray.h"
#include "llcallingcard.h"
+#include "llchannelmanager.h"
#include "llconsole.h"
-#include "lldrawable.h"
#include "llfirstuse.h"
-#include "llfloaterreg.h"
-#include "llspeakers.h"
#include "llfloatercamera.h"
#include "llfloatercustomize.h"
-
-#include "llfloaterland.h"
-#include "llfloatersnapshot.h"
+#include "llfloaterreg.h"
#include "llfloatertools.h"
-#include "llfloaterworldmap.h"
-
#include "llgroupactions.h"
-
-#include "llfocusmgr.h"
#include "llgroupmgr.h"
#include "llhomelocationresponder.h"
-#include "llimview.h"
#include "llhudmanager.h"
#include "lljoystickbutton.h"
-#include "llmenugl.h"
#include "llmorphview.h"
#include "llmoveview.h"
+#include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state
+#include "llnearbychatbar.h"
#include "llparcel.h"
-#include "llquantize.h"
-#include "llrand.h"
-#include "llregionhandle.h"
#include "llsdutil.h"
-#include "llselectmgr.h"
+#include "llsidetray.h"
#include "llsky.h"
-#include "llslurl.h"
#include "llsmoothstep.h"
-#include "llsidetray.h"
#include "llstatusbar.h"
-#include "llteleportflags.h"
-#include "llteleporthistory.h"
-#include "lltexturestats.h"
-#include "lltexturestats.h"
#include "lltool.h"
-#include "lltoolcomp.h"
#include "lltoolmgr.h"
-#include "lluictrlfactory.h"
-#include "llurldispatcher.h"
-
-#include "llviewercamera.h"
+#include "lltrans.h"
+#include "llviewercontrol.h"
#include "llviewerdisplay.h"
+#include "llviewerjoystick.h"
#include "llviewermediafocus.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
#include "llviewerstats.h"
-#include "llviewerwindow.h"
-#include "llviewercontrol.h"
-#include "llviewerjoystick.h"
-
#include "llvoavatarself.h"
#include "llwindow.h"
#include "llworld.h"
#include "llworldmap.h"
-#include "pipeline.h"
-#include "lltrans.h"
-#include "llbottomtray.h"
-#include "llnearbychatbar.h"
-#include "stringize.h"
-#include "llcapabilitylistener.h"
-
-#include "llnavigationbar.h" //to show/hide navigation bar when changing mouse look state
-#include "llagentui.h"
-#include "llchannelmanager.h"
-
using namespace LLVOAvatarDefines;
extern LLMenuBarGL* gMenuBarView;
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 99a9bdd8e6..4162dfce1e 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -36,14 +36,13 @@
#include "indra_constants.h"
#include "llevent.h" // LLObservable base class
#include "llagentaccess.h"
-#include "llagentaccess.h"
#include "llagentconstants.h"
-#include "llhudeffectpointat.h" // ELookAtType
-#include "llhudeffectlookat.h" // EPointAtType
-#include "llpointer.h"
+#include "llagentdata.h" // gAgentID, gAgentSessionID
#include "llcharacter.h" // LLAnimPauseRequest
#include "llfollowcam.h" // Ventrella
-#include "llagentdata.h" // gAgentID, gAgentSessionID
+#include "llhudeffectlookat.h" // EPointAtType
+#include "llhudeffectpointat.h" // ELookAtType
+#include "llpointer.h"
#include "lluicolor.h"
#include "llvoavatardefines.h"
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 6cb96d1336..6b2033fc6f 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -62,7 +62,7 @@ class LLInitialWearablesFetch : public LLInventoryFetchDescendentsObserver
{
public:
LLInitialWearablesFetch() {}
- ~LLInitialWearablesFetch() {}
+ ~LLInitialWearablesFetch();
virtual void done();
struct InitialWearableData
@@ -84,7 +84,6 @@ public:
protected:
void processWearablesMessage();
void processContents();
- static void onIdle(void *userdata);
};
class LLLibraryOutfitsFetch : public LLInventoryFetchDescendentsObserver
@@ -2159,6 +2158,11 @@ void LLLibraryOutfitsFetch::contentsDone(void)
// to avoid gInventory.notifyObservers recursion.
//--------------------------------------------------------------------
+LLInitialWearablesFetch::~LLInitialWearablesFetch()
+{
+ llinfos << "~LLInitialWearablesFetch" << llendl;
+}
+
// virtual
void LLInitialWearablesFetch::done()
{
@@ -2166,15 +2170,7 @@ void LLInitialWearablesFetch::done()
// gInventory.notifyObservers. The results will be handled in the next
// idle tick instead.
gInventory.removeObserver(this);
- gIdleCallbacks.addFunction(onIdle, this);
-}
-
-// static
-void LLInitialWearablesFetch::onIdle(void *data)
-{
- gIdleCallbacks.deleteFunction(onIdle, data);
- LLInitialWearablesFetch *self = reinterpret_cast<LLInitialWearablesFetch*>(data);
- self->processContents();
+ doOnIdle(boost::bind(&LLInitialWearablesFetch::processContents,this));
}
void LLInitialWearablesFetch::processContents()
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 80ac9e4085..60c6061e96 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -40,7 +40,7 @@
#include "llinventorybridge.h"
#include "llinventoryobserver.h"
#include "llnotifications.h"
-#include "llpanelappearance.h"
+#include "llsidepanelappearance.h"
#include "llsidetray.h"
#include "llvoavatar.h"
#include "llvoavatarself.h"
@@ -96,7 +96,8 @@ public:
mAppend(append)
{}
~LLOutfitObserver() {}
- virtual void done(); //public
+ virtual void done();
+ void doWearCategory();
protected:
LLUUID mCatID;
@@ -106,6 +107,12 @@ protected:
void LLOutfitObserver::done()
{
+ gInventory.removeObserver(this);
+ doOnIdle(boost::bind(&LLOutfitObserver::doWearCategory,this));
+}
+
+void LLOutfitObserver::doWearCategory()
+{
// We now have an outfit ready to be copied to agent inventory. Do
// it, and wear that outfit normally.
if(mCopyItems)
@@ -175,6 +182,7 @@ void LLOutfitObserver::done()
// Wear the inventory category.
LLAppearanceManager::instance().wearInventoryCategoryOnAvatar(gInventory.getCategory(mCatID), mAppend);
}
+ delete this;
}
class LLOutfitFetch : public LLInventoryFetchDescendentsObserver
@@ -222,7 +230,6 @@ void LLOutfitFetch::done()
// loop.
//dec_busy_count();
gInventory.removeObserver(this);
- delete this;
// increment busy count and either tell the inventory to check &
// call done, or add this object to the inventory for observation.
@@ -241,6 +248,7 @@ void LLOutfitFetch::done()
// will call done for us when everything is here.
gInventory.addObserver(outfit_observer);
}
+ delete this;
}
class LLUpdateAppearanceOnDestroy: public LLInventoryCallback
@@ -457,7 +465,7 @@ void LLAppearanceManager::filterWearableItems(
// Create links to all listed items.
void LLAppearanceManager::linkAll(const LLUUID& category,
LLInventoryModel::item_array_t& items,
- LLPointer<LLInventoryCallback> cb)
+ LLPointer<LLInventoryCallback> cb)
{
for (S32 i=0; i<items.count(); i++)
{
@@ -530,10 +538,10 @@ void LLAppearanceManager::updateCOF(const LLUUID& category, bool append)
LLAssetType::AT_LINK_FOLDER, link_waiter);
// Update the current outfit name of the appearance sidepanel.
- LLPanelAppearance* panel_appearance = dynamic_cast<LLPanelAppearance *>(LLSideTray::getInstance()->getPanel("panel_appearance"));
+ LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance *>(LLSideTray::getInstance()->getPanel("sidepanel_appearance"));
if (panel_appearance)
{
- panel_appearance->refreshCurrentLookName(catp->getName());
+ panel_appearance->refreshCurrentOutfitName(catp->getName());
}
}
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 88d3320d1f..12ffa336b4 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -36,6 +36,7 @@
#include "llsingleton.h"
#include "llinventorymodel.h"
#include "llviewerinventory.h"
+#include "llcallbacklist.h"
class LLWearable;
struct LLWearableHoldingPattern;
@@ -81,6 +82,11 @@ public:
void setAttachmentInvLinkEnable(bool val);
void linkRegisteredAttachments();
+ // utility function for bulk linking.
+ void linkAll(const LLUUID& category,
+ LLInventoryModel::item_array_t& items,
+ LLPointer<LLInventoryCallback> cb);
+
protected:
LLAppearanceManager();
~LLAppearanceManager();
@@ -88,9 +94,6 @@ protected:
private:
void filterWearableItems(LLInventoryModel::item_array_t& items, S32 max_per_type);
- void linkAll(const LLUUID& category,
- LLInventoryModel::item_array_t& items,
- LLPointer<LLInventoryCallback> cb);
void getDescendentsOfAssetType(const LLUUID& category,
LLInventoryModel::item_array_t& items,
@@ -111,4 +114,36 @@ private:
#define SUPPORT_ENSEMBLES 0
+// Shim class and template function to allow arbitrary boost::bind
+// expressions to be run as one-time idle callbacks.
+template <typename T>
+class OnIdleCallback
+{
+public:
+ OnIdleCallback(T callable):
+ mCallable(callable)
+ {
+ }
+ static void onIdle(void *data)
+ {
+ gIdleCallbacks.deleteFunction(onIdle, data);
+ OnIdleCallback<T>* self = reinterpret_cast<OnIdleCallback<T>*>(data);
+ self->call();
+ delete self;
+ }
+ void call()
+ {
+ mCallable();
+ }
+private:
+ T mCallable;
+};
+
+template <typename T>
+void doOnIdle(T callable)
+{
+ OnIdleCallback<T>* cb_functor = new OnIdleCallback<T>(callable);
+ gIdleCallbacks.addFunction(&OnIdleCallback<T>::onIdle,cb_functor);
+}
+
#endif
diff --git a/indra/newview/llcallingcard.h b/indra/newview/llcallingcard.h
index bd58b2fbe6..47b0dcb903 100644
--- a/indra/newview/llcallingcard.h
+++ b/indra/newview/llcallingcard.h
@@ -45,6 +45,7 @@
//class LLInventoryObserver;
class LLMessageSystem;
class LLTrackingData;
+
class LLFriendObserver
{
public:
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index d39a17ca3b..bf74c5c936 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -133,8 +133,8 @@ LLFolderViewItem::LLFolderViewItem(LLFolderViewItem::Params p)
mIconOpen(p.icon_open),
mListener(p.listener),
mArrowImage(p.folder_arrow_image),
- mBoxImage(p.selection_image)
-, mDontShowInHierarhy(false)
+ mBoxImage(p.selection_image),
+ mDontShowInHierarchy(false)
{
refresh();
}
@@ -411,7 +411,7 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)
S32 LLFolderViewItem::getItemHeight()
{
- if (mDontShowInHierarhy) return 0;
+ if (mDontShowInHierarchy) return 0;
S32 icon_height = mIcon->getHeight();
S32 label_height = llround(getLabelFontForStyle(mLabelStyle)->getLineHeight());
@@ -819,7 +819,7 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
void LLFolderViewItem::draw()
{
- if (mDontShowInHierarhy) return;
+ if (mDontShowInHierarchy) return;
static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
@@ -995,14 +995,14 @@ void LLFolderViewItem::draw()
S32 right = left + font->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2;
S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3);
S32 top = getRect().getHeight();
-
+
LLRect box_rect(left, top, right, bottom);
sBoxImage->draw(box_rect, sFilterBGColor);
F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mStringMatchOffset);
F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD;
font->renderUTF8( combined_string, mStringMatchOffset, match_string_left, y,
- sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
- filter_string_length, S32_MAX, &right_x, FALSE );
+ sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+ filter_string_length, S32_MAX, &right_x, FALSE );
}
}
}
@@ -2166,6 +2166,7 @@ BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
{
+ /* Disable outfit double click to wear
const LLUUID &cat_uuid = getListener()->getUUID();
const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid);
if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)
@@ -2173,6 +2174,7 @@ BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
getListener()->performAction(NULL, NULL,"replaceoutfit");
return TRUE;
}
+ */
BOOL handled = FALSE;
if( mIsOpen )
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index 7c429fc76e..30387812a6 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -158,7 +158,7 @@ protected:
LLUIImagePtr mBoxImage;
BOOL mIsLoading;
LLTimer mTimeSinceRequestStart;
- bool mDontShowInHierarhy;
+ bool mDontShowInHierarchy;
// helper function to change the selection from the root.
void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected);
@@ -201,8 +201,8 @@ public:
// makes sure that this view and it's children are the right size.
virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
virtual S32 getItemHeight();
- void setDontShowInHierarchy(bool dont_show) { mDontShowInHierarhy = dont_show; }
- bool getDontShowInHierarchy() { return mDontShowInHierarhy; }
+ void setDontShowInHierarchy(bool dont_show) { mDontShowInHierarchy = dont_show; }
+ bool getDontShowInHierarchy() { return mDontShowInHierarchy; }
// applies filters to control visibility of inventory items
virtual void filter( LLInventoryFilter& filter);
@@ -343,7 +343,7 @@ typedef bool (*sort_order_f)(LLFolderViewItem* a, LLFolderViewItem* b);
//
// An instance of an LLFolderViewFolder represents a collection of
// more folders and items. This is used to build the hierarchy of
-// items found in the folder view. :)
+// items found in the folder view.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLFolderViewFolder : public LLFolderViewItem
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index d18f9affe3..2d8b058ed8 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -162,16 +162,6 @@ std::string ICON_NAME[ICON_NAME_COUNT] =
"inv_item_linkfolder.tga"
};
-
-// +=================================================+
-// | LLInventoryPanelObserver |
-// +=================================================+
-void LLInventoryPanelObserver::changed(U32 mask)
-{
- mIP->modelChanged(mask);
-}
-
-
// +=================================================+
// | LLInvFVBridge |
// +=================================================+
@@ -1682,6 +1672,25 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
// if target is an outfit or current outfit folder we use link
if (move_is_into_current_outfit || move_is_into_outfit)
{
+ if (inv_cat->getPreferredType() == LLFolderType::FT_NONE)
+ {
+ if (move_is_into_current_outfit)
+ {
+ // traverse category and add all contents to currently worn.
+ BOOL append = true;
+ LLAppearanceManager::instance().wearInventoryCategory(inv_cat, false, append);
+ }
+ else
+ {
+ // Recursively create links in target outfit.
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ gInventory.collectDescendents(inv_cat->getUUID(), cats, items, LLInventoryModel::EXCLUDE_TRASH);
+ LLAppearanceManager::instance().linkAll(mUUID,items,NULL);
+ }
+ }
+ else
+ {
#if SUPPORT_ENSEMBLES
// BAP - should skip if dup.
if (move_is_into_current_outfit)
@@ -1700,6 +1709,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
cb);
}
#endif
+ }
}
else
{
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 4c7b0a0517..56cb0f93ed 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -107,22 +107,6 @@ struct LLAttachmentRezAction
S32 mAttachPt;
};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInventoryPanelObserver
-//
-// Bridge to support knowing when the inventory has changed.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLInventoryPanelObserver : public LLInventoryObserver
-{
-public:
- LLInventoryPanelObserver(LLInventoryPanel* ip) : mIP(ip) {}
- virtual ~LLInventoryPanelObserver() {}
- virtual void changed(U32 mask);
-protected:
- LLInventoryPanel* mIP;
-};
-
const std::string safe_inv_type_lookup(LLInventoryType::EType inv_type);
void hide_context_entries(LLMenuGL& menu,
const std::vector<std::string> &entries_to_show,
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 7ec8d3d003..085c96c93d 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -100,13 +100,18 @@ BOOL LLInventoryFilter::check(LLFolderViewItem* item)
bool passed_type = false;
if (mFilterOps.mFilterForCategories)
{
- if (listener->getInventoryType() == LLInventoryType::IT_CATEGORY)
+ // Pass if this item is a category of the filter type, or
+ // if its parent is a category of the filter type.
+ LLUUID uuid = listener->getUUID();
+ if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)
{
- LLViewerInventoryCategory *cat = gInventory.getCategory(listener->getUUID());
- if (cat)
- {
- passed_type |= ((1LL << cat->getPreferredType() & mFilterOps.mFilterTypes) != U64(0));
- }
+ const LLInventoryObject *obj = gInventory.getObject(uuid);
+ uuid = obj->getParentUUID();
+ }
+ LLViewerInventoryCategory *cat = gInventory.getCategory(uuid);
+ if (cat)
+ {
+ passed_type |= ((1LL << cat->getPreferredType() & mFilterOps.mFilterTypes) != U64(0));
}
}
else
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 95cc68ddbe..efd40576a7 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -1,136 +1,136 @@
-/**
- * @file llinventoryfunctions.h
- * @brief Miscellaneous inventory-related functions and classes
- * class definition
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLINVENTORYFUNCTIONS_H
-#define LL_LLINVENTORYFUNCTIONS_H
-
-#include "llassetstorage.h"
-#include "lldarray.h"
-#include "llfloater.h"
-#include "llinventory.h"
-#include "llinventoryfilter.h"
-#include "llfolderview.h"
-#include "llinventorymodel.h"
-#include "lluictrlfactory.h"
-#include <set>
-
-
-class LLFolderViewItem;
-class LLInventoryFilter;
-class LLInventoryModel;
-class LLInventoryPanel;
-class LLInvFVBridge;
-class LLInventoryFVBridgeBuilder;
-class LLMenuBarGL;
-class LLCheckBoxCtrl;
-class LLSpinCtrl;
-class LLScrollContainer;
-class LLTextBox;
-class LLIconCtrl;
-class LLSaveFolderState;
-class LLFilterEditor;
-class LLTabContainer;
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// This is a collection of miscellaneous functions and classes
-// that don't fit cleanly into any other class header.
-//
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLInventoryState
-{
-public:
- // HACK: Until we can route this info through the instant message hierarchy
- static BOOL sWearNewClothing;
- static LLUUID sWearNewClothingTransactionID; // wear all clothing in this transaction
-};
-
-class LLSelectFirstFilteredItem : public LLFolderViewFunctor
-{
-public:
- LLSelectFirstFilteredItem() : mItemSelected(FALSE) {}
- virtual ~LLSelectFirstFilteredItem() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item);
- BOOL wasItemSelected() { return mItemSelected; }
-protected:
- BOOL mItemSelected;
-};
-
-class LLOpenFilteredFolders : public LLFolderViewFunctor
-{
-public:
- LLOpenFilteredFolders() {}
- virtual ~LLOpenFilteredFolders() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item);
-};
-
-class LLSaveFolderState : public LLFolderViewFunctor
-{
-public:
- LLSaveFolderState() : mApply(FALSE) {}
- virtual ~LLSaveFolderState() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item) {}
- void setApply(BOOL apply);
- void clearOpenFolders() { mOpenFolders.clear(); }
-protected:
- std::set<LLUUID> mOpenFolders;
- BOOL mApply;
-};
-
-class LLOpenFoldersWithSelection : public LLFolderViewFunctor
-{
-public:
- LLOpenFoldersWithSelection() {}
- virtual ~LLOpenFoldersWithSelection() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item);
-};
-
-const std::string& get_item_icon_name(LLAssetType::EType asset_type,
- LLInventoryType::EType inventory_type,
- U32 attachment_point,
- BOOL item_is_multi );
-
-LLUIImagePtr get_item_icon(LLAssetType::EType asset_type,
- LLInventoryType::EType inventory_type,
- U32 attachment_point,
- BOOL item_is_multi );
-
-#endif // LL_LLINVENTORYFUNCTIONS_H
-
-
-
+/**
+ * @file llinventoryfunctions.h
+ * @brief Miscellaneous inventory-related functions and classes
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLINVENTORYFUNCTIONS_H
+#define LL_LLINVENTORYFUNCTIONS_H
+
+#include "llassetstorage.h"
+#include "lldarray.h"
+#include "llfloater.h"
+#include "llinventory.h"
+#include "llinventoryfilter.h"
+#include "llfolderview.h"
+#include "llinventorymodel.h"
+#include "lluictrlfactory.h"
+#include <set>
+
+
+class LLFolderViewItem;
+class LLInventoryFilter;
+class LLInventoryModel;
+class LLInventoryPanel;
+class LLInvFVBridge;
+class LLInventoryFVBridgeBuilder;
+class LLMenuBarGL;
+class LLCheckBoxCtrl;
+class LLSpinCtrl;
+class LLScrollContainer;
+class LLTextBox;
+class LLIconCtrl;
+class LLSaveFolderState;
+class LLFilterEditor;
+class LLTabContainer;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// This is a collection of miscellaneous functions and classes
+// that don't fit cleanly into any other class header.
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLInventoryState
+{
+public:
+ // HACK: Until we can route this info through the instant message hierarchy
+ static BOOL sWearNewClothing;
+ static LLUUID sWearNewClothingTransactionID; // wear all clothing in this transaction
+};
+
+class LLSelectFirstFilteredItem : public LLFolderViewFunctor
+{
+public:
+ LLSelectFirstFilteredItem() : mItemSelected(FALSE) {}
+ virtual ~LLSelectFirstFilteredItem() {}
+ virtual void doFolder(LLFolderViewFolder* folder);
+ virtual void doItem(LLFolderViewItem* item);
+ BOOL wasItemSelected() { return mItemSelected; }
+protected:
+ BOOL mItemSelected;
+};
+
+class LLOpenFilteredFolders : public LLFolderViewFunctor
+{
+public:
+ LLOpenFilteredFolders() {}
+ virtual ~LLOpenFilteredFolders() {}
+ virtual void doFolder(LLFolderViewFolder* folder);
+ virtual void doItem(LLFolderViewItem* item);
+};
+
+class LLSaveFolderState : public LLFolderViewFunctor
+{
+public:
+ LLSaveFolderState() : mApply(FALSE) {}
+ virtual ~LLSaveFolderState() {}
+ virtual void doFolder(LLFolderViewFolder* folder);
+ virtual void doItem(LLFolderViewItem* item) {}
+ void setApply(BOOL apply);
+ void clearOpenFolders() { mOpenFolders.clear(); }
+protected:
+ std::set<LLUUID> mOpenFolders;
+ BOOL mApply;
+};
+
+class LLOpenFoldersWithSelection : public LLFolderViewFunctor
+{
+public:
+ LLOpenFoldersWithSelection() {}
+ virtual ~LLOpenFoldersWithSelection() {}
+ virtual void doFolder(LLFolderViewFolder* folder);
+ virtual void doItem(LLFolderViewItem* item);
+};
+
+const std::string& get_item_icon_name(LLAssetType::EType asset_type,
+ LLInventoryType::EType inventory_type,
+ U32 attachment_point,
+ BOOL item_is_multi );
+
+LLUIImagePtr get_item_icon(LLAssetType::EType asset_type,
+ LLInventoryType::EType inventory_type,
+ U32 attachment_point,
+ BOOL item_is_multi );
+
+#endif // LL_LLINVENTORYFUNCTIONS_H
+
+
+
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 3a8b8bdf9e..450ce92412 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -36,8 +36,6 @@
#include "llinventorypanel.h"
-// Seraph TODO: Remove unnecessary headers
-
#include "llagent.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
@@ -56,6 +54,22 @@ const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("Recent
const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string("");
static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryPanelObserver
+//
+// Bridge to support knowing when the inventory has changed.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLInventoryPanelObserver : public LLInventoryObserver
+{
+public:
+ LLInventoryPanelObserver(LLInventoryPanel* ip) : mIP(ip) {}
+ virtual ~LLInventoryPanelObserver() {}
+ virtual void changed(U32 mask);
+protected:
+ LLInventoryPanel* mIP;
+};
+
LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
LLPanel(p),
mInventoryObserver(NULL),
@@ -131,27 +145,10 @@ BOOL LLInventoryPanel::postBuild()
mInventoryObserver = new LLInventoryPanelObserver(this);
mInventory->addObserver(mInventoryObserver);
- // determine the root folder, if any, so inventory contents show just the children
- // of that folder (i.e. not including the folder itself).
- const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString);
-
- if ("INVENTORY" == mStartFolderString)
- {
- mStartFolderID = gInventory.getRootFolderID();
- }
- else if ("LIBRARY" == mStartFolderString)
- {
- mStartFolderID = gInventory.getLibraryRootFolderID();
- }
- else
- {
- mStartFolderID = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
- }
-
// build view of inventory if we need default full hierarchy and inventory ready, otherwise wait for modelChanged() callback
if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mHasInventoryConnection)
{
- rebuildViewsFor(mStartFolderID);
+ rebuildViews();
mHasInventoryConnection = true;
defaultOpenInventory();
}
@@ -258,7 +255,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
// inventory just initialized, do complete build
if ((mask & LLInventoryObserver::ADD) && gInventory.getChangedIDs().empty() && !mHasInventoryConnection)
{
- rebuildViewsFor(mStartFolderID);
+ rebuildViews();
mHasInventoryConnection = true;
defaultOpenInventory();
return;
@@ -378,6 +375,24 @@ void LLInventoryPanel::modelChanged(U32 mask)
}
+void LLInventoryPanel::rebuildViews()
+{
+ // Determine the root folder and rebuild the views starting
+ // at that folder.
+ const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString);
+
+ if ("LIBRARY" == mStartFolderString)
+ {
+ mStartFolderID = gInventory.getLibraryRootFolderID();
+ }
+ else
+ {
+ mStartFolderID = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
+ }
+
+ rebuildViewsFor(mStartFolderID);
+}
+
void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
{
LLFolderViewItem* old_view = NULL;
@@ -396,88 +411,86 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
{
LLMemType mt(LLMemType::MTYPE_INVENTORY_BUILD_NEW_VIEWS);
LLFolderViewItem* itemp = NULL;
- LLInventoryObject* objectp = NULL;
-
- // Don't add the start folder (the inventory panel will show contents
- // beginning with the children of the starting folder, excluding the starting folder itself).
- if (id != mStartFolderID)
+ LLInventoryObject* objectp = gInventory.getObject(id);
+ if (objectp)
{
- objectp = gInventory.getObject(id);
- if (objectp)
- {
- const LLUUID &parent_id = objectp->getParentUUID();
- // If this item's parent is the starting folder, then just add it to the top level (recall that
- // the starting folder isn't actually represented in the view, parent_folder would be NULL in
- // this case otherwise).
- LLFolderViewFolder* parent_folder = (parent_id == mStartFolderID ?
- mFolders : (LLFolderViewFolder*)mFolders->getItemByID(parent_id));
-
+ const LLUUID &parent_id = objectp->getParentUUID();
+ LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolders->getItemByID(parent_id);
+ if (id == mStartFolderID)
+ parent_folder = mFolders;
+
+ if (!parent_folder)
+ {
// This item exists outside the inventory's hierarchy, so don't add it.
- if (!parent_folder)
- {
- return;
- }
-
- if (objectp->getType() <= LLAssetType::AT_NONE ||
- objectp->getType() >= LLAssetType::AT_COUNT)
- {
- llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : " <<
- ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID() << llendl;
- return;
- }
+ return;
+ }
+
+ if (objectp->getType() <= LLAssetType::AT_NONE ||
+ objectp->getType() >= LLAssetType::AT_COUNT)
+ {
+ llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : " <<
+ ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID() << llendl;
+ return;
+ }
+
+ if (objectp->getType() == LLAssetType::AT_CATEGORY &&
+ objectp->getActualType() != LLAssetType::AT_LINK_FOLDER)
+ {
+ LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
+ objectp->getType(),
+ LLInventoryType::IT_CATEGORY,
+ this,
+ objectp->getUUID());
- if (objectp->getType() == LLAssetType::AT_CATEGORY &&
- objectp->getActualType() != LLAssetType::AT_LINK_FOLDER)
+ if (new_listener)
{
- LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
- objectp->getType(),
- LLInventoryType::IT_CATEGORY,
- this,
- objectp->getUUID());
-
- if (new_listener)
+ LLFolderViewFolder::Params p;
+ p.name = new_listener->getDisplayName();
+ p.icon = new_listener->getIcon();
+ p.root = mFolders;
+ p.listener = new_listener;
+ p.tool_tip = p.name;
+ LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(p);
+ folderp->setItemSortOrder(mFolders->getSortOrder());
+ itemp = folderp;
+
+ // Hide the root folder, so we can show the contents of a folder
+ // flat but still have the parent folder present for listener-related
+ // operations.
+ if (id == mStartFolderID)
{
- LLFolderViewFolder::Params p;
- p.name = new_listener->getDisplayName();
- p.icon = new_listener->getIcon();
- p.root = mFolders;
- p.listener = new_listener;
- p.tool_tip = p.name;
- LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(p);
-
- folderp->setItemSortOrder(mFolders->getSortOrder());
- itemp = folderp;
+ folderp->setDontShowInHierarchy(TRUE);
}
}
- else
+ }
+ else
+ {
+ // Build new view for item
+ LLInventoryItem* item = (LLInventoryItem*)objectp;
+ LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(),
+ item->getActualType(),
+ item->getInventoryType(),
+ this,
+ item->getUUID(),
+ item->getFlags());
+
+ if (new_listener)
{
- // Build new view for item
- LLInventoryItem* item = (LLInventoryItem*)objectp;
- LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(),
- item->getActualType(),
- item->getInventoryType(),
- this,
- item->getUUID(),
- item->getFlags());
-
- if (new_listener)
- {
- LLFolderViewItem::Params params;
- params.name(new_listener->getDisplayName());
- params.icon(new_listener->getIcon());
- params.creation_date(new_listener->getCreationDate());
- params.root(mFolders);
- params.listener(new_listener);
- params.rect(LLRect (0, 0, 0, 0));
- params.tool_tip = params.name;
- itemp = LLUICtrlFactory::create<LLFolderViewItem> (params);
- }
+ LLFolderViewItem::Params params;
+ params.name(new_listener->getDisplayName());
+ params.icon(new_listener->getIcon());
+ params.creation_date(new_listener->getCreationDate());
+ params.root(mFolders);
+ params.listener(new_listener);
+ params.rect(LLRect (0, 0, 0, 0));
+ params.tool_tip = params.name;
+ itemp = LLUICtrlFactory::create<LLFolderViewItem> (params);
}
+ }
- if (itemp)
- {
- itemp->addToFolder(parent_folder, mFolders);
- }
+ if (itemp)
+ {
+ itemp->addToFolder(parent_folder, mFolders);
}
}
@@ -875,3 +888,11 @@ void example_param_block_usage()
LLUICtrlFactory::create<LLInventoryPanel>(param_block);
}
+
+// +=================================================+
+// | LLInventoryPanelObserver |
+// +=================================================+
+void LLInventoryPanelObserver::changed(U32 mask)
+{
+ mIP->modelChanged(mask);
+}
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index e398c44105..0ccee337c9 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -162,6 +162,10 @@ public:
void unSelectAll() { mFolders->setSelection(NULL, FALSE, FALSE); }
protected:
+ // Destroys the old views, and regenerates them based on the
+ // start folder ID.
+ void rebuildViews();
+
// Given the id and the parent, build all of the folder views.
void rebuildViewsFor(const LLUUID& id);
virtual void buildNewViews(const LLUUID& id); // made virtual to support derived classes. EXT-719
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index ce1a7f98df..e199db37ab 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -97,10 +97,10 @@ BOOL LLLandmarksPanel::postBuild()
U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER);
mSortByDate = sort_order & LLInventoryFilter::SO_DATE;
- initFavoritesInventroyPanel();
- initLandmarksInventroyPanel();
- initMyInventroyPanel();
- initLibraryInventroyPanel();
+ initFavoritesInventoryPanel();
+ initLandmarksInventoryPanel();
+ initMyInventoryPanel();
+ initLibraryInventoryPanel();
getChild<LLAccordionCtrlTab>("tab_favorites")->setDisplayChildren(true);
getChild<LLAccordionCtrlTab>("tab_landmarks")->setDisplayChildren(true);
@@ -357,7 +357,7 @@ void LLLandmarksPanel::setErrorStatus(U32 status, const std::string& reason)
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
-void LLLandmarksPanel::initFavoritesInventroyPanel()
+void LLLandmarksPanel::initFavoritesInventoryPanel()
{
mFavoritesInventoryPanel = getChild<LLInventorySubTreePanel>("favorites_list");
@@ -366,7 +366,7 @@ void LLLandmarksPanel::initFavoritesInventroyPanel()
initAccordion("tab_favorites", mFavoritesInventoryPanel);
}
-void LLLandmarksPanel::initLandmarksInventroyPanel()
+void LLLandmarksPanel::initLandmarksInventoryPanel()
{
mLandmarksInventoryPanel = getChild<LLInventorySubTreePanel>("landmarks_list");
@@ -380,7 +380,7 @@ void LLLandmarksPanel::initLandmarksInventroyPanel()
initAccordion("tab_landmarks", mLandmarksInventoryPanel);
}
-void LLLandmarksPanel::initMyInventroyPanel()
+void LLLandmarksPanel::initMyInventoryPanel()
{
mMyInventoryPanel= getChild<LLInventorySubTreePanel>("my_inventory_list");
@@ -389,7 +389,7 @@ void LLLandmarksPanel::initMyInventroyPanel()
initAccordion("tab_inventory", mMyInventoryPanel);
}
-void LLLandmarksPanel::initLibraryInventroyPanel()
+void LLLandmarksPanel::initLibraryInventoryPanel()
{
mLibraryInventoryPanel = getChild<LLInventorySubTreePanel>("library_list");
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index 745f9364c2..097d79badf 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -78,10 +78,10 @@ protected:
/*virtual*/ void setErrorStatus(U32 status, const std::string& reason);
private:
- void initFavoritesInventroyPanel();
- void initLandmarksInventroyPanel();
- void initMyInventroyPanel();
- void initLibraryInventroyPanel();
+ void initFavoritesInventoryPanel();
+ void initLandmarksInventoryPanel();
+ void initMyInventoryPanel();
+ void initLibraryInventoryPanel();
void initLandmarksPanel(LLInventorySubTreePanel* inventory_list);
void initAccordion(const std::string& accordion_tab_name, LLInventorySubTreePanel* inventory_list);
void onAccordionExpandedCollapsed(const LLSD& param, LLInventorySubTreePanel* inventory_list);
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index e3b2ab77aa..9f723169e1 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -49,7 +49,7 @@
#include "llviewermenu.h"
#include "llviewertexturelist.h"
-static LLRegisterPanelClassWrapper<LLPanelMainInventory> t_inventory("panel_main_inventory"); // Seraph is this redundant with constructor?
+static LLRegisterPanelClassWrapper<LLPanelMainInventory> t_inventory("panel_main_inventory");
void on_file_loaded_for_save(BOOL success,
LLViewerFetchedTexture *src_vi,
@@ -197,28 +197,6 @@ BOOL LLPanelMainInventory::postBuild()
return TRUE;
}
-void LLPanelMainInventory::initListCommandsHandlers()
-{
- mListCommands = getChild<LLPanel>("bottom_panel");
-
- mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelMainInventory::onGearButtonClick, this));
- mListCommands->childSetAction("trash_btn", boost::bind(&LLPanelMainInventory::onTrashButtonClick, this));
- mListCommands->childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this));
-
- LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>("trash_btn");
- trash_btn->setDragAndDropHandler(boost::bind(&LLPanelMainInventory::handleDragAndDropToTrash, this
- , _4 // BOOL drop
- , _5 // EDragAndDropType cargo_type
- , _7 // EAcceptance* accept
- ));
-
- mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2));
- mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
- mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-
-}
-
// Destroys the object
LLPanelMainInventory::~LLPanelMainInventory( void )
{
@@ -863,9 +841,30 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
self->childSetValue("check_snapshot", FALSE);
}
+//////////////////////////////////////////////////////////////////////////////////
+// List Commands //
+void LLPanelMainInventory::initListCommandsHandlers()
+{
+ mListCommands = getChild<LLPanel>("bottom_panel");
+ mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelMainInventory::onGearButtonClick, this));
+ mListCommands->childSetAction("trash_btn", boost::bind(&LLPanelMainInventory::onTrashButtonClick, this));
+ mListCommands->childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this));
+ LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>("trash_btn");
+ trash_btn->setDragAndDropHandler(boost::bind(&LLPanelMainInventory::handleDragAndDropToTrash, this
+ , _4 // BOOL drop
+ , _5 // EDragAndDropType cargo_type
+ , _7 // EAcceptance* accept
+ ));
+
+ mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2));
+ mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
+ mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+
+}
void LLPanelMainInventory::updateListCommands()
{
@@ -1018,3 +1017,6 @@ bool LLPanelMainInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropType
}
return true;
}
+
+// List Commands //
+////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index fbc0f09c50..627be21577 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -111,7 +111,20 @@ protected:
void resetFilters();
void setSortBy(const LLSD& userdata);
- // List Commands Handlers
+private:
+ LLFloaterInventoryFinder* getFinder();
+
+ LLFilterEditor* mFilterEditor;
+ LLTabContainer* mFilterTabs;
+ LLHandle<LLFloater> mFinderHandle;
+ LLInventoryPanel* mActivePanel;
+ LLSaveFolderState* mSavedFolderState;
+ std::string mFilterText;
+
+
+ //////////////////////////////////////////////////////////////////////////////////
+ // List Commands //
+protected:
void initListCommandsHandlers();
void updateListCommands();
void onGearButtonClick();
@@ -122,22 +135,12 @@ protected:
BOOL isActionEnabled(const LLSD& command_name);
void onCustomAction(const LLSD& command_name);
bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept);
-
-
private:
- LLFloaterInventoryFinder* getFinder();
-
- LLFilterEditor* mFilterEditor;
- LLTabContainer* mFilterTabs;
- LLHandle<LLFloater> mFinderHandle;
- LLInventoryPanel* mActivePanel;
- LLSaveFolderState* mSavedFolderState;
-
LLPanel* mListCommands;
LLMenuGL* mMenuGearDefault;
LLMenuGL* mMenuAdd;
-
- std::string mFilterText;
+ // List Commands //
+ ////////////////////////////////////////////////////////////////////////////////
};
#endif // LL_LLPANELMAININVENTORY_H
diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h
index 6722bb212e..7a39d8fabc 100644
--- a/indra/newview/llpanelobjectinventory.h
+++ b/indra/newview/llpanelobjectinventory.h
@@ -1,102 +1,102 @@
-/**
- * @file llpanelobjectinventory.h
- * @brief LLPanelObjectInventory class definition
- *
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLPANELOBJECTINVENTORY_H
-#define LL_LLPANELOBJECTINVENTORY_H
-
-#include "llvoinventorylistener.h"
-#include "llpanel.h"
-
-#include "llinventory.h"
-
-class LLScrollContainer;
-class LLFolderView;
-class LLFolderViewFolder;
-class LLViewerObject;
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLPanelObjectInventory
-//
-// This class represents the panel used to view and control a
-// particular task's inventory.
-//
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLPanelObjectInventory : public LLPanel, public LLVOInventoryListener
-{
-public:
- // dummy param block for template registration purposes
- struct Params : public LLPanel::Params {};
-
- LLPanelObjectInventory(const Params&);
- virtual ~LLPanelObjectInventory();
-
- virtual BOOL postBuild();
-
- void doToSelected(const LLSD& userdata);
-
- void refresh();
- const LLUUID& getTaskUUID() { return mTaskUUID;}
- void removeSelectedItem();
- void startRenamingSelectedItem();
-
- LLFolderView* getRootFolder() const { return mFolders; }
-
- virtual void draw();
- virtual void deleteAllChildren();
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg);
-
- static void idle(void* user_data);
-
-protected:
- void reset();
- /*virtual*/ void inventoryChanged(LLViewerObject* object,
- InventoryObjectList* inventory,
- S32 serial_num,
- void* user_data);
- void updateInventory();
- void createFolderViews(LLInventoryObject* inventory_root, InventoryObjectList& contents);
- void createViewsForCategory(InventoryObjectList* inventory,
- LLInventoryObject* parent,
- LLFolderViewFolder* folder);
- void clearContents();
-
-private:
- LLScrollContainer* mScroller;
- LLFolderView* mFolders;
-
- LLUUID mTaskUUID;
- BOOL mHaveInventory;
- BOOL mIsInventoryEmpty;
- BOOL mInventoryNeedsUpdate;
-};
-
-#endif // LL_LLPANELOBJECTINVENTORY_H
+/**
+ * @file llpanelobjectinventory.h
+ * @brief LLPanelObjectInventory class definition
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELOBJECTINVENTORY_H
+#define LL_LLPANELOBJECTINVENTORY_H
+
+#include "llvoinventorylistener.h"
+#include "llpanel.h"
+
+#include "llinventory.h"
+
+class LLScrollContainer;
+class LLFolderView;
+class LLFolderViewFolder;
+class LLViewerObject;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLPanelObjectInventory
+//
+// This class represents the panel used to view and control a
+// particular task's inventory.
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLPanelObjectInventory : public LLPanel, public LLVOInventoryListener
+{
+public:
+ // dummy param block for template registration purposes
+ struct Params : public LLPanel::Params {};
+
+ LLPanelObjectInventory(const Params&);
+ virtual ~LLPanelObjectInventory();
+
+ virtual BOOL postBuild();
+
+ void doToSelected(const LLSD& userdata);
+
+ void refresh();
+ const LLUUID& getTaskUUID() { return mTaskUUID;}
+ void removeSelectedItem();
+ void startRenamingSelectedItem();
+
+ LLFolderView* getRootFolder() const { return mFolders; }
+
+ virtual void draw();
+ virtual void deleteAllChildren();
+ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg);
+
+ static void idle(void* user_data);
+
+protected:
+ void reset();
+ /*virtual*/ void inventoryChanged(LLViewerObject* object,
+ InventoryObjectList* inventory,
+ S32 serial_num,
+ void* user_data);
+ void updateInventory();
+ void createFolderViews(LLInventoryObject* inventory_root, InventoryObjectList& contents);
+ void createViewsForCategory(InventoryObjectList* inventory,
+ LLInventoryObject* parent,
+ LLFolderViewFolder* folder);
+ void clearContents();
+
+private:
+ LLScrollContainer* mScroller;
+ LLFolderView* mFolders;
+
+ LLUUID mTaskUUID;
+ BOOL mHaveInventory;
+ BOOL mIsInventoryEmpty;
+ BOOL mInventoryNeedsUpdate;
+};
+
+#endif // LL_LLPANELOBJECTINVENTORY_H
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
new file mode 100644
index 0000000000..5ad9bf056e
--- /dev/null
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -0,0 +1,347 @@
+/**
+ * @file llpaneloutfitsinventory.cpp
+ * @brief Outfits inventory panel
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpaneloutfitsinventory.h"
+
+#include "llagent.h"
+#include "llagentwearables.h"
+
+#include "llbutton.h"
+#include "llfloaterreg.h"
+#include "llfloaterworldmap.h"
+#include "llfloaterinventory.h"
+#include "llfoldervieweventlistener.h"
+#include "llinventoryfunctions.h"
+#include "llinventorypanel.h"
+#include "lllandmark.h"
+#include "llsidepanelappearance.h"
+#include "llsidetray.h"
+#include "lltabcontainer.h"
+#include "llviewerfoldertype.h"
+#include "llviewerjointattachment.h"
+#include "llvoavatarself.h"
+
+// List Commands
+#include "lldndbutton.h"
+#include "llmenugl.h"
+#include "llviewermenu.h"
+
+static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
+
+LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
+ mInventoryPanel(NULL),
+ mParent(NULL)
+{
+ mSavedFolderState = new LLSaveFolderState();
+ mSavedFolderState->setApply(FALSE);
+}
+
+LLPanelOutfitsInventory::~LLPanelOutfitsInventory()
+{
+ delete mSavedFolderState;
+}
+
+// virtual
+BOOL LLPanelOutfitsInventory::postBuild()
+{
+ mInventoryPanel = getChild<LLInventoryPanel>("outfits_list");
+ mInventoryPanel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, TRUE);
+ mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_MY_OUTFITS);
+ mInventoryPanel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onSelectionChange, this, _1, _2));
+
+ initListCommandsHandlers();
+ return TRUE;
+}
+
+void LLPanelOutfitsInventory::updateParent()
+{
+ if (mParent)
+ {
+ mParent->updateVerbs();
+ }
+}
+
+void LLPanelOutfitsInventory::setParent(LLSidepanelAppearance* parent)
+{
+ mParent = parent;
+}
+
+// virtual
+void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
+{
+ if (string == "")
+ {
+ mInventoryPanel->setFilterSubString(LLStringUtil::null);
+
+ // re-open folders that were initially open
+ mSavedFolderState->setApply(TRUE);
+ getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+ LLOpenFoldersWithSelection opener;
+ getRootFolder()->applyFunctorRecursively(opener);
+ getRootFolder()->scrollToShowSelection();
+ }
+
+ gInventory.startBackgroundFetch();
+
+ if (mInventoryPanel->getFilterSubString().empty() && string.empty())
+ {
+ // current filter and new filter empty, do nothing
+ return;
+ }
+
+ // save current folder open state if no filter currently applied
+ if (getRootFolder()->getFilterSubString().empty())
+ {
+ mSavedFolderState->setApply(FALSE);
+ getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+ }
+
+ // set new filter string
+ mInventoryPanel->setFilterSubString(string);
+}
+
+void LLPanelOutfitsInventory::onWear()
+{
+ LLFolderViewEventListener* listenerp = getCorrectListenerForAction();
+ if (listenerp)
+ {
+ listenerp->performAction(NULL, NULL,"replaceoutfit");
+ }
+}
+
+void LLPanelOutfitsInventory::onEdit()
+{
+}
+
+void LLPanelOutfitsInventory::onNew()
+{
+ const std::string& outfit_name = LLViewerFolderType::lookupNewCategoryName(LLFolderType::FT_OUTFIT);
+ LLUUID outfit_folder = gAgentWearables.makeNewOutfitLinks(outfit_name);
+ getRootFolder()->setSelectionByID(outfit_folder, TRUE);
+ getRootFolder()->setNeedsAutoRename(TRUE);
+}
+
+void LLPanelOutfitsInventory::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)
+{
+ updateParent();
+}
+
+void LLPanelOutfitsInventory::onSelectorButtonClicked()
+{
+ /*
+ LLFolderViewItem* cur_item = getRootFolder()->getCurSelectedItem();
+
+ LLFolderViewEventListener* listenerp = cur_item->getListener();
+ if (getIsCorrectType(listenerp))
+ {
+ LLSD key;
+ key["type"] = "look";
+ key["id"] = listenerp->getUUID();
+
+ LLSideTray::getInstance()->showPanel("sidepanel_appearance", key);
+ }
+ */
+}
+
+LLFolderViewEventListener *LLPanelOutfitsInventory::getCorrectListenerForAction()
+{
+ LLFolderViewItem* current_item = getRootFolder()->getCurSelectedItem();
+ if (!current_item)
+ return NULL;
+
+ LLFolderViewEventListener* listenerp = current_item->getListener();
+ if (getIsCorrectType(listenerp))
+ {
+ return listenerp;
+ }
+ return NULL;
+}
+
+bool LLPanelOutfitsInventory::getIsCorrectType(const LLFolderViewEventListener *listenerp) const
+{
+ if (listenerp->getInventoryType() == LLInventoryType::IT_CATEGORY)
+ {
+ LLViewerInventoryCategory *cat = gInventory.getCategory(listenerp->getUUID());
+ if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+LLFolderView *LLPanelOutfitsInventory::getRootFolder()
+{
+ return mInventoryPanel->getRootFolder();
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+// List Commands //
+
+void LLPanelOutfitsInventory::initListCommandsHandlers()
+{
+ mListCommands = getChild<LLPanel>("bottom_panel");
+
+ mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelOutfitsInventory::onGearButtonClick, this));
+ mListCommands->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this));
+ mListCommands->childSetAction("add_btn", boost::bind(&LLPanelOutfitsInventory::onAddButtonClick, this));
+
+ LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>("trash_btn");
+ trash_btn->setDragAndDropHandler(boost::bind(&LLPanelOutfitsInventory::handleDragAndDropToTrash, this
+ , _4 // BOOL drop
+ , _5 // EDragAndDropType cargo_type
+ , _7 // EAcceptance* accept
+ ));
+
+ mCommitCallbackRegistrar.add("panel_outfits_inventory_gear_default.Custom.Action", boost::bind(&LLPanelOutfitsInventory::onCustomAction, this, _2));
+ mEnableCallbackRegistrar.add("panel_outfits_inventory_gear_default.Enable", boost::bind(&LLPanelOutfitsInventory::isActionEnabled, this, _2));
+ mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("panel_outfits_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+}
+
+void LLPanelOutfitsInventory::updateListCommands()
+{
+ bool trash_enabled = isActionEnabled("delete");
+
+ mListCommands->childSetEnabled("trash_btn", trash_enabled);
+}
+
+void LLPanelOutfitsInventory::onGearButtonClick()
+{
+ showActionMenu(mMenuGearDefault,"options_gear_btn");
+}
+
+void LLPanelOutfitsInventory::onAddButtonClick()
+{
+ onNew();
+}
+
+void LLPanelOutfitsInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name)
+{
+ if (menu)
+ {
+ menu->buildDrawLabels();
+ menu->updateParent(LLMenuGL::sMenuContainer);
+ LLView* spawning_view = getChild<LLView> (spawning_view_name);
+ S32 menu_x, menu_y;
+ //show menu in co-ordinates of panel
+ spawning_view->localPointToOtherView(0, spawning_view->getRect().getHeight(), &menu_x, &menu_y, this);
+ menu_y += menu->getRect().getHeight();
+ LLMenuGL::showPopup(this, menu, menu_x, menu_y);
+ }
+}
+
+void LLPanelOutfitsInventory::onTrashButtonClick()
+{
+ onClipboardAction("delete");
+}
+
+void LLPanelOutfitsInventory::onClipboardAction(const LLSD& userdata)
+{
+ std::string command_name = userdata.asString();
+ getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
+}
+
+void LLPanelOutfitsInventory::onCustomAction(const LLSD& userdata)
+{
+ if (!isActionEnabled(userdata))
+ return;
+
+ const std::string command_name = userdata.asString();
+ if (command_name == "new")
+ {
+ onNew();
+ }
+ if (command_name == "edit")
+ {
+ onEdit();
+ }
+ if (command_name == "wear")
+ {
+ onWear();
+ }
+ if (command_name == "delete")
+ {
+ onClipboardAction("delete");
+ }
+}
+
+BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
+{
+ const std::string command_name = userdata.asString();
+ if (command_name == "delete")
+ {
+ BOOL can_delete = FALSE;
+ LLFolderView *folder = getActivePanel()->getRootFolder();
+ if (folder)
+ {
+ can_delete = TRUE;
+ std::set<LLUUID> selection_set;
+ folder->getSelectionList(selection_set);
+ for (std::set<LLUUID>::iterator iter = selection_set.begin();
+ iter != selection_set.end();
+ ++iter)
+ {
+ const LLUUID &item_id = (*iter);
+ LLFolderViewItem *item = folder->getItemByID(item_id);
+ can_delete &= item->getListener()->isItemRemovable();
+ }
+ return can_delete;
+ }
+ return FALSE;
+ }
+ if (command_name == "edit" ||
+ command_name == "wear")
+ {
+ return (getCorrectListenerForAction() != NULL);
+ }
+ return TRUE;
+}
+
+bool LLPanelOutfitsInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept)
+{
+ *accept = ACCEPT_NO;
+
+ const bool is_enabled = isActionEnabled("delete");
+ if (is_enabled) *accept = ACCEPT_YES_MULTI;
+
+ if (is_enabled && drop)
+ {
+ onClipboardAction("delete");
+ }
+ return true;
+}
+
+// List Commands //
+////////////////////////////////////////////////////////////////////////////////
+
diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h
new file mode 100644
index 0000000000..4d903a389b
--- /dev/null
+++ b/indra/newview/llpaneloutfitsinventory.h
@@ -0,0 +1,102 @@
+/**
+ * @file llpaneloutfitsinventory.h
+ * @brief Outfits inventory panel
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELOUTFITSINVENTORY_H
+#define LL_LLPANELOUTFITSINVENTORY_H
+
+#include "llpanel.h"
+#include "llinventoryobserver.h"
+
+class LLFolderView;
+class LLFolderViewItem;
+class LLFolderViewEventListener;
+class LLInventoryPanel;
+class LLSaveFolderState;
+class LLButton;
+class LLMenuGL;
+class LLSidepanelAppearance;
+
+class LLPanelOutfitsInventory : public LLPanel
+{
+public:
+ LLPanelOutfitsInventory();
+ virtual ~LLPanelOutfitsInventory();
+
+ /*virtual*/ BOOL postBuild();
+
+ void onSearchEdit(const std::string& string);
+ void onWear();
+ void onEdit();
+ void onNew();
+
+ void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
+ void onSelectorButtonClicked();
+
+ LLInventoryPanel* getActivePanel() { return mInventoryPanel; }
+
+ // If a compatible listener type is selected, then return a pointer to that.
+ // Otherwise, return NULL.
+ LLFolderViewEventListener* getCorrectListenerForAction();
+ void setParent(LLSidepanelAppearance *parent);
+protected:
+ void updateParent();
+ bool getIsCorrectType(const LLFolderViewEventListener *listenerp) const;
+ LLFolderView* getRootFolder();
+
+private:
+ LLSidepanelAppearance* mParent;
+ LLInventoryPanel* mInventoryPanel;
+ LLSaveFolderState* mSavedFolderState;
+
+
+ //////////////////////////////////////////////////////////////////////////////////
+ // List Commands //
+protected:
+ void initListCommandsHandlers();
+ void updateListCommands();
+ void onGearButtonClick();
+ void onAddButtonClick();
+ void showActionMenu(LLMenuGL* menu, std::string spawning_view_name);
+ void onTrashButtonClick();
+ void onClipboardAction(const LLSD& userdata);
+ BOOL isActionEnabled(const LLSD& command_name);
+ void onCustomAction(const LLSD& command_name);
+ bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept);
+private:
+ LLPanel* mListCommands;
+ LLMenuGL* mMenuGearDefault;
+ LLMenuGL* mMenuAdd;
+ // //
+ ////////////////////////////////////////////////////////////////////////////////
+};
+
+#endif //LL_LLPANELOUTFITSINVENTORY_H
diff --git a/indra/newview/llscrollingpanelparam.cpp b/indra/newview/llscrollingpanelparam.cpp
index 1fbaeb94f5..b5e55df1f5 100644
--- a/indra/newview/llscrollingpanelparam.cpp
+++ b/indra/newview/llscrollingpanelparam.cpp
@@ -73,9 +73,9 @@ LLScrollingPanelParam::LLScrollingPanelParam( const LLPanel::Params& panel_param
F32 min_weight = param->getMinWeight();
F32 max_weight = param->getMaxWeight();
- mHintMin = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, param, min_weight);
+ mHintMin = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, (LLViewerVisualParam*) wearable->getVisualParam(param->getID()), min_weight);
pos_x += PARAM_HINT_WIDTH + 3 * BTN_BORDER;
- mHintMax = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, param, max_weight );
+ mHintMax = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, (LLViewerVisualParam*) wearable->getVisualParam(param->getID()), max_weight );
mHintMin->setAllowsUpdates( FALSE );
mHintMax->setAllowsUpdates( FALSE );
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
new file mode 100644
index 0000000000..aeab3e2876
--- /dev/null
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -0,0 +1,372 @@
+/**
+ * @file llsidepanelappearance.cpp
+ * @brief Side Bar "Appearance" panel
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llsidepanelappearance.h"
+
+#include "llagent.h"
+#include "llagentwearables.h"
+#include "llfiltereditor.h"
+#include "llfloaterreg.h"
+#include "llfloaterworldmap.h"
+#include "llpaneleditwearable.h"
+#include "llpaneloutfitsinventory.h"
+#include "lltextbox.h"
+#include "lluictrlfactory.h"
+#include "llviewerregion.h"
+#include "llvoavatarself.h"
+#include "llwearable.h"
+
+static LLRegisterPanelClassWrapper<LLSidepanelAppearance> t_appearance("sidepanel_appearance");
+
+class LLCurrentlyWornFetchObserver : public LLInventoryFetchObserver
+{
+public:
+ LLCurrentlyWornFetchObserver(LLSidepanelAppearance *panel) :
+ mPanel(panel)
+ {}
+ ~LLCurrentlyWornFetchObserver() {}
+ virtual void done()
+ {
+ mPanel->inventoryFetched();
+ gInventory.removeObserver(this);
+ }
+private:
+ LLSidepanelAppearance *mPanel;
+};
+
+LLSidepanelAppearance::LLSidepanelAppearance() :
+ LLPanel(),
+ mFilterSubString(LLStringUtil::null),
+ mFilterEditor(NULL),
+ mLookInfo(NULL),
+ mCurrLookPanel(NULL)
+{
+ //LLUICtrlFactory::getInstance()->buildPanel(this, "panel_appearance.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()
+ mFetchWorn = new LLCurrentlyWornFetchObserver(this);
+}
+
+LLSidepanelAppearance::~LLSidepanelAppearance()
+{
+}
+
+// virtual
+BOOL LLSidepanelAppearance::postBuild()
+{
+ mEditAppearanceBtn = getChild<LLButton>("editappearance_btn");
+ mEditAppearanceBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditAppearanceButtonClicked, this));
+
+ mWearBtn = getChild<LLButton>("wear_btn");
+ mWearBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onWearButtonClicked, this));
+
+ mEditBtn = getChild<LLButton>("edit_btn");
+ mEditBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditButtonClicked, this));
+
+ mNewLookBtn = getChild<LLButton>("newlook_btn");
+ mNewLookBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onNewOutfitButtonClicked, this));
+ mNewLookBtn->setEnabled(false);
+
+ mOverflowBtn = getChild<LLButton>("overflow_btn");
+
+ mFilterEditor = getChild<LLFilterEditor>("Filter");
+ if (mFilterEditor)
+ {
+ mFilterEditor->setCommitCallback(boost::bind(&LLSidepanelAppearance::onFilterEdit, this, _2));
+ }
+
+ mPanelOutfitsInventory = dynamic_cast<LLPanelOutfitsInventory *>(getChild<LLPanel>("panel_outfits_inventory"));
+ mPanelOutfitsInventory->setParent(this);
+
+ mLookInfo = dynamic_cast<LLPanelLookInfo*>(getChild<LLPanel>("panel_look_info"));
+ if (mLookInfo)
+ {
+ LLButton* back_btn = mLookInfo->getChild<LLButton>("back_btn");
+ if (back_btn)
+ {
+ back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onBackButtonClicked, this));
+ }
+
+ // *TODO: Assign the action to an appropriate event.
+ // mOverflowBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::toggleMediaPanel, this));
+ }
+
+ mEditWearable = dynamic_cast<LLPanelEditWearable*>(getChild<LLPanel>("panel_edit_wearable"));
+ if (mEditWearable)
+ {
+ LLButton* edit_wearable_back_btn = mEditWearable->getChild<LLButton>("back_btn");
+ if (edit_wearable_back_btn)
+ {
+ edit_wearable_back_btn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onEditWearBackClicked, this));
+ }
+ }
+
+ mCurrentLookName = getChild<LLTextBox>("currentlook_name");
+
+ mCurrLookPanel = getChild<LLPanel>("panel_currentlook");
+
+ return TRUE;
+}
+
+// virtual
+void LLSidepanelAppearance::onOpen(const LLSD& key)
+{
+ fetchInventory();
+ refreshCurrentOutfitName();
+
+ if(key.size() == 0)
+ return;
+
+ toggleLookInfoPanel(TRUE);
+ updateVerbs();
+
+ mLookInfoType = key["type"].asString();
+
+ if (mLookInfoType == "look")
+ {
+ LLInventoryCategory *pLook = gInventory.getCategory(key["id"].asUUID());
+ if (pLook)
+ mLookInfo->displayLookInfo(pLook);
+ }
+}
+
+void LLSidepanelAppearance::onFilterEdit(const std::string& search_string)
+{
+ if (mFilterSubString != search_string)
+ {
+ mFilterSubString = search_string;
+
+ // Searches are case-insensitive
+ LLStringUtil::toUpper(mFilterSubString);
+ LLStringUtil::trimHead(mFilterSubString);
+
+ mPanelOutfitsInventory->onSearchEdit(mFilterSubString);
+ }
+}
+
+void LLSidepanelAppearance::onWearButtonClicked()
+{
+ if (!mLookInfo->getVisible())
+ {
+ mPanelOutfitsInventory->onWear();
+ }
+}
+
+void LLSidepanelAppearance::onEditAppearanceButtonClicked()
+{
+ if (gAgentWearables.areWearablesLoaded())
+ {
+ gAgent.changeCameraToCustomizeAvatar();
+ }
+}
+
+void LLSidepanelAppearance::onEditButtonClicked()
+{
+ toggleLookInfoPanel(FALSE);
+ toggleWearableEditPanel(TRUE, NULL);
+ /*if (mLookInfo->getVisible())
+ {
+ }
+ else
+ {
+ mPanelOutfitsInventory->onEdit();
+ }*/
+}
+
+void LLSidepanelAppearance::onNewOutfitButtonClicked()
+{
+ if (!mLookInfo->getVisible())
+ {
+ mPanelOutfitsInventory->onNew();
+ }
+}
+
+
+void LLSidepanelAppearance::onBackButtonClicked()
+{
+ toggleLookInfoPanel(FALSE);
+}
+
+void LLSidepanelAppearance::onEditWearBackClicked()
+{
+ mEditWearable->saveChanges();
+ toggleWearableEditPanel(FALSE, NULL);
+ toggleLookInfoPanel(TRUE);
+}
+
+void LLSidepanelAppearance::toggleLookInfoPanel(BOOL visible)
+{
+ if (!mLookInfo)
+ return;
+
+ mLookInfo->setVisible(visible);
+ mPanelOutfitsInventory->setVisible(!visible);
+ mFilterEditor->setVisible(!visible);
+ mWearBtn->setVisible(!visible);
+ mEditBtn->setVisible(!visible);
+ mNewLookBtn->setVisible(!visible);
+ mOverflowBtn->setVisible(!visible);
+ mCurrLookPanel->setVisible(!visible);
+}
+
+void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable)
+{
+ if (!wearable)
+ {
+ wearable = gAgentWearables.getWearable(WT_SHAPE, 0);
+ }
+ if (!mEditWearable || !wearable)
+ {
+ return;
+ }
+
+ mEditWearable->setVisible(visible);
+ mFilterEditor->setVisible(!visible);
+ mPanelOutfitsInventory->setVisible(!visible);
+}
+
+void LLSidepanelAppearance::updateVerbs()
+{
+ bool is_look_info_visible = mLookInfo->getVisible();
+ mOverflowBtn->setEnabled(false);
+
+ if (!is_look_info_visible)
+ {
+ const bool is_correct_type = (mPanelOutfitsInventory->getCorrectListenerForAction() != NULL);
+ mEditBtn->setEnabled(is_correct_type);
+ mWearBtn->setEnabled(is_correct_type);
+ }
+ else
+ {
+ mEditBtn->setEnabled(FALSE);
+ mWearBtn->setEnabled(FALSE);
+ }
+}
+
+void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string name)
+{
+ if (name == "")
+ {
+ const LLUUID current_outfit_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+ // Can't search on AT_OUTFIT since links to categories return AT_CATEGORY for type since they don't
+ // return preferred type.
+ LLIsType is_category( LLAssetType::AT_CATEGORY );
+ gInventory.collectDescendentsIf(current_outfit_cat,
+ cat_array,
+ item_array,
+ false,
+ is_category,
+ false);
+ for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
+ iter != item_array.end();
+ iter++)
+ {
+ const LLViewerInventoryItem *item = (*iter);
+ const LLViewerInventoryCategory *cat = item->getLinkedCategory();
+ if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)
+ {
+ mCurrentLookName->setText(cat->getName());
+ return;
+ }
+ }
+ mCurrentLookName->setText(std::string(""));
+ }
+ else
+ {
+ mCurrentLookName->setText(name);
+ }
+}
+
+//static
+void LLSidepanelAppearance::editWearable(LLWearable *wearable, void *data)
+{
+ LLSidepanelAppearance *panel = (LLSidepanelAppearance*) data;
+ panel->toggleLookInfoPanel(FALSE);
+ panel->toggleWearableEditPanel(TRUE, wearable);
+}
+
+// Fetch currently worn items and only enable the New Look button after everything's been
+// fetched. Alternatively, we could stuff this logic into llagentwearables::makeNewOutfitLinks.
+void LLSidepanelAppearance::fetchInventory()
+{
+
+ mNewLookBtn->setEnabled(false);
+ LLInventoryFetchObserver::item_ref_t ids;
+ LLUUID item_id;
+ for(S32 type = (S32)WT_SHAPE; type < (S32)WT_COUNT; ++type)
+ {
+ // MULTI_WEARABLE:
+ item_id = gAgentWearables.getWearableItemID((EWearableType)type,0);
+ if(item_id.notNull())
+ {
+ ids.push_back(item_id);
+ }
+ }
+
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
+ if( avatar )
+ {
+ for (LLVOAvatar::attachment_map_t::const_iterator iter = avatar->mAttachmentPoints.begin();
+ iter != avatar->mAttachmentPoints.end(); ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (!attachment) continue;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = (*attachment_iter);
+ if (!attached_object) continue;
+ const LLUUID& item_id = attached_object->getItemID();
+ if (item_id.isNull()) continue;
+ ids.push_back(item_id);
+ }
+ }
+ }
+
+ mFetchWorn->fetchItems(ids);
+ // If no items to be fetched, done will never be triggered.
+ // TODO: Change LLInventoryFetchObserver::fetchItems to trigger done() on this condition.
+ if (mFetchWorn->isEverythingComplete())
+ {
+ mFetchWorn->done();
+ }
+ else
+ {
+ gInventory.addObserver(mFetchWorn);
+ }
+}
+
+void LLSidepanelAppearance::inventoryFetched()
+{
+ mNewLookBtn->setEnabled(true);
+}
diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h
new file mode 100644
index 0000000000..496a1fef72
--- /dev/null
+++ b/indra/newview/llsidepanelappearance.h
@@ -0,0 +1,102 @@
+/**
+ * @file llsidepanelappearance.h
+ * @brief Side Bar "Appearance" panel
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSIDEPANELAPPEARANCE_H
+#define LL_LLSIDEPANELAPPEARANCE_H
+
+#include "llpanel.h"
+#include "llinventoryobserver.h"
+
+#include "llinventory.h"
+#include "llpanellookinfo.h"
+
+class LLFilterEditor;
+class LLCurrentlyWornFetchObserver;
+class LLPanelEditWearable;
+class LLWearable;
+class LLPanelOutfitsInventory;
+
+class LLSidepanelAppearance : public LLPanel
+{
+public:
+ LLSidepanelAppearance();
+ virtual ~LLSidepanelAppearance();
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
+
+ void refreshCurrentOutfitName(const std::string name = "");
+
+ static void editWearable(LLWearable *wearable, void *data);
+
+ void fetchInventory();
+ void inventoryFetched();
+ void updateVerbs();
+
+private:
+ void onFilterEdit(const std::string& search_string);
+
+ void onEditAppearanceButtonClicked();
+ void onWearButtonClicked();
+ void onEditButtonClicked();
+ void onNewOutfitButtonClicked();
+ void onBackButtonClicked();
+ void onEditWearBackClicked();
+ void toggleLookInfoPanel(BOOL visible);
+ void toggleWearableEditPanel(BOOL visible, LLWearable* wearable);
+
+ LLFilterEditor* mFilterEditor;
+ LLPanelOutfitsInventory* mPanelOutfitsInventory;
+ LLPanelLookInfo* mLookInfo;
+ LLPanelEditWearable* mEditWearable;
+
+ LLButton* mEditAppearanceBtn;
+ LLButton* mWearBtn;
+ LLButton* mEditBtn;
+ LLButton* mNewLookBtn;
+ LLButton* mOverflowBtn;
+ LLPanel* mCurrLookPanel;
+
+ LLTextBox* mCurrentLookName;
+
+ // Used to make sure the user's inventory is in memory.
+ LLCurrentlyWornFetchObserver* mFetchWorn;
+
+ // Search string for filtering landmarks and teleport
+ // history locations
+ std::string mFilterSubString;
+
+ // Information type currently shown in Look Information panel
+ std::string mLookInfoType;
+
+};
+
+#endif //LL_LLSIDEPANELAPPEARANCE_H
diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index d7d7b5f44b..4fb75f7a49 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -146,8 +146,9 @@ void LLVisualParamHint::preRender(BOOL clear_depth)
{
LLVOAvatarSelf* avatarp = gAgent.getAvatarObject();
- mLastParamWeight = avatarp->getVisualParamWeight(mVisualParam);
- avatarp->setVisualParamWeight(mVisualParam, mVisualParamWeight);
+ mLastParamWeight = mVisualParam->getWeight();
+ mVisualParam->setWeight(mVisualParamWeight, FALSE);
+ avatarp->setVisualParamWeight(mVisualParam->getID(), mVisualParamWeight, FALSE);
avatarp->setVisualParamWeight("Blink_Left", 0.f);
avatarp->setVisualParamWeight("Blink_Right", 0.f);
avatarp->updateComposites();
@@ -242,7 +243,8 @@ BOOL LLVisualParamHint::render()
gGL.setSceneBlendType(LLRender::BT_ALPHA);
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}
- avatarp->setVisualParamWeight(mVisualParam, mLastParamWeight);
+ avatarp->setVisualParamWeight(mVisualParam->getID(), mLastParamWeight);
+ mVisualParam->setWeight(mLastParamWeight, FALSE);
gGL.color4f(1,1,1,1);
mGLTexturep->setGLTextureCreated(true);
return TRUE;
diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp
index e37dffd526..2849cfa20e 100644
--- a/indra/newview/llwearable.cpp
+++ b/indra/newview/llwearable.cpp
@@ -225,7 +225,13 @@ BOOL LLWearable::importFile( LLFILE* file )
return FALSE;
}
- if( mDefinitionVersion > LLWearable::sCurrentDefinitionVersion )
+
+ // Temoprary hack to allow wearables with definition version 24 to still load.
+ // This should only affect lindens and NDA'd testers who have saved wearables in 2.0
+ // the extra check for version == 24 can be removed before release, once internal testers
+ // have loaded these wearables again. See hack pt 2 at bottom of function to ensure that
+ // these wearables get re-saved with version definition 22.
+ if( mDefinitionVersion > LLWearable::sCurrentDefinitionVersion && mDefinitionVersion != 24 )
{
llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
return FALSE;
@@ -414,6 +420,18 @@ BOOL LLWearable::importFile( LLFILE* file )
// copy all saved param values to working params
revertValues();
+ // Hack pt 2. If the wearable we just loaded has definition version 24,
+ // then force a re-save of this wearable after slamming the version number to 22.
+ // This number was incorrectly incremented for internal builds before release, and
+ // this fix will ensure that the affected wearables are re-saved with the right version number.
+ // the versions themselves are compatible. This code can be removed before release.
+ if( mDefinitionVersion == 24 )
+ {
+ mDefinitionVersion = 22;
+ U32 index = gAgentWearables.getWearableIndex(this);
+ gAgentWearables.saveWearable(mType,index,TRUE);
+ }
+
return TRUE;
}
diff --git a/indra/newview/skins/default/html/da/loading/loading.html b/indra/newview/skins/default/html/da/loading/loading.html
index 5f3426eb60..cdad5702b9 100644
--- a/indra/newview/skins/default/html/da/loading/loading.html
+++ b/indra/newview/skins/default/html/da/loading/loading.html
@@ -1,10 +1,10 @@
-<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
-<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
-<table width="100%" height="100%" border="0">
- <tr>
- <td align="center" valign="middle" style="font-size:0.8em;">
- <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Indlæser...
- </td>
- </tr>
-</table>
-</body>
+<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Indlæser...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/de/loading/loading.html b/indra/newview/skins/default/html/de/loading/loading.html
index 44a621b216..3eddbc24f5 100644
--- a/indra/newview/skins/default/html/de/loading/loading.html
+++ b/indra/newview/skins/default/html/de/loading/loading.html
@@ -1,10 +1,10 @@
-<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
-<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
-<table width="100%" height="100%" border="0">
- <tr>
- <td align="center" valign="middle" style="font-size:0.8em;">
- <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Wird geladen...
- </td>
- </tr>
-</table>
-</body>
+<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Wird geladen...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/en-us/loading/loading.html b/indra/newview/skins/default/html/en-us/loading/loading.html
index 1c62d2f73e..34e5c84c4d 100644
--- a/indra/newview/skins/default/html/en-us/loading/loading.html
+++ b/indra/newview/skins/default/html/en-us/loading/loading.html
@@ -1,9 +1,9 @@
-<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
-<table width="100%" height="100%" border="0">
- <tr>
- <td align="center" valign="middle" style="font-size:0.8em;">
- <img src="sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;loading...
- </td>
- </tr>
-</table>
-</body>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;loading...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/es/loading/loading.html b/indra/newview/skins/default/html/es/loading/loading.html
index c4260b34c0..f03284ba8c 100644
--- a/indra/newview/skins/default/html/es/loading/loading.html
+++ b/indra/newview/skins/default/html/es/loading/loading.html
@@ -1,10 +1,10 @@
-<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
-<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
-<table width="100%" height="100%" border="0">
- <tr>
- <td align="center" valign="middle" style="font-size:0.8em;">
- <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Cargando...
- </td>
- </tr>
-</table>
-</body>
+<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Cargando...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/fr/loading/loading.html b/indra/newview/skins/default/html/fr/loading/loading.html
index b3953448e9..23c0ef03bc 100644
--- a/indra/newview/skins/default/html/fr/loading/loading.html
+++ b/indra/newview/skins/default/html/fr/loading/loading.html
@@ -1,10 +1,10 @@
-<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
-<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
-<table width="100%" height="100%" border="0">
- <tr>
- <td align="center" valign="middle" style="font-size:0.8em;">
- <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Chargement...
- </td>
- </tr>
-</table>
-</body>
+<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Chargement...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/hu/loading/loading.html b/indra/newview/skins/default/html/hu/loading/loading.html
index ab15a073ba..ade91f76c2 100644
--- a/indra/newview/skins/default/html/hu/loading/loading.html
+++ b/indra/newview/skins/default/html/hu/loading/loading.html
@@ -1,10 +1,10 @@
-<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
-<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
-<table width="100%" height="100%" border="0">
- <tr>
- <td align="center" valign="middle" style="font-size:0.8em;">
- <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Betöltés folyamatban...
- </td>
- </tr>
-</table>
-</body>
+<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Betöltés folyamatban...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/it/loading/loading.html b/indra/newview/skins/default/html/it/loading/loading.html
index ab37e41f04..0f9af31f6e 100644
--- a/indra/newview/skins/default/html/it/loading/loading.html
+++ b/indra/newview/skins/default/html/it/loading/loading.html
@@ -1,10 +1,10 @@
-<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
-<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
-<table width="100%" height="100%" border="0">
- <tr>
- <td align="center" valign="middle" style="font-size:0.8em;">
- <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Attendi...
- </td>
- </tr>
-</table>
-</body>
+<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Attendi...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/ja/loading/loading.html b/indra/newview/skins/default/html/ja/loading/loading.html
index 35cf74a35f..069dc5d12f 100644
--- a/indra/newview/skins/default/html/ja/loading/loading.html
+++ b/indra/newview/skins/default/html/ja/loading/loading.html
@@ -1,10 +1,10 @@
-<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
-<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
-<table width="100%" height="100%" border="0">
- <tr>
- <td align="center" valign="middle" style="font-size:0.8em;">
- <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;ロード中...
- </td>
- </tr>
-</table>
-</body>
+<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;ロード中...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/nl/loading/loading.html b/indra/newview/skins/default/html/nl/loading/loading.html
index 0215bd7e47..39a8691f3f 100644
--- a/indra/newview/skins/default/html/nl/loading/loading.html
+++ b/indra/newview/skins/default/html/nl/loading/loading.html
@@ -1,10 +1,10 @@
-<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
-<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
-<table width="100%" height="100%" border="0">
- <tr>
- <td align="center" valign="middle" style="font-size:0.8em;">
- <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Laden...
- </td>
- </tr>
-</table>
-</body>
+<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Laden...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/pl/loading/loading.html b/indra/newview/skins/default/html/pl/loading/loading.html
index 50f3dfb0c5..515890c2d5 100644
--- a/indra/newview/skins/default/html/pl/loading/loading.html
+++ b/indra/newview/skins/default/html/pl/loading/loading.html
@@ -1,10 +1,10 @@
-<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
-<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
-<table width="100%" height="100%" border="0">
- <tr>
- <td align="center" valign="middle" style="font-size:0.8em;">
- <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Ładowanie...
- </td>
- </tr>
-</table>
-</body>
+<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Ładowanie...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/pt/loading/loading.html b/indra/newview/skins/default/html/pt/loading/loading.html
index a83e1123d0..635ea62406 100644
--- a/indra/newview/skins/default/html/pt/loading/loading.html
+++ b/indra/newview/skins/default/html/pt/loading/loading.html
@@ -1,10 +1,10 @@
-<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
-<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
-<table width="100%" height="100%" border="0">
- <tr>
- <td align="center" valign="middle" style="font-size:0.8em;">
- <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Carregando...
- </td>
- </tr>
-</table>
-</body>
+<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Carregando...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/ru/loading/loading.html b/indra/newview/skins/default/html/ru/loading/loading.html
index 892c0b9f7f..dcc0d73c1a 100644
--- a/indra/newview/skins/default/html/ru/loading/loading.html
+++ b/indra/newview/skins/default/html/ru/loading/loading.html
@@ -1,10 +1,10 @@
-<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
-<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
-<table width="100%" height="100%" border="0">
- <tr>
- <td align="center" valign="middle" style="font-size:0.8em;">
- <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Загрузка...
- </td>
- </tr>
-</table>
-</body>
+<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Загрузка...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/tr/loading/loading.html b/indra/newview/skins/default/html/tr/loading/loading.html
index 1ac07bff34..e7812e7c8e 100644
--- a/indra/newview/skins/default/html/tr/loading/loading.html
+++ b/indra/newview/skins/default/html/tr/loading/loading.html
@@ -1,10 +1,10 @@
-<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
-<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
-<table width="100%" height="100%" border="0">
- <tr>
- <td align="center" valign="middle" style="font-size:0.8em;">
- <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Yükleniyor...
- </td>
- </tr>
-</table>
-</body>
+<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Yükleniyor...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/uk/loading/loading.html b/indra/newview/skins/default/html/uk/loading/loading.html
index 3b5b8679b4..0f67994635 100644
--- a/indra/newview/skins/default/html/uk/loading/loading.html
+++ b/indra/newview/skins/default/html/uk/loading/loading.html
@@ -1,10 +1,10 @@
-<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
-<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
-<table width="100%" height="100%" border="0">
- <tr>
- <td align="center" valign="middle" style="font-size:0.8em;">
- <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Завантаж...
- </td>
- </tr>
-</table>
-</body>
+<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;Завантаж...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/html/zh/loading/loading.html b/indra/newview/skins/default/html/zh/loading/loading.html
index d1d5d25c92..462ea291d9 100644
--- a/indra/newview/skins/default/html/zh/loading/loading.html
+++ b/indra/newview/skins/default/html/zh/loading/loading.html
@@ -1,10 +1,10 @@
-<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
-<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
-<table width="100%" height="100%" border="0">
- <tr>
- <td align="center" valign="middle" style="font-size:0.8em;">
- <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;请等待...
- </td>
- </tr>
-</table>
-</body>
+<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;">
+<table width="100%" height="100%" border="0">
+ <tr>
+ <td align="center" valign="middle" style="font-size:0.8em;">
+ <img src="../../en-us/loading/sl_logo_rotate_black.gif" align="absmiddle"><br/>&nbsp;&nbsp;&nbsp;请等待...
+ </td>
+ </tr>
+</table>
+</body>
diff --git a/indra/newview/skins/default/xui/da/panel_edit_profile.xml b/indra/newview/skins/default/xui/da/panel_edit_profile.xml
index b4d0fa20ef..74b7c7dd72 100644
--- a/indra/newview/skins/default/xui/da/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_profile.xml
@@ -1,45 +1,45 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel name="edit_profile_panel">
- <string name="CaptionTextAcctInfo">
- [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
- </string>
- <string name="AcctTypeResident"
- value="Beboer" />
- <string name="AcctTypeTrial"
- value="På prøve" />
- <string name="AcctTypeCharterMember"
- value="æresmedlem" />
- <string name="AcctTypeEmployee"
- value="Linden Lab medarbejder" />
- <string name="PaymentInfoUsed"
- value="Betalende medlem" />
- <string name="PaymentInfoOnFile"
- value="Registreret betalende" />
- <string name="NoPaymentInfoOnFile"
- value="Ingen betalingsinfo" />
- <string name="AgeVerified"
- value="Alders-checket" />
- <string name="NotAgeVerified"
- value="Ikke alders-checket" />
- <string name="partner_edit_link_url">
- http://www.secondlife.com/account/partners.php?lang=da
- </string>
- <panel name="scroll_content_panel">
- <panel name="data_panel" >
- <panel name="lifes_images_panel">
- <panel name="second_life_image_panel">
- <text name="second_life_photo_title_text">
- [SECOND_LIFE]:
- </text>
- </panel>
- </panel>
- <text name="title_partner_text" value="Partner:"/>
- <panel name="partner_data_panel">
- <text name="partner_text" value="[FIRST] [LAST]"/>
- </panel>
- <text name="text_box3">
- Optaget autosvar:
- </text>
- </panel>
- </panel>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="edit_profile_panel">
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string name="AcctTypeResident"
+ value="Beboer" />
+ <string name="AcctTypeTrial"
+ value="På prøve" />
+ <string name="AcctTypeCharterMember"
+ value="æresmedlem" />
+ <string name="AcctTypeEmployee"
+ value="Linden Lab medarbejder" />
+ <string name="PaymentInfoUsed"
+ value="Betalende medlem" />
+ <string name="PaymentInfoOnFile"
+ value="Registreret betalende" />
+ <string name="NoPaymentInfoOnFile"
+ value="Ingen betalingsinfo" />
+ <string name="AgeVerified"
+ value="Alders-checket" />
+ <string name="NotAgeVerified"
+ value="Ikke alders-checket" />
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=da
+ </string>
+ <panel name="scroll_content_panel">
+ <panel name="data_panel" >
+ <panel name="lifes_images_panel">
+ <panel name="second_life_image_panel">
+ <text name="second_life_photo_title_text">
+ [SECOND_LIFE]:
+ </text>
+ </panel>
+ </panel>
+ <text name="title_partner_text" value="Partner:"/>
+ <panel name="partner_data_panel">
+ <text name="partner_text" value="[FIRST] [LAST]"/>
+ </panel>
+ <text name="text_box3">
+ Optaget autosvar:
+ </text>
+ </panel>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml
index f05684db10..4b91dc6294 100644
--- a/indra/newview/skins/default/xui/en/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml
@@ -63,7 +63,7 @@
left="0"
mouse_opaque="true"
name="my_inventory_list"
- start_folder="INVENTORY"
+ start_folder="My Inventory"
width="380"/>
</accordion_tab>
<accordion_tab
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
new file mode 100644
index 0000000000..f511ec0d6f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="Outfits"
+ bottom="0"
+ height="326"
+ left="0"
+ width="310"
+ border="true"
+ follows="left|top|right|bottom">
+ <inventory_panel
+ allow_multi_select="true"
+ border="true"
+ bottom="0"
+ follows="left|top|right|bottom"
+ height="326"
+ left="0"
+ mouse_opaque="true"
+ name="outfits_list"
+ width="310"
+ start_folder="My Outfits"/>
+ <button bottom="0"
+ halign="center"
+ height="16"
+ label=">"
+ enabled="false"
+ mouse_opaque="false"
+ name="selector"
+ width="20"
+ left="0"
+ visible="false"
+ follows="right|bottom"
+ tool_tip="View outfit properties"/>
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ bottom="0"
+ follows="left|right|bottom"
+ height="30"
+ layout="bottomleft"
+ left="0"
+ visible="true"
+ name="bottom_panel"
+ width="310">
+ <button
+ follows="bottom|left"
+ tool_tip="Show additional options"
+ height="18"
+ image_disabled="OptionsMenu_Disabled"
+ image_selected="OptionsMenu_Press"
+ image_unselected="OptionsMenu_Off"
+ layout="topleft"
+ left="10"
+ name="options_gear_btn"
+ picture_style="true"
+ top="6"
+ width="18" />
+ <button
+ follows="bottom|left"
+ height="18"
+ image_selected="AddItem_Press"
+ image_unselected="AddItem_Off"
+ image_disabled="AddItem_Disabled"
+ layout="topleft"
+ left_pad="5"
+ name="add_btn"
+ picture_style="true"
+ tool_tip="Add new item"
+ width="18" />
+ <dnd_button
+ follows="bottom|right"
+ height="18"
+ image_selected="TrashItem_Press"
+ image_unselected="TrashItem_Off"
+ layout="topleft"
+ right="-5"
+ name="trash_btn"
+ picture_style="true"
+ tool_tip="Remove selected item"
+ top="6"
+ width="18" />
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory_gear_default.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory_gear_default.xml
new file mode 100644
index 0000000000..c8c79f8761
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory_gear_default.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ bottom="806"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="menu_gear_default"
+ visible="false">
+ <menu_item_call
+ label="New Outfit"
+ layout="topleft"
+ name="new">
+ <on_click
+ function="panel_outfits_inventory_gear_default.Custom.Action"
+ parameter="new" />
+ <on_enable
+ function="panel_outfits_inventory_gear_default.Enable"
+ parameter="new" />
+ </menu_item_call>
+ <menu_item_call
+ label="Wear Outfit"
+ layout="topleft"
+ name="wear">
+ <on_click
+ function="panel_outfits_inventory_gear_default.Custom.Action"
+ parameter="wear" />
+ <on_enable
+ function="panel_outfits_inventory_gear_default.Enable"
+ parameter="wear" />
+ </menu_item_call>
+ <menu_item_call
+ label="Delete Outfit"
+ layout="topleft"
+ name="delete">
+ <on_click
+ function="panel_outfits_inventory_gear_default.Custom.Action"
+ parameter="delete" />
+ <on_enable
+ function="panel_outfits_inventory_gear_default.Enable"
+ parameter="delete" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml
index a419a02d75..d02354a647 100644
--- a/indra/newview/skins/default/xui/en/panel_side_tray.xml
+++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml
@@ -120,9 +120,9 @@
background_visible="true"
>
<panel
- class="panel_appearance"
- name="panel_appearance"
- filename="panel_appearance.xml"
+ class="sidepanel_appearance"
+ name="sidepanel_appearance"
+ filename="sidepanel_appearance.xml"
label="Edit Appearance"
font="SansSerifBold"
/>
diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
new file mode 100644
index 0000000000..2ce156cfda
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ follows="all"
+ height="400"
+ label="Appearance"
+ layout="topleft"
+ min_height="350"
+ min_width="240"
+ name="appearance panel"
+ width="333">
+ <string
+ name="looks_tab_title"
+ value="Outfits" />
+ <panel
+ left="5" width="320" height="55"
+ background_visible="true"
+ background_opaque="false"
+ bg_alpha_color="0.2 0.2 0.2 1.0"
+ name="panel_currentlook"
+ follows="left|top|right">
+ <text
+ top="-5" width="200" left="5" height="10" follows="left|right|top"
+ font="SansSerif" text_color="LtGray" word_wrap="true"
+ mouse_opaque="false" name="currentlook_title">
+ Current Outfit
+ </text>
+ <text
+ top="-30" left="8" height="10" follows="left|right|top"
+ font="SansSerifBold" text_color="white" word_wrap="true"
+ mouse_opaque="false" name="currentlook_name" >
+ MyOutfit
+ </text>
+ <button
+ follows="left|right|top"
+ font="SansSerif"
+ top="28" right="-105" width="60" height="20"
+ layout="topleft"
+ label="Edit"
+ name="editappearance_btn"/>
+ </panel>
+
+ <filter_editor
+ follows="left|top|right"
+ font="SansSerif"
+ label="Filter"
+ layout="topleft"
+ left="15"
+ width="313"
+ height="20"
+ name="Filter" />
+ <panel
+ class="panel_outfits_inventory"
+ filename="panel_outfits_inventory.xml"
+ name="panel_outfits_inventory"
+ follows="all"
+ height="271"
+ halign="center"
+ layout="topleft"
+ left="10"
+ top_pad="19"
+ width="313" />
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Wear"
+ layout="topleft"
+ left="10"
+ name="wear_btn"
+ top_pad="0"
+ width="80" />
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="New Outfit"
+ layout="topleft"
+ left_pad="0"
+ name="newlook_btn"
+ top_delta="0"
+ width="90" />
+
+ <panel
+ class="panel_look_info"
+ filename="panel_look_info.xml"
+ follows="all"
+ layout="topleft"
+ left="0"
+ name="panel_look_info"
+ top="-200"
+ visible="false" />
+
+ <panel
+ class="panel_edit_wearable"
+ filename="panel_edit_wearable.xml"
+ follows="all"
+ layout="topleft"
+ left="0"
+ name="panel_edit_wearable"
+ top="-200"
+ visible="false"
+ width="333" />
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_edit_profile.xml b/indra/newview/skins/default/xui/es/panel_edit_profile.xml
index c12dd8d58c..bcf4128e01 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_profile.xml
@@ -1,45 +1,45 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel name="edit_profile_panel">
- <string name="CaptionTextAcctInfo">
- [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
- </string>
- <string name="AcctTypeResident"
- value="Residente" />
- <string name="AcctTypeTrial"
- value="Prueba" />
- <string name="AcctTypeCharterMember"
- value="Miembro fundador" />
- <string name="AcctTypeEmployee"
- value="Empleado de Linden Lab" />
- <string name="PaymentInfoUsed"
- value="Ha usado una forma de pago" />
- <string name="PaymentInfoOnFile"
- value="Hay infor. de la forma de pago" />
- <string name="NoPaymentInfoOnFile"
- value="Sin infor. de la forma de pago" />
- <string name="AgeVerified"
- value="Edad verificada" />
- <string name="NotAgeVerified"
- value="Edad no verificada" />
- <string name="partner_edit_link_url">
- http://www.secondlife.com/account/partners.php?lang=es
- </string>
- <panel name="scroll_content_panel">
- <panel name="data_panel" >
- <panel name="lifes_images_panel">
- <panel name="second_life_image_panel">
- <text name="second_life_photo_title_text">
- [SECOND_LIFE]:
- </text>
- </panel>
- </panel>
- <text name="title_partner_text" value="Compañero/a:"/>
- <panel name="partner_data_panel">
- <text name="partner_text" value="[FIRST] [LAST]"/>
- </panel>
- <text name="text_box3">
- Mensaje en el estado ocupado:
- </text>
- </panel>
- </panel>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="edit_profile_panel">
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string name="AcctTypeResident"
+ value="Residente" />
+ <string name="AcctTypeTrial"
+ value="Prueba" />
+ <string name="AcctTypeCharterMember"
+ value="Miembro fundador" />
+ <string name="AcctTypeEmployee"
+ value="Empleado de Linden Lab" />
+ <string name="PaymentInfoUsed"
+ value="Ha usado una forma de pago" />
+ <string name="PaymentInfoOnFile"
+ value="Hay infor. de la forma de pago" />
+ <string name="NoPaymentInfoOnFile"
+ value="Sin infor. de la forma de pago" />
+ <string name="AgeVerified"
+ value="Edad verificada" />
+ <string name="NotAgeVerified"
+ value="Edad no verificada" />
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=es
+ </string>
+ <panel name="scroll_content_panel">
+ <panel name="data_panel" >
+ <panel name="lifes_images_panel">
+ <panel name="second_life_image_panel">
+ <text name="second_life_photo_title_text">
+ [SECOND_LIFE]:
+ </text>
+ </panel>
+ </panel>
+ <text name="title_partner_text" value="Compañero/a:"/>
+ <panel name="partner_data_panel">
+ <text name="partner_text" value="[FIRST] [LAST]"/>
+ </panel>
+ <text name="text_box3">
+ Mensaje en el estado ocupado:
+ </text>
+ </panel>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_edit_profile.xml b/indra/newview/skins/default/xui/it/panel_edit_profile.xml
index 33f3c367c2..0eba7bf3b6 100644
--- a/indra/newview/skins/default/xui/it/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_profile.xml
@@ -1,45 +1,45 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel name="edit_profile_panel">
- <string name="CaptionTextAcctInfo">
- [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
- </string>
- <string name="AcctTypeResident"
- value="Residente" />
- <string name="AcctTypeTrial"
- value="Prova" />
- <string name="AcctTypeCharterMember"
- value="Membro privilegiato" />
- <string name="AcctTypeEmployee"
- value="Impiegato della Linden Lab" />
- <string name="PaymentInfoUsed"
- value="Info. di pagamento usate" />
- <string name="PaymentInfoOnFile"
- value="Info. di pagamento in archivio" />
- <string name="NoPaymentInfoOnFile"
- value="Nessuna info. di pagamento" />
- <string name="AgeVerified"
- value="Età verificata" />
- <string name="NotAgeVerified"
- value="Età non verificata" />
- <string name="partner_edit_link_url">
- http://www.secondlife.com/account/partners.php?lang=it
- </string>
- <panel name="scroll_content_panel">
- <panel name="data_panel" >
- <panel name="lifes_images_panel">
- <panel name="second_life_image_panel">
- <text name="second_life_photo_title_text">
- [SECOND_LIFE]:
- </text>
- </panel>
- </panel>
- <text name="title_partner_text" value="Partner:"/>
- <panel name="partner_data_panel">
- <text name="partner_text" value="[FIRST] [LAST]"/>
- </panel>
- <text name="text_box3">
- Risposta agli IM quando sono in &apos;Occupato&apos;:
- </text>
- </panel>
- </panel>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="edit_profile_panel">
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string name="AcctTypeResident"
+ value="Residente" />
+ <string name="AcctTypeTrial"
+ value="Prova" />
+ <string name="AcctTypeCharterMember"
+ value="Membro privilegiato" />
+ <string name="AcctTypeEmployee"
+ value="Impiegato della Linden Lab" />
+ <string name="PaymentInfoUsed"
+ value="Info. di pagamento usate" />
+ <string name="PaymentInfoOnFile"
+ value="Info. di pagamento in archivio" />
+ <string name="NoPaymentInfoOnFile"
+ value="Nessuna info. di pagamento" />
+ <string name="AgeVerified"
+ value="Età verificata" />
+ <string name="NotAgeVerified"
+ value="Età non verificata" />
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=it
+ </string>
+ <panel name="scroll_content_panel">
+ <panel name="data_panel" >
+ <panel name="lifes_images_panel">
+ <panel name="second_life_image_panel">
+ <text name="second_life_photo_title_text">
+ [SECOND_LIFE]:
+ </text>
+ </panel>
+ </panel>
+ <text name="title_partner_text" value="Partner:"/>
+ <panel name="partner_data_panel">
+ <text name="partner_text" value="[FIRST] [LAST]"/>
+ </panel>
+ <text name="text_box3">
+ Risposta agli IM quando sono in &apos;Occupato&apos;:
+ </text>
+ </panel>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/nl/panel_edit_profile.xml b/indra/newview/skins/default/xui/nl/panel_edit_profile.xml
index 172395e20a..00f8c087de 100644
--- a/indra/newview/skins/default/xui/nl/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/nl/panel_edit_profile.xml
@@ -1,45 +1,45 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel name="edit_profile_panel">
- <string name="CaptionTextAcctInfo">
- [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
- </string>
- <string name="AcctTypeResident"
- value="Inwoner" />
- <string name="AcctTypeTrial"
- value="Proef" />
- <string name="AcctTypeCharterMember"
- value="Charter lid" />
- <string name="AcctTypeEmployee"
- value="Linden Lab werknemer" />
- <string name="PaymentInfoUsed"
- value="Betalingsinformatie gebruikt" />
- <string name="PaymentInfoOnFile"
- value="Betalingsinformatie aanwezig" />
- <string name="NoPaymentInfoOnFile"
- value="Geen betalingsinfo aanwezig" />
- <string name="AgeVerified"
- value="Leeftijd geverifieerd" />
- <string name="NotAgeVerified"
- value="Leeftijd niet geverifieerd" />
- <string name="partner_edit_link_url">
- http://www.secondlife.com/account/partners.php?lang=nl
- </string>
- <panel name="scroll_content_panel">
- <panel name="data_panel" >
- <panel name="lifes_images_panel">
- <panel name="second_life_image_panel">
- <text name="second_life_photo_title_text">
- [SECOND_LIFE]:
- </text>
- </panel>
- </panel>
- <text name="title_partner_text" value="Partner:"/>
- <panel name="partner_data_panel">
- <text name="partner_text" value="[FIRST] [LAST]"/>
- </panel>
- <text name="text_box3">
- Antwoord bij Niet Storen:
- </text>
- </panel>
- </panel>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="edit_profile_panel">
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string name="AcctTypeResident"
+ value="Inwoner" />
+ <string name="AcctTypeTrial"
+ value="Proef" />
+ <string name="AcctTypeCharterMember"
+ value="Charter lid" />
+ <string name="AcctTypeEmployee"
+ value="Linden Lab werknemer" />
+ <string name="PaymentInfoUsed"
+ value="Betalingsinformatie gebruikt" />
+ <string name="PaymentInfoOnFile"
+ value="Betalingsinformatie aanwezig" />
+ <string name="NoPaymentInfoOnFile"
+ value="Geen betalingsinfo aanwezig" />
+ <string name="AgeVerified"
+ value="Leeftijd geverifieerd" />
+ <string name="NotAgeVerified"
+ value="Leeftijd niet geverifieerd" />
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=nl
+ </string>
+ <panel name="scroll_content_panel">
+ <panel name="data_panel" >
+ <panel name="lifes_images_panel">
+ <panel name="second_life_image_panel">
+ <text name="second_life_photo_title_text">
+ [SECOND_LIFE]:
+ </text>
+ </panel>
+ </panel>
+ <text name="title_partner_text" value="Partner:"/>
+ <panel name="partner_data_panel">
+ <text name="partner_text" value="[FIRST] [LAST]"/>
+ </panel>
+ <text name="text_box3">
+ Antwoord bij Niet Storen:
+ </text>
+ </panel>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_profile.xml b/indra/newview/skins/default/xui/pl/panel_edit_profile.xml
index 97fa3118f8..e449a92d7e 100644
--- a/indra/newview/skins/default/xui/pl/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_profile.xml
@@ -1,45 +1,45 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel name="edit_profile_panel">
- <string name="CaptionTextAcctInfo">
- [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
- </string>
- <string name="AcctTypeResident"
- value="Rezydent" />
- <string name="AcctTypeTrial"
- value="Próbne" />
- <string name="AcctTypeCharterMember"
- value="Członek-zalożyciel" />
- <string name="AcctTypeEmployee"
- value="Pracownik Linden Lab" />
- <string name="PaymentInfoUsed"
- value="Dane Konta Używane" />
- <string name="PaymentInfoOnFile"
- value="Dane Konta Dostępne" />
- <string name="NoPaymentInfoOnFile"
- value="Brak Danych Konta" />
- <string name="AgeVerified"
- value="Wiek Zweryfikowany" />
- <string name="NotAgeVerified"
- value="Brak Weryfikacji Wieku" />
- <string name="partner_edit_link_url">
- http://www.secondlife.com/account/partners.php?lang=pl
- </string>
- <panel name="scroll_content_panel">
- <panel name="data_panel" >
- <panel name="lifes_images_panel">
- <panel name="second_life_image_panel">
- <text name="second_life_photo_title_text">
- [SECOND_LIFE]:
- </text>
- </panel>
- </panel>
- <text name="title_partner_text" value="Partner:"/>
- <panel name="partner_data_panel">
- <text name="partner_text" value="[FIRST] [LAST]"/>
- </panel>
- <text name="text_box3">
- Pracuś Mówi:
- </text>
- </panel>
- </panel>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="edit_profile_panel">
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string name="AcctTypeResident"
+ value="Rezydent" />
+ <string name="AcctTypeTrial"
+ value="Próbne" />
+ <string name="AcctTypeCharterMember"
+ value="Członek-zalożyciel" />
+ <string name="AcctTypeEmployee"
+ value="Pracownik Linden Lab" />
+ <string name="PaymentInfoUsed"
+ value="Dane Konta Używane" />
+ <string name="PaymentInfoOnFile"
+ value="Dane Konta Dostępne" />
+ <string name="NoPaymentInfoOnFile"
+ value="Brak Danych Konta" />
+ <string name="AgeVerified"
+ value="Wiek Zweryfikowany" />
+ <string name="NotAgeVerified"
+ value="Brak Weryfikacji Wieku" />
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=pl
+ </string>
+ <panel name="scroll_content_panel">
+ <panel name="data_panel" >
+ <panel name="lifes_images_panel">
+ <panel name="second_life_image_panel">
+ <text name="second_life_photo_title_text">
+ [SECOND_LIFE]:
+ </text>
+ </panel>
+ </panel>
+ <text name="title_partner_text" value="Partner:"/>
+ <panel name="partner_data_panel">
+ <text name="partner_text" value="[FIRST] [LAST]"/>
+ </panel>
+ <text name="text_box3">
+ Pracuś Mówi:
+ </text>
+ </panel>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_profile.xml b/indra/newview/skins/default/xui/pt/panel_edit_profile.xml
index a989cab167..e97e77cfe6 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_profile.xml
@@ -1,45 +1,45 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel name="edit_profile_panel">
- <string name="CaptionTextAcctInfo">
- [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
- </string>
- <string name="AcctTypeResident"
- value="Residente" />
- <string name="AcctTypeTrial"
- value="Teste" />
- <string name="AcctTypeCharterMember"
- value="Estatuto do membro" />
- <string name="AcctTypeEmployee"
- value="Contratado da Linden Lab" />
- <string name="PaymentInfoUsed"
- value="Infor. de pagamento utilizadas" />
- <string name="PaymentInfoOnFile"
- value="Infor. de pagamento no arquivo" />
- <string name="NoPaymentInfoOnFile"
- value="Sem infor. de pagamento no arquivo" />
- <string name="AgeVerified"
- value="Idade Verificada" />
- <string name="NotAgeVerified"
- value="Idade não Verificada" />
- <string name="partner_edit_link_url">
- http://www.secondlife.com/account/partners.php?lang=pt
- </string>
- <panel name="scroll_content_panel">
- <panel name="data_panel" >
- <panel name="lifes_images_panel">
- <panel name="second_life_image_panel">
- <text name="second_life_photo_title_text">
- [SECOND_LIFE]:
- </text>
- </panel>
- </panel>
- <text name="title_partner_text" value="Parceiro:"/>
- <panel name="partner_data_panel">
- <text name="partner_text" value="[FIRST] [LAST]"/>
- </panel>
- <text name="text_box3">
- Resposta no Modo Ocupado:
- </text>
- </panel>
- </panel>
-</panel>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="edit_profile_panel">
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string name="AcctTypeResident"
+ value="Residente" />
+ <string name="AcctTypeTrial"
+ value="Teste" />
+ <string name="AcctTypeCharterMember"
+ value="Estatuto do membro" />
+ <string name="AcctTypeEmployee"
+ value="Contratado da Linden Lab" />
+ <string name="PaymentInfoUsed"
+ value="Infor. de pagamento utilizadas" />
+ <string name="PaymentInfoOnFile"
+ value="Infor. de pagamento no arquivo" />
+ <string name="NoPaymentInfoOnFile"
+ value="Sem infor. de pagamento no arquivo" />
+ <string name="AgeVerified"
+ value="Idade Verificada" />
+ <string name="NotAgeVerified"
+ value="Idade não Verificada" />
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=pt
+ </string>
+ <panel name="scroll_content_panel">
+ <panel name="data_panel" >
+ <panel name="lifes_images_panel">
+ <panel name="second_life_image_panel">
+ <text name="second_life_photo_title_text">
+ [SECOND_LIFE]:
+ </text>
+ </panel>
+ </panel>
+ <text name="title_partner_text" value="Parceiro:"/>
+ <panel name="partner_data_panel">
+ <text name="partner_text" value="[FIRST] [LAST]"/>
+ </panel>
+ <text name="text_box3">
+ Resposta no Modo Ocupado:
+ </text>
+ </panel>
+ </panel>
+</panel>
diff --git a/indra/tools/vstool/README.txt b/indra/tools/vstool/README.txt
index 6f64aa41df..e419180031 100644
--- a/indra/tools/vstool/README.txt
+++ b/indra/tools/vstool/README.txt
@@ -1,9 +1,9 @@
-VSTool is a command line utility to manipulate VisualStudio settings.
-
-The windows cmake project configuration uses VSTool.exe
-
-A handy upgrade:
- figure out how to make cmake build this csharp app
- - or write the app using script (jscript?!?) so it doesn't need to be built.
-
-
+VSTool is a command line utility to manipulate VisualStudio settings.
+
+The windows cmake project configuration uses VSTool.exe
+
+A handy upgrade:
+ figure out how to make cmake build this csharp app
+ - or write the app using script (jscript?!?) so it doesn't need to be built.
+
+
diff --git a/indra/tools/vstool/VSTool.csproj b/indra/tools/vstool/VSTool.csproj
index 5d8764b6bf..24f1031f81 100644
--- a/indra/tools/vstool/VSTool.csproj
+++ b/indra/tools/vstool/VSTool.csproj
@@ -1,95 +1,95 @@
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <ProjectType>Local</ProjectType>
- <ProductVersion>8.0.50727</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{96943E2D-1373-4617-A117-D0F997A94919}</ProjectGuid>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ApplicationIcon>
- </ApplicationIcon>
- <AssemblyKeyContainerName>
- </AssemblyKeyContainerName>
- <AssemblyName>VSTool</AssemblyName>
- <AssemblyOriginatorKeyFile>
- </AssemblyOriginatorKeyFile>
- <DefaultClientScript>JScript</DefaultClientScript>
- <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
- <DefaultTargetSchema>IE50</DefaultTargetSchema>
- <DelaySign>false</DelaySign>
- <OutputType>Exe</OutputType>
- <RootNamespace>VSTool</RootNamespace>
- <RunPostBuildEvent>Always</RunPostBuildEvent>
- <StartupObject>VSTool.VSToolMain</StartupObject>
- <FileUpgradeFlags>
- </FileUpgradeFlags>
- <UpgradeBackupLocation>
- </UpgradeBackupLocation>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <OutputPath>.\</OutputPath>
- <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
- <BaseAddress>285212672</BaseAddress>
- <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
- <ConfigurationOverrideFile>
- </ConfigurationOverrideFile>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <DocumentationFile>
- </DocumentationFile>
- <DebugSymbols>true</DebugSymbols>
- <FileAlignment>4096</FileAlignment>
- <NoStdLib>false</NoStdLib>
- <NoWarn>
- </NoWarn>
- <Optimize>false</Optimize>
- <RegisterForComInterop>false</RegisterForComInterop>
- <RemoveIntegerChecks>false</RemoveIntegerChecks>
- <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
- <WarningLevel>4</WarningLevel>
- <DebugType>full</DebugType>
- <ErrorReport>prompt</ErrorReport>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <OutputPath>.\</OutputPath>
- <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
- <BaseAddress>285212672</BaseAddress>
- <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
- <ConfigurationOverrideFile>
- </ConfigurationOverrideFile>
- <DefineConstants>TRACE</DefineConstants>
- <DocumentationFile>
- </DocumentationFile>
- <DebugSymbols>false</DebugSymbols>
- <FileAlignment>4096</FileAlignment>
- <NoStdLib>false</NoStdLib>
- <NoWarn>
- </NoWarn>
- <Optimize>true</Optimize>
- <RegisterForComInterop>false</RegisterForComInterop>
- <RemoveIntegerChecks>false</RemoveIntegerChecks>
- <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
- <WarningLevel>4</WarningLevel>
- <DebugType>none</DebugType>
- <ErrorReport>prompt</ErrorReport>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System">
- <Name>System</Name>
- </Reference>
- <Reference Include="System.Data">
- <Name>System.Data</Name>
- </Reference>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="main.cs">
- <SubType>Code</SubType>
- </Compile>
- </ItemGroup>
- <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
- <PropertyGroup>
- <PreBuildEvent>
- </PreBuildEvent>
- <PostBuildEvent>
- </PostBuildEvent>
- </PropertyGroup>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectType>Local</ProjectType>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{96943E2D-1373-4617-A117-D0F997A94919}</ProjectGuid>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ApplicationIcon>
+ </ApplicationIcon>
+ <AssemblyKeyContainerName>
+ </AssemblyKeyContainerName>
+ <AssemblyName>VSTool</AssemblyName>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <DefaultClientScript>JScript</DefaultClientScript>
+ <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+ <DefaultTargetSchema>IE50</DefaultTargetSchema>
+ <DelaySign>false</DelaySign>
+ <OutputType>Exe</OutputType>
+ <RootNamespace>VSTool</RootNamespace>
+ <RunPostBuildEvent>Always</RunPostBuildEvent>
+ <StartupObject>VSTool.VSToolMain</StartupObject>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <OutputPath>.\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DocumentationFile>
+ </DocumentationFile>
+ <DebugSymbols>true</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>
+ </NoWarn>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>4</WarningLevel>
+ <DebugType>full</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <OutputPath>.\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <ConfigurationOverrideFile>
+ </ConfigurationOverrideFile>
+ <DefineConstants>TRACE</DefineConstants>
+ <DocumentationFile>
+ </DocumentationFile>
+ <DebugSymbols>false</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <NoWarn>
+ </NoWarn>
+ <Optimize>true</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>4</WarningLevel>
+ <DebugType>none</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System">
+ <Name>System</Name>
+ </Reference>
+ <Reference Include="System.Data">
+ <Name>System.Data</Name>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="main.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>
+ </PreBuildEvent>
+ <PostBuildEvent>
+ </PostBuildEvent>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/indra/tools/vstool/VSTool.sln b/indra/tools/vstool/VSTool.sln
index 543a0a2efc..8859671802 100644
--- a/indra/tools/vstool/VSTool.sln
+++ b/indra/tools/vstool/VSTool.sln
@@ -1,19 +1,19 @@
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSTool", "VSTool.csproj", "{96943E2D-1373-4617-A117-D0F997A94919}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSTool", "VSTool.csproj", "{96943E2D-1373-4617-A117-D0F997A94919}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/indra/tools/vstool/main.cs b/indra/tools/vstool/main.cs
index 5c41c916e2..cc268d59d9 100644
--- a/indra/tools/vstool/main.cs
+++ b/indra/tools/vstool/main.cs
@@ -1,711 +1,711 @@
-// Code about getting running instances visual studio
-// was borrowed from
-// http://www.codeproject.com/KB/cs/automatingvisualstudio.aspx
-
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Runtime.InteropServices.ComTypes;
-using Microsoft.CSharp;
-
-namespace VSTool
-{
- // The MessageFilter class comes from:
- // http://msdn.microsoft.com/en-us/library/ms228772(VS.80).aspx
- // It allows vstool to get timing error messages from
- // visualstudio and handle them.
- public class MessageFilter : IOleMessageFilter
- {
- //
- // Class containing the IOleMessageFilter
- // thread error-handling functions.
-
- // Start the filter.
- public static void Register()
- {
- IOleMessageFilter newFilter = new MessageFilter();
- IOleMessageFilter oldFilter = null;
- CoRegisterMessageFilter(newFilter, out oldFilter);
- }
-
- // Done with the filter, close it.
- public static void Revoke()
- {
- IOleMessageFilter oldFilter = null;
- CoRegisterMessageFilter(null, out oldFilter);
- }
-
- //
- // IOleMessageFilter functions.
- // Handle incoming thread requests.
- int IOleMessageFilter.HandleInComingCall(int dwCallType,
- System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr
- lpInterfaceInfo)
- {
- //Return the flag SERVERCALL_ISHANDLED.
- return 0;
- }
-
- // Thread call was rejected, so try again.
- int IOleMessageFilter.RetryRejectedCall(System.IntPtr
- hTaskCallee, int dwTickCount, int dwRejectType)
- {
- if (dwRejectType == 2)
- // flag = SERVERCALL_RETRYLATER.
- {
- // Retry the thread call immediately if return >=0 &
- // <100.
- return 99;
- }
- // Too busy; cancel call.
- return -1;
- }
-
- int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee,
- int dwTickCount, int dwPendingType)
- {
- //Return the flag PENDINGMSG_WAITDEFPROCESS.
- return 2;
- }
-
- // Implement the IOleMessageFilter interface.
- [DllImport("Ole32.dll")]
- private static extern int
- CoRegisterMessageFilter(IOleMessageFilter newFilter, out
- IOleMessageFilter oldFilter);
- }
-
- [ComImport(), Guid("00000016-0000-0000-C000-000000000046"),
- InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
- interface IOleMessageFilter
- {
- [PreserveSig]
- int HandleInComingCall(
- int dwCallType,
- IntPtr hTaskCaller,
- int dwTickCount,
- IntPtr lpInterfaceInfo);
-
- [PreserveSig]
- int RetryRejectedCall(
- IntPtr hTaskCallee,
- int dwTickCount,
- int dwRejectType);
-
- [PreserveSig]
- int MessagePending(
- IntPtr hTaskCallee,
- int dwTickCount,
- int dwPendingType);
- }
-
- class ViaCOM
- {
- public static object GetProperty(object from_obj, string prop_name)
- {
- try
- {
- Type objType = from_obj.GetType();
- return objType.InvokeMember(
- prop_name,
- BindingFlags.GetProperty, null,
- from_obj,
- null);
- }
- catch (Exception e)
- {
- Console.WriteLine("Error getting property: \"{0}\"", prop_name);
- Console.WriteLine(e.Message);
- throw e;
- }
- }
-
- public static object SetProperty(object from_obj, string prop_name, object new_value)
- {
- try
- {
- object[] args = { new_value };
- Type objType = from_obj.GetType();
- return objType.InvokeMember(
- prop_name,
- BindingFlags.DeclaredOnly |
- BindingFlags.Public |
- BindingFlags.NonPublic |
- BindingFlags.Instance |
- BindingFlags.SetProperty,
- null,
- from_obj,
- args);
- }
- catch (Exception e)
- {
- Console.WriteLine("Error setting property: \"{0}\"", prop_name);
- Console.WriteLine(e.Message);
- throw e;
- }
- }
-
- public static object CallMethod(object from_obj, string method_name, params object[] args)
- {
- try
- {
- Type objType = from_obj.GetType();
- return objType.InvokeMember(
- method_name,
- BindingFlags.DeclaredOnly |
- BindingFlags.Public |
- BindingFlags.NonPublic |
- BindingFlags.Instance |
- BindingFlags.InvokeMethod,
- null,
- from_obj,
- args);
- }
- catch (Exception e)
- {
- Console.WriteLine("Error calling method \"{0}\"", method_name);
- Console.WriteLine(e.Message);
- throw e;
- }
- }
- };
-
- /// <summary>
- /// The main entry point class for VSTool.
- /// </summary>
- class VSToolMain
- {
- #region Interop imports
- [DllImport("ole32.dll")]
- public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);
-
- [DllImport("ole32.dll")]
- public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc);
- #endregion
-
- static System.Boolean ignore_case = true;
-
- static string solution_name = null;
- static bool use_new_vs = false;
- static Hashtable projectDict = new Hashtable();
- static string startup_project = null;
- static string config = null;
-
- static object dte = null;
- static object solution = null;
-
- /// <summary>
- /// The main entry point for the application.
- /// </summary>
- [STAThread]
- static int Main(string[] args)
- {
- int retVal = 0;
- bool need_save = false;
-
- try
- {
- parse_command_line(args);
-
- Console.WriteLine("Editing solution: {0}", solution_name);
-
- bool found_open_solution = GetDTEAndSolution();
-
- if (dte == null || solution == null)
- {
- retVal = 1;
- }
- else
- {
- MessageFilter.Register();
-
- // Walk through all of the projects in the solution
- // and list the type of each project.
- foreach (DictionaryEntry p in projectDict)
- {
- string project_name = (string)p.Key;
- string working_dir = (string)p.Value;
- if (SetProjectWorkingDir(solution, project_name, working_dir))
- {
- need_save = true;
- }
- }
-
- if (config != null)
- {
- need_save = SetActiveConfig(config);
- }
-
- if (startup_project != null)
- {
- need_save = SetStartupProject(startup_project);
- }
-
- if (need_save)
- {
- if (found_open_solution == false)
- {
- ViaCOM.CallMethod(solution, "Close", null);
- }
- }
- }
- }
- catch (Exception e)
- {
- Console.WriteLine(e.Message);
- retVal = 1;
- }
- finally
- {
- if (solution != null)
- {
- Marshal.ReleaseComObject(solution);
- solution = null;
- }
-
- if (dte != null)
- {
- Marshal.ReleaseComObject(dte);
- dte = null;
- }
-
- MessageFilter.Revoke();
- }
- return retVal;
- }
-
- public static bool parse_command_line(string[] args)
- {
- string options_desc =
- "--solution <solution_name> : MSVC solution name. (required)\n" +
- "--use_new_vs : Ignore running versions of visual studio.\n" +
- "--workingdir <project> <dir> : Set working dir of a VC project.\n" +
- "--config <config> : Set the active config for the solution.\n" +
- "--startup <project> : Set the startup project for the solution.\n";
-
- try
- {
- // Command line param parsing loop.
- int i = 0;
- for (; i < args.Length; ++i)
- {
- if ("--solution" == args[i])
- {
- if (solution_name != null)
- {
- throw new ApplicationException("Found second --solution option");
- }
- solution_name = args[++i];
- }
- else if ("--use_new_vs" == args[i])
- {
- use_new_vs = true;
- }
-
- else if ("--workingdir" == args[i])
- {
- string project_name = args[++i];
- string working_dir = args[++i];
- projectDict.Add(project_name, working_dir);
- }
- else if ("--config" == args[i])
- {
- if (config != null)
- {
- throw new ApplicationException("Found second --config option");
- }
- config = args[++i];
- }
- else if ("--startup" == args[i])
- {
- if (startup_project != null)
- {
- throw new ApplicationException("Found second --startup option");
- }
- startup_project = args[++i];
- }
- else
- {
- throw new ApplicationException("Found unrecognized token on command line: " + args[i]);
- }
- }
-
- if (solution_name == null)
- {
- throw new ApplicationException("The --solution option is required.");
- }
- }
- catch(ApplicationException e)
- {
-
- Console.WriteLine("Oops! " + e.Message);
- Console.Write("Command line:");
- foreach (string arg in args)
- {
- Console.Write(" " + arg);
- }
- Console.Write("\n\n");
- Console.WriteLine("VSTool command line usage");
- Console.Write(options_desc);
- throw e;
- }
- return true;
- }
-
- public static bool GetDTEAndSolution()
- {
- bool found_open_solution = true;
-
- Console.WriteLine("Looking for existing VisualStudio instance...");
-
- // Get an instance of the currently running Visual Studio .NET IDE.
- // dte = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.7.1");
- string full_solution_name = System.IO.Path.GetFullPath(solution_name);
- if (false == use_new_vs)
- {
- dte = GetIDEInstance(full_solution_name);
- }
-
- if (dte == null)
- {
- try
- {
- Console.WriteLine(" Didn't find open solution, starting new background VisualStudio instance...");
- Console.WriteLine(" Reading .sln file version...");
- string version = GetSolutionVersion(full_solution_name);
-
- Console.WriteLine(" Using version: {0}...", version);
- string progid = GetVSProgID(version);
-
- Type objType = Type.GetTypeFromProgID(progid);
- dte = System.Activator.CreateInstance(objType);
- Console.WriteLine(" Reading solution: \"{0}\"", full_solution_name);
-
- solution = ViaCOM.GetProperty(dte, "Solution");
- object[] openArgs = { full_solution_name };
- ViaCOM.CallMethod(solution, "Open", openArgs);
- }
- catch (Exception e)
- {
- Console.WriteLine(e.Message);
- Console.WriteLine("Quitting do to error opening: {0}", full_solution_name);
- solution = null;
- dte = null;
- return found_open_solution;
- }
- found_open_solution = false;
- }
-
- if (solution == null)
- {
- solution = ViaCOM.GetProperty(dte, "Solution");
- }
-
- return found_open_solution;
- }
-
- /// <summary>
- /// Get the DTE object for the instance of Visual Studio IDE that has
- /// the specified solution open.
- /// </summary>
- /// <param name="solutionFile">The absolute filename of the solution</param>
- /// <returns>Corresponding DTE object or null if no such IDE is running</returns>
- public static object GetIDEInstance( string solutionFile )
- {
- Hashtable runningInstances = GetIDEInstances( true );
- IDictionaryEnumerator enumerator = runningInstances.GetEnumerator();
-
- while ( enumerator.MoveNext() )
- {
- try
- {
- object ide = enumerator.Value;
- if (ide != null)
- {
- object sol = ViaCOM.GetProperty(ide, "Solution");
- if (0 == string.Compare((string)ViaCOM.GetProperty(sol, "FullName"), solutionFile, ignore_case))
- {
- return ide;
- }
- }
- }
- catch{}
- }
-
- return null;
- }
-
- /// <summary>
- /// Get a table of the currently running instances of the Visual Studio .NET IDE.
- /// </summary>
- /// <param name="openSolutionsOnly">Only return instances that have opened a solution</param>
- /// <returns>A hashtable mapping the name of the IDE in the running object table to the corresponding DTE object</returns>
- public static Hashtable GetIDEInstances( bool openSolutionsOnly )
- {
- Hashtable runningIDEInstances = new Hashtable();
- Hashtable runningObjects = GetRunningObjectTable();
-
- IDictionaryEnumerator rotEnumerator = runningObjects.GetEnumerator();
- while ( rotEnumerator.MoveNext() )
- {
- string candidateName = (string) rotEnumerator.Key;
- if (!candidateName.StartsWith("!VisualStudio.DTE"))
- continue;
-
- object ide = rotEnumerator.Value;
- if (ide == null)
- continue;
-
- if (openSolutionsOnly)
- {
- try
- {
- object sol = ViaCOM.GetProperty(ide, "Solution");
- string solutionFile = (string)ViaCOM.GetProperty(sol, "FullName");
- if (solutionFile != String.Empty)
- {
- runningIDEInstances[ candidateName ] = ide;
- }
- }
- catch {}
- }
- else
- {
- runningIDEInstances[ candidateName ] = ide;
- }
- }
- return runningIDEInstances;
- }
-
- /// <summary>
- /// Get a snapshot of the running object table (ROT).
- /// </summary>
- /// <returns>A hashtable mapping the name of the object in the ROT to the corresponding object</returns>
- [STAThread]
- public static Hashtable GetRunningObjectTable()
- {
- Hashtable result = new Hashtable();
-
- int numFetched = 0;
- IRunningObjectTable runningObjectTable;
- IEnumMoniker monikerEnumerator;
- IMoniker[] monikers = new IMoniker[1];
-
- GetRunningObjectTable(0, out runningObjectTable);
- runningObjectTable.EnumRunning(out monikerEnumerator);
- monikerEnumerator.Reset();
-
- while (monikerEnumerator.Next(1, monikers, new IntPtr(numFetched)) == 0)
- {
- IBindCtx ctx;
- CreateBindCtx(0, out ctx);
-
- string runningObjectName;
- monikers[0].GetDisplayName(ctx, null, out runningObjectName);
-
- object runningObjectVal;
- runningObjectTable.GetObject( monikers[0], out runningObjectVal);
-
- result[ runningObjectName ] = runningObjectVal;
- }
-
- return result;
- }
-
- public static string GetSolutionVersion(string solutionFullFileName)
- {
- string version;
- System.IO.StreamReader solutionStreamReader = null;
- string firstLine;
- string format;
-
- try
- {
- solutionStreamReader = new System.IO.StreamReader(solutionFullFileName);
- do
- {
- firstLine = solutionStreamReader.ReadLine();
- }
- while (firstLine == "");
-
- format = firstLine.Substring(firstLine.LastIndexOf(" ")).Trim();
-
- switch(format)
- {
- case "7.00":
- version = "VC70";
- break;
-
- case "8.00":
- version = "VC71";
- break;
-
- case "9.00":
- version = "VC80";
- break;
-
- case "10.00":
- version = "VC90";
- break;
- default:
- throw new ApplicationException("Unknown .sln version: " + format);
- }
- }
- finally
- {
- if(solutionStreamReader != null)
- {
- solutionStreamReader.Close();
- }
- }
-
- return version;
- }
-
- public static string GetVSProgID(string version)
- {
- string progid = null;
- switch(version)
- {
- case "VC70":
- progid = "VisualStudio.DTE.7";
- break;
-
- case "VC71":
- progid = "VisualStudio.DTE.7.1";
- break;
-
- case "VC80":
- progid = "VisualStudio.DTE.8.0";
- break;
-
- case "VC90":
- progid = "VisualStudio.DTE.9.0";
- break;
- default:
- throw new ApplicationException("Can't handle VS version: " + version);
- }
-
- return progid;
- }
-
- public static bool SetProjectWorkingDir(object sol, string project_name, string working_dir)
- {
- bool made_change = false;
- Console.WriteLine("Looking for project {0}...", project_name);
- try
- {
- object prjs = ViaCOM.GetProperty(sol, "Projects");
- object count = ViaCOM.GetProperty(prjs, "Count");
- for(int i = 1; i <= (int)count; ++i)
- {
- object[] prjItemArgs = { (object)i };
- object prj = ViaCOM.CallMethod(prjs, "Item", prjItemArgs);
- string name = (string)ViaCOM.GetProperty(prj, "Name");
- if (0 == string.Compare(name, project_name, ignore_case))
- {
- Console.WriteLine("Found project: {0}", project_name);
- Console.WriteLine("Setting working directory");
-
- string full_project_name = (string)ViaCOM.GetProperty(prj, "FullName");
- Console.WriteLine(full_project_name);
-
- // *NOTE:Mani Thanks to incompatibilities between different versions of the
- // VCProjectEngine.dll assembly, we can't cast the objects recevied from the DTE to
- // the VCProjectEngine types from a different version than the one built
- // with. ie, VisualStudio.DTE.7.1 objects can't be converted in a project built
- // in VS 8.0. To avoid this problem, we can use the com object interfaces directly,
- // without the type casting. Its tedious code, but it seems to work.
-
- // oCfgs should be assigned to a 'Project.Configurations' collection.
- object oCfgs = ViaCOM.GetProperty(ViaCOM.GetProperty(prj, "Object"), "Configurations");
-
- // oCount will be assigned to the number of configs present in oCfgs.
- object oCount = ViaCOM.GetProperty(oCfgs, "Count");
-
- for (int cfgIndex = 1; cfgIndex <= (int)oCount; ++cfgIndex)
- {
- object[] itemArgs = {(object)cfgIndex};
- object oCfg = ViaCOM.CallMethod(oCfgs, "Item", itemArgs);
- object oDebugSettings = ViaCOM.GetProperty(oCfg, "DebugSettings");
- ViaCOM.SetProperty(oDebugSettings, "WorkingDirectory", (object)working_dir);
- }
-
- break;
- }
- }
- made_change = true;
- }
- catch( Exception e )
- {
- Console.WriteLine(e.Message);
- Console.WriteLine("Failed to set working dir for project, {0}.", project_name);
- }
-
- return made_change;
- }
-
- public static bool SetStartupProject(string startup_project)
- {
- bool result = false;
- try
- {
- // You need the 'unique name of the project to set StartupProjects.
- // find the project by generic name.
- Console.WriteLine("Trying to set \"{0}\" to the startup project", startup_project);
- object prjs = ViaCOM.GetProperty(solution, "Projects");
- object count = ViaCOM.GetProperty(prjs, "Count");
- for (int i = 1; i <= (int)count; ++i)
- {
- object[] itemArgs = { (object)i };
- object prj = ViaCOM.CallMethod(prjs, "Item", itemArgs);
- object prjName = ViaCOM.GetProperty(prj, "Name");
- if (0 == string.Compare((string)prjName, startup_project, ignore_case))
- {
- object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild");
- ViaCOM.SetProperty(solBuild, "StartupProjects", ViaCOM.GetProperty(prj, "UniqueName"));
- Console.WriteLine(" Success!");
- result = true;
- break;
- }
- }
-
- if (result == false)
- {
- Console.WriteLine(" Could not find project \"{0}\" in the solution.", startup_project);
- }
- }
- catch (Exception e)
- {
- Console.WriteLine(" Failed to set the startup project!");
- Console.WriteLine(e.Message);
- }
- return result;
- }
-
- public static bool SetActiveConfig(string config)
- {
- bool result = false;
- try
- {
- Console.WriteLine("Trying to set active config to \"{0}\"", config);
- object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild");
- object solCfgs = ViaCOM.GetProperty(solBuild, "SolutionConfigurations");
- object[] itemArgs = { (object)config };
- object solCfg = ViaCOM.CallMethod(solCfgs, "Item", itemArgs);
- ViaCOM.CallMethod(solCfg, "Activate", null);
- Console.WriteLine(" Success!");
- result = true;
- }
- catch (Exception e)
- {
- Console.WriteLine(" Failed to set \"{0}\" as the active config.", config);
- Console.WriteLine(e.Message);
- }
- return result;
- }
- }
-}
+// Code about getting running instances visual studio
+// was borrowed from
+// http://www.codeproject.com/KB/cs/automatingvisualstudio.aspx
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.ComTypes;
+using Microsoft.CSharp;
+
+namespace VSTool
+{
+ // The MessageFilter class comes from:
+ // http://msdn.microsoft.com/en-us/library/ms228772(VS.80).aspx
+ // It allows vstool to get timing error messages from
+ // visualstudio and handle them.
+ public class MessageFilter : IOleMessageFilter
+ {
+ //
+ // Class containing the IOleMessageFilter
+ // thread error-handling functions.
+
+ // Start the filter.
+ public static void Register()
+ {
+ IOleMessageFilter newFilter = new MessageFilter();
+ IOleMessageFilter oldFilter = null;
+ CoRegisterMessageFilter(newFilter, out oldFilter);
+ }
+
+ // Done with the filter, close it.
+ public static void Revoke()
+ {
+ IOleMessageFilter oldFilter = null;
+ CoRegisterMessageFilter(null, out oldFilter);
+ }
+
+ //
+ // IOleMessageFilter functions.
+ // Handle incoming thread requests.
+ int IOleMessageFilter.HandleInComingCall(int dwCallType,
+ System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr
+ lpInterfaceInfo)
+ {
+ //Return the flag SERVERCALL_ISHANDLED.
+ return 0;
+ }
+
+ // Thread call was rejected, so try again.
+ int IOleMessageFilter.RetryRejectedCall(System.IntPtr
+ hTaskCallee, int dwTickCount, int dwRejectType)
+ {
+ if (dwRejectType == 2)
+ // flag = SERVERCALL_RETRYLATER.
+ {
+ // Retry the thread call immediately if return >=0 &
+ // <100.
+ return 99;
+ }
+ // Too busy; cancel call.
+ return -1;
+ }
+
+ int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee,
+ int dwTickCount, int dwPendingType)
+ {
+ //Return the flag PENDINGMSG_WAITDEFPROCESS.
+ return 2;
+ }
+
+ // Implement the IOleMessageFilter interface.
+ [DllImport("Ole32.dll")]
+ private static extern int
+ CoRegisterMessageFilter(IOleMessageFilter newFilter, out
+ IOleMessageFilter oldFilter);
+ }
+
+ [ComImport(), Guid("00000016-0000-0000-C000-000000000046"),
+ InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ interface IOleMessageFilter
+ {
+ [PreserveSig]
+ int HandleInComingCall(
+ int dwCallType,
+ IntPtr hTaskCaller,
+ int dwTickCount,
+ IntPtr lpInterfaceInfo);
+
+ [PreserveSig]
+ int RetryRejectedCall(
+ IntPtr hTaskCallee,
+ int dwTickCount,
+ int dwRejectType);
+
+ [PreserveSig]
+ int MessagePending(
+ IntPtr hTaskCallee,
+ int dwTickCount,
+ int dwPendingType);
+ }
+
+ class ViaCOM
+ {
+ public static object GetProperty(object from_obj, string prop_name)
+ {
+ try
+ {
+ Type objType = from_obj.GetType();
+ return objType.InvokeMember(
+ prop_name,
+ BindingFlags.GetProperty, null,
+ from_obj,
+ null);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Error getting property: \"{0}\"", prop_name);
+ Console.WriteLine(e.Message);
+ throw e;
+ }
+ }
+
+ public static object SetProperty(object from_obj, string prop_name, object new_value)
+ {
+ try
+ {
+ object[] args = { new_value };
+ Type objType = from_obj.GetType();
+ return objType.InvokeMember(
+ prop_name,
+ BindingFlags.DeclaredOnly |
+ BindingFlags.Public |
+ BindingFlags.NonPublic |
+ BindingFlags.Instance |
+ BindingFlags.SetProperty,
+ null,
+ from_obj,
+ args);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Error setting property: \"{0}\"", prop_name);
+ Console.WriteLine(e.Message);
+ throw e;
+ }
+ }
+
+ public static object CallMethod(object from_obj, string method_name, params object[] args)
+ {
+ try
+ {
+ Type objType = from_obj.GetType();
+ return objType.InvokeMember(
+ method_name,
+ BindingFlags.DeclaredOnly |
+ BindingFlags.Public |
+ BindingFlags.NonPublic |
+ BindingFlags.Instance |
+ BindingFlags.InvokeMethod,
+ null,
+ from_obj,
+ args);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Error calling method \"{0}\"", method_name);
+ Console.WriteLine(e.Message);
+ throw e;
+ }
+ }
+ };
+
+ /// <summary>
+ /// The main entry point class for VSTool.
+ /// </summary>
+ class VSToolMain
+ {
+ #region Interop imports
+ [DllImport("ole32.dll")]
+ public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);
+
+ [DllImport("ole32.dll")]
+ public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc);
+ #endregion
+
+ static System.Boolean ignore_case = true;
+
+ static string solution_name = null;
+ static bool use_new_vs = false;
+ static Hashtable projectDict = new Hashtable();
+ static string startup_project = null;
+ static string config = null;
+
+ static object dte = null;
+ static object solution = null;
+
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [STAThread]
+ static int Main(string[] args)
+ {
+ int retVal = 0;
+ bool need_save = false;
+
+ try
+ {
+ parse_command_line(args);
+
+ Console.WriteLine("Editing solution: {0}", solution_name);
+
+ bool found_open_solution = GetDTEAndSolution();
+
+ if (dte == null || solution == null)
+ {
+ retVal = 1;
+ }
+ else
+ {
+ MessageFilter.Register();
+
+ // Walk through all of the projects in the solution
+ // and list the type of each project.
+ foreach (DictionaryEntry p in projectDict)
+ {
+ string project_name = (string)p.Key;
+ string working_dir = (string)p.Value;
+ if (SetProjectWorkingDir(solution, project_name, working_dir))
+ {
+ need_save = true;
+ }
+ }
+
+ if (config != null)
+ {
+ need_save = SetActiveConfig(config);
+ }
+
+ if (startup_project != null)
+ {
+ need_save = SetStartupProject(startup_project);
+ }
+
+ if (need_save)
+ {
+ if (found_open_solution == false)
+ {
+ ViaCOM.CallMethod(solution, "Close", null);
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ retVal = 1;
+ }
+ finally
+ {
+ if (solution != null)
+ {
+ Marshal.ReleaseComObject(solution);
+ solution = null;
+ }
+
+ if (dte != null)
+ {
+ Marshal.ReleaseComObject(dte);
+ dte = null;
+ }
+
+ MessageFilter.Revoke();
+ }
+ return retVal;
+ }
+
+ public static bool parse_command_line(string[] args)
+ {
+ string options_desc =
+ "--solution <solution_name> : MSVC solution name. (required)\n" +
+ "--use_new_vs : Ignore running versions of visual studio.\n" +
+ "--workingdir <project> <dir> : Set working dir of a VC project.\n" +
+ "--config <config> : Set the active config for the solution.\n" +
+ "--startup <project> : Set the startup project for the solution.\n";
+
+ try
+ {
+ // Command line param parsing loop.
+ int i = 0;
+ for (; i < args.Length; ++i)
+ {
+ if ("--solution" == args[i])
+ {
+ if (solution_name != null)
+ {
+ throw new ApplicationException("Found second --solution option");
+ }
+ solution_name = args[++i];
+ }
+ else if ("--use_new_vs" == args[i])
+ {
+ use_new_vs = true;
+ }
+
+ else if ("--workingdir" == args[i])
+ {
+ string project_name = args[++i];
+ string working_dir = args[++i];
+ projectDict.Add(project_name, working_dir);
+ }
+ else if ("--config" == args[i])
+ {
+ if (config != null)
+ {
+ throw new ApplicationException("Found second --config option");
+ }
+ config = args[++i];
+ }
+ else if ("--startup" == args[i])
+ {
+ if (startup_project != null)
+ {
+ throw new ApplicationException("Found second --startup option");
+ }
+ startup_project = args[++i];
+ }
+ else
+ {
+ throw new ApplicationException("Found unrecognized token on command line: " + args[i]);
+ }
+ }
+
+ if (solution_name == null)
+ {
+ throw new ApplicationException("The --solution option is required.");
+ }
+ }
+ catch(ApplicationException e)
+ {
+
+ Console.WriteLine("Oops! " + e.Message);
+ Console.Write("Command line:");
+ foreach (string arg in args)
+ {
+ Console.Write(" " + arg);
+ }
+ Console.Write("\n\n");
+ Console.WriteLine("VSTool command line usage");
+ Console.Write(options_desc);
+ throw e;
+ }
+ return true;
+ }
+
+ public static bool GetDTEAndSolution()
+ {
+ bool found_open_solution = true;
+
+ Console.WriteLine("Looking for existing VisualStudio instance...");
+
+ // Get an instance of the currently running Visual Studio .NET IDE.
+ // dte = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.7.1");
+ string full_solution_name = System.IO.Path.GetFullPath(solution_name);
+ if (false == use_new_vs)
+ {
+ dte = GetIDEInstance(full_solution_name);
+ }
+
+ if (dte == null)
+ {
+ try
+ {
+ Console.WriteLine(" Didn't find open solution, starting new background VisualStudio instance...");
+ Console.WriteLine(" Reading .sln file version...");
+ string version = GetSolutionVersion(full_solution_name);
+
+ Console.WriteLine(" Using version: {0}...", version);
+ string progid = GetVSProgID(version);
+
+ Type objType = Type.GetTypeFromProgID(progid);
+ dte = System.Activator.CreateInstance(objType);
+ Console.WriteLine(" Reading solution: \"{0}\"", full_solution_name);
+
+ solution = ViaCOM.GetProperty(dte, "Solution");
+ object[] openArgs = { full_solution_name };
+ ViaCOM.CallMethod(solution, "Open", openArgs);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ Console.WriteLine("Quitting do to error opening: {0}", full_solution_name);
+ solution = null;
+ dte = null;
+ return found_open_solution;
+ }
+ found_open_solution = false;
+ }
+
+ if (solution == null)
+ {
+ solution = ViaCOM.GetProperty(dte, "Solution");
+ }
+
+ return found_open_solution;
+ }
+
+ /// <summary>
+ /// Get the DTE object for the instance of Visual Studio IDE that has
+ /// the specified solution open.
+ /// </summary>
+ /// <param name="solutionFile">The absolute filename of the solution</param>
+ /// <returns>Corresponding DTE object or null if no such IDE is running</returns>
+ public static object GetIDEInstance( string solutionFile )
+ {
+ Hashtable runningInstances = GetIDEInstances( true );
+ IDictionaryEnumerator enumerator = runningInstances.GetEnumerator();
+
+ while ( enumerator.MoveNext() )
+ {
+ try
+ {
+ object ide = enumerator.Value;
+ if (ide != null)
+ {
+ object sol = ViaCOM.GetProperty(ide, "Solution");
+ if (0 == string.Compare((string)ViaCOM.GetProperty(sol, "FullName"), solutionFile, ignore_case))
+ {
+ return ide;
+ }
+ }
+ }
+ catch{}
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Get a table of the currently running instances of the Visual Studio .NET IDE.
+ /// </summary>
+ /// <param name="openSolutionsOnly">Only return instances that have opened a solution</param>
+ /// <returns>A hashtable mapping the name of the IDE in the running object table to the corresponding DTE object</returns>
+ public static Hashtable GetIDEInstances( bool openSolutionsOnly )
+ {
+ Hashtable runningIDEInstances = new Hashtable();
+ Hashtable runningObjects = GetRunningObjectTable();
+
+ IDictionaryEnumerator rotEnumerator = runningObjects.GetEnumerator();
+ while ( rotEnumerator.MoveNext() )
+ {
+ string candidateName = (string) rotEnumerator.Key;
+ if (!candidateName.StartsWith("!VisualStudio.DTE"))
+ continue;
+
+ object ide = rotEnumerator.Value;
+ if (ide == null)
+ continue;
+
+ if (openSolutionsOnly)
+ {
+ try
+ {
+ object sol = ViaCOM.GetProperty(ide, "Solution");
+ string solutionFile = (string)ViaCOM.GetProperty(sol, "FullName");
+ if (solutionFile != String.Empty)
+ {
+ runningIDEInstances[ candidateName ] = ide;
+ }
+ }
+ catch {}
+ }
+ else
+ {
+ runningIDEInstances[ candidateName ] = ide;
+ }
+ }
+ return runningIDEInstances;
+ }
+
+ /// <summary>
+ /// Get a snapshot of the running object table (ROT).
+ /// </summary>
+ /// <returns>A hashtable mapping the name of the object in the ROT to the corresponding object</returns>
+ [STAThread]
+ public static Hashtable GetRunningObjectTable()
+ {
+ Hashtable result = new Hashtable();
+
+ int numFetched = 0;
+ IRunningObjectTable runningObjectTable;
+ IEnumMoniker monikerEnumerator;
+ IMoniker[] monikers = new IMoniker[1];
+
+ GetRunningObjectTable(0, out runningObjectTable);
+ runningObjectTable.EnumRunning(out monikerEnumerator);
+ monikerEnumerator.Reset();
+
+ while (monikerEnumerator.Next(1, monikers, new IntPtr(numFetched)) == 0)
+ {
+ IBindCtx ctx;
+ CreateBindCtx(0, out ctx);
+
+ string runningObjectName;
+ monikers[0].GetDisplayName(ctx, null, out runningObjectName);
+
+ object runningObjectVal;
+ runningObjectTable.GetObject( monikers[0], out runningObjectVal);
+
+ result[ runningObjectName ] = runningObjectVal;
+ }
+
+ return result;
+ }
+
+ public static string GetSolutionVersion(string solutionFullFileName)
+ {
+ string version;
+ System.IO.StreamReader solutionStreamReader = null;
+ string firstLine;
+ string format;
+
+ try
+ {
+ solutionStreamReader = new System.IO.StreamReader(solutionFullFileName);
+ do
+ {
+ firstLine = solutionStreamReader.ReadLine();
+ }
+ while (firstLine == "");
+
+ format = firstLine.Substring(firstLine.LastIndexOf(" ")).Trim();
+
+ switch(format)
+ {
+ case "7.00":
+ version = "VC70";
+ break;
+
+ case "8.00":
+ version = "VC71";
+ break;
+
+ case "9.00":
+ version = "VC80";
+ break;
+
+ case "10.00":
+ version = "VC90";
+ break;
+ default:
+ throw new ApplicationException("Unknown .sln version: " + format);
+ }
+ }
+ finally
+ {
+ if(solutionStreamReader != null)
+ {
+ solutionStreamReader.Close();
+ }
+ }
+
+ return version;
+ }
+
+ public static string GetVSProgID(string version)
+ {
+ string progid = null;
+ switch(version)
+ {
+ case "VC70":
+ progid = "VisualStudio.DTE.7";
+ break;
+
+ case "VC71":
+ progid = "VisualStudio.DTE.7.1";
+ break;
+
+ case "VC80":
+ progid = "VisualStudio.DTE.8.0";
+ break;
+
+ case "VC90":
+ progid = "VisualStudio.DTE.9.0";
+ break;
+ default:
+ throw new ApplicationException("Can't handle VS version: " + version);
+ }
+
+ return progid;
+ }
+
+ public static bool SetProjectWorkingDir(object sol, string project_name, string working_dir)
+ {
+ bool made_change = false;
+ Console.WriteLine("Looking for project {0}...", project_name);
+ try
+ {
+ object prjs = ViaCOM.GetProperty(sol, "Projects");
+ object count = ViaCOM.GetProperty(prjs, "Count");
+ for(int i = 1; i <= (int)count; ++i)
+ {
+ object[] prjItemArgs = { (object)i };
+ object prj = ViaCOM.CallMethod(prjs, "Item", prjItemArgs);
+ string name = (string)ViaCOM.GetProperty(prj, "Name");
+ if (0 == string.Compare(name, project_name, ignore_case))
+ {
+ Console.WriteLine("Found project: {0}", project_name);
+ Console.WriteLine("Setting working directory");
+
+ string full_project_name = (string)ViaCOM.GetProperty(prj, "FullName");
+ Console.WriteLine(full_project_name);
+
+ // *NOTE:Mani Thanks to incompatibilities between different versions of the
+ // VCProjectEngine.dll assembly, we can't cast the objects recevied from the DTE to
+ // the VCProjectEngine types from a different version than the one built
+ // with. ie, VisualStudio.DTE.7.1 objects can't be converted in a project built
+ // in VS 8.0. To avoid this problem, we can use the com object interfaces directly,
+ // without the type casting. Its tedious code, but it seems to work.
+
+ // oCfgs should be assigned to a 'Project.Configurations' collection.
+ object oCfgs = ViaCOM.GetProperty(ViaCOM.GetProperty(prj, "Object"), "Configurations");
+
+ // oCount will be assigned to the number of configs present in oCfgs.
+ object oCount = ViaCOM.GetProperty(oCfgs, "Count");
+
+ for (int cfgIndex = 1; cfgIndex <= (int)oCount; ++cfgIndex)
+ {
+ object[] itemArgs = {(object)cfgIndex};
+ object oCfg = ViaCOM.CallMethod(oCfgs, "Item", itemArgs);
+ object oDebugSettings = ViaCOM.GetProperty(oCfg, "DebugSettings");
+ ViaCOM.SetProperty(oDebugSettings, "WorkingDirectory", (object)working_dir);
+ }
+
+ break;
+ }
+ }
+ made_change = true;
+ }
+ catch( Exception e )
+ {
+ Console.WriteLine(e.Message);
+ Console.WriteLine("Failed to set working dir for project, {0}.", project_name);
+ }
+
+ return made_change;
+ }
+
+ public static bool SetStartupProject(string startup_project)
+ {
+ bool result = false;
+ try
+ {
+ // You need the 'unique name of the project to set StartupProjects.
+ // find the project by generic name.
+ Console.WriteLine("Trying to set \"{0}\" to the startup project", startup_project);
+ object prjs = ViaCOM.GetProperty(solution, "Projects");
+ object count = ViaCOM.GetProperty(prjs, "Count");
+ for (int i = 1; i <= (int)count; ++i)
+ {
+ object[] itemArgs = { (object)i };
+ object prj = ViaCOM.CallMethod(prjs, "Item", itemArgs);
+ object prjName = ViaCOM.GetProperty(prj, "Name");
+ if (0 == string.Compare((string)prjName, startup_project, ignore_case))
+ {
+ object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild");
+ ViaCOM.SetProperty(solBuild, "StartupProjects", ViaCOM.GetProperty(prj, "UniqueName"));
+ Console.WriteLine(" Success!");
+ result = true;
+ break;
+ }
+ }
+
+ if (result == false)
+ {
+ Console.WriteLine(" Could not find project \"{0}\" in the solution.", startup_project);
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(" Failed to set the startup project!");
+ Console.WriteLine(e.Message);
+ }
+ return result;
+ }
+
+ public static bool SetActiveConfig(string config)
+ {
+ bool result = false;
+ try
+ {
+ Console.WriteLine("Trying to set active config to \"{0}\"", config);
+ object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild");
+ object solCfgs = ViaCOM.GetProperty(solBuild, "SolutionConfigurations");
+ object[] itemArgs = { (object)config };
+ object solCfg = ViaCOM.CallMethod(solCfgs, "Item", itemArgs);
+ ViaCOM.CallMethod(solCfg, "Activate", null);
+ Console.WriteLine(" Success!");
+ result = true;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(" Failed to set \"{0}\" as the active config.", config);
+ Console.WriteLine(e.Message);
+ }
+ return result;
+ }
+ }
+}