diff options
68 files changed, 14386 insertions, 14406 deletions
diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py index 17bce6f434..fff78ecbe3 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 0d6f18c5d4..50129b4526 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/llapr.h b/indra/llcommon/llapr.h index 0898aeec47..a1fcd2cf8d 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -1,259 +1,259 @@ -/** 
 - * @file llapr.h
 - * @author Phoenix
 - * @date 2004-11-28
 - * @brief Helper functions for using the apache portable runtime library.
 - *
 - * $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_LLAPR_H
 -#define LL_LLAPR_H
 -
 -#if LL_LINUX || LL_SOLARIS
 -#include <sys/param.h>  // Need PATH_MAX in APR headers...
 -#endif
 -
 -#include <boost/noncopyable.hpp>
 -
 -#include "apr_thread_proc.h"
 -#include "apr_thread_mutex.h"
 -#include "apr_getopt.h"
 -#include "apr_signal.h"
 -#include "apr_atomic.h"
 -#include "llstring.h"
 -
 -extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp;
 -extern apr_thread_mutex_t* gCallStacksLogMutexp;
 -
 -/** 
 - * @brief initialize the common apr constructs -- apr itself, the
 - * global pool, and a mutex.
 - */
 -void LL_COMMON_API ll_init_apr();
 -
 -/** 
 - * @brief Cleanup those common apr constructs.
 - */
 -void LL_COMMON_API ll_cleanup_apr();
 -
 -//
 -//LL apr_pool
 -//manage apr_pool_t, destroy allocated apr_pool in the destruction function.
 -//
 -class LL_COMMON_API LLAPRPool
 -{
 -public:
 -	LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE) ;
 -	~LLAPRPool() ;
 -
 -	apr_pool_t* getAPRPool() ;
 -	apr_status_t getStatus() {return mStatus ; }
 -
 -protected:
 -	void releaseAPRPool() ;
 -	void createAPRPool() ;
 -
 -protected:
 -	apr_pool_t*  mPool ;              //pointing to an apr_pool
 -	apr_pool_t*  mParent ;			  //parent pool
 -	apr_size_t   mMaxSize ;           //max size of mPool, mPool should return memory to system if allocated memory beyond this limit. However it seems not to work.
 -	apr_status_t mStatus ;            //status when creating the pool
 -	BOOL         mReleasePoolFlag ;   //if set, mPool is destroyed when LLAPRPool is deleted. default value is true.
 -};
 -
 -//
 -//volatile LL apr_pool
 -//which clears memory automatically.
 -//so it can not hold static data or data after memory is cleared
 -//
 -class LL_COMMON_API LLVolatileAPRPool : public LLAPRPool
 -{
 -public:
 -	LLVolatileAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE);
 -	~LLVolatileAPRPool(){}
 -
 -	apr_pool_t* getVolatileAPRPool() ;
 -	
 -	void        clearVolatileAPRPool() ;
 -
 -	BOOL        isFull() ;
 -	BOOL        isEmpty() {return !mNumActiveRef ;}
 -private:
 -	S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool.
 -	S32 mNumTotalRef ;  //number of total pointers pointing to the apr_pool since last creating.   
 -} ;
 -
 -/** 
 - * @class LLScopedLock
 - * @brief Small class to help lock and unlock mutexes.
 - *
 - * This class is used to have a stack level lock once you already have
 - * an apr mutex handy. The constructor handles the lock, and the
 - * destructor handles the unlock. Instances of this class are
 - * <b>not</b> thread safe.
 - */
 -class LL_COMMON_API LLScopedLock : private boost::noncopyable
 -{
 -public:
 -	/**
 -	 * @brief Constructor which accepts a mutex, and locks it.
 -	 *
 -	 * @param mutex An allocated APR mutex. If you pass in NULL,
 -	 * this wrapper will not lock.
 -	 */
 -	LLScopedLock(apr_thread_mutex_t* mutex);
 -
 -	/**
 -	 * @brief Destructor which unlocks the mutex if still locked.
 -	 */
 -	~LLScopedLock();
 -
 -	/** 
 -	 * @brief Check lock.
 -	 */
 -	bool isLocked() const { return mLocked; }
 -
 -	/** 
 -	 * @brief This method unlocks the mutex.
 -	 */
 -	void unlock();
 -
 -protected:
 -	bool mLocked;
 -	apr_thread_mutex_t* mMutex;
 -};
 -
 -template <typename Type> class LLAtomic32
 -{
 -public:
 -	LLAtomic32<Type>() {};
 -	LLAtomic32<Type>(Type x) {apr_atomic_set32(&mData, apr_uint32_t(x)); };
 -	~LLAtomic32<Type>() {};
 -
 -	operator const Type() { apr_uint32_t data = apr_atomic_read32(&mData); return Type(data); }
 -	Type operator =(const Type& x) { apr_atomic_set32(&mData, apr_uint32_t(x)); return Type(mData); }
 -	void operator -=(Type x) { apr_atomic_sub32(&mData, apr_uint32_t(x)); }
 -	void operator +=(Type x) { apr_atomic_add32(&mData, apr_uint32_t(x)); }
 -	Type operator ++(int) { return apr_atomic_inc32(&mData); } // Type++
 -	Type operator --(int) { return apr_atomic_dec32(&mData); } // Type--
 -	
 -private:
 -	apr_uint32_t mData;
 -};
 -
 -typedef LLAtomic32<U32> LLAtomicU32;
 -typedef LLAtomic32<S32> LLAtomicS32;
 -
 -// File IO convenience functions.
 -// Returns NULL if the file fails to openm sets *sizep to file size of not NULL
 -// abbreviated flags
 -#define LL_APR_R (APR_READ) // "r"
 -#define LL_APR_W (APR_CREATE|APR_TRUNCATE|APR_WRITE) // "w"
 -#define LL_APR_RB (APR_READ|APR_BINARY) // "rb"
 -#define LL_APR_WB (APR_CREATE|APR_TRUNCATE|APR_WRITE|APR_BINARY) // "wb"
 -#define LL_APR_RPB (APR_READ|APR_WRITE|APR_BINARY) // "r+b"
 -#define LL_APR_WPB (APR_CREATE|APR_TRUNCATE|APR_READ|APR_WRITE|APR_BINARY) // "w+b"
 -
 -//
 -//apr_file manager
 -//which: 1)only keeps one file open;
 -//       2)closes the open file in the destruction function
 -//       3)informs the apr_pool to clean the memory when the file is closed.
 -//Note: please close an open file at the earliest convenience. 
 -//      especially do not put some time-costly operations between open() and close().
 -//      otherwise it might lock the APRFilePool.
 -//there are two different apr_pools the APRFile can use:
 -//      1, a temperary pool passed to an APRFile function, which is used within this function and only once.
 -//      2, a global pool.
 -//
 -class LL_COMMON_API LLAPRFile
 -{
 -private:
 -	apr_file_t* mFile ;
 -	LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp pool. 
 -
 -public:
 -	LLAPRFile() ;
 -	~LLAPRFile() ;
 -
 -	apr_status_t open(LLVolatileAPRPool* pool, const std::string& filename, apr_int32_t flags, S32* sizep = NULL);
 -	apr_status_t open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool = NULL, S32* sizep = NULL);
 -	apr_status_t close() ;
 -
 -	// Returns actual offset, -1 if seek fails
 -	S32 seek(apr_seek_where_t where, S32 offset);
 -	apr_status_t eof() { return apr_file_eof(mFile);}
 -
 -	// Returns bytes read/written, 0 if read/write fails:
 -	S32 read(void* buf, S32 nbytes);
 -	S32 write(const void* buf, S32 nbytes);
 -	
 -	apr_file_t* getFileHandle() {return mFile;}	
 -
 -private:
 -	apr_pool_t* getAPRFilePool(apr_pool_t* pool) ;
 -
 -//
 -//*******************************************************************************************************************************
 -//static components
 -//
 -public:
 -	static LLVolatileAPRPool *sAPRFilePoolp ; //a global apr_pool for APRFile, which is used only when local pool does not exist.
 -
 -private:
 -	static apr_file_t* open(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags);
 -	static apr_status_t close(apr_file_t* file, LLVolatileAPRPool* pool) ;
 -	static S32 seek(apr_file_t* file, apr_seek_where_t where, S32 offset);
 -public:
 -	// returns false if failure:
 -	static bool remove(const std::string& filename, LLVolatileAPRPool* pool = NULL);
 -	static bool rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool = NULL);
 -	static bool isExist(const std::string& filename, LLVolatileAPRPool* pool = NULL, apr_int32_t flags = APR_READ);
 -	static S32 size(const std::string& filename, LLVolatileAPRPool* pool = NULL);
 -	static bool makeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL);
 -	static bool removeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL);
 -
 -	// Returns bytes read/written, 0 if read/write fails:
 -	static S32 readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL);	
 -	static S32 writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL);	
 -//*******************************************************************************************************************************
 -};
 -
 -/**
 - * @brief Function which approprately logs error or remains quiet on
 - * APR_SUCCESS.
 - * @return Returns <code>true</code> if status is an error condition.
 - */
 -bool LL_COMMON_API ll_apr_warn_status(apr_status_t status);
 -
 -void LL_COMMON_API ll_apr_assert_status(apr_status_t status);
 -
 -extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool
 -
 -#endif // LL_LLAPR_H
 +/**  + * @file llapr.h + * @author Phoenix + * @date 2004-11-28 + * @brief Helper functions for using the apache portable runtime library. + * + * $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_LLAPR_H +#define LL_LLAPR_H + +#if LL_LINUX || LL_SOLARIS +#include <sys/param.h>  // Need PATH_MAX in APR headers... +#endif + +#include <boost/noncopyable.hpp> + +#include "apr_thread_proc.h" +#include "apr_thread_mutex.h" +#include "apr_getopt.h" +#include "apr_signal.h" +#include "apr_atomic.h" +#include "llstring.h" + +extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp; +extern apr_thread_mutex_t* gCallStacksLogMutexp; + +/**  + * @brief initialize the common apr constructs -- apr itself, the + * global pool, and a mutex. + */ +void LL_COMMON_API ll_init_apr(); + +/**  + * @brief Cleanup those common apr constructs. + */ +void LL_COMMON_API ll_cleanup_apr(); + +// +//LL apr_pool +//manage apr_pool_t, destroy allocated apr_pool in the destruction function. +// +class LL_COMMON_API LLAPRPool +{ +public: +	LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE) ; +	~LLAPRPool() ; + +	apr_pool_t* getAPRPool() ; +	apr_status_t getStatus() {return mStatus ; } + +protected: +	void releaseAPRPool() ; +	void createAPRPool() ; + +protected: +	apr_pool_t*  mPool ;              //pointing to an apr_pool +	apr_pool_t*  mParent ;			  //parent pool +	apr_size_t   mMaxSize ;           //max size of mPool, mPool should return memory to system if allocated memory beyond this limit. However it seems not to work. +	apr_status_t mStatus ;            //status when creating the pool +	BOOL         mReleasePoolFlag ;   //if set, mPool is destroyed when LLAPRPool is deleted. default value is true. +}; + +// +//volatile LL apr_pool +//which clears memory automatically. +//so it can not hold static data or data after memory is cleared +// +class LL_COMMON_API LLVolatileAPRPool : public LLAPRPool +{ +public: +	LLVolatileAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE); +	~LLVolatileAPRPool(){} + +	apr_pool_t* getVolatileAPRPool() ; +	 +	void        clearVolatileAPRPool() ; + +	BOOL        isFull() ; +	BOOL        isEmpty() {return !mNumActiveRef ;} +private: +	S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool. +	S32 mNumTotalRef ;  //number of total pointers pointing to the apr_pool since last creating.    +} ; + +/**  + * @class LLScopedLock + * @brief Small class to help lock and unlock mutexes. + * + * This class is used to have a stack level lock once you already have + * an apr mutex handy. The constructor handles the lock, and the + * destructor handles the unlock. Instances of this class are + * <b>not</b> thread safe. + */ +class LL_COMMON_API LLScopedLock : private boost::noncopyable +{ +public: +	/** +	 * @brief Constructor which accepts a mutex, and locks it. +	 * +	 * @param mutex An allocated APR mutex. If you pass in NULL, +	 * this wrapper will not lock. +	 */ +	LLScopedLock(apr_thread_mutex_t* mutex); + +	/** +	 * @brief Destructor which unlocks the mutex if still locked. +	 */ +	~LLScopedLock(); + +	/**  +	 * @brief Check lock. +	 */ +	bool isLocked() const { return mLocked; } + +	/**  +	 * @brief This method unlocks the mutex. +	 */ +	void unlock(); + +protected: +	bool mLocked; +	apr_thread_mutex_t* mMutex; +}; + +template <typename Type> class LLAtomic32 +{ +public: +	LLAtomic32<Type>() {}; +	LLAtomic32<Type>(Type x) {apr_atomic_set32(&mData, apr_uint32_t(x)); }; +	~LLAtomic32<Type>() {}; + +	operator const Type() { apr_uint32_t data = apr_atomic_read32(&mData); return Type(data); } +	Type operator =(const Type& x) { apr_atomic_set32(&mData, apr_uint32_t(x)); return Type(mData); } +	void operator -=(Type x) { apr_atomic_sub32(&mData, apr_uint32_t(x)); } +	void operator +=(Type x) { apr_atomic_add32(&mData, apr_uint32_t(x)); } +	Type operator ++(int) { return apr_atomic_inc32(&mData); } // Type++ +	Type operator --(int) { return apr_atomic_dec32(&mData); } // Type-- +	 +private: +	apr_uint32_t mData; +}; + +typedef LLAtomic32<U32> LLAtomicU32; +typedef LLAtomic32<S32> LLAtomicS32; + +// File IO convenience functions. +// Returns NULL if the file fails to openm sets *sizep to file size of not NULL +// abbreviated flags +#define LL_APR_R (APR_READ) // "r" +#define LL_APR_W (APR_CREATE|APR_TRUNCATE|APR_WRITE) // "w" +#define LL_APR_RB (APR_READ|APR_BINARY) // "rb" +#define LL_APR_WB (APR_CREATE|APR_TRUNCATE|APR_WRITE|APR_BINARY) // "wb" +#define LL_APR_RPB (APR_READ|APR_WRITE|APR_BINARY) // "r+b" +#define LL_APR_WPB (APR_CREATE|APR_TRUNCATE|APR_READ|APR_WRITE|APR_BINARY) // "w+b" + +// +//apr_file manager +//which: 1)only keeps one file open; +//       2)closes the open file in the destruction function +//       3)informs the apr_pool to clean the memory when the file is closed. +//Note: please close an open file at the earliest convenience.  +//      especially do not put some time-costly operations between open() and close(). +//      otherwise it might lock the APRFilePool. +//there are two different apr_pools the APRFile can use: +//      1, a temperary pool passed to an APRFile function, which is used within this function and only once. +//      2, a global pool. +// +class LL_COMMON_API LLAPRFile +{ +private: +	apr_file_t* mFile ; +	LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp pool.  + +public: +	LLAPRFile() ; +	~LLAPRFile() ; + +	apr_status_t open(LLVolatileAPRPool* pool, const std::string& filename, apr_int32_t flags, S32* sizep = NULL); +	apr_status_t open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool = NULL, S32* sizep = NULL); +	apr_status_t close() ; + +	// Returns actual offset, -1 if seek fails +	S32 seek(apr_seek_where_t where, S32 offset); +	apr_status_t eof() { return apr_file_eof(mFile);} + +	// Returns bytes read/written, 0 if read/write fails: +	S32 read(void* buf, S32 nbytes); +	S32 write(const void* buf, S32 nbytes); +	 +	apr_file_t* getFileHandle() {return mFile;}	 + +private: +	apr_pool_t* getAPRFilePool(apr_pool_t* pool) ; + +// +//******************************************************************************************************************************* +//static components +// +public: +	static LLVolatileAPRPool *sAPRFilePoolp ; //a global apr_pool for APRFile, which is used only when local pool does not exist. + +private: +	static apr_file_t* open(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags); +	static apr_status_t close(apr_file_t* file, LLVolatileAPRPool* pool) ; +	static S32 seek(apr_file_t* file, apr_seek_where_t where, S32 offset); +public: +	// returns false if failure: +	static bool remove(const std::string& filename, LLVolatileAPRPool* pool = NULL); +	static bool rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool = NULL); +	static bool isExist(const std::string& filename, LLVolatileAPRPool* pool = NULL, apr_int32_t flags = APR_READ); +	static S32 size(const std::string& filename, LLVolatileAPRPool* pool = NULL); +	static bool makeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL); +	static bool removeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL); + +	// Returns bytes read/written, 0 if read/write fails: +	static S32 readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL);	 +	static S32 writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL);	 +//******************************************************************************************************************************* +}; + +/** + * @brief Function which approprately logs error or remains quiet on + * APR_SUCCESS. + * @return Returns <code>true</code> if status is an error condition. + */ +bool LL_COMMON_API ll_apr_warn_status(apr_status_t status); + +void LL_COMMON_API ll_apr_assert_status(apr_status_t status); + +extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool + +#endif // LL_LLAPR_H diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index 33705cd2b1..3c760e4d91 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -1,205 +1,205 @@ -/** 
 - * @file llassettype.h
 - * @brief Declaration of LLAssetType.
 - *
 - * $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_LLASSETTYPE_H
 -#define LL_LLASSETTYPE_H
 -
 -#include <string>
 -
 -#include "stdenums.h" 	// for EDragAndDropType
 -
 -class LL_COMMON_API LLAssetType
 -{
 -public:
 -	enum EType
 -	{
 -		AT_TEXTURE = 0,
 -			// Used for painting the faces of geometry.
 -			// Stored in typical j2c stream format.
 -
 -		AT_SOUND = 1, 
 -			// Used to fill the aural spectrum.
 -
 -		AT_CALLINGCARD = 2,
 -		    // Links instant message access to the user on the card.
 -			// : E.G. A card for yourself, for linden support, for
 -			// : the guy you were talking to in the coliseum.
 -
 -		AT_LANDMARK = 3,
 -			// Links to places in the world with location and a screen shot or image saved.
 -			// : E.G. Home, linden headquarters, the coliseum, destinations where 
 -			// : we want to increase traffic.
 -
 -		AT_SCRIPT = 4,
 -			// Valid scripts that can be attached to an object.
 -			// : E.G. Open a door, jump into the air.
 -
 -		AT_CLOTHING = 5,
 -			// A collection of textures and parameters that can be worn by an avatar.
 -
 -		AT_OBJECT = 6,
 -			// Any combination of textures, sounds, and scripts that are
 -			// associated with a fixed piece of geometry.
 -			// : E.G. A hot tub, a house with working door.
 -
 -		AT_NOTECARD = 7,
 -			// Just text.
 -
 -		AT_CATEGORY = 8,
 -			// Holds a collection of inventory items.
 -			// It's treated as an item in the inventory and therefore needs a type.
 -
 -		AT_ROOT_CATEGORY = 9,
 -			// A user's root inventory category.
 -			// We decided to expose it visually, so it seems logical to fold
 -			// it into the asset types.
 -
 -		AT_LSL_TEXT = 10,
 -		AT_LSL_BYTECODE = 11,
 -			// The LSL is the scripting language. 
 -			// We've split it into a text and bytecode representation.
 -		
 -		AT_TEXTURE_TGA = 12,
 -			// Uncompressed TGA texture.
 -
 -		AT_BODYPART = 13,
 -			// A collection of textures and parameters that can be worn by an avatar.
 -
 -		AT_TRASH = 14,
 -			// Only to be used as a marker for a category preferred type. 
 -			// Using this, we can throw things in the trash before completely deleting.
 -
 -		AT_SNAPSHOT_CATEGORY = 15,
 -			// A marker for a folder meant for snapshots. 
 -			// No actual assets will be snapshots, though if there were, you
 -			// could interpret them as textures.
 -
 -		AT_LOST_AND_FOUND = 16,
 -			// Used to stuff lost&found items into.
 -
 -		AT_SOUND_WAV = 17,
 -			// Uncompressed sound.
 -
 -		AT_IMAGE_TGA = 18,
 -			// Uncompressed image, non-square.
 -			// Not appropriate for use as a texture.
 -
 -		AT_IMAGE_JPEG = 19,
 -			// Compressed image, non-square.
 -			// Not appropriate for use as a texture.
 -
 -		AT_ANIMATION = 20,
 -			// Animation.
 -
 -		AT_GESTURE = 21,
 -			// Gesture, sequence of animations, sounds, chat, wait steps.
 -
 -		AT_SIMSTATE = 22,
 -			// Simstate file.
 -
 -		AT_FAVORITE = 23,
 -			// favorite items
 -
 -		AT_LINK = 24,
 -			// Inventory symbolic link
 -
 -		AT_LINK_FOLDER = 25,
 -			// Inventory folder link
 -
 -		AT_FOLDER_ENSEMBLE_START = 26,
 -		AT_FOLDER_ENSEMBLE_END = 45,
 -			// This range is reserved for special clothing folder types.
 -
 -		AT_CURRENT_OUTFIT = 46,
 -			// Current outfit
 -
 -		AT_OUTFIT = 47,
 -			// Predefined outfit ("look")
 -
 -		AT_MY_OUTFITS = 48,
 -			// Folder that holds your outfits.
 -
 -		
 -		AT_COUNT = 49,
 -
 -			// +*********************************************************+
 -			// |  TO ADD AN ELEMENT TO THIS ENUM:                        |
 -			// +*********************************************************+
 -			// | 1. INSERT BEFORE AT_COUNT                               |
 -			// | 2. INCREMENT AT_COUNT BY 1                              |
 -			// | 3. ADD TO LLAssetDictionary in LLAssetType.cpp          |
 -			// | 3. ADD TO DEFAULT_ASSET_FOR_INV in LLInventoryType.cpp  |
 -			// +*********************************************************+
 -
 -		AT_NONE = -1
 -	};
 -
 -	// machine transation between type and strings
 -	static EType 				lookup(const char* name); // safe conversion to std::string, *TODO: deprecate
 -	static EType 				lookup(const std::string& type_name);
 -	static const char*			lookup(EType asset_type);
 -
 -	// translation from a type to a human readable form.
 -	static EType 				lookupHumanReadable(const char* desc_name); // safe conversion to std::string, *TODO: deprecate
 -	static EType 				lookupHumanReadable(const std::string& readable_name);
 -	static const char*			lookupHumanReadable(EType asset_type);
 -
 -	// Generate a good default description. You may want to add a verb
 -	// or agent name after this depending on your application.
 -	static void 				generateDescriptionFor(LLAssetType::EType asset_type,
 -													   std::string& description);
 -
 -	static EType 				getType(const std::string& desc_name);
 -	static const std::string&	getDesc(EType asset_type);
 -	static EDragAndDropType   	lookupDragAndDropType(EType asset_type);
 -
 -	static bool 				lookupCanLink(EType asset_type);
 -	static bool 				lookupIsLinkType(EType asset_type);
 -
 -	static const char*  		lookupCategoryName(EType asset_type);
 -	static bool 				lookupIsProtectedCategoryType(EType asset_type);
 -	static bool 				lookupIsEnsembleCategoryType(EType asset_type);
 -
 -	/* TODO: Change return types from "const char *" to "const std::string &".
 -	This is fairly straightforward, but requires changing some calls to use .c_str().
 -	e.g.:
 -	-	fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
 -	+	fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType).c_str());
 -	*/
 -	
 -private:
 -	// don't instantiate or derive one of these objects
 -	LLAssetType( void ) {}
 -	~LLAssetType( void ) {}
 -};
 -
 -#endif // LL_LLASSETTYPE_H
 +/**  + * @file llassettype.h + * @brief Declaration of LLAssetType. + * + * $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_LLASSETTYPE_H +#define LL_LLASSETTYPE_H + +#include <string> + +#include "stdenums.h" 	// for EDragAndDropType + +class LL_COMMON_API LLAssetType +{ +public: +	enum EType +	{ +		AT_TEXTURE = 0, +			// Used for painting the faces of geometry. +			// Stored in typical j2c stream format. + +		AT_SOUND = 1,  +			// Used to fill the aural spectrum. + +		AT_CALLINGCARD = 2, +		    // Links instant message access to the user on the card. +			// : E.G. A card for yourself, for linden support, for +			// : the guy you were talking to in the coliseum. + +		AT_LANDMARK = 3, +			// Links to places in the world with location and a screen shot or image saved. +			// : E.G. Home, linden headquarters, the coliseum, destinations where  +			// : we want to increase traffic. + +		AT_SCRIPT = 4, +			// Valid scripts that can be attached to an object. +			// : E.G. Open a door, jump into the air. + +		AT_CLOTHING = 5, +			// A collection of textures and parameters that can be worn by an avatar. + +		AT_OBJECT = 6, +			// Any combination of textures, sounds, and scripts that are +			// associated with a fixed piece of geometry. +			// : E.G. A hot tub, a house with working door. + +		AT_NOTECARD = 7, +			// Just text. + +		AT_CATEGORY = 8, +			// Holds a collection of inventory items. +			// It's treated as an item in the inventory and therefore needs a type. + +		AT_ROOT_CATEGORY = 9, +			// A user's root inventory category. +			// We decided to expose it visually, so it seems logical to fold +			// it into the asset types. + +		AT_LSL_TEXT = 10, +		AT_LSL_BYTECODE = 11, +			// The LSL is the scripting language.  +			// We've split it into a text and bytecode representation. +		 +		AT_TEXTURE_TGA = 12, +			// Uncompressed TGA texture. + +		AT_BODYPART = 13, +			// A collection of textures and parameters that can be worn by an avatar. + +		AT_TRASH = 14, +			// Only to be used as a marker for a category preferred type.  +			// Using this, we can throw things in the trash before completely deleting. + +		AT_SNAPSHOT_CATEGORY = 15, +			// A marker for a folder meant for snapshots.  +			// No actual assets will be snapshots, though if there were, you +			// could interpret them as textures. + +		AT_LOST_AND_FOUND = 16, +			// Used to stuff lost&found items into. + +		AT_SOUND_WAV = 17, +			// Uncompressed sound. + +		AT_IMAGE_TGA = 18, +			// Uncompressed image, non-square. +			// Not appropriate for use as a texture. + +		AT_IMAGE_JPEG = 19, +			// Compressed image, non-square. +			// Not appropriate for use as a texture. + +		AT_ANIMATION = 20, +			// Animation. + +		AT_GESTURE = 21, +			// Gesture, sequence of animations, sounds, chat, wait steps. + +		AT_SIMSTATE = 22, +			// Simstate file. + +		AT_FAVORITE = 23, +			// favorite items + +		AT_LINK = 24, +			// Inventory symbolic link + +		AT_LINK_FOLDER = 25, +			// Inventory folder link + +		AT_FOLDER_ENSEMBLE_START = 26, +		AT_FOLDER_ENSEMBLE_END = 45, +			// This range is reserved for special clothing folder types. + +		AT_CURRENT_OUTFIT = 46, +			// Current outfit + +		AT_OUTFIT = 47, +			// Predefined outfit ("look") + +		AT_MY_OUTFITS = 48, +			// Folder that holds your outfits. + +		 +		AT_COUNT = 49, + +			// +*********************************************************+ +			// |  TO ADD AN ELEMENT TO THIS ENUM:                        | +			// +*********************************************************+ +			// | 1. INSERT BEFORE AT_COUNT                               | +			// | 2. INCREMENT AT_COUNT BY 1                              | +			// | 3. ADD TO LLAssetDictionary in LLAssetType.cpp          | +			// | 3. ADD TO DEFAULT_ASSET_FOR_INV in LLInventoryType.cpp  | +			// +*********************************************************+ + +		AT_NONE = -1 +	}; + +	// machine transation between type and strings +	static EType 				lookup(const char* name); // safe conversion to std::string, *TODO: deprecate +	static EType 				lookup(const std::string& type_name); +	static const char*			lookup(EType asset_type); + +	// translation from a type to a human readable form. +	static EType 				lookupHumanReadable(const char* desc_name); // safe conversion to std::string, *TODO: deprecate +	static EType 				lookupHumanReadable(const std::string& readable_name); +	static const char*			lookupHumanReadable(EType asset_type); + +	// Generate a good default description. You may want to add a verb +	// or agent name after this depending on your application. +	static void 				generateDescriptionFor(LLAssetType::EType asset_type, +													   std::string& description); + +	static EType 				getType(const std::string& desc_name); +	static const std::string&	getDesc(EType asset_type); +	static EDragAndDropType   	lookupDragAndDropType(EType asset_type); + +	static bool 				lookupCanLink(EType asset_type); +	static bool 				lookupIsLinkType(EType asset_type); + +	static const char*  		lookupCategoryName(EType asset_type); +	static bool 				lookupIsProtectedCategoryType(EType asset_type); +	static bool 				lookupIsEnsembleCategoryType(EType asset_type); + +	/* TODO: Change return types from "const char *" to "const std::string &". +	This is fairly straightforward, but requires changing some calls to use .c_str(). +	e.g.: +	-	fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType)); +	+	fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType).c_str()); +	*/ +	 +private: +	// don't instantiate or derive one of these objects +	LLAssetType( void ) {} +	~LLAssetType( void ) {} +}; + +#endif // LL_LLASSETTYPE_H diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index 6c5fa5af6d..141b0df43c 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/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h index 671f2a4d1c..5a86b90bff 100644 --- a/indra/llcommon/lleventdispatcher.h +++ b/indra/llcommon/lleventdispatcher.h @@ -1,130 +1,130 @@ -/**
 - * @file   lleventdispatcher.h
 - * @author Nat Goodspeed
 - * @date   2009-06-18
 - * @brief  Central mechanism for dispatching events by string name. This is
 - *         useful when you have a single LLEventPump listener on which you can
 - *         request different operations, vs. instantiating a different
 - *         LLEventPump for each such operation.
 - * 
 - * $LicenseInfo:firstyear=2009&license=viewergpl$
 - * Copyright (c) 2009, Linden Research, Inc.
 - * $/LicenseInfo$
 - */
 -
 -#if ! defined(LL_LLEVENTDISPATCHER_H)
 -#define LL_LLEVENTDISPATCHER_H
 -
 -#include <string>
 -#include <map>
 -#include <boost/function.hpp>
 -#include <boost/bind.hpp>
 -#include <typeinfo>
 -#include "llevents.h"
 -
 -class LLSD;
 -
 -/**
 - * Given an LLSD map, examine a string-valued key and call a corresponding
 - * callable. This class is designed to be contained by an LLEventPump
 - * listener class that will register some of its own methods, though any
 - * callable can be used.
 - */
 -class LL_COMMON_API LLEventDispatcher
 -{
 -public:
 -    LLEventDispatcher(const std::string& desc, const std::string& key);
 -    virtual ~LLEventDispatcher();
 -
 -    /// Accept any C++ callable, typically a boost::bind() expression
 -    typedef boost::function<void(const LLSD&)> Callable;
 -
 -    /**
 -     * Register a @a callable by @a name. The optional @a required parameter
 -     * is used to validate the structure of each incoming event (see
 -     * llsd_matches()).
 -     */
 -    void add(const std::string& name, const Callable& callable, const LLSD& required=LLSD());
 -
 -    /**
 -     * Special case: a subclass of this class can pass an unbound member
 -     * function pointer without explicitly specifying the
 -     * <tt>boost::bind()</tt> expression.
 -     */
 -    template <class CLASS>
 -    void add(const std::string& name, void (CLASS::*method)(const LLSD&),
 -             const LLSD& required=LLSD())
 -    {
 -        addMethod<CLASS>(name, method, required);
 -    }
 -
 -    /// Overload for both const and non-const methods
 -    template <class CLASS>
 -    void add(const std::string& name, void (CLASS::*method)(const LLSD&) const,
 -             const LLSD& required=LLSD())
 -    {
 -        addMethod<CLASS>(name, method, required);
 -    }
 -
 -    /// Unregister a callable
 -    bool remove(const std::string& name);
 -
 -    /// Call a registered callable with an explicitly-specified name. If no
 -    /// such callable exists, die with LL_ERRS. If the @a event fails to match
 -    /// the @a required prototype specified at add() time, die with LL_ERRS.
 -    void operator()(const std::string& name, const LLSD& event) const;
 -
 -    /// Extract the @a key value from the incoming @a event, and call the
 -    /// callable whose name is specified by that map @a key. If no such
 -    /// callable exists, die with LL_ERRS. If the @a event fails to match the
 -    /// @a required prototype specified at add() time, die with LL_ERRS.
 -    void operator()(const LLSD& event) const;
 -
 -    /// Fetch the Callable for the specified name. If no such name was
 -    /// registered, return an empty() Callable.
 -    Callable get(const std::string& name) const;
 -
 -private:
 -    template <class CLASS, typename METHOD>
 -    void addMethod(const std::string& name, const METHOD& method, const LLSD& required)
 -    {
 -        CLASS* downcast = dynamic_cast<CLASS*>(this);
 -        if (! downcast)
 -        {
 -            addFail(name, typeid(CLASS).name());
 -        }
 -        else
 -        {
 -            add(name, boost::bind(method, downcast, _1), required);
 -        }
 -    }
 -    void addFail(const std::string& name, const std::string& classname) const;
 -    /// try to dispatch, return @c true if success
 -    bool attemptCall(const std::string& name, const LLSD& event) const;
 -
 -    std::string mDesc, mKey;
 -    typedef std::map<std::string, std::pair<Callable, LLSD> > DispatchMap;
 -    DispatchMap mDispatch;
 -};
 -
 -/**
 - * Bundle an LLEventPump and a listener with an LLEventDispatcher. A class
 - * that contains (or derives from) LLDispatchListener need only specify the
 - * LLEventPump name and dispatch key, and add() its methods. Incoming events
 - * will automatically be dispatched.
 - */
 -class LL_COMMON_API LLDispatchListener: public LLEventDispatcher
 -{
 -public:
 -    LLDispatchListener(const std::string& pumpname, const std::string& key);
 -
 -    std::string getPumpName() const { return mPump.getName(); }
 -
 -private:
 -    bool process(const LLSD& event);
 -
 -    LLEventStream mPump;
 -    LLTempBoundListener mBoundListener;
 -};
 -
 -#endif /* ! defined(LL_LLEVENTDISPATCHER_H) */
 +/** + * @file   lleventdispatcher.h + * @author Nat Goodspeed + * @date   2009-06-18 + * @brief  Central mechanism for dispatching events by string name. This is + *         useful when you have a single LLEventPump listener on which you can + *         request different operations, vs. instantiating a different + *         LLEventPump for each such operation. + *  + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLEVENTDISPATCHER_H) +#define LL_LLEVENTDISPATCHER_H + +#include <string> +#include <map> +#include <boost/function.hpp> +#include <boost/bind.hpp> +#include <typeinfo> +#include "llevents.h" + +class LLSD; + +/** + * Given an LLSD map, examine a string-valued key and call a corresponding + * callable. This class is designed to be contained by an LLEventPump + * listener class that will register some of its own methods, though any + * callable can be used. + */ +class LL_COMMON_API LLEventDispatcher +{ +public: +    LLEventDispatcher(const std::string& desc, const std::string& key); +    virtual ~LLEventDispatcher(); + +    /// Accept any C++ callable, typically a boost::bind() expression +    typedef boost::function<void(const LLSD&)> Callable; + +    /** +     * Register a @a callable by @a name. The optional @a required parameter +     * is used to validate the structure of each incoming event (see +     * llsd_matches()). +     */ +    void add(const std::string& name, const Callable& callable, const LLSD& required=LLSD()); + +    /** +     * Special case: a subclass of this class can pass an unbound member +     * function pointer without explicitly specifying the +     * <tt>boost::bind()</tt> expression. +     */ +    template <class CLASS> +    void add(const std::string& name, void (CLASS::*method)(const LLSD&), +             const LLSD& required=LLSD()) +    { +        addMethod<CLASS>(name, method, required); +    } + +    /// Overload for both const and non-const methods +    template <class CLASS> +    void add(const std::string& name, void (CLASS::*method)(const LLSD&) const, +             const LLSD& required=LLSD()) +    { +        addMethod<CLASS>(name, method, required); +    } + +    /// Unregister a callable +    bool remove(const std::string& name); + +    /// Call a registered callable with an explicitly-specified name. If no +    /// such callable exists, die with LL_ERRS. If the @a event fails to match +    /// the @a required prototype specified at add() time, die with LL_ERRS. +    void operator()(const std::string& name, const LLSD& event) const; + +    /// Extract the @a key value from the incoming @a event, and call the +    /// callable whose name is specified by that map @a key. If no such +    /// callable exists, die with LL_ERRS. If the @a event fails to match the +    /// @a required prototype specified at add() time, die with LL_ERRS. +    void operator()(const LLSD& event) const; + +    /// Fetch the Callable for the specified name. If no such name was +    /// registered, return an empty() Callable. +    Callable get(const std::string& name) const; + +private: +    template <class CLASS, typename METHOD> +    void addMethod(const std::string& name, const METHOD& method, const LLSD& required) +    { +        CLASS* downcast = dynamic_cast<CLASS*>(this); +        if (! downcast) +        { +            addFail(name, typeid(CLASS).name()); +        } +        else +        { +            add(name, boost::bind(method, downcast, _1), required); +        } +    } +    void addFail(const std::string& name, const std::string& classname) const; +    /// try to dispatch, return @c true if success +    bool attemptCall(const std::string& name, const LLSD& event) const; + +    std::string mDesc, mKey; +    typedef std::map<std::string, std::pair<Callable, LLSD> > DispatchMap; +    DispatchMap mDispatch; +}; + +/** + * Bundle an LLEventPump and a listener with an LLEventDispatcher. A class + * that contains (or derives from) LLDispatchListener need only specify the + * LLEventPump name and dispatch key, and add() its methods. Incoming events + * will automatically be dispatched. + */ +class LL_COMMON_API LLDispatchListener: public LLEventDispatcher +{ +public: +    LLDispatchListener(const std::string& pumpname, const std::string& key); + +    std::string getPumpName() const { return mPump.getName(); } + +private: +    bool process(const LLSD& event); + +    LLEventStream mPump; +    LLTempBoundListener mBoundListener; +}; + +#endif /* ! defined(LL_LLEVENTDISPATCHER_H) */ diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index 64e5cb5da7..192d79b27d 100644 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -1,943 +1,943 @@ -/**
 - * @file   llevents.h
 - * @author Kent Quirk, Nat Goodspeed
 - * @date   2008-09-11
 - * @brief  This is an implementation of the event system described at
 - *         https://wiki.lindenlab.com/wiki/Viewer:Messaging/Event_System,
 - *         originally introduced in llnotifications.h. It has nothing
 - *         whatsoever to do with the older system in llevent.h.
 - * 
 - * $LicenseInfo:firstyear=2008&license=viewergpl$
 - * Copyright (c) 2008, Linden Research, Inc.
 - * $/LicenseInfo$
 - */
 -
 -#if ! defined(LL_LLEVENTS_H)
 -#define LL_LLEVENTS_H
 -
 -#include <string>
 -#include <map>
 -#include <set>
 -#include <vector>
 -#include <deque>
 -#include <stdexcept>
 -#if LL_WINDOWS
 -	#pragma warning (push)
 -	#pragma warning (disable : 4263) // boost::signals2::expired_slot::what() has const mismatch
 -	#pragma warning (disable : 4264) 
 -#endif
 -#include <boost/signals2.hpp>
 -#if LL_WINDOWS
 -	#pragma warning (pop)
 -#endif
 -
 -#include <boost/bind.hpp>
 -#include <boost/shared_ptr.hpp>
 -#include <boost/enable_shared_from_this.hpp>
 -#include <boost/utility.hpp>        // noncopyable
 -#include <boost/optional/optional.hpp>
 -#include <boost/visit_each.hpp>
 -#include <boost/ref.hpp>            // reference_wrapper
 -#include <boost/type_traits/is_pointer.hpp>
 -#include <boost/function.hpp>
 -#include <boost/static_assert.hpp>
 -#include "llsd.h"
 -#include "llsingleton.h"
 -#include "lldependencies.h"
 -
 -// override this to allow binding free functions with more parameters
 -#ifndef LLEVENTS_LISTENER_ARITY
 -#define LLEVENTS_LISTENER_ARITY 10
 -#endif
 -
 -// hack for testing
 -#ifndef testable
 -#define testable private
 -#endif
 -
 -/*****************************************************************************
 -*   Signal and handler declarations
 -*   Using a single handler signature means that we can have a common handler
 -*   type, rather than needing a distinct one for each different handler.
 -*****************************************************************************/
 -
 -/**
 - * A boost::signals Combiner that stops the first time a handler returns true
 - * We need this because we want to have our handlers return bool, so that
 - * we have the option to cause a handler to stop further processing. The
 - * default handler fails when the signal returns a value but has no slots.
 - */
 -struct LLStopWhenHandled
 -{
 -    typedef bool result_type;
 -
 -    template<typename InputIterator>
 -    result_type operator()(InputIterator first, InputIterator last) const
 -    {
 -        for (InputIterator si = first; si != last; ++si)
 -		{
 -            if (*si)
 -			{
 -                return true;
 -			}
 -		}
 -        return false;
 -    }
 -};
 -
 -/**
 - * We want to have a standard signature for all signals; this way,
 - * we can easily document a protocol for communicating across
 - * dlls and into scripting languages someday.
 - *
 - * We want to return a bool to indicate whether the signal has been
 - * handled and should NOT be passed on to other listeners.
 - * Return true to stop further handling of the signal, and false
 - * to continue.
 - *
 - * We take an LLSD because this way the contents of the signal
 - * are independent of the API used to communicate it.
 - * It is const ref because then there's low cost to pass it;
 - * if you only need to inspect it, it's very cheap.
 - *
 - * @internal
 - * The @c float template parameter indicates that we will internally use @c
 - * float to indicate relative listener order on a given LLStandardSignal.
 - * Don't worry, the @c float values are strictly internal! They are not part
 - * of the interface, for the excellent reason that requiring the caller to
 - * specify a numeric key to establish order means that the caller must know
 - * the universe of possible values. We use LLDependencies for that instead.
 - */
 -typedef boost::signals2::signal<bool(const LLSD&), LLStopWhenHandled, float>  LLStandardSignal;
 -/// Methods that forward listeners (e.g. constructed with
 -/// <tt>boost::bind()</tt>) should accept (const LLEventListener&)
 -typedef LLStandardSignal::slot_type LLEventListener;
 -/// Result of registering a listener, supports <tt>connected()</tt>,
 -/// <tt>disconnect()</tt> and <tt>blocked()</tt>
 -typedef boost::signals2::connection LLBoundListener;
 -/// Storing an LLBoundListener in LLTempBoundListener will disconnect the
 -/// referenced listener when the LLTempBoundListener instance is destroyed.
 -typedef boost::signals2::scoped_connection LLTempBoundListener;
 -
 -/**
 - * A common idiom for event-based code is to accept either a callable --
 - * directly called on completion -- or the string name of an LLEventPump on
 - * which to post the completion event. Specifying a parameter as <tt>const
 - * LLListenerOrPumpName&</tt> allows either.
 - *
 - * Calling a validly-constructed LLListenerOrPumpName, passing the LLSD
 - * 'event' object, either calls the callable or posts the event to the named
 - * LLEventPump.
 - *
 - * A default-constructed LLListenerOrPumpName is 'empty'. (This is useful as
 - * the default value of an optional method parameter.) Calling it throws
 - * LLListenerOrPumpName::Empty. Test for this condition beforehand using
 - * either <tt>if (param)</tt> or <tt>if (! param)</tt>.
 - */
 -class LL_COMMON_API LLListenerOrPumpName
 -{
 -public:
 -    /// passing string name of LLEventPump
 -    LLListenerOrPumpName(const std::string& pumpname);
 -    /// passing string literal (overload so compiler isn't forced to infer
 -    /// double conversion)
 -    LLListenerOrPumpName(const char* pumpname);
 -    /// passing listener -- the "anything else" catch-all case. The type of an
 -    /// object constructed by boost::bind() isn't intended to be written out.
 -    /// Normally we'd just accept 'const LLEventListener&', but that would
 -    /// require double implicit conversion: boost::bind() object to
 -    /// LLEventListener, LLEventListener to LLListenerOrPumpName. So use a
 -    /// template to forward anything.
 -    template<typename T>
 -    LLListenerOrPumpName(const T& listener): mListener(listener) {}
 -
 -    /// for omitted method parameter: uninitialized mListener
 -    LLListenerOrPumpName() {}
 -
 -    /// test for validity
 -    operator bool() const { return bool(mListener); }
 -    bool operator! () const { return ! mListener; }
 -
 -    /// explicit accessor
 -    const LLEventListener& getListener() const { return *mListener; }
 -
 -    /// implicit conversion to LLEventListener
 -    operator LLEventListener() const { return *mListener; }
 -
 -    /// allow calling directly
 -    bool operator()(const LLSD& event) const;
 -
 -    /// exception if you try to call when empty
 -    struct Empty: public std::runtime_error
 -    {
 -        Empty(const std::string& what):
 -            std::runtime_error(std::string("LLListenerOrPumpName::Empty: ") + what) {}
 -    };
 -
 -private:
 -    boost::optional<LLEventListener> mListener;
 -};
 -
 -/*****************************************************************************
 -*   LLEventPumps
 -*****************************************************************************/
 -class LLEventPump;
 -
 -/**
 - * LLEventPumps is a Singleton manager through which one typically accesses
 - * this subsystem.
 - */
 -class LL_COMMON_API LLEventPumps: public LLSingleton<LLEventPumps>
 -{
 -    friend class LLSingleton<LLEventPumps>;
 -public:
 -    /**
 -     * Find or create an LLEventPump instance with a specific name. We return
 -     * a reference so there's no question about ownership. obtain() @em finds
 -     * an instance without conferring @em ownership.
 -     */
 -    LLEventPump& obtain(const std::string& name);
 -    /**
 -     * Flush all known LLEventPump instances
 -     */
 -    void flush();
 -
 -    /**
 -     * Reset all known LLEventPump instances
 -     * workaround for DEV-35406 crash on shutdown
 -     */
 -    void reset();
 -
 -private:
 -    friend class LLEventPump;
 -    /**
 -     * Register a new LLEventPump instance (internal)
 -     */
 -    std::string registerNew(const LLEventPump&, const std::string& name, bool tweak);
 -    /**
 -     * Unregister a doomed LLEventPump instance (internal)
 -     */
 -    void unregister(const LLEventPump&);
 -
 -private:
 -    LLEventPumps();
 -    ~LLEventPumps();
 -
 -testable:
 -    // Map of all known LLEventPump instances, whether or not we instantiated
 -    // them. We store a plain old LLEventPump* because this map doesn't claim
 -    // ownership of the instances. Though the common usage pattern is to
 -    // request an instance using obtain(), it's fair to instantiate an
 -    // LLEventPump subclass statically, as a class member, on the stack or on
 -    // the heap. In such cases, the instantiating party is responsible for its
 -    // lifespan.
 -    typedef std::map<std::string, LLEventPump*> PumpMap;
 -    PumpMap mPumpMap;
 -    // Set of all LLEventPumps we instantiated. Membership in this set means
 -    // we claim ownership, and will delete them when this LLEventPumps is
 -    // destroyed.
 -    typedef std::set<LLEventPump*> PumpSet;
 -    PumpSet mOurPumps;
 -    // LLEventPump names that should be instantiated as LLEventQueue rather
 -    // than as LLEventStream
 -    typedef std::set<std::string> PumpNames;
 -    PumpNames mQueueNames;
 -};
 -
 -/*****************************************************************************
 -*   details
 -*****************************************************************************/
 -namespace LLEventDetail
 -{
 -    /// Any callable capable of connecting an LLEventListener to an
 -    /// LLStandardSignal to produce an LLBoundListener can be mapped to this
 -    /// signature.
 -    typedef boost::function<LLBoundListener(const LLEventListener&)> ConnectFunc;
 -
 -    /**
 -     * Utility template function to use Visitor appropriately
 -     *
 -     * @param listener Callable to connect, typically a boost::bind()
 -     * expression. This will be visited by Visitor using boost::visit_each().
 -     * @param connect_func Callable that will connect() @a listener to an
 -     * LLStandardSignal, returning LLBoundListener.
 -     */
 -    template <typename LISTENER>
 -    LLBoundListener visit_and_connect(const LISTENER& listener,
 -                                      const ConnectFunc& connect_func);
 -} // namespace LLEventDetail
 -
 -/*****************************************************************************
 -*   LLEventTrackable
 -*****************************************************************************/
 -/**
 - * LLEventTrackable wraps boost::signals2::trackable, which resembles
 - * boost::trackable. Derive your listener class from LLEventTrackable instead,
 - * and use something like
 - * <tt>LLEventPump::listen(boost::bind(&YourTrackableSubclass::method,
 - * instance, _1))</tt>. This will implicitly disconnect when the object
 - * referenced by @c instance is destroyed.
 - *
 - * @note
 - * LLEventTrackable doesn't address a couple of cases:
 - * * Object destroyed during call
 - *   - You enter a slot call in thread A.
 - *   - Thread B destroys the object, which of course disconnects it from any
 - *     future slot calls.
 - *   - Thread A's call uses 'this', which now refers to a defunct object.
 - *     Undefined behavior results.
 - * * Call during destruction
 - *   - @c MySubclass is derived from LLEventTrackable.
 - *   - @c MySubclass registers one of its own methods using
 - *     <tt>LLEventPump::listen()</tt>.
 - *   - The @c MySubclass object begins destruction. <tt>~MySubclass()</tt>
 - *     runs, destroying state specific to the subclass. (For instance, a
 - *     <tt>Foo*</tt> data member is <tt>delete</tt>d but not zeroed.)
 - *   - The listening method will not be disconnected until
 - *     <tt>~LLEventTrackable()</tt> runs.
 - *   - Before we get there, another thread posts data to the @c LLEventPump
 - *     instance, calling the @c MySubclass method.
 - *   - The method in question relies on valid @c MySubclass state. (For
 - *     instance, it attempts to dereference the <tt>Foo*</tt> pointer that was
 - *     <tt>delete</tt>d but not zeroed.)
 - *   - Undefined behavior results.
 - * If you suspect you may encounter any such scenario, you're better off
 - * managing the lifespan of your object with <tt>boost::shared_ptr</tt>.
 - * Passing <tt>LLEventPump::listen()</tt> a <tt>boost::bind()</tt> expression
 - * involving a <tt>boost::weak_ptr<Foo></tt> is recognized specially, engaging
 - * thread-safe Boost.Signals2 machinery.
 - */
 -typedef boost::signals2::trackable LLEventTrackable;
 -
 -/*****************************************************************************
 -*   LLEventPump
 -*****************************************************************************/
 -/**
 - * LLEventPump is the base class interface through which we access the
 - * concrete subclasses LLEventStream and LLEventQueue.
 - *
 - * @NOTE
 - * LLEventPump derives from LLEventTrackable so that when you "chain"
 - * LLEventPump instances together, they will automatically disconnect on
 - * destruction. Please see LLEventTrackable documentation for situations in
 - * which this may be perilous across threads.
 - */
 -class LL_COMMON_API LLEventPump: public LLEventTrackable
 -{
 -public:
 -    /**
 -     * Exception thrown by LLEventPump(). You are trying to instantiate an
 -     * LLEventPump (subclass) using the same name as some other instance, and
 -     * you didn't pass <tt>tweak=true</tt> to permit it to generate a unique
 -     * variant.
 -     */
 -    struct DupPumpName: public std::runtime_error
 -    {
 -        DupPumpName(const std::string& what):
 -            std::runtime_error(std::string("DupPumpName: ") + what) {}
 -    };
 -
 -    /**
 -     * Instantiate an LLEventPump (subclass) with the string name by which it
 -     * can be found using LLEventPumps::obtain().
 -     *
 -     * If you pass (or default) @a tweak to @c false, then a duplicate name
 -     * will throw DupPumpName. This won't happen if LLEventPumps::obtain()
 -     * instantiates the LLEventPump, because obtain() uses find-or-create
 -     * logic. It can only happen if you instantiate an LLEventPump in your own
 -     * code -- and a collision with the name of some other LLEventPump is
 -     * likely to cause much more subtle problems!
 -     *
 -     * When you hand-instantiate an LLEventPump, consider passing @a tweak as
 -     * @c true. This directs LLEventPump() to append a suffix to the passed @a
 -     * name to make it unique. You can retrieve the adjusted name by calling
 -     * getName() on your new instance.
 -     */
 -    LLEventPump(const std::string& name, bool tweak=false);
 -    virtual ~LLEventPump();
 -
 -    /// group exceptions thrown by listen(). We use exceptions because these
 -    /// particular errors are likely to be coding errors, found and fixed by
 -    /// the developer even before preliminary checkin.
 -    struct ListenError: public std::runtime_error
 -    {
 -        ListenError(const std::string& what): std::runtime_error(what) {}
 -    };
 -    /**
 -     * exception thrown by listen(). You are attempting to register a
 -     * listener on this LLEventPump using the same listener name as an
 -     * already-registered listener.
 -     */
 -    struct DupListenerName: public ListenError
 -    {
 -        DupListenerName(const std::string& what):
 -            ListenError(std::string("DupListenerName: ") + what)
 -        {}
 -    };
 -    /**
 -     * exception thrown by listen(). The order dependencies specified for your
 -     * listener are incompatible with existing listeners.
 -     *
 -     * Consider listener "a" which specifies before "b" and "b" which
 -     * specifies before "c". You are now attempting to register "c" before
 -     * "a". There is no order that can satisfy all constraints.
 -     */
 -    struct Cycle: public ListenError
 -    {
 -        Cycle(const std::string& what): ListenError(std::string("Cycle: ") + what) {}
 -    };
 -    /**
 -     * exception thrown by listen(). This one means that your new listener
 -     * would force a change to the order of previously-registered listeners,
 -     * and we don't have a good way to implement that.
 -     *
 -     * Consider listeners "some", "other" and "third". "some" and "other" are
 -     * registered earlier without specifying relative order, so "other"
 -     * happens to be first. Now you attempt to register "third" after "some"
 -     * and before "other". Whoops, that would require swapping "some" and
 -     * "other", which we can't do. Instead we throw this exception.
 -     *
 -     * It may not be possible to change the registration order so we already
 -     * know "third"s order requirement by the time we register the second of
 -     * "some" and "other". A solution would be to specify that "some" must
 -     * come before "other", or equivalently that "other" must come after
 -     * "some".
 -     */
 -    struct OrderChange: public ListenError
 -    {
 -        OrderChange(const std::string& what): ListenError(std::string("OrderChange: ") + what) {}
 -    };
 -
 -    /// used by listen()
 -    typedef std::vector<std::string> NameList;
 -    /// convenience placeholder for when you explicitly want to pass an empty
 -    /// NameList
 -    const static NameList empty;
 -
 -    /// Get this LLEventPump's name
 -    std::string getName() const { return mName; }
 -
 -    /**
 -     * Register a new listener with a unique name. Specify an optional list
 -     * of other listener names after which this one must be called, likewise
 -     * an optional list of other listener names before which this one must be
 -     * called. The other listeners mentioned need not yet be registered
 -     * themselves. listen() can throw any ListenError; see ListenError
 -     * subclasses.
 -     *
 -     * The listener name must be unique among active listeners for this
 -     * LLEventPump, else you get DupListenerName. If you don't care to invent
 -     * a name yourself, use inventName(). (I was tempted to recognize e.g. ""
 -     * and internally generate a distinct name for that case. But that would
 -     * handle badly the scenario in which you want to add, remove, re-add,
 -     * etc. the same listener: each new listen() call would necessarily
 -     * perform a new dependency sort. Assuming you specify the same
 -     * after/before lists each time, using inventName() when you first
 -     * instantiate your listener, then passing the same name on each listen()
 -     * call, allows us to optimize away the second and subsequent dependency
 -     * sorts.
 -     *
 -     * If (as is typical) you pass a <tt>boost::bind()</tt> expression as @a
 -     * listener, listen() will inspect the components of that expression. If a
 -     * bound object matches any of several cases, the connection will
 -     * automatically be disconnected when that object is destroyed.
 -     *
 -     * * You bind a <tt>boost::weak_ptr</tt>.
 -     * * Binding a <tt>boost::shared_ptr</tt> that way would ensure that the
 -     *   referenced object would @em never be destroyed, since the @c
 -     *   shared_ptr stored in the LLEventPump would remain an outstanding
 -     *   reference. Use the weaken() function to convert your @c shared_ptr to
 -     *   @c weak_ptr. Because this is easy to forget, binding a @c shared_ptr
 -     *   will produce a compile error (@c BOOST_STATIC_ASSERT failure).
 -     * * You bind a simple pointer or reference to an object derived from
 -     *   <tt>boost::enable_shared_from_this</tt>. (UNDER CONSTRUCTION)
 -     * * You bind a simple pointer or reference to an object derived from
 -     *   LLEventTrackable. Unlike the cases described above, though, this is
 -     *   vulnerable to a couple of cross-thread race conditions, as described
 -     *   in the LLEventTrackable documentation.
 -     */
 -    template <typename LISTENER>
 -    LLBoundListener listen(const std::string& name, const LISTENER& listener,
 -                           const NameList& after=NameList(),
 -                           const NameList& before=NameList())
 -    {
 -        // Examine listener, using our listen_impl() method to make the
 -        // actual connection.
 -        // This is why listen() is a template. Conversion from boost::bind()
 -        // to LLEventListener performs type erasure, so it's important to look
 -        // at the boost::bind object itself before that happens.
 -        return LLEventDetail::visit_and_connect(listener,
 -                                                boost::bind(&LLEventPump::listen_impl,
 -                                                            this,
 -                                                            name,
 -                                                            _1,
 -                                                            after,
 -                                                            before));
 -    }
 -
 -    /// Get the LLBoundListener associated with the passed name (dummy
 -    /// LLBoundListener if not found)
 -    virtual LLBoundListener getListener(const std::string& name) const;
 -    /**
 -     * Instantiate one of these to block an existing connection:
 -     * @code
 -     * { // in some local scope
 -     *     LLEventPump::Blocker block(someLLBoundListener);
 -     *     // code that needs the connection blocked
 -     * } // unblock the connection again
 -     * @endcode
 -     */
 -    typedef boost::signals2::shared_connection_block Blocker;
 -    /// Unregister a listener by name. Prefer this to
 -    /// <tt>getListener(name).disconnect()</tt> because stopListening() also
 -    /// forgets this name.
 -    virtual void stopListening(const std::string& name);
 -    /// Post an event to all listeners. The @c bool return is only meaningful
 -    /// if the underlying leaf class is LLEventStream -- beware of relying on
 -    /// it too much! Truthfully, we return @c bool mostly to permit chaining
 -    /// one LLEventPump as a listener on another.
 -    virtual bool post(const LLSD&) = 0;
 -    /// Enable/disable: while disabled, silently ignore all post() calls
 -    virtual void enable(bool enabled=true) { mEnabled = enabled; }
 -    /// query
 -    virtual bool enabled() const { return mEnabled; }
 -
 -    /// Generate a distinct name for a listener -- see listen()
 -    static std::string inventName(const std::string& pfx="listener");
 -
 -private:
 -    friend class LLEventPumps;
 -    /// flush queued events
 -    virtual void flush() {}
 -
 -    virtual void reset();
 -
 -private:
 -    virtual LLBoundListener listen_impl(const std::string& name, const LLEventListener&,
 -                                        const NameList& after,
 -                                        const NameList& before);
 -    std::string mName;
 -
 -protected:
 -    /// implement the dispatching
 -    boost::scoped_ptr<LLStandardSignal> mSignal;
 -
 -    /// valve open?
 -    bool mEnabled;
 -    /// Map of named listeners. This tracks the listeners that actually exist
 -    /// at this moment. When we stopListening(), we discard the entry from
 -    /// this map.
 -    typedef std::map<std::string, boost::signals2::connection> ConnectionMap;
 -    ConnectionMap mConnections;
 -    typedef LLDependencies<std::string, float> DependencyMap;
 -    /// Dependencies between listeners. For each listener, track the float
 -    /// used to establish its place in mSignal's order. This caches all the
 -    /// listeners that have ever registered; stopListening() does not discard
 -    /// the entry from this map. This is to avoid a new dependency sort if the
 -    /// same listener with the same dependencies keeps hopping on and off this
 -    /// LLEventPump.
 -    DependencyMap mDeps;
 -};
 -
 -/*****************************************************************************
 -*   LLEventStream
 -*****************************************************************************/
 -/**
 - * LLEventStream is a thin wrapper around LLStandardSignal. Posting an
 - * event immediately calls all registered listeners.
 - */
 -class LL_COMMON_API LLEventStream: public LLEventPump
 -{
 -public:
 -    LLEventStream(const std::string& name, bool tweak=false): LLEventPump(name, tweak) {}
 -    virtual ~LLEventStream() {}
 -
 -    /// Post an event to all listeners
 -    virtual bool post(const LLSD& event);
 -};
 -
 -/*****************************************************************************
 -*   LLEventQueue
 -*****************************************************************************/
 -/**
 - * LLEventQueue isa LLEventPump whose post() method defers calling registered
 - * listeners until flush() is called.
 - */
 -class LL_COMMON_API LLEventQueue: public LLEventPump
 -{
 -public:
 -    LLEventQueue(const std::string& name, bool tweak=false): LLEventPump(name, tweak) {}
 -    virtual ~LLEventQueue() {}
 -
 -    /// Post an event to all listeners
 -    virtual bool post(const LLSD& event);
 -
 -private:
 -    /// flush queued events
 -    virtual void flush();
 -
 -private:
 -    typedef std::deque<LLSD> EventQueue;
 -    EventQueue mEventQueue;
 -};
 -
 -/*****************************************************************************
 -*   LLReqID
 -*****************************************************************************/
 -/**
 - * This class helps the implementer of a given event API to honor the
 - * ["reqid"] convention. By this convention, each event API stamps into its
 - * response LLSD a ["reqid"] key whose value echoes the ["reqid"] value, if
 - * any, from the corresponding request.
 - *
 - * This supports an (atypical, but occasionally necessary) use case in which
 - * two or more asynchronous requests are multiplexed onto the same ["reply"]
 - * LLEventPump. Since the response events could arrive in arbitrary order, the
 - * caller must be able to demux them. It does so by matching the ["reqid"]
 - * value in each response with the ["reqid"] value in the corresponding
 - * request.
 - *
 - * It is the caller's responsibility to ensure distinct ["reqid"] values for
 - * that case. Though LLSD::UUID is guaranteed to work, it might be overkill:
 - * the "namespace" of unique ["reqid"] values is simply the set of requests
 - * specifying the same ["reply"] LLEventPump name.
 - *
 - * Making a given event API echo the request's ["reqid"] into the response is
 - * nearly trivial. This helper is mostly for mnemonic purposes, to serve as a
 - * place to put these comments. We hope that each time a coder implements a
 - * new event API based on some existing one, s/he will say, "Huh, what's an
 - * LLReqID?" and look up this material.
 - *
 - * The hardest part about the convention is deciding where to store the
 - * ["reqid"] value. Ironically, LLReqID can't help with that: you must store
 - * an LLReqID instance in whatever storage will persist until the reply is
 - * sent. For example, if the request ultimately ends up using a Responder
 - * subclass, storing an LLReqID instance in the Responder works.
 - *
 - * @note
 - * The @em implementer of an event API must honor the ["reqid"] convention.
 - * However, the @em caller of an event API need only use it if s/he is sharing
 - * the same ["reply"] LLEventPump for two or more asynchronous event API
 - * requests.
 - *
 - * In most cases, it's far easier for the caller to instantiate a local
 - * LLEventStream and pass its name to the event API in question. Then it's
 - * perfectly reasonable not to set a ["reqid"] key in the request, ignoring
 - * the @c isUndefined() ["reqid"] value in the response.
 - */
 -class LL_COMMON_API LLReqID
 -{
 -public:
 -    /**
 -     * If you have the request in hand at the time you instantiate the
 -     * LLReqID, pass that request to extract its ["reqid"].
 - */
 -    LLReqID(const LLSD& request):
 -        mReqid(request["reqid"])
 -    {}
 -    /// If you don't yet have the request, use setFrom() later.
 -    LLReqID() {}
 -
 -    /// Extract and store the ["reqid"] value from an incoming request.
 -    void setFrom(const LLSD& request)
 -    {
 -        mReqid = request["reqid"];
 -    }
 -
 -    /// Set ["reqid"] key into a pending response LLSD object.
 -    void stamp(LLSD& response) const;
 -
 -    /// Make a whole new response LLSD object with our ["reqid"].
 -    LLSD makeResponse() const
 -    {
 -        LLSD response;
 -        stamp(response);
 -        return response;
 -    }
 -
 -    /// Not really sure of a use case for this accessor...
 -    LLSD getReqID() const { return mReqid; }
 -
 -private:
 -    LLSD mReqid;
 -};
 -
 -/*****************************************************************************
 -*   Underpinnings
 -*****************************************************************************/
 -/**
 - * We originally provided a suite of overloaded
 - * LLEventTrackable::listenTo(LLEventPump&, ...) methods that would call
 - * LLEventPump::listen(...) and then pass the returned LLBoundListener to
 - * LLEventTrackable::track(). This was workable but error-prone: the coder
 - * must remember to call listenTo() rather than the more straightforward
 - * listen() method.
 - *
 - * Now we publish only the single canonical listen() method, so there's a
 - * uniform mechanism. Having a single way to do this is good, in that there's
 - * no question in the coder's mind which of several alternatives to choose.
 - *
 - * To support automatic connection management, we use boost::visit_each
 - * (http://www.boost.org/doc/libs/1_37_0/doc/html/boost/visit_each.html) to
 - * inspect each argument of a boost::bind expression. (Although the visit_each
 - * mechanism was first introduced with the original Boost.Signals library, it
 - * was only later documented.)
 - *
 - * Cases:
 - * * At least one of the function's arguments is a boost::weak_ptr<T>. Pass
 - *   the corresponding shared_ptr to slot_type::track(). Ideally that would be
 - *   the object whose method we want to call, but in fact we do the same for
 - *   any weak_ptr we might find among the bound arguments. If we're passing
 - *   our bound method a weak_ptr to some object, wouldn't the destruction of
 - *   that object invalidate the call? So we disconnect automatically when any
 - *   such object is destroyed. This is the mechanism preferred by boost::
 - *   signals2.
 - * * One of the functions's arguments is a boost::shared_ptr<T>. This produces
 - *   a compile error: the bound copy of the shared_ptr stored in the
 - *   boost_bind object stored in the signal object would make the referenced
 - *   T object immortal. We provide a weaken() function. Pass
 - *   weaken(your_shared_ptr) instead. (We can inspect, but not modify, the
 - *   boost::bind object. Otherwise we'd replace the shared_ptr with weak_ptr
 - *   implicitly and just proceed.)
 - * * One of the function's arguments is a plain pointer/reference to an object
 - *   derived from boost::enable_shared_from_this. We assume that this object
 - *   is managed using boost::shared_ptr, so we implicitly extract a shared_ptr
 - *   and track that. (UNDER CONSTRUCTION)
 - * * One of the function's arguments is derived from LLEventTrackable. Pass
 - *   the LLBoundListener to its LLEventTrackable::track(). This is vulnerable
 - *   to a couple different race conditions, as described in LLEventTrackable
 - *   documentation. (NOTE: Now that LLEventTrackable is a typedef for
 - *   boost::signals2::trackable, the Signals2 library handles this itself, so
 - *   our visitor needs no special logic for this case.)
 - * * Any other argument type is irrelevant to automatic connection management.
 - */
 -
 -namespace LLEventDetail
 -{
 -    template <typename F>
 -    const F& unwrap(const F& f) { return f; }
 -
 -    template <typename F>
 -    const F& unwrap(const boost::reference_wrapper<F>& f) { return f.get(); }
 -
 -    // Most of the following is lifted from the Boost.Signals use of
 -    // visit_each.
 -    template<bool Cond> struct truth {};
 -
 -    /**
 -     * boost::visit_each() Visitor, used on a template argument <tt>const F&
 -     * f</tt> as follows (see visit_and_connect()):
 -     * @code
 -     * LLEventListener listener(f);
 -     * Visitor visitor(listener); // bind listener so it can track() shared_ptrs
 -     * using boost::visit_each;   // allow unqualified visit_each() call for ADL
 -     * visit_each(visitor, unwrap(f));
 -     * @endcode
 -     */
 -    class Visitor
 -    {
 -    public:
 -        /**
 -         * Visitor binds a reference to LLEventListener so we can track() any
 -         * shared_ptrs we find in the argument list.
 -         */
 -        Visitor(LLEventListener& listener):
 -            mListener(listener)
 -        {
 -        }
 -
 -        /**
 -         * boost::visit_each() calls this method for each component of a
 -         * boost::bind() expression.
 -         */
 -        template <typename T>
 -        void operator()(const T& t) const
 -        {
 -            decode(t, 0);
 -        }
 -
 -    private:
 -        // decode() decides between a reference wrapper and anything else
 -        // boost::ref() variant
 -        template<typename T>
 -        void decode(const boost::reference_wrapper<T>& t, int) const
 -        {
 -//          add_if_trackable(t.get_pointer());
 -        }
 -
 -        // decode() anything else
 -        template<typename T>
 -        void decode(const T& t, long) const
 -        {
 -            typedef truth<(boost::is_pointer<T>::value)> is_a_pointer;
 -            maybe_get_pointer(t, is_a_pointer());
 -        }
 -
 -        // maybe_get_pointer() decides between a pointer and a non-pointer
 -        // plain pointer variant
 -        template<typename T>
 -        void maybe_get_pointer(const T& t, truth<true>) const
 -        {
 -//          add_if_trackable(t);
 -        }
 -
 -        // shared_ptr variant
 -        template<typename T>
 -        void maybe_get_pointer(const boost::shared_ptr<T>& t, truth<false>) const
 -        {
 -            // If we have a shared_ptr to this object, it doesn't matter
 -            // whether the object is derived from LLEventTrackable, so no
 -            // further analysis of T is needed.
 -//          mListener.track(t);
 -
 -            // Make this case illegal. Passing a bound shared_ptr to
 -            // slot_type::track() is useless, since the bound shared_ptr will
 -            // keep the object alive anyway! Force the coder to cast to weak_ptr.
 -
 -            // Trivial as it is, make the BOOST_STATIC_ASSERT() condition
 -            // dependent on template param so the macro is only evaluated if
 -            // this method is in fact instantiated, as described here:
 -            // http://www.boost.org/doc/libs/1_34_1/doc/html/boost_staticassert.html
 -
 -            // ATTENTION: Don't bind a shared_ptr<anything> using
 -            // LLEventPump::listen(boost::bind()). Doing so captures a copy of
 -            // the shared_ptr, making the referenced object effectively
 -            // immortal. Use the weaken() function, e.g.:
 -            // somepump.listen(boost::bind(...weaken(my_shared_ptr)...));
 -            // This lets us automatically disconnect when the referenced
 -            // object is destroyed.
 -            BOOST_STATIC_ASSERT(sizeof(T) == 0);
 -        }
 -
 -        // weak_ptr variant
 -        template<typename T>
 -        void maybe_get_pointer(const boost::weak_ptr<T>& t, truth<false>) const
 -        {
 -            // If we have a weak_ptr to this object, it doesn't matter
 -            // whether the object is derived from LLEventTrackable, so no
 -            // further analysis of T is needed.
 -            mListener.track(t);
 -//          std::cout << "Found weak_ptr<" << typeid(T).name() << ">!\n";
 -        }
 -
 -#if 0
 -        // reference to anything derived from boost::enable_shared_from_this
 -        template <typename T>
 -        inline void maybe_get_pointer(const boost::enable_shared_from_this<T>& ct,
 -                                      truth<false>) const
 -        {
 -            // Use the slot_type::track(shared_ptr) mechanism. Cast away
 -            // const-ness because (in our code base anyway) it's unusual
 -            // to find shared_ptr<const T>.
 -            boost::enable_shared_from_this<T>&
 -                t(const_cast<boost::enable_shared_from_this<T>&>(ct));
 -            std::cout << "Capturing shared_from_this()" << std::endl;
 -            boost::shared_ptr<T> sp(t.shared_from_this());
 -/*==========================================================================*|
 -            std::cout << "Capturing weak_ptr" << std::endl;
 -            boost::weak_ptr<T> wp(sp);
 -|*==========================================================================*/
 -            std::cout << "Tracking shared__ptr" << std::endl;
 -            mListener.track(sp);
 -        }
 -#endif
 -
 -        // non-pointer variant
 -        template<typename T>
 -        void maybe_get_pointer(const T& t, truth<false>) const
 -        {
 -            // Take the address of this object, because the object itself may be
 -            // trackable
 -//          add_if_trackable(boost::addressof(t));
 -        }
 -
 -/*==========================================================================*|
 -        // add_if_trackable() adds LLEventTrackable objects to mTrackables
 -        inline void add_if_trackable(const LLEventTrackable* t) const
 -        {
 -            if (t)
 -            {
 -            }
 -        }
 -
 -        // pointer to anything not an LLEventTrackable subclass
 -        inline void add_if_trackable(const void*) const
 -        {
 -        }
 -
 -        // pointer to free function
 -        // The following construct uses the preprocessor to generate
 -        // add_if_trackable() overloads accepting pointer-to-function taking
 -        // 0, 1, ..., LLEVENTS_LISTENER_ARITY parameters of arbitrary type.
 -#define BOOST_PP_LOCAL_MACRO(n)                                     \
 -        template <typename R                                        \
 -                  BOOST_PP_COMMA_IF(n)                              \
 -                  BOOST_PP_ENUM_PARAMS(n, typename T)>              \
 -        inline void                                                 \
 -        add_if_trackable(R (*)(BOOST_PP_ENUM_PARAMS(n, T))) const   \
 -        {                                                           \
 -        }
 -#define BOOST_PP_LOCAL_LIMITS (0, LLEVENTS_LISTENER_ARITY)
 -#include BOOST_PP_LOCAL_ITERATE()
 -#undef  BOOST_PP_LOCAL_MACRO
 -#undef  BOOST_PP_LOCAL_LIMITS
 -|*==========================================================================*/
 -
 -        /// Bind a reference to the LLEventListener to call its track() method.
 -        LLEventListener& mListener;
 -    };
 -
 -    /**
 -     * Utility template function to use Visitor appropriately
 -     *
 -     * @param raw_listener Callable to connect, typically a boost::bind()
 -     * expression. This will be visited by Visitor using boost::visit_each().
 -     * @param connect_funct Callable that will connect() @a raw_listener to an
 -     * LLStandardSignal, returning LLBoundListener.
 -     */
 -    template <typename LISTENER>
 -    LLBoundListener visit_and_connect(const LISTENER& raw_listener,
 -                                      const ConnectFunc& connect_func)
 -    {
 -        // Capture the listener
 -        LLEventListener listener(raw_listener);
 -        // Define our Visitor, binding the listener so we can call
 -        // listener.track() if we discover any shared_ptr<Foo>.
 -        LLEventDetail::Visitor visitor(listener);
 -        // Allow unqualified visit_each() call for ADL
 -        using boost::visit_each;
 -        // Visit each component of a boost::bind() expression. Pass
 -        // 'raw_listener', our template argument, rather than 'listener' from
 -        // which type details have been erased. unwrap() comes from
 -        // Boost.Signals, in case we were passed a boost::ref().
 -        visit_each(visitor, LLEventDetail::unwrap(raw_listener));
 -        // Make the connection using passed function. At present, wrapping
 -        // this functionality into this function is a bit silly: we don't
 -        // really need a visit_and_connect() function any more, just a visit()
 -        // function. The definition of this function dates from when, after
 -        // visit_each(), after establishing the connection, we had to
 -        // postprocess the new connection with the visitor object. That's no
 -        // longer necessary.
 -        return connect_func(listener);
 -    }
 -} // namespace LLEventDetail
 -
 -// Somewhat to my surprise, passing boost::bind(...boost::weak_ptr<T>...) to
 -// listen() fails in Boost code trying to instantiate LLEventListener (i.e.
 -// LLStandardSignal::slot_type) because the boost::get_pointer() utility function isn't
 -// specialized for boost::weak_ptr. This remedies that omission.
 -namespace boost
 -{
 -    template <typename T>
 -    T* get_pointer(const weak_ptr<T>& ptr) { return shared_ptr<T>(ptr).get(); }
 -}
 -
 -/// Since we forbid use of listen(boost::bind(...shared_ptr<T>...)), provide an
 -/// easy way to cast to the corresponding weak_ptr.
 -template <typename T>
 -boost::weak_ptr<T> weaken(const boost::shared_ptr<T>& ptr)
 -{
 -    return boost::weak_ptr<T>(ptr);
 -}
 -
 -#endif /* ! defined(LL_LLEVENTS_H) */
 +/** + * @file   llevents.h + * @author Kent Quirk, Nat Goodspeed + * @date   2008-09-11 + * @brief  This is an implementation of the event system described at + *         https://wiki.lindenlab.com/wiki/Viewer:Messaging/Event_System, + *         originally introduced in llnotifications.h. It has nothing + *         whatsoever to do with the older system in llevent.h. + *  + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * Copyright (c) 2008, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_LLEVENTS_H) +#define LL_LLEVENTS_H + +#include <string> +#include <map> +#include <set> +#include <vector> +#include <deque> +#include <stdexcept> +#if LL_WINDOWS +	#pragma warning (push) +	#pragma warning (disable : 4263) // boost::signals2::expired_slot::what() has const mismatch +	#pragma warning (disable : 4264)  +#endif +#include <boost/signals2.hpp> +#if LL_WINDOWS +	#pragma warning (pop) +#endif + +#include <boost/bind.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> +#include <boost/utility.hpp>        // noncopyable +#include <boost/optional/optional.hpp> +#include <boost/visit_each.hpp> +#include <boost/ref.hpp>            // reference_wrapper +#include <boost/type_traits/is_pointer.hpp> +#include <boost/function.hpp> +#include <boost/static_assert.hpp> +#include "llsd.h" +#include "llsingleton.h" +#include "lldependencies.h" + +// override this to allow binding free functions with more parameters +#ifndef LLEVENTS_LISTENER_ARITY +#define LLEVENTS_LISTENER_ARITY 10 +#endif + +// hack for testing +#ifndef testable +#define testable private +#endif + +/***************************************************************************** +*   Signal and handler declarations +*   Using a single handler signature means that we can have a common handler +*   type, rather than needing a distinct one for each different handler. +*****************************************************************************/ + +/** + * A boost::signals Combiner that stops the first time a handler returns true + * We need this because we want to have our handlers return bool, so that + * we have the option to cause a handler to stop further processing. The + * default handler fails when the signal returns a value but has no slots. + */ +struct LLStopWhenHandled +{ +    typedef bool result_type; + +    template<typename InputIterator> +    result_type operator()(InputIterator first, InputIterator last) const +    { +        for (InputIterator si = first; si != last; ++si) +		{ +            if (*si) +			{ +                return true; +			} +		} +        return false; +    } +}; + +/** + * We want to have a standard signature for all signals; this way, + * we can easily document a protocol for communicating across + * dlls and into scripting languages someday. + * + * We want to return a bool to indicate whether the signal has been + * handled and should NOT be passed on to other listeners. + * Return true to stop further handling of the signal, and false + * to continue. + * + * We take an LLSD because this way the contents of the signal + * are independent of the API used to communicate it. + * It is const ref because then there's low cost to pass it; + * if you only need to inspect it, it's very cheap. + * + * @internal + * The @c float template parameter indicates that we will internally use @c + * float to indicate relative listener order on a given LLStandardSignal. + * Don't worry, the @c float values are strictly internal! They are not part + * of the interface, for the excellent reason that requiring the caller to + * specify a numeric key to establish order means that the caller must know + * the universe of possible values. We use LLDependencies for that instead. + */ +typedef boost::signals2::signal<bool(const LLSD&), LLStopWhenHandled, float>  LLStandardSignal; +/// Methods that forward listeners (e.g. constructed with +/// <tt>boost::bind()</tt>) should accept (const LLEventListener&) +typedef LLStandardSignal::slot_type LLEventListener; +/// Result of registering a listener, supports <tt>connected()</tt>, +/// <tt>disconnect()</tt> and <tt>blocked()</tt> +typedef boost::signals2::connection LLBoundListener; +/// Storing an LLBoundListener in LLTempBoundListener will disconnect the +/// referenced listener when the LLTempBoundListener instance is destroyed. +typedef boost::signals2::scoped_connection LLTempBoundListener; + +/** + * A common idiom for event-based code is to accept either a callable -- + * directly called on completion -- or the string name of an LLEventPump on + * which to post the completion event. Specifying a parameter as <tt>const + * LLListenerOrPumpName&</tt> allows either. + * + * Calling a validly-constructed LLListenerOrPumpName, passing the LLSD + * 'event' object, either calls the callable or posts the event to the named + * LLEventPump. + * + * A default-constructed LLListenerOrPumpName is 'empty'. (This is useful as + * the default value of an optional method parameter.) Calling it throws + * LLListenerOrPumpName::Empty. Test for this condition beforehand using + * either <tt>if (param)</tt> or <tt>if (! param)</tt>. + */ +class LL_COMMON_API LLListenerOrPumpName +{ +public: +    /// passing string name of LLEventPump +    LLListenerOrPumpName(const std::string& pumpname); +    /// passing string literal (overload so compiler isn't forced to infer +    /// double conversion) +    LLListenerOrPumpName(const char* pumpname); +    /// passing listener -- the "anything else" catch-all case. The type of an +    /// object constructed by boost::bind() isn't intended to be written out. +    /// Normally we'd just accept 'const LLEventListener&', but that would +    /// require double implicit conversion: boost::bind() object to +    /// LLEventListener, LLEventListener to LLListenerOrPumpName. So use a +    /// template to forward anything. +    template<typename T> +    LLListenerOrPumpName(const T& listener): mListener(listener) {} + +    /// for omitted method parameter: uninitialized mListener +    LLListenerOrPumpName() {} + +    /// test for validity +    operator bool() const { return bool(mListener); } +    bool operator! () const { return ! mListener; } + +    /// explicit accessor +    const LLEventListener& getListener() const { return *mListener; } + +    /// implicit conversion to LLEventListener +    operator LLEventListener() const { return *mListener; } + +    /// allow calling directly +    bool operator()(const LLSD& event) const; + +    /// exception if you try to call when empty +    struct Empty: public std::runtime_error +    { +        Empty(const std::string& what): +            std::runtime_error(std::string("LLListenerOrPumpName::Empty: ") + what) {} +    }; + +private: +    boost::optional<LLEventListener> mListener; +}; + +/***************************************************************************** +*   LLEventPumps +*****************************************************************************/ +class LLEventPump; + +/** + * LLEventPumps is a Singleton manager through which one typically accesses + * this subsystem. + */ +class LL_COMMON_API LLEventPumps: public LLSingleton<LLEventPumps> +{ +    friend class LLSingleton<LLEventPumps>; +public: +    /** +     * Find or create an LLEventPump instance with a specific name. We return +     * a reference so there's no question about ownership. obtain() @em finds +     * an instance without conferring @em ownership. +     */ +    LLEventPump& obtain(const std::string& name); +    /** +     * Flush all known LLEventPump instances +     */ +    void flush(); + +    /** +     * Reset all known LLEventPump instances +     * workaround for DEV-35406 crash on shutdown +     */ +    void reset(); + +private: +    friend class LLEventPump; +    /** +     * Register a new LLEventPump instance (internal) +     */ +    std::string registerNew(const LLEventPump&, const std::string& name, bool tweak); +    /** +     * Unregister a doomed LLEventPump instance (internal) +     */ +    void unregister(const LLEventPump&); + +private: +    LLEventPumps(); +    ~LLEventPumps(); + +testable: +    // Map of all known LLEventPump instances, whether or not we instantiated +    // them. We store a plain old LLEventPump* because this map doesn't claim +    // ownership of the instances. Though the common usage pattern is to +    // request an instance using obtain(), it's fair to instantiate an +    // LLEventPump subclass statically, as a class member, on the stack or on +    // the heap. In such cases, the instantiating party is responsible for its +    // lifespan. +    typedef std::map<std::string, LLEventPump*> PumpMap; +    PumpMap mPumpMap; +    // Set of all LLEventPumps we instantiated. Membership in this set means +    // we claim ownership, and will delete them when this LLEventPumps is +    // destroyed. +    typedef std::set<LLEventPump*> PumpSet; +    PumpSet mOurPumps; +    // LLEventPump names that should be instantiated as LLEventQueue rather +    // than as LLEventStream +    typedef std::set<std::string> PumpNames; +    PumpNames mQueueNames; +}; + +/***************************************************************************** +*   details +*****************************************************************************/ +namespace LLEventDetail +{ +    /// Any callable capable of connecting an LLEventListener to an +    /// LLStandardSignal to produce an LLBoundListener can be mapped to this +    /// signature. +    typedef boost::function<LLBoundListener(const LLEventListener&)> ConnectFunc; + +    /** +     * Utility template function to use Visitor appropriately +     * +     * @param listener Callable to connect, typically a boost::bind() +     * expression. This will be visited by Visitor using boost::visit_each(). +     * @param connect_func Callable that will connect() @a listener to an +     * LLStandardSignal, returning LLBoundListener. +     */ +    template <typename LISTENER> +    LLBoundListener visit_and_connect(const LISTENER& listener, +                                      const ConnectFunc& connect_func); +} // namespace LLEventDetail + +/***************************************************************************** +*   LLEventTrackable +*****************************************************************************/ +/** + * LLEventTrackable wraps boost::signals2::trackable, which resembles + * boost::trackable. Derive your listener class from LLEventTrackable instead, + * and use something like + * <tt>LLEventPump::listen(boost::bind(&YourTrackableSubclass::method, + * instance, _1))</tt>. This will implicitly disconnect when the object + * referenced by @c instance is destroyed. + * + * @note + * LLEventTrackable doesn't address a couple of cases: + * * Object destroyed during call + *   - You enter a slot call in thread A. + *   - Thread B destroys the object, which of course disconnects it from any + *     future slot calls. + *   - Thread A's call uses 'this', which now refers to a defunct object. + *     Undefined behavior results. + * * Call during destruction + *   - @c MySubclass is derived from LLEventTrackable. + *   - @c MySubclass registers one of its own methods using + *     <tt>LLEventPump::listen()</tt>. + *   - The @c MySubclass object begins destruction. <tt>~MySubclass()</tt> + *     runs, destroying state specific to the subclass. (For instance, a + *     <tt>Foo*</tt> data member is <tt>delete</tt>d but not zeroed.) + *   - The listening method will not be disconnected until + *     <tt>~LLEventTrackable()</tt> runs. + *   - Before we get there, another thread posts data to the @c LLEventPump + *     instance, calling the @c MySubclass method. + *   - The method in question relies on valid @c MySubclass state. (For + *     instance, it attempts to dereference the <tt>Foo*</tt> pointer that was + *     <tt>delete</tt>d but not zeroed.) + *   - Undefined behavior results. + * If you suspect you may encounter any such scenario, you're better off + * managing the lifespan of your object with <tt>boost::shared_ptr</tt>. + * Passing <tt>LLEventPump::listen()</tt> a <tt>boost::bind()</tt> expression + * involving a <tt>boost::weak_ptr<Foo></tt> is recognized specially, engaging + * thread-safe Boost.Signals2 machinery. + */ +typedef boost::signals2::trackable LLEventTrackable; + +/***************************************************************************** +*   LLEventPump +*****************************************************************************/ +/** + * LLEventPump is the base class interface through which we access the + * concrete subclasses LLEventStream and LLEventQueue. + * + * @NOTE + * LLEventPump derives from LLEventTrackable so that when you "chain" + * LLEventPump instances together, they will automatically disconnect on + * destruction. Please see LLEventTrackable documentation for situations in + * which this may be perilous across threads. + */ +class LL_COMMON_API LLEventPump: public LLEventTrackable +{ +public: +    /** +     * Exception thrown by LLEventPump(). You are trying to instantiate an +     * LLEventPump (subclass) using the same name as some other instance, and +     * you didn't pass <tt>tweak=true</tt> to permit it to generate a unique +     * variant. +     */ +    struct DupPumpName: public std::runtime_error +    { +        DupPumpName(const std::string& what): +            std::runtime_error(std::string("DupPumpName: ") + what) {} +    }; + +    /** +     * Instantiate an LLEventPump (subclass) with the string name by which it +     * can be found using LLEventPumps::obtain(). +     * +     * If you pass (or default) @a tweak to @c false, then a duplicate name +     * will throw DupPumpName. This won't happen if LLEventPumps::obtain() +     * instantiates the LLEventPump, because obtain() uses find-or-create +     * logic. It can only happen if you instantiate an LLEventPump in your own +     * code -- and a collision with the name of some other LLEventPump is +     * likely to cause much more subtle problems! +     * +     * When you hand-instantiate an LLEventPump, consider passing @a tweak as +     * @c true. This directs LLEventPump() to append a suffix to the passed @a +     * name to make it unique. You can retrieve the adjusted name by calling +     * getName() on your new instance. +     */ +    LLEventPump(const std::string& name, bool tweak=false); +    virtual ~LLEventPump(); + +    /// group exceptions thrown by listen(). We use exceptions because these +    /// particular errors are likely to be coding errors, found and fixed by +    /// the developer even before preliminary checkin. +    struct ListenError: public std::runtime_error +    { +        ListenError(const std::string& what): std::runtime_error(what) {} +    }; +    /** +     * exception thrown by listen(). You are attempting to register a +     * listener on this LLEventPump using the same listener name as an +     * already-registered listener. +     */ +    struct DupListenerName: public ListenError +    { +        DupListenerName(const std::string& what): +            ListenError(std::string("DupListenerName: ") + what) +        {} +    }; +    /** +     * exception thrown by listen(). The order dependencies specified for your +     * listener are incompatible with existing listeners. +     * +     * Consider listener "a" which specifies before "b" and "b" which +     * specifies before "c". You are now attempting to register "c" before +     * "a". There is no order that can satisfy all constraints. +     */ +    struct Cycle: public ListenError +    { +        Cycle(const std::string& what): ListenError(std::string("Cycle: ") + what) {} +    }; +    /** +     * exception thrown by listen(). This one means that your new listener +     * would force a change to the order of previously-registered listeners, +     * and we don't have a good way to implement that. +     * +     * Consider listeners "some", "other" and "third". "some" and "other" are +     * registered earlier without specifying relative order, so "other" +     * happens to be first. Now you attempt to register "third" after "some" +     * and before "other". Whoops, that would require swapping "some" and +     * "other", which we can't do. Instead we throw this exception. +     * +     * It may not be possible to change the registration order so we already +     * know "third"s order requirement by the time we register the second of +     * "some" and "other". A solution would be to specify that "some" must +     * come before "other", or equivalently that "other" must come after +     * "some". +     */ +    struct OrderChange: public ListenError +    { +        OrderChange(const std::string& what): ListenError(std::string("OrderChange: ") + what) {} +    }; + +    /// used by listen() +    typedef std::vector<std::string> NameList; +    /// convenience placeholder for when you explicitly want to pass an empty +    /// NameList +    const static NameList empty; + +    /// Get this LLEventPump's name +    std::string getName() const { return mName; } + +    /** +     * Register a new listener with a unique name. Specify an optional list +     * of other listener names after which this one must be called, likewise +     * an optional list of other listener names before which this one must be +     * called. The other listeners mentioned need not yet be registered +     * themselves. listen() can throw any ListenError; see ListenError +     * subclasses. +     * +     * The listener name must be unique among active listeners for this +     * LLEventPump, else you get DupListenerName. If you don't care to invent +     * a name yourself, use inventName(). (I was tempted to recognize e.g. "" +     * and internally generate a distinct name for that case. But that would +     * handle badly the scenario in which you want to add, remove, re-add, +     * etc. the same listener: each new listen() call would necessarily +     * perform a new dependency sort. Assuming you specify the same +     * after/before lists each time, using inventName() when you first +     * instantiate your listener, then passing the same name on each listen() +     * call, allows us to optimize away the second and subsequent dependency +     * sorts. +     * +     * If (as is typical) you pass a <tt>boost::bind()</tt> expression as @a +     * listener, listen() will inspect the components of that expression. If a +     * bound object matches any of several cases, the connection will +     * automatically be disconnected when that object is destroyed. +     * +     * * You bind a <tt>boost::weak_ptr</tt>. +     * * Binding a <tt>boost::shared_ptr</tt> that way would ensure that the +     *   referenced object would @em never be destroyed, since the @c +     *   shared_ptr stored in the LLEventPump would remain an outstanding +     *   reference. Use the weaken() function to convert your @c shared_ptr to +     *   @c weak_ptr. Because this is easy to forget, binding a @c shared_ptr +     *   will produce a compile error (@c BOOST_STATIC_ASSERT failure). +     * * You bind a simple pointer or reference to an object derived from +     *   <tt>boost::enable_shared_from_this</tt>. (UNDER CONSTRUCTION) +     * * You bind a simple pointer or reference to an object derived from +     *   LLEventTrackable. Unlike the cases described above, though, this is +     *   vulnerable to a couple of cross-thread race conditions, as described +     *   in the LLEventTrackable documentation. +     */ +    template <typename LISTENER> +    LLBoundListener listen(const std::string& name, const LISTENER& listener, +                           const NameList& after=NameList(), +                           const NameList& before=NameList()) +    { +        // Examine listener, using our listen_impl() method to make the +        // actual connection. +        // This is why listen() is a template. Conversion from boost::bind() +        // to LLEventListener performs type erasure, so it's important to look +        // at the boost::bind object itself before that happens. +        return LLEventDetail::visit_and_connect(listener, +                                                boost::bind(&LLEventPump::listen_impl, +                                                            this, +                                                            name, +                                                            _1, +                                                            after, +                                                            before)); +    } + +    /// Get the LLBoundListener associated with the passed name (dummy +    /// LLBoundListener if not found) +    virtual LLBoundListener getListener(const std::string& name) const; +    /** +     * Instantiate one of these to block an existing connection: +     * @code +     * { // in some local scope +     *     LLEventPump::Blocker block(someLLBoundListener); +     *     // code that needs the connection blocked +     * } // unblock the connection again +     * @endcode +     */ +    typedef boost::signals2::shared_connection_block Blocker; +    /// Unregister a listener by name. Prefer this to +    /// <tt>getListener(name).disconnect()</tt> because stopListening() also +    /// forgets this name. +    virtual void stopListening(const std::string& name); +    /// Post an event to all listeners. The @c bool return is only meaningful +    /// if the underlying leaf class is LLEventStream -- beware of relying on +    /// it too much! Truthfully, we return @c bool mostly to permit chaining +    /// one LLEventPump as a listener on another. +    virtual bool post(const LLSD&) = 0; +    /// Enable/disable: while disabled, silently ignore all post() calls +    virtual void enable(bool enabled=true) { mEnabled = enabled; } +    /// query +    virtual bool enabled() const { return mEnabled; } + +    /// Generate a distinct name for a listener -- see listen() +    static std::string inventName(const std::string& pfx="listener"); + +private: +    friend class LLEventPumps; +    /// flush queued events +    virtual void flush() {} + +    virtual void reset(); + +private: +    virtual LLBoundListener listen_impl(const std::string& name, const LLEventListener&, +                                        const NameList& after, +                                        const NameList& before); +    std::string mName; + +protected: +    /// implement the dispatching +    boost::scoped_ptr<LLStandardSignal> mSignal; + +    /// valve open? +    bool mEnabled; +    /// Map of named listeners. This tracks the listeners that actually exist +    /// at this moment. When we stopListening(), we discard the entry from +    /// this map. +    typedef std::map<std::string, boost::signals2::connection> ConnectionMap; +    ConnectionMap mConnections; +    typedef LLDependencies<std::string, float> DependencyMap; +    /// Dependencies between listeners. For each listener, track the float +    /// used to establish its place in mSignal's order. This caches all the +    /// listeners that have ever registered; stopListening() does not discard +    /// the entry from this map. This is to avoid a new dependency sort if the +    /// same listener with the same dependencies keeps hopping on and off this +    /// LLEventPump. +    DependencyMap mDeps; +}; + +/***************************************************************************** +*   LLEventStream +*****************************************************************************/ +/** + * LLEventStream is a thin wrapper around LLStandardSignal. Posting an + * event immediately calls all registered listeners. + */ +class LL_COMMON_API LLEventStream: public LLEventPump +{ +public: +    LLEventStream(const std::string& name, bool tweak=false): LLEventPump(name, tweak) {} +    virtual ~LLEventStream() {} + +    /// Post an event to all listeners +    virtual bool post(const LLSD& event); +}; + +/***************************************************************************** +*   LLEventQueue +*****************************************************************************/ +/** + * LLEventQueue isa LLEventPump whose post() method defers calling registered + * listeners until flush() is called. + */ +class LL_COMMON_API LLEventQueue: public LLEventPump +{ +public: +    LLEventQueue(const std::string& name, bool tweak=false): LLEventPump(name, tweak) {} +    virtual ~LLEventQueue() {} + +    /// Post an event to all listeners +    virtual bool post(const LLSD& event); + +private: +    /// flush queued events +    virtual void flush(); + +private: +    typedef std::deque<LLSD> EventQueue; +    EventQueue mEventQueue; +}; + +/***************************************************************************** +*   LLReqID +*****************************************************************************/ +/** + * This class helps the implementer of a given event API to honor the + * ["reqid"] convention. By this convention, each event API stamps into its + * response LLSD a ["reqid"] key whose value echoes the ["reqid"] value, if + * any, from the corresponding request. + * + * This supports an (atypical, but occasionally necessary) use case in which + * two or more asynchronous requests are multiplexed onto the same ["reply"] + * LLEventPump. Since the response events could arrive in arbitrary order, the + * caller must be able to demux them. It does so by matching the ["reqid"] + * value in each response with the ["reqid"] value in the corresponding + * request. + * + * It is the caller's responsibility to ensure distinct ["reqid"] values for + * that case. Though LLSD::UUID is guaranteed to work, it might be overkill: + * the "namespace" of unique ["reqid"] values is simply the set of requests + * specifying the same ["reply"] LLEventPump name. + * + * Making a given event API echo the request's ["reqid"] into the response is + * nearly trivial. This helper is mostly for mnemonic purposes, to serve as a + * place to put these comments. We hope that each time a coder implements a + * new event API based on some existing one, s/he will say, "Huh, what's an + * LLReqID?" and look up this material. + * + * The hardest part about the convention is deciding where to store the + * ["reqid"] value. Ironically, LLReqID can't help with that: you must store + * an LLReqID instance in whatever storage will persist until the reply is + * sent. For example, if the request ultimately ends up using a Responder + * subclass, storing an LLReqID instance in the Responder works. + * + * @note + * The @em implementer of an event API must honor the ["reqid"] convention. + * However, the @em caller of an event API need only use it if s/he is sharing + * the same ["reply"] LLEventPump for two or more asynchronous event API + * requests. + * + * In most cases, it's far easier for the caller to instantiate a local + * LLEventStream and pass its name to the event API in question. Then it's + * perfectly reasonable not to set a ["reqid"] key in the request, ignoring + * the @c isUndefined() ["reqid"] value in the response. + */ +class LL_COMMON_API LLReqID +{ +public: +    /** +     * If you have the request in hand at the time you instantiate the +     * LLReqID, pass that request to extract its ["reqid"]. + */ +    LLReqID(const LLSD& request): +        mReqid(request["reqid"]) +    {} +    /// If you don't yet have the request, use setFrom() later. +    LLReqID() {} + +    /// Extract and store the ["reqid"] value from an incoming request. +    void setFrom(const LLSD& request) +    { +        mReqid = request["reqid"]; +    } + +    /// Set ["reqid"] key into a pending response LLSD object. +    void stamp(LLSD& response) const; + +    /// Make a whole new response LLSD object with our ["reqid"]. +    LLSD makeResponse() const +    { +        LLSD response; +        stamp(response); +        return response; +    } + +    /// Not really sure of a use case for this accessor... +    LLSD getReqID() const { return mReqid; } + +private: +    LLSD mReqid; +}; + +/***************************************************************************** +*   Underpinnings +*****************************************************************************/ +/** + * We originally provided a suite of overloaded + * LLEventTrackable::listenTo(LLEventPump&, ...) methods that would call + * LLEventPump::listen(...) and then pass the returned LLBoundListener to + * LLEventTrackable::track(). This was workable but error-prone: the coder + * must remember to call listenTo() rather than the more straightforward + * listen() method. + * + * Now we publish only the single canonical listen() method, so there's a + * uniform mechanism. Having a single way to do this is good, in that there's + * no question in the coder's mind which of several alternatives to choose. + * + * To support automatic connection management, we use boost::visit_each + * (http://www.boost.org/doc/libs/1_37_0/doc/html/boost/visit_each.html) to + * inspect each argument of a boost::bind expression. (Although the visit_each + * mechanism was first introduced with the original Boost.Signals library, it + * was only later documented.) + * + * Cases: + * * At least one of the function's arguments is a boost::weak_ptr<T>. Pass + *   the corresponding shared_ptr to slot_type::track(). Ideally that would be + *   the object whose method we want to call, but in fact we do the same for + *   any weak_ptr we might find among the bound arguments. If we're passing + *   our bound method a weak_ptr to some object, wouldn't the destruction of + *   that object invalidate the call? So we disconnect automatically when any + *   such object is destroyed. This is the mechanism preferred by boost:: + *   signals2. + * * One of the functions's arguments is a boost::shared_ptr<T>. This produces + *   a compile error: the bound copy of the shared_ptr stored in the + *   boost_bind object stored in the signal object would make the referenced + *   T object immortal. We provide a weaken() function. Pass + *   weaken(your_shared_ptr) instead. (We can inspect, but not modify, the + *   boost::bind object. Otherwise we'd replace the shared_ptr with weak_ptr + *   implicitly and just proceed.) + * * One of the function's arguments is a plain pointer/reference to an object + *   derived from boost::enable_shared_from_this. We assume that this object + *   is managed using boost::shared_ptr, so we implicitly extract a shared_ptr + *   and track that. (UNDER CONSTRUCTION) + * * One of the function's arguments is derived from LLEventTrackable. Pass + *   the LLBoundListener to its LLEventTrackable::track(). This is vulnerable + *   to a couple different race conditions, as described in LLEventTrackable + *   documentation. (NOTE: Now that LLEventTrackable is a typedef for + *   boost::signals2::trackable, the Signals2 library handles this itself, so + *   our visitor needs no special logic for this case.) + * * Any other argument type is irrelevant to automatic connection management. + */ + +namespace LLEventDetail +{ +    template <typename F> +    const F& unwrap(const F& f) { return f; } + +    template <typename F> +    const F& unwrap(const boost::reference_wrapper<F>& f) { return f.get(); } + +    // Most of the following is lifted from the Boost.Signals use of +    // visit_each. +    template<bool Cond> struct truth {}; + +    /** +     * boost::visit_each() Visitor, used on a template argument <tt>const F& +     * f</tt> as follows (see visit_and_connect()): +     * @code +     * LLEventListener listener(f); +     * Visitor visitor(listener); // bind listener so it can track() shared_ptrs +     * using boost::visit_each;   // allow unqualified visit_each() call for ADL +     * visit_each(visitor, unwrap(f)); +     * @endcode +     */ +    class Visitor +    { +    public: +        /** +         * Visitor binds a reference to LLEventListener so we can track() any +         * shared_ptrs we find in the argument list. +         */ +        Visitor(LLEventListener& listener): +            mListener(listener) +        { +        } + +        /** +         * boost::visit_each() calls this method for each component of a +         * boost::bind() expression. +         */ +        template <typename T> +        void operator()(const T& t) const +        { +            decode(t, 0); +        } + +    private: +        // decode() decides between a reference wrapper and anything else +        // boost::ref() variant +        template<typename T> +        void decode(const boost::reference_wrapper<T>& t, int) const +        { +//          add_if_trackable(t.get_pointer()); +        } + +        // decode() anything else +        template<typename T> +        void decode(const T& t, long) const +        { +            typedef truth<(boost::is_pointer<T>::value)> is_a_pointer; +            maybe_get_pointer(t, is_a_pointer()); +        } + +        // maybe_get_pointer() decides between a pointer and a non-pointer +        // plain pointer variant +        template<typename T> +        void maybe_get_pointer(const T& t, truth<true>) const +        { +//          add_if_trackable(t); +        } + +        // shared_ptr variant +        template<typename T> +        void maybe_get_pointer(const boost::shared_ptr<T>& t, truth<false>) const +        { +            // If we have a shared_ptr to this object, it doesn't matter +            // whether the object is derived from LLEventTrackable, so no +            // further analysis of T is needed. +//          mListener.track(t); + +            // Make this case illegal. Passing a bound shared_ptr to +            // slot_type::track() is useless, since the bound shared_ptr will +            // keep the object alive anyway! Force the coder to cast to weak_ptr. + +            // Trivial as it is, make the BOOST_STATIC_ASSERT() condition +            // dependent on template param so the macro is only evaluated if +            // this method is in fact instantiated, as described here: +            // http://www.boost.org/doc/libs/1_34_1/doc/html/boost_staticassert.html + +            // ATTENTION: Don't bind a shared_ptr<anything> using +            // LLEventPump::listen(boost::bind()). Doing so captures a copy of +            // the shared_ptr, making the referenced object effectively +            // immortal. Use the weaken() function, e.g.: +            // somepump.listen(boost::bind(...weaken(my_shared_ptr)...)); +            // This lets us automatically disconnect when the referenced +            // object is destroyed. +            BOOST_STATIC_ASSERT(sizeof(T) == 0); +        } + +        // weak_ptr variant +        template<typename T> +        void maybe_get_pointer(const boost::weak_ptr<T>& t, truth<false>) const +        { +            // If we have a weak_ptr to this object, it doesn't matter +            // whether the object is derived from LLEventTrackable, so no +            // further analysis of T is needed. +            mListener.track(t); +//          std::cout << "Found weak_ptr<" << typeid(T).name() << ">!\n"; +        } + +#if 0 +        // reference to anything derived from boost::enable_shared_from_this +        template <typename T> +        inline void maybe_get_pointer(const boost::enable_shared_from_this<T>& ct, +                                      truth<false>) const +        { +            // Use the slot_type::track(shared_ptr) mechanism. Cast away +            // const-ness because (in our code base anyway) it's unusual +            // to find shared_ptr<const T>. +            boost::enable_shared_from_this<T>& +                t(const_cast<boost::enable_shared_from_this<T>&>(ct)); +            std::cout << "Capturing shared_from_this()" << std::endl; +            boost::shared_ptr<T> sp(t.shared_from_this()); +/*==========================================================================*| +            std::cout << "Capturing weak_ptr" << std::endl; +            boost::weak_ptr<T> wp(sp); +|*==========================================================================*/ +            std::cout << "Tracking shared__ptr" << std::endl; +            mListener.track(sp); +        } +#endif + +        // non-pointer variant +        template<typename T> +        void maybe_get_pointer(const T& t, truth<false>) const +        { +            // Take the address of this object, because the object itself may be +            // trackable +//          add_if_trackable(boost::addressof(t)); +        } + +/*==========================================================================*| +        // add_if_trackable() adds LLEventTrackable objects to mTrackables +        inline void add_if_trackable(const LLEventTrackable* t) const +        { +            if (t) +            { +            } +        } + +        // pointer to anything not an LLEventTrackable subclass +        inline void add_if_trackable(const void*) const +        { +        } + +        // pointer to free function +        // The following construct uses the preprocessor to generate +        // add_if_trackable() overloads accepting pointer-to-function taking +        // 0, 1, ..., LLEVENTS_LISTENER_ARITY parameters of arbitrary type. +#define BOOST_PP_LOCAL_MACRO(n)                                     \ +        template <typename R                                        \ +                  BOOST_PP_COMMA_IF(n)                              \ +                  BOOST_PP_ENUM_PARAMS(n, typename T)>              \ +        inline void                                                 \ +        add_if_trackable(R (*)(BOOST_PP_ENUM_PARAMS(n, T))) const   \ +        {                                                           \ +        } +#define BOOST_PP_LOCAL_LIMITS (0, LLEVENTS_LISTENER_ARITY) +#include BOOST_PP_LOCAL_ITERATE() +#undef  BOOST_PP_LOCAL_MACRO +#undef  BOOST_PP_LOCAL_LIMITS +|*==========================================================================*/ + +        /// Bind a reference to the LLEventListener to call its track() method. +        LLEventListener& mListener; +    }; + +    /** +     * Utility template function to use Visitor appropriately +     * +     * @param raw_listener Callable to connect, typically a boost::bind() +     * expression. This will be visited by Visitor using boost::visit_each(). +     * @param connect_funct Callable that will connect() @a raw_listener to an +     * LLStandardSignal, returning LLBoundListener. +     */ +    template <typename LISTENER> +    LLBoundListener visit_and_connect(const LISTENER& raw_listener, +                                      const ConnectFunc& connect_func) +    { +        // Capture the listener +        LLEventListener listener(raw_listener); +        // Define our Visitor, binding the listener so we can call +        // listener.track() if we discover any shared_ptr<Foo>. +        LLEventDetail::Visitor visitor(listener); +        // Allow unqualified visit_each() call for ADL +        using boost::visit_each; +        // Visit each component of a boost::bind() expression. Pass +        // 'raw_listener', our template argument, rather than 'listener' from +        // which type details have been erased. unwrap() comes from +        // Boost.Signals, in case we were passed a boost::ref(). +        visit_each(visitor, LLEventDetail::unwrap(raw_listener)); +        // Make the connection using passed function. At present, wrapping +        // this functionality into this function is a bit silly: we don't +        // really need a visit_and_connect() function any more, just a visit() +        // function. The definition of this function dates from when, after +        // visit_each(), after establishing the connection, we had to +        // postprocess the new connection with the visitor object. That's no +        // longer necessary. +        return connect_func(listener); +    } +} // namespace LLEventDetail + +// Somewhat to my surprise, passing boost::bind(...boost::weak_ptr<T>...) to +// listen() fails in Boost code trying to instantiate LLEventListener (i.e. +// LLStandardSignal::slot_type) because the boost::get_pointer() utility function isn't +// specialized for boost::weak_ptr. This remedies that omission. +namespace boost +{ +    template <typename T> +    T* get_pointer(const weak_ptr<T>& ptr) { return shared_ptr<T>(ptr).get(); } +} + +/// Since we forbid use of listen(boost::bind(...shared_ptr<T>...)), provide an +/// easy way to cast to the corresponding weak_ptr. +template <typename T> +boost::weak_ptr<T> weaken(const boost::shared_ptr<T>& ptr) +{ +    return boost::weak_ptr<T>(ptr); +} + +#endif /* ! defined(LL_LLEVENTS_H) */ diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 905d736d62..45b84ea3ea 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 09f19532b7..1c6f64dd8b 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 5952a3a7c5..677fad3034 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 48baa50edb..48244480b1 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -1,168 +1,168 @@ -/** 
 - * @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 : 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 : 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 3cb074257b..6558df70a4 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 b84b1aa6ad..9f857f0fd3 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 edbb007f61..31e70e0fe4 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/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp index fb6d5b2905..de927de1cd 100644 --- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp +++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp @@ -1,1098 +1,1098 @@ -/**
 - * @file media_plugin_quicktime.cpp
 - * @brief QuickTime plugin for LLMedia API plugin system
 - *
 - * $LicenseInfo:firstyear=2008&license=viewergpl$
 - *
 - * Copyright (c) 2008, Linden Research, Inc.
 - *
 - * Second Life Viewer Source Code
 - * The source code in this file ("Source Code") is provided by Linden Lab
 - * to you under the terms of the GNU General Public License, version 2.0
 - * ("GPL"), unless you have obtained a separate licensing agreement
 - * ("Other License"), formally executed by you and Linden Lab.  Terms of
 - * the GPL can be found in doc/GPL-license.txt in this distribution, or
 - * online at http://secondlife.com/developers/opensource/gplv2
 - *
 - * There are special exceptions to the terms and conditions of the GPL as
 - * it is applied to this Source Code. View the full text of the exception
 - * in the file doc/FLOSS-exception.txt in this software distribution, or
 - * online at http://secondlife.com/developers/opensource/flossexception
 - *
 - * By copying, modifying or distributing this software, you acknowledge
 - * that you have read and understood your obligations described above,
 - * and agree to abide by those obligations.
 - *
 - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 - * COMPLETENESS OR PERFORMANCE.
 - * $/LicenseInfo$
 - */
 -
 -#include "linden_common.h"
 -
 -#include "llgl.h"
 -
 -#include "llplugininstance.h"
 -#include "llpluginmessage.h"
 -#include "llpluginmessageclasses.h"
 -#include "media_plugin_base.h"
 -
 -#if LL_QUICKTIME_ENABLED
 -
 -#if defined(LL_DARWIN)
 -	#include <QuickTime/QuickTime.h>
 -#elif defined(LL_WINDOWS)
 -	#include "MacTypes.h"
 -	#include "QTML.h"
 -	#include "Movies.h"
 -	#include "QDoffscreen.h"
 -	#include "FixMath.h"
 -	#include "QTLoadLibraryUtils.h"
 -#endif
 -
 -// TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint
 -////////////////////////////////////////////////////////////////////////////////
 -//
 -class MediaPluginQuickTime : public MediaPluginBase
 -{
 -public:
 -	MediaPluginQuickTime(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
 -	~MediaPluginQuickTime();
 -
 -	/* virtual */ void receiveMessage(const char *message_string);
 -
 -private:
 -
 -	int mNaturalWidth;
 -	int mNaturalHeight;
 -	Movie mMovieHandle;
 -	GWorldPtr mGWorldHandle;
 -	ComponentInstance mMovieController;
 -	int mCurVolume;
 -	bool mMediaSizeChanging;
 -	bool mIsLooping;
 -	std::string mMovieTitle;
 -	bool mReceivedTitle;
 -	const int mMinWidth;
 -	const int mMaxWidth;
 -	const int mMinHeight;
 -	const int mMaxHeight;
 -	F64 mPlayRate;
 -	std::string mNavigateURL;
 -
 -	enum ECommand {
 -		COMMAND_NONE,
 -		COMMAND_STOP,
 -		COMMAND_PLAY,
 -		COMMAND_FAST_FORWARD,
 -		COMMAND_FAST_REWIND,
 -		COMMAND_PAUSE,
 -		COMMAND_SEEK,
 -	};
 -	ECommand mCommand;
 -
 -	// Override this to add current time and duration to the message
 -	/*virtual*/ void setDirty(int left, int top, int right, int bottom)
 -	{
 -		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated");
 -
 -		message.setValueS32("left", left);
 -		message.setValueS32("top", top);
 -		message.setValueS32("right", right);
 -		message.setValueS32("bottom", bottom);
 -
 -		if(mMovieHandle)
 -		{
 -			message.setValueReal("current_time", getCurrentTime());
 -			message.setValueReal("duration", getDuration());
 -			message.setValueReal("current_rate", Fix2X(GetMovieRate(mMovieHandle)));
 -		}
 -
 -		sendMessage(message);
 -	}
 -
 -
 -	static Rect rectFromSize(int width, int height)
 -	{
 -		Rect result;
 -
 -
 -		result.left = 0;
 -		result.top = 0;
 -		result.right = width;
 -		result.bottom = height;
 -
 -		return result;
 -	}
 -
 -	Fixed getPlayRate(void)
 -	{
 -		Fixed result;
 -		if(mPlayRate == 0.0f)
 -		{
 -			// Default to the movie's preferred rate
 -			result = GetMoviePreferredRate(mMovieHandle);
 -			if(result == 0)
 -			{
 -				// Don't return a 0 play rate, ever.
 -				std::cerr << "Movie's preferred rate is 0, forcing to 1.0." << std::endl;
 -				result = X2Fix(1.0f);
 -			}
 -		}
 -		else
 -		{
 -			result = X2Fix(mPlayRate);
 -		}
 -
 -		return result;
 -	}
 -
 -	void load( const std::string url )
 -	{
 -
 -		if ( url.empty() )
 -			return;
 -
 -		// Stop and unload any existing movie before starting another one.
 -		unload();
 -
 -		setStatus(STATUS_LOADING);
 -
 -		//In case std::string::c_str() makes a copy of the url data,
 -		//make sure there is memory to hold it before allocating memory for handle.
 -		//if fails, NewHandleClear(...) should return NULL.
 -		const char* url_string = url.c_str() ;
 -		Handle handle = NewHandleClear( ( Size )( url.length() + 1 ) );
 -
 -		if ( NULL == handle || noErr != MemError() || NULL == *handle )
 -		{
 -			setStatus(STATUS_ERROR);
 -			return;
 -		}
 -
 -		BlockMove( url_string, *handle, ( Size )( url.length() + 1 ) );
 -
 -		OSErr err = NewMovieFromDataRef( &mMovieHandle, newMovieActive | newMovieDontInteractWithUser | newMovieAsyncOK | newMovieIdleImportOK, nil, handle, URLDataHandlerSubType );
 -		DisposeHandle( handle );
 -		if ( noErr != err )
 -		{
 -			setStatus(STATUS_ERROR);
 -			return;
 -		};
 -		
 -		mNavigateURL = url;
 -		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin");
 -		message.setValue("uri", mNavigateURL);
 -		sendMessage(message);
 -
 -		// do pre-roll actions (typically fired for streaming movies but not always)
 -		PrePrerollMovie( mMovieHandle, 0, getPlayRate(), moviePrePrerollCompleteCallback, ( void * )this );
 -
 -		Rect movie_rect = rectFromSize(mWidth, mHeight);
 -
 -		// make a new movie controller
 -		mMovieController = NewMovieController( mMovieHandle, &movie_rect, mcNotVisible | mcTopLeftMovie );
 -
 -		// movie controller
 -		MCSetActionFilterWithRefCon( mMovieController, mcActionFilterCallBack, ( long )this );
 -
 -		SetMoviePlayHints( mMovieHandle, hintsAllowDynamicResize, hintsAllowDynamicResize );
 -
 -		// function that gets called when a frame is drawn
 -		SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, movieDrawingCompleteCallback, ( long )this );
 -
 -		setStatus(STATUS_LOADED);
 -
 -		sizeChanged();
 -	};
 -
 -	bool unload()
 -	{
 -		// new movie and have to get title again
 -		mReceivedTitle = false;
 -
 -		if ( mMovieHandle )
 -		{
 -			StopMovie( mMovieHandle );
 -			if ( mMovieController )
 -			{
 -				MCMovieChanged( mMovieController, mMovieHandle );
 -			};
 -		};
 -
 -		if ( mMovieController )
 -		{
 -			MCSetActionFilterWithRefCon( mMovieController, NULL, (long)this );
 -			DisposeMovieController( mMovieController );
 -			mMovieController = NULL;
 -		};
 -
 -		if ( mMovieHandle )
 -		{
 -			SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, nil, ( long )this );
 -			DisposeMovie( mMovieHandle );
 -			mMovieHandle = NULL;
 -		};
 -
 -		if ( mGWorldHandle )
 -		{
 -			DisposeGWorld( mGWorldHandle );
 -			mGWorldHandle = NULL;
 -		};
 -
 -		setStatus(STATUS_NONE);
 -
 -		return true;
 -	}
 -
 -	bool navigateTo( const std::string url )
 -	{
 -		unload();
 -		load( url );
 -
 -		return true;
 -	};
 -
 -	bool sizeChanged()
 -	{
 -		if ( ! mMovieHandle )
 -			return false;
 -
 -		// Check to see whether the movie's natural size has updated
 -		{
 -			int width, height;
 -			getMovieNaturalSize(&width, &height);
 -			if((width != 0) && (height != 0) && ((width != mNaturalWidth) || (height != mNaturalHeight)))
 -			{
 -				mNaturalWidth = width;
 -				mNaturalHeight = height;
 -
 -				LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request");
 -				message.setValue("name", mTextureSegmentName);
 -				message.setValueS32("width", width);
 -				message.setValueS32("height", height);
 -				sendMessage(message);
 -				//std::cerr << "<--- Sending size change request to application with name: " << mTextureSegmentName << " - size is " << width << " x " << height << std::endl;
 -			}
 -		}
 -
 -		// sanitize destination size
 -		Rect dest_rect = rectFromSize(mWidth, mHeight);
 -
 -		// media depth won't change
 -		int depth_bits = mDepth * 8;
 -		long rowbytes = mDepth * mTextureWidth;
 -
 -		GWorldPtr old_gworld_handle = mGWorldHandle;
 -
 -		if(mPixels != NULL)
 -		{
 -			// We have pixels.  Set up a GWorld pointing at the texture.
 -			OSErr result = NewGWorldFromPtr( &mGWorldHandle, depth_bits, &dest_rect, NULL, NULL, 0, (Ptr)mPixels, rowbytes);
 -			if ( noErr != result )
 -			{
 -				// TODO: unrecoverable??  throw exception?  return something?
 -				return false;
 -			}
 -		}
 -		else
 -		{
 -			// We don't have pixels. Create a fake GWorld we can point the movie at when it's not safe to render normally.
 -			Rect tempRect = rectFromSize(1, 1);
 -			OSErr result = NewGWorld( &mGWorldHandle, depth_bits, &tempRect, NULL, NULL, 0);
 -			if ( noErr != result )
 -			{
 -				// TODO: unrecoverable??  throw exception?  return something?
 -				return false;
 -			}
 -		}
 -
 -		SetMovieGWorld( mMovieHandle, mGWorldHandle, GetGWorldDevice( mGWorldHandle ) );
 -
 -		// If the GWorld was already set up, delete it.
 -		if(old_gworld_handle != NULL)
 -		{
 -			DisposeGWorld( old_gworld_handle );
 -		}
 -
 -		// Set up the movie display matrix
 -		{
 -			// scale movie to fit rect and invert vertically to match opengl image format
 -			MatrixRecord transform;
 -			SetIdentityMatrix( &transform );	// transforms are additive so start from identify matrix
 -			double scaleX = (double) mWidth / mNaturalWidth;
 -			double scaleY = -1.0 * (double) mHeight / mNaturalHeight;
 -			double centerX = mWidth / 2.0;
 -			double centerY = mHeight / 2.0;
 -			ScaleMatrix( &transform, X2Fix( scaleX ), X2Fix( scaleY ), X2Fix( centerX ), X2Fix( centerY ) );
 -			SetMovieMatrix( mMovieHandle, &transform );
 -		}
 -
 -		// update movie controller
 -		if ( mMovieController )
 -		{
 -			MCSetControllerPort( mMovieController, mGWorldHandle );
 -			MCPositionController( mMovieController, &dest_rect, &dest_rect,
 -								  mcTopLeftMovie | mcPositionDontInvalidate );
 -			MCMovieChanged( mMovieController, mMovieHandle );
 -		}
 -
 -
 -		// Emit event with size change so the calling app knows about it too
 -		// TODO:
 -		//LLMediaEvent event( this );
 -		//mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event );
 -
 -		return true;
 -	}
 -	static Boolean mcActionFilterCallBack( MovieController mc, short action, void *params, long ref )
 -	{
 -		Boolean result = false;
 -
 -		MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref;
 -
 -		switch( action )
 -		{
 -			// handle window resizing
 -			case mcActionControllerSizeChanged:
 -				// Ensure that the movie draws correctly at the new size
 -				self->sizeChanged();
 -				break;
 -
 -			// Block any movie controller actions that open URLs.
 -			case mcActionLinkToURL:
 -			case mcActionGetNextURL:
 -			case mcActionLinkToURLExtended:
 -				// Prevent the movie controller from handling the message
 -				result = true;
 -				break;
 -
 -			default:
 -				break;
 -		};
 -
 -		return result;
 -	};
 -
 -	static OSErr movieDrawingCompleteCallback( Movie call_back_movie, long ref )
 -	{
 -		MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref;
 -
 -		// IMPORTANT: typically, a consumer who is observing this event will set a flag
 -		// when this event is fired then render later. Be aware that the media stream
 -		// can change during this period - dimensions, depth, format etc.
 -		//LLMediaEvent event( self );
 -//		self->updateQuickTime();
 -		// TODO ^^^
 -
 -
 -		if ( self->mWidth > 0 && self->mHeight > 0 )
 -			self->setDirty( 0, 0, self->mWidth, self->mHeight );
 -
 -		return noErr;
 -	};
 -
 -	static void moviePrePrerollCompleteCallback( Movie movie, OSErr preroll_err, void *ref )
 -	{
 -		MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref;
 -
 -		// TODO:
 -		//LLMediaEvent event( self );
 -		//self->mEventEmitter.update( &LLMediaObserver::onMediaPreroll, event );
 -		
 -		// Send a "navigate complete" event.
 -		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete");
 -		message.setValue("uri", self->mNavigateURL);
 -		message.setValueS32("result_code", 200);
 -		message.setValue("result_string", "OK");
 -		self->sendMessage(message);
 -	};
 -
 -
 -	void rewind()
 -	{
 -		GoToBeginningOfMovie( mMovieHandle );
 -		MCMovieChanged( mMovieController, mMovieHandle );
 -	};
 -
 -	bool processState()
 -	{
 -		if ( mCommand == COMMAND_PLAY )
 -		{
 -			if ( mStatus == STATUS_LOADED || mStatus == STATUS_PAUSED || mStatus == STATUS_PLAYING || mStatus == STATUS_DONE )
 -			{
 -				long state = GetMovieLoadState( mMovieHandle );
 -
 -				if ( state >= kMovieLoadStatePlaythroughOK )
 -				{
 -					// if the movie is at the end (generally because it reached it naturally)
 -					// and we play is requested, jump back to the start of the movie.
 -					// note: this is different from having loop flag set.
 -					if ( IsMovieDone( mMovieHandle ) )
 -					{
 -						Fixed rate = X2Fix( 0.0 );
 -						MCDoAction( mMovieController, mcActionPlay, (void*)rate );
 -						rewind();
 -					};
 -
 -					MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)getPlayRate() );
 -					MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume );
 -					setStatus(STATUS_PLAYING);
 -					mCommand = COMMAND_NONE;
 -				};
 -			};
 -		}
 -		else
 -		if ( mCommand == COMMAND_STOP )
 -		{
 -			if ( mStatus == STATUS_PLAYING || mStatus == STATUS_PAUSED || mStatus == STATUS_DONE )
 -			{
 -				if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK )
 -				{
 -					Fixed rate = X2Fix( 0.0 );
 -					MCDoAction( mMovieController, mcActionPlay, (void*)rate );
 -					rewind();
 -
 -					setStatus(STATUS_LOADED);
 -					mCommand = COMMAND_NONE;
 -				};
 -			};
 -		}
 -		else
 -		if ( mCommand == COMMAND_PAUSE )
 -		{
 -			if ( mStatus == STATUS_PLAYING )
 -			{
 -				if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK )
 -				{
 -					Fixed rate = X2Fix( 0.0 );
 -					MCDoAction( mMovieController, mcActionPlay, (void*)rate );
 -					setStatus(STATUS_PAUSED);
 -					mCommand = COMMAND_NONE;
 -				};
 -			};
 -		};
 -
 -		return true;
 -	};
 -
 -	void play(F64 rate)
 -	{
 -		mPlayRate = rate;
 -		mCommand = COMMAND_PLAY;
 -	};
 -
 -	void stop()
 -	{
 -		mCommand = COMMAND_STOP;
 -	};
 -
 -	void pause()
 -	{
 -		mCommand = COMMAND_PAUSE;
 -	};
 -
 -	void getMovieNaturalSize(int *movie_width, int *movie_height)
 -	{
 -		Rect rect;
 -
 -		GetMovieNaturalBoundsRect( mMovieHandle, &rect );
 -
 -		int width  = ( rect.right - rect.left );
 -		int height = ( rect.bottom - rect.top );
 -
 -		// make sure width and height fall in valid range
 -		if ( width < mMinWidth )
 -			width = mMinWidth;
 -
 -		if ( width > mMaxWidth )
 -			width = mMaxWidth;
 -
 -		if ( height < mMinHeight )
 -			height = mMinHeight;
 -
 -		if ( height > mMaxHeight )
 -			height = mMaxHeight;
 -
 -		// return the new rect
 -		*movie_width = width;
 -		*movie_height = height;
 -	}
 -
 -	void updateQuickTime(int milliseconds)
 -	{
 -		if ( ! mMovieHandle )
 -			return;
 -
 -		if ( ! mMovieController )
 -			return;
 -
 -		// service QuickTime
 -		// Calling it this way doesn't have good behavior on Windows...
 -//		MoviesTask( mMovieHandle, milliseconds );
 -		// This was the original, but I think using both MoviesTask and MCIdle is redundant.  Trying with only MCIdle.
 -//		MoviesTask( mMovieHandle, 0 );
 -
 -		MCIdle( mMovieController );
 -
 -		if ( ! mGWorldHandle )
 -			return;
 -
 -		if ( mMediaSizeChanging )
 -			return;
 -
 -		// update state machine
 -		processState();
 -
 -		// see if title arrived and if so, update member variable with contents
 -		checkTitle();
 -		
 -		// QT call to see if we are at the end - can't do with controller
 -		if ( IsMovieDone( mMovieHandle ) )
 -		{
 -			// special code for looping - need to rewind at the end of the movie
 -			if ( mIsLooping )
 -			{
 -				// go back to start
 -				rewind();
 -
 -				if ( mMovieController )
 -				{
 -					// kick off new play
 -					MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)getPlayRate() );
 -
 -					// set the volume
 -					MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume );
 -				};
 -			}
 -			else
 -			{
 -				if(mStatus == STATUS_PLAYING)
 -				{
 -					setStatus(STATUS_DONE);
 -				}
 -			}
 -		}
 -
 -	};
 -
 -	int getDataWidth() const
 -	{
 -		if ( mGWorldHandle )
 -		{
 -			int depth = mDepth;
 -
 -			if (depth < 1)
 -				depth = 1;
 -
 -			// ALWAYS use the row bytes from the PixMap if we have a GWorld because
 -			// sometimes it's not the same as mMediaDepth * mMediaWidth !
 -			PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle );
 -			return QTGetPixMapHandleRowBytes( pix_map_handle ) / depth;
 -		}
 -		else
 -		{
 -			// TODO :   return LLMediaImplCommon::getaDataWidth();
 -			return 0;
 -		}
 -	};
 -
 -	void seek( F64 time )
 -	{
 -		if ( mMovieController )
 -		{
 -			TimeRecord when;
 -			when.scale = GetMovieTimeScale( mMovieHandle );
 -			when.base = 0;
 -
 -			// 'time' is in (floating point) seconds.  The timebase time will be in 'units', where
 -			// there are 'scale' units per second.
 -			SInt64 raw_time = ( SInt64 )( time * (double)( when.scale ) );
 -
 -			when.value.hi = ( SInt32 )( raw_time >> 32 );
 -			when.value.lo = ( SInt32 )( ( raw_time & 0x00000000FFFFFFFF ) );
 -
 -			MCDoAction( mMovieController, mcActionGoToTime, &when );
 -		};
 -	};
 -
 -	F64 getLoadedDuration() 	  	 
 -	{ 	  	 
 -		TimeValue duration; 	  	 
 -		if(GetMaxLoadedTimeInMovie( mMovieHandle, &duration ) != noErr) 	  	 
 -		{ 	  	 
 -			// If GetMaxLoadedTimeInMovie returns an error, return the full duration of the movie. 	  	 
 -			duration = GetMovieDuration( mMovieHandle ); 	  	 
 -		} 	  	 
 -		TimeValue scale = GetMovieTimeScale( mMovieHandle ); 	  	 
 -
 -		return (F64)duration / (F64)scale; 	  	 
 -	}; 	  	 
 -
 -	F64 getDuration()
 -	{
 -		TimeValue duration = GetMovieDuration( mMovieHandle );
 -		TimeValue scale = GetMovieTimeScale( mMovieHandle );
 -
 -		return (F64)duration / (F64)scale;
 -	};
 -
 -	F64 getCurrentTime()
 -	{
 -		TimeValue curr_time = GetMovieTime( mMovieHandle, 0 );
 -		TimeValue scale = GetMovieTimeScale( mMovieHandle );
 -
 -		return (F64)curr_time / (F64)scale;
 -	};
 -
 -	void setVolume( F64 volume )
 -	{
 -		mCurVolume = (short)(volume * ( double ) 0x100 );
 -
 -		if ( mMovieController )
 -		{
 -			MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume );
 -		};
 -	};
 -
 -	////////////////////////////////////////////////////////////////////////////////
 -	//
 -	void update(int milliseconds = 0)
 -	{
 -		updateQuickTime(milliseconds);
 -	};
 -
 -	////////////////////////////////////////////////////////////////////////////////
 -	//
 -	void mouseDown( int x, int y )
 -	{
 -	};
 -
 -	////////////////////////////////////////////////////////////////////////////////
 -	//
 -	void mouseUp( int x, int y )
 -	{
 -	};
 -
 -	////////////////////////////////////////////////////////////////////////////////
 -	//
 -	void mouseMove( int x, int y )
 -	{
 -	};
 -
 -	////////////////////////////////////////////////////////////////////////////////
 -	//
 -	void keyPress( unsigned char key )
 -	{
 -	};
 -
 -	////////////////////////////////////////////////////////////////////////////////
 -	// Grab movie title into mMovieTitle - should be called repeatedly
 -	// until it returns true since movie title takes a while to become 
 -	// available.
 -	const bool getMovieTitle()
 -	{
 -		// grab meta data from movie
 -		QTMetaDataRef media_data_ref;
 -		OSErr result = QTCopyMovieMetaData( mMovieHandle, &media_data_ref );
 -		if ( noErr != result ) 
 -			return false;
 -
 -		// look up "Display Name" in meta data
 -		OSType meta_data_key = kQTMetaDataCommonKeyDisplayName;
 -		QTMetaDataItem item = kQTMetaDataItemUninitialized;
 -		result = QTMetaDataGetNextItem( media_data_ref, kQTMetaDataStorageFormatWildcard, 
 -										0, kQTMetaDataKeyFormatCommon, 
 -										(const UInt8 *)&meta_data_key, 
 -										sizeof( meta_data_key ), &item );
 -		if ( noErr != result ) 
 -			return false;
 -
 -		// find the size of the title
 -		ByteCount size;
 -		result = QTMetaDataGetItemValue( media_data_ref, item, NULL, 0, &size );
 -		if ( noErr != result || size <= 0 ) 
 -			return false;
 -
 -		// allocate some space and grab it
 -		UInt8* item_data = new UInt8( size );
 -		memset( item_data, 0, size * sizeof( UInt8* ) );
 -		result = QTMetaDataGetItemValue( media_data_ref, item, item_data, size, NULL );
 -		if ( noErr != result ) 
 -			return false;
 -
 -		// save it
 -		mMovieTitle = std::string( (char* )item_data );
 -
 -		// clean up
 -		delete [] item_data;
 -
 -		return true;
 -	};
 -
 -	// called regularly to see if title changed
 -	void checkTitle()
 -	{
 -		// we did already receive title so keep checking
 -		if ( ! mReceivedTitle )
 -		{
 -			// grab title from movie meta data
 -			if ( getMovieTitle() )
 -			{
 -				// pass back to host application
 -				LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
 -				message.setValue("name", mMovieTitle );
 -				sendMessage( message );
 -
 -				// stop looking once we find a title for this movie.
 -				// TODO: this may to be reset if movie title changes
 -				// during playback but this is okay for now
 -				mReceivedTitle = true;
 -			};
 -		};
 -	};
 -};
 -
 -MediaPluginQuickTime::MediaPluginQuickTime(
 -	LLPluginInstance::sendMessageFunction host_send_func,
 -	void *host_user_data ) :
 -	MediaPluginBase(host_send_func, host_user_data),
 -	mMinWidth( 0 ),
 -	mMaxWidth( 2048 ),
 -	mMinHeight( 0 ),
 -	mMaxHeight( 2048 )
 -{
 -//	std::cerr << "MediaPluginQuickTime constructor" << std::endl;
 -
 -	mNaturalWidth = -1;
 -	mNaturalHeight = -1;
 -	mMovieHandle = 0;
 -	mGWorldHandle = 0;
 -	mMovieController = 0;
 -	mCurVolume = 0x99;
 -	mMediaSizeChanging = false;
 -	mIsLooping = false;
 -	mMovieTitle = std::string();
 -	mReceivedTitle = false;
 -	mCommand = COMMAND_NONE;
 -	mPlayRate = 0.0f;
 -	mStatus = STATUS_NONE;
 -}
 -
 -MediaPluginQuickTime::~MediaPluginQuickTime()
 -{
 -//	std::cerr << "MediaPluginQuickTime destructor" << std::endl;
 -
 -	ExitMovies();
 -
 -#ifdef LL_WINDOWS
 -	TerminateQTML();
 -//		std::cerr << "QuickTime closing down" << std::endl;
 -#endif
 -}
 -
 -
 -void MediaPluginQuickTime::receiveMessage(const char *message_string)
 -{
 -//	std::cerr << "MediaPluginQuickTime::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
 -	LLPluginMessage message_in;
 -
 -	if(message_in.parse(message_string) >= 0)
 -	{
 -		std::string message_class = message_in.getClass();
 -		std::string message_name = message_in.getName();
 -		if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
 -		{
 -			if(message_name == "init")
 -			{
 -				LLPluginMessage message("base", "init_response");
 -				LLSD versions = LLSD::emptyMap();
 -				versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
 -				versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
 -				// Normally a plugin would only specify one of these two subclasses, but this is a demo...
 -				versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION;
 -				message.setValueLLSD("versions", versions);
 -
 -				#ifdef LL_WINDOWS
 -
 -				// QuickTime 7.6.4 has an issue (that was not present in 7.6.2) with initializing QuickTime
 -				// according to this article: http://lists.apple.com/archives/QuickTime-API/2009/Sep/msg00097.html
 -				// The solution presented there appears to work.
 -				QTLoadLibrary("qtcf.dll");
 -
 -				// main initialization for QuickTime - only required on Windows
 -				OSErr result = InitializeQTML( 0L );
 -				if ( result != noErr )
 -				{
 -					//TODO: If no QT on Windows, this fails - respond accordingly.
 -				}
 -				else
 -				{
 -					//std::cerr << "QuickTime initialized" << std::endl;
 -				};
 -				#endif
 -
 -				// required for both Windows and Mac
 -				EnterMovies();
 -
 -				std::string plugin_version = "QuickTime media plugin, QuickTime version ";
 -
 -				long version = 0;
 -				Gestalt( gestaltQuickTimeVersion, &version );
 -				std::ostringstream codec( "" );
 -				codec << std::hex << version << std::dec;
 -				plugin_version += codec.str();
 -				message.setValue("plugin_version", plugin_version);
 -				sendMessage(message);
 -
 -				// Plugin gets to decide the texture parameters to use.
 -				message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
 -				#if defined(LL_WINDOWS)
 -					// Values for Windows
 -					mDepth = 3;
 -					message.setValueU32("format", GL_RGB);
 -					message.setValueU32("type", GL_UNSIGNED_BYTE);
 -
 -					// We really want to pad the texture width to a multiple of 32 bytes, but since we're using 3-byte pixels, it doesn't come out even.
 -					// Padding to a multiple of 3*32 guarantees it'll divide out properly.
 -					message.setValueU32("padding", 32 * 3);
 -				#else
 -					// Values for Mac
 -					mDepth = 4;
 -					message.setValueU32("format", GL_BGRA_EXT);
 -					#ifdef __BIG_ENDIAN__
 -						message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV );
 -					#else
 -						message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8);
 -					#endif
 -
 -					// Pad texture width to a multiple of 32 bytes, to line up with cache lines.
 -					message.setValueU32("padding", 32);
 -				#endif
 -				message.setValueS32("depth", mDepth);
 -				message.setValueU32("internalformat", GL_RGB);
 -				message.setValueBoolean("coords_opengl", true);	// true == use OpenGL-style coordinates, false == (0,0) is upper left.
 -				message.setValueBoolean("allow_downsample", true);
 -				sendMessage(message);
 -			}
 -			else if(message_name == "idle")
 -			{
 -				// no response is necessary here.
 -				F64 time = message_in.getValueReal("time");
 -
 -				// Convert time to milliseconds for update()
 -				update((int)(time * 1000.0f));
 -			}
 -			else if(message_name == "cleanup")
 -			{
 -				// TODO: clean up here
 -			}
 -			else if(message_name == "shm_added")
 -			{
 -				SharedSegmentInfo info;
 -				info.mAddress = message_in.getValuePointer("address");
 -				info.mSize = (size_t)message_in.getValueS32("size");
 -				std::string name = message_in.getValue("name");
 -//				std::cerr << "MediaPluginQuickTime::receiveMessage: shared memory added, name: " << name
 -//					<< ", size: " << info.mSize
 -//					<< ", address: " << info.mAddress
 -//					<< std::endl;
 -
 -				mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
 -
 -			}
 -			else if(message_name == "shm_remove")
 -			{
 -				std::string name = message_in.getValue("name");
 -
 -//				std::cerr << "MediaPluginQuickTime::receiveMessage: shared memory remove, name = " << name << std::endl;
 -
 -				SharedSegmentMap::iterator iter = mSharedSegments.find(name);
 -				if(iter != mSharedSegments.end())
 -				{
 -					if(mPixels == iter->second.mAddress)
 -					{
 -						// This is the currently active pixel buffer.  Make sure we stop drawing to it.
 -						mPixels = NULL;
 -						mTextureSegmentName.clear();
 -
 -						// Make sure the movie GWorld is no longer pointed at the shared segment.
 -						sizeChanged();
 -					}
 -					mSharedSegments.erase(iter);
 -				}
 -				else
 -				{
 -//					std::cerr << "MediaPluginQuickTime::receiveMessage: unknown shared memory region!" << std::endl;
 -				}
 -
 -				// Send the response so it can be cleaned up.
 -				LLPluginMessage message("base", "shm_remove_response");
 -				message.setValue("name", name);
 -				sendMessage(message);
 -			}
 -			else
 -			{
 -//				std::cerr << "MediaPluginQuickTime::receiveMessage: unknown base message: " << message_name << std::endl;
 -			}
 -		}
 -		else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
 -		{
 -			if(message_name == "size_change")
 -			{
 -				std::string name = message_in.getValue("name");
 -				S32 width = message_in.getValueS32("width");
 -				S32 height = message_in.getValueS32("height");
 -				S32 texture_width = message_in.getValueS32("texture_width");
 -				S32 texture_height = message_in.getValueS32("texture_height");
 -
 -				//std::cerr << "---->Got size change instruction from application with name: " << name << " - size is " << width << " x " << height << std::endl;
 -
 -				LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
 -				message.setValue("name", name);
 -				message.setValueS32("width", width);
 -				message.setValueS32("height", height);
 -				message.setValueS32("texture_width", texture_width);
 -				message.setValueS32("texture_height", texture_height);
 -				sendMessage(message);
 -
 -				if(!name.empty())
 -				{
 -					// Find the shared memory region with this name
 -					SharedSegmentMap::iterator iter = mSharedSegments.find(name);
 -					if(iter != mSharedSegments.end())
 -					{
 -//						std::cerr << "%%% Got size change, new size is " << width << " by " << height << std::endl;
 -//						std::cerr << "%%%%  texture size is " << texture_width << " by " << texture_height << std::endl;
 -
 -						mPixels = (unsigned char*)iter->second.mAddress;
 -						mTextureSegmentName = name;
 -						mWidth = width;
 -						mHeight = height;
 -
 -						mTextureWidth = texture_width;
 -						mTextureHeight = texture_height;
 -
 -						mMediaSizeChanging = false;
 -
 -						sizeChanged();
 -
 -						update();
 -					};
 -				};
 -			}
 -			else if(message_name == "load_uri")
 -			{
 -				std::string uri = message_in.getValue("uri");
 -				load( uri );
 -				sendStatus();
 -			}
 -			else if(message_name == "mouse_event")
 -			{
 -				std::string event = message_in.getValue("event");
 -				S32 x = message_in.getValueS32("x");
 -				S32 y = message_in.getValueS32("y");
 -
 -				if(event == "down")
 -				{
 -					mouseDown(x, y);
 -				}
 -				else if(event == "up")
 -				{
 -					mouseUp(x, y);
 -				}
 -				else if(event == "move")
 -				{
 -					mouseMove(x, y);
 -				};
 -			};
 -		}
 -		else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
 -		{
 -			if(message_name == "stop")
 -			{
 -				stop();
 -			}
 -			else if(message_name == "start")
 -			{
 -				F64 rate = 0.0;
 -				if(message_in.hasValue("rate"))
 -				{
 -					rate = message_in.getValueReal("rate");
 -				}
 -				play(rate);
 -			}
 -			else if(message_name == "pause")
 -			{
 -				pause();
 -			}
 -			else if(message_name == "seek")
 -			{
 -				F64 time = message_in.getValueReal("time");
 -				seek(time);
 -			}
 -			else if(message_name == "set_loop")
 -			{
 -				bool loop = message_in.getValueBoolean("loop");
 -				mIsLooping = loop;
 -			}
 -			else if(message_name == "set_volume")
 -			{
 -				F64 volume = message_in.getValueReal("volume");
 -				setVolume(volume);
 -			}
 -		}
 -		else
 -		{
 -//			std::cerr << "MediaPluginQuickTime::receiveMessage: unknown message class: " << message_class << std::endl;
 -		};
 -	};
 -}
 -
 -int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
 -{
 -	MediaPluginQuickTime *self = new MediaPluginQuickTime(host_send_func, host_user_data);
 -	*plugin_send_func = MediaPluginQuickTime::staticReceiveMessage;
 -	*plugin_user_data = (void*)self;
 -
 -	return 0;
 -}
 -
 -#else // LL_QUICKTIME_ENABLED
 -
 -// Stubbed-out class with constructor/destructor (necessary or windows linker
 -// will just think its dead code and optimize it all out)
 -class MediaPluginQuickTime : public MediaPluginBase
 -{
 -public:
 -	MediaPluginQuickTime(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
 -	~MediaPluginQuickTime();
 -	/* virtual */ void receiveMessage(const char *message_string);
 -};
 -
 -MediaPluginQuickTime::MediaPluginQuickTime(
 -	LLPluginInstance::sendMessageFunction host_send_func,
 -	void *host_user_data ) :
 -	MediaPluginBase(host_send_func, host_user_data)
 -{
 -    // no-op
 -}
 -
 -MediaPluginQuickTime::~MediaPluginQuickTime()
 -{
 -    // no-op
 -}
 -
 -void MediaPluginQuickTime::receiveMessage(const char *message_string)
 -{
 -    // no-op
 -}
 -
 -// We're building without quicktime enabled.  Just refuse to initialize.
 -int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
 -{
 -    return -1;
 -}
 -
 -#endif // LL_QUICKTIME_ENABLED
 +/** + * @file media_plugin_quicktime.cpp + * @brief QuickTime plugin for LLMedia API plugin system + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llgl.h" + +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" +#include "media_plugin_base.h" + +#if LL_QUICKTIME_ENABLED + +#if defined(LL_DARWIN) +	#include <QuickTime/QuickTime.h> +#elif defined(LL_WINDOWS) +	#include "MacTypes.h" +	#include "QTML.h" +	#include "Movies.h" +	#include "QDoffscreen.h" +	#include "FixMath.h" +	#include "QTLoadLibraryUtils.h" +#endif + +// TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint +//////////////////////////////////////////////////////////////////////////////// +// +class MediaPluginQuickTime : public MediaPluginBase +{ +public: +	MediaPluginQuickTime(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); +	~MediaPluginQuickTime(); + +	/* virtual */ void receiveMessage(const char *message_string); + +private: + +	int mNaturalWidth; +	int mNaturalHeight; +	Movie mMovieHandle; +	GWorldPtr mGWorldHandle; +	ComponentInstance mMovieController; +	int mCurVolume; +	bool mMediaSizeChanging; +	bool mIsLooping; +	std::string mMovieTitle; +	bool mReceivedTitle; +	const int mMinWidth; +	const int mMaxWidth; +	const int mMinHeight; +	const int mMaxHeight; +	F64 mPlayRate; +	std::string mNavigateURL; + +	enum ECommand { +		COMMAND_NONE, +		COMMAND_STOP, +		COMMAND_PLAY, +		COMMAND_FAST_FORWARD, +		COMMAND_FAST_REWIND, +		COMMAND_PAUSE, +		COMMAND_SEEK, +	}; +	ECommand mCommand; + +	// Override this to add current time and duration to the message +	/*virtual*/ void setDirty(int left, int top, int right, int bottom) +	{ +		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated"); + +		message.setValueS32("left", left); +		message.setValueS32("top", top); +		message.setValueS32("right", right); +		message.setValueS32("bottom", bottom); + +		if(mMovieHandle) +		{ +			message.setValueReal("current_time", getCurrentTime()); +			message.setValueReal("duration", getDuration()); +			message.setValueReal("current_rate", Fix2X(GetMovieRate(mMovieHandle))); +		} + +		sendMessage(message); +	} + + +	static Rect rectFromSize(int width, int height) +	{ +		Rect result; + + +		result.left = 0; +		result.top = 0; +		result.right = width; +		result.bottom = height; + +		return result; +	} + +	Fixed getPlayRate(void) +	{ +		Fixed result; +		if(mPlayRate == 0.0f) +		{ +			// Default to the movie's preferred rate +			result = GetMoviePreferredRate(mMovieHandle); +			if(result == 0) +			{ +				// Don't return a 0 play rate, ever. +				std::cerr << "Movie's preferred rate is 0, forcing to 1.0." << std::endl; +				result = X2Fix(1.0f); +			} +		} +		else +		{ +			result = X2Fix(mPlayRate); +		} + +		return result; +	} + +	void load( const std::string url ) +	{ + +		if ( url.empty() ) +			return; + +		// Stop and unload any existing movie before starting another one. +		unload(); + +		setStatus(STATUS_LOADING); + +		//In case std::string::c_str() makes a copy of the url data, +		//make sure there is memory to hold it before allocating memory for handle. +		//if fails, NewHandleClear(...) should return NULL. +		const char* url_string = url.c_str() ; +		Handle handle = NewHandleClear( ( Size )( url.length() + 1 ) ); + +		if ( NULL == handle || noErr != MemError() || NULL == *handle ) +		{ +			setStatus(STATUS_ERROR); +			return; +		} + +		BlockMove( url_string, *handle, ( Size )( url.length() + 1 ) ); + +		OSErr err = NewMovieFromDataRef( &mMovieHandle, newMovieActive | newMovieDontInteractWithUser | newMovieAsyncOK | newMovieIdleImportOK, nil, handle, URLDataHandlerSubType ); +		DisposeHandle( handle ); +		if ( noErr != err ) +		{ +			setStatus(STATUS_ERROR); +			return; +		}; +		 +		mNavigateURL = url; +		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); +		message.setValue("uri", mNavigateURL); +		sendMessage(message); + +		// do pre-roll actions (typically fired for streaming movies but not always) +		PrePrerollMovie( mMovieHandle, 0, getPlayRate(), moviePrePrerollCompleteCallback, ( void * )this ); + +		Rect movie_rect = rectFromSize(mWidth, mHeight); + +		// make a new movie controller +		mMovieController = NewMovieController( mMovieHandle, &movie_rect, mcNotVisible | mcTopLeftMovie ); + +		// movie controller +		MCSetActionFilterWithRefCon( mMovieController, mcActionFilterCallBack, ( long )this ); + +		SetMoviePlayHints( mMovieHandle, hintsAllowDynamicResize, hintsAllowDynamicResize ); + +		// function that gets called when a frame is drawn +		SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, movieDrawingCompleteCallback, ( long )this ); + +		setStatus(STATUS_LOADED); + +		sizeChanged(); +	}; + +	bool unload() +	{ +		// new movie and have to get title again +		mReceivedTitle = false; + +		if ( mMovieHandle ) +		{ +			StopMovie( mMovieHandle ); +			if ( mMovieController ) +			{ +				MCMovieChanged( mMovieController, mMovieHandle ); +			}; +		}; + +		if ( mMovieController ) +		{ +			MCSetActionFilterWithRefCon( mMovieController, NULL, (long)this ); +			DisposeMovieController( mMovieController ); +			mMovieController = NULL; +		}; + +		if ( mMovieHandle ) +		{ +			SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, nil, ( long )this ); +			DisposeMovie( mMovieHandle ); +			mMovieHandle = NULL; +		}; + +		if ( mGWorldHandle ) +		{ +			DisposeGWorld( mGWorldHandle ); +			mGWorldHandle = NULL; +		}; + +		setStatus(STATUS_NONE); + +		return true; +	} + +	bool navigateTo( const std::string url ) +	{ +		unload(); +		load( url ); + +		return true; +	}; + +	bool sizeChanged() +	{ +		if ( ! mMovieHandle ) +			return false; + +		// Check to see whether the movie's natural size has updated +		{ +			int width, height; +			getMovieNaturalSize(&width, &height); +			if((width != 0) && (height != 0) && ((width != mNaturalWidth) || (height != mNaturalHeight))) +			{ +				mNaturalWidth = width; +				mNaturalHeight = height; + +				LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request"); +				message.setValue("name", mTextureSegmentName); +				message.setValueS32("width", width); +				message.setValueS32("height", height); +				sendMessage(message); +				//std::cerr << "<--- Sending size change request to application with name: " << mTextureSegmentName << " - size is " << width << " x " << height << std::endl; +			} +		} + +		// sanitize destination size +		Rect dest_rect = rectFromSize(mWidth, mHeight); + +		// media depth won't change +		int depth_bits = mDepth * 8; +		long rowbytes = mDepth * mTextureWidth; + +		GWorldPtr old_gworld_handle = mGWorldHandle; + +		if(mPixels != NULL) +		{ +			// We have pixels.  Set up a GWorld pointing at the texture. +			OSErr result = NewGWorldFromPtr( &mGWorldHandle, depth_bits, &dest_rect, NULL, NULL, 0, (Ptr)mPixels, rowbytes); +			if ( noErr != result ) +			{ +				// TODO: unrecoverable??  throw exception?  return something? +				return false; +			} +		} +		else +		{ +			// We don't have pixels. Create a fake GWorld we can point the movie at when it's not safe to render normally. +			Rect tempRect = rectFromSize(1, 1); +			OSErr result = NewGWorld( &mGWorldHandle, depth_bits, &tempRect, NULL, NULL, 0); +			if ( noErr != result ) +			{ +				// TODO: unrecoverable??  throw exception?  return something? +				return false; +			} +		} + +		SetMovieGWorld( mMovieHandle, mGWorldHandle, GetGWorldDevice( mGWorldHandle ) ); + +		// If the GWorld was already set up, delete it. +		if(old_gworld_handle != NULL) +		{ +			DisposeGWorld( old_gworld_handle ); +		} + +		// Set up the movie display matrix +		{ +			// scale movie to fit rect and invert vertically to match opengl image format +			MatrixRecord transform; +			SetIdentityMatrix( &transform );	// transforms are additive so start from identify matrix +			double scaleX = (double) mWidth / mNaturalWidth; +			double scaleY = -1.0 * (double) mHeight / mNaturalHeight; +			double centerX = mWidth / 2.0; +			double centerY = mHeight / 2.0; +			ScaleMatrix( &transform, X2Fix( scaleX ), X2Fix( scaleY ), X2Fix( centerX ), X2Fix( centerY ) ); +			SetMovieMatrix( mMovieHandle, &transform ); +		} + +		// update movie controller +		if ( mMovieController ) +		{ +			MCSetControllerPort( mMovieController, mGWorldHandle ); +			MCPositionController( mMovieController, &dest_rect, &dest_rect, +								  mcTopLeftMovie | mcPositionDontInvalidate ); +			MCMovieChanged( mMovieController, mMovieHandle ); +		} + + +		// Emit event with size change so the calling app knows about it too +		// TODO: +		//LLMediaEvent event( this ); +		//mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); + +		return true; +	} +	static Boolean mcActionFilterCallBack( MovieController mc, short action, void *params, long ref ) +	{ +		Boolean result = false; + +		MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref; + +		switch( action ) +		{ +			// handle window resizing +			case mcActionControllerSizeChanged: +				// Ensure that the movie draws correctly at the new size +				self->sizeChanged(); +				break; + +			// Block any movie controller actions that open URLs. +			case mcActionLinkToURL: +			case mcActionGetNextURL: +			case mcActionLinkToURLExtended: +				// Prevent the movie controller from handling the message +				result = true; +				break; + +			default: +				break; +		}; + +		return result; +	}; + +	static OSErr movieDrawingCompleteCallback( Movie call_back_movie, long ref ) +	{ +		MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref; + +		// IMPORTANT: typically, a consumer who is observing this event will set a flag +		// when this event is fired then render later. Be aware that the media stream +		// can change during this period - dimensions, depth, format etc. +		//LLMediaEvent event( self ); +//		self->updateQuickTime(); +		// TODO ^^^ + + +		if ( self->mWidth > 0 && self->mHeight > 0 ) +			self->setDirty( 0, 0, self->mWidth, self->mHeight ); + +		return noErr; +	}; + +	static void moviePrePrerollCompleteCallback( Movie movie, OSErr preroll_err, void *ref ) +	{ +		MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref; + +		// TODO: +		//LLMediaEvent event( self ); +		//self->mEventEmitter.update( &LLMediaObserver::onMediaPreroll, event ); +		 +		// Send a "navigate complete" event. +		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); +		message.setValue("uri", self->mNavigateURL); +		message.setValueS32("result_code", 200); +		message.setValue("result_string", "OK"); +		self->sendMessage(message); +	}; + + +	void rewind() +	{ +		GoToBeginningOfMovie( mMovieHandle ); +		MCMovieChanged( mMovieController, mMovieHandle ); +	}; + +	bool processState() +	{ +		if ( mCommand == COMMAND_PLAY ) +		{ +			if ( mStatus == STATUS_LOADED || mStatus == STATUS_PAUSED || mStatus == STATUS_PLAYING || mStatus == STATUS_DONE ) +			{ +				long state = GetMovieLoadState( mMovieHandle ); + +				if ( state >= kMovieLoadStatePlaythroughOK ) +				{ +					// if the movie is at the end (generally because it reached it naturally) +					// and we play is requested, jump back to the start of the movie. +					// note: this is different from having loop flag set. +					if ( IsMovieDone( mMovieHandle ) ) +					{ +						Fixed rate = X2Fix( 0.0 ); +						MCDoAction( mMovieController, mcActionPlay, (void*)rate ); +						rewind(); +					}; + +					MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)getPlayRate() ); +					MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); +					setStatus(STATUS_PLAYING); +					mCommand = COMMAND_NONE; +				}; +			}; +		} +		else +		if ( mCommand == COMMAND_STOP ) +		{ +			if ( mStatus == STATUS_PLAYING || mStatus == STATUS_PAUSED || mStatus == STATUS_DONE ) +			{ +				if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) +				{ +					Fixed rate = X2Fix( 0.0 ); +					MCDoAction( mMovieController, mcActionPlay, (void*)rate ); +					rewind(); + +					setStatus(STATUS_LOADED); +					mCommand = COMMAND_NONE; +				}; +			}; +		} +		else +		if ( mCommand == COMMAND_PAUSE ) +		{ +			if ( mStatus == STATUS_PLAYING ) +			{ +				if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) +				{ +					Fixed rate = X2Fix( 0.0 ); +					MCDoAction( mMovieController, mcActionPlay, (void*)rate ); +					setStatus(STATUS_PAUSED); +					mCommand = COMMAND_NONE; +				}; +			}; +		}; + +		return true; +	}; + +	void play(F64 rate) +	{ +		mPlayRate = rate; +		mCommand = COMMAND_PLAY; +	}; + +	void stop() +	{ +		mCommand = COMMAND_STOP; +	}; + +	void pause() +	{ +		mCommand = COMMAND_PAUSE; +	}; + +	void getMovieNaturalSize(int *movie_width, int *movie_height) +	{ +		Rect rect; + +		GetMovieNaturalBoundsRect( mMovieHandle, &rect ); + +		int width  = ( rect.right - rect.left ); +		int height = ( rect.bottom - rect.top ); + +		// make sure width and height fall in valid range +		if ( width < mMinWidth ) +			width = mMinWidth; + +		if ( width > mMaxWidth ) +			width = mMaxWidth; + +		if ( height < mMinHeight ) +			height = mMinHeight; + +		if ( height > mMaxHeight ) +			height = mMaxHeight; + +		// return the new rect +		*movie_width = width; +		*movie_height = height; +	} + +	void updateQuickTime(int milliseconds) +	{ +		if ( ! mMovieHandle ) +			return; + +		if ( ! mMovieController ) +			return; + +		// service QuickTime +		// Calling it this way doesn't have good behavior on Windows... +//		MoviesTask( mMovieHandle, milliseconds ); +		// This was the original, but I think using both MoviesTask and MCIdle is redundant.  Trying with only MCIdle. +//		MoviesTask( mMovieHandle, 0 ); + +		MCIdle( mMovieController ); + +		if ( ! mGWorldHandle ) +			return; + +		if ( mMediaSizeChanging ) +			return; + +		// update state machine +		processState(); + +		// see if title arrived and if so, update member variable with contents +		checkTitle(); +		 +		// QT call to see if we are at the end - can't do with controller +		if ( IsMovieDone( mMovieHandle ) ) +		{ +			// special code for looping - need to rewind at the end of the movie +			if ( mIsLooping ) +			{ +				// go back to start +				rewind(); + +				if ( mMovieController ) +				{ +					// kick off new play +					MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)getPlayRate() ); + +					// set the volume +					MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); +				}; +			} +			else +			{ +				if(mStatus == STATUS_PLAYING) +				{ +					setStatus(STATUS_DONE); +				} +			} +		} + +	}; + +	int getDataWidth() const +	{ +		if ( mGWorldHandle ) +		{ +			int depth = mDepth; + +			if (depth < 1) +				depth = 1; + +			// ALWAYS use the row bytes from the PixMap if we have a GWorld because +			// sometimes it's not the same as mMediaDepth * mMediaWidth ! +			PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle ); +			return QTGetPixMapHandleRowBytes( pix_map_handle ) / depth; +		} +		else +		{ +			// TODO :   return LLMediaImplCommon::getaDataWidth(); +			return 0; +		} +	}; + +	void seek( F64 time ) +	{ +		if ( mMovieController ) +		{ +			TimeRecord when; +			when.scale = GetMovieTimeScale( mMovieHandle ); +			when.base = 0; + +			// 'time' is in (floating point) seconds.  The timebase time will be in 'units', where +			// there are 'scale' units per second. +			SInt64 raw_time = ( SInt64 )( time * (double)( when.scale ) ); + +			when.value.hi = ( SInt32 )( raw_time >> 32 ); +			when.value.lo = ( SInt32 )( ( raw_time & 0x00000000FFFFFFFF ) ); + +			MCDoAction( mMovieController, mcActionGoToTime, &when ); +		}; +	}; + +	F64 getLoadedDuration() 	  	  +	{ 	  	  +		TimeValue duration; 	  	  +		if(GetMaxLoadedTimeInMovie( mMovieHandle, &duration ) != noErr) 	  	  +		{ 	  	  +			// If GetMaxLoadedTimeInMovie returns an error, return the full duration of the movie. 	  	  +			duration = GetMovieDuration( mMovieHandle ); 	  	  +		} 	  	  +		TimeValue scale = GetMovieTimeScale( mMovieHandle ); 	  	  + +		return (F64)duration / (F64)scale; 	  	  +	}; 	  	  + +	F64 getDuration() +	{ +		TimeValue duration = GetMovieDuration( mMovieHandle ); +		TimeValue scale = GetMovieTimeScale( mMovieHandle ); + +		return (F64)duration / (F64)scale; +	}; + +	F64 getCurrentTime() +	{ +		TimeValue curr_time = GetMovieTime( mMovieHandle, 0 ); +		TimeValue scale = GetMovieTimeScale( mMovieHandle ); + +		return (F64)curr_time / (F64)scale; +	}; + +	void setVolume( F64 volume ) +	{ +		mCurVolume = (short)(volume * ( double ) 0x100 ); + +		if ( mMovieController ) +		{ +			MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); +		}; +	}; + +	//////////////////////////////////////////////////////////////////////////////// +	// +	void update(int milliseconds = 0) +	{ +		updateQuickTime(milliseconds); +	}; + +	//////////////////////////////////////////////////////////////////////////////// +	// +	void mouseDown( int x, int y ) +	{ +	}; + +	//////////////////////////////////////////////////////////////////////////////// +	// +	void mouseUp( int x, int y ) +	{ +	}; + +	//////////////////////////////////////////////////////////////////////////////// +	// +	void mouseMove( int x, int y ) +	{ +	}; + +	//////////////////////////////////////////////////////////////////////////////// +	// +	void keyPress( unsigned char key ) +	{ +	}; + +	//////////////////////////////////////////////////////////////////////////////// +	// Grab movie title into mMovieTitle - should be called repeatedly +	// until it returns true since movie title takes a while to become  +	// available. +	const bool getMovieTitle() +	{ +		// grab meta data from movie +		QTMetaDataRef media_data_ref; +		OSErr result = QTCopyMovieMetaData( mMovieHandle, &media_data_ref ); +		if ( noErr != result )  +			return false; + +		// look up "Display Name" in meta data +		OSType meta_data_key = kQTMetaDataCommonKeyDisplayName; +		QTMetaDataItem item = kQTMetaDataItemUninitialized; +		result = QTMetaDataGetNextItem( media_data_ref, kQTMetaDataStorageFormatWildcard,  +										0, kQTMetaDataKeyFormatCommon,  +										(const UInt8 *)&meta_data_key,  +										sizeof( meta_data_key ), &item ); +		if ( noErr != result )  +			return false; + +		// find the size of the title +		ByteCount size; +		result = QTMetaDataGetItemValue( media_data_ref, item, NULL, 0, &size ); +		if ( noErr != result || size <= 0 )  +			return false; + +		// allocate some space and grab it +		UInt8* item_data = new UInt8( size ); +		memset( item_data, 0, size * sizeof( UInt8* ) ); +		result = QTMetaDataGetItemValue( media_data_ref, item, item_data, size, NULL ); +		if ( noErr != result )  +			return false; + +		// save it +		mMovieTitle = std::string( (char* )item_data ); + +		// clean up +		delete [] item_data; + +		return true; +	}; + +	// called regularly to see if title changed +	void checkTitle() +	{ +		// we did already receive title so keep checking +		if ( ! mReceivedTitle ) +		{ +			// grab title from movie meta data +			if ( getMovieTitle() ) +			{ +				// pass back to host application +				LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); +				message.setValue("name", mMovieTitle ); +				sendMessage( message ); + +				// stop looking once we find a title for this movie. +				// TODO: this may to be reset if movie title changes +				// during playback but this is okay for now +				mReceivedTitle = true; +			}; +		}; +	}; +}; + +MediaPluginQuickTime::MediaPluginQuickTime( +	LLPluginInstance::sendMessageFunction host_send_func, +	void *host_user_data ) : +	MediaPluginBase(host_send_func, host_user_data), +	mMinWidth( 0 ), +	mMaxWidth( 2048 ), +	mMinHeight( 0 ), +	mMaxHeight( 2048 ) +{ +//	std::cerr << "MediaPluginQuickTime constructor" << std::endl; + +	mNaturalWidth = -1; +	mNaturalHeight = -1; +	mMovieHandle = 0; +	mGWorldHandle = 0; +	mMovieController = 0; +	mCurVolume = 0x99; +	mMediaSizeChanging = false; +	mIsLooping = false; +	mMovieTitle = std::string(); +	mReceivedTitle = false; +	mCommand = COMMAND_NONE; +	mPlayRate = 0.0f; +	mStatus = STATUS_NONE; +} + +MediaPluginQuickTime::~MediaPluginQuickTime() +{ +//	std::cerr << "MediaPluginQuickTime destructor" << std::endl; + +	ExitMovies(); + +#ifdef LL_WINDOWS +	TerminateQTML(); +//		std::cerr << "QuickTime closing down" << std::endl; +#endif +} + + +void MediaPluginQuickTime::receiveMessage(const char *message_string) +{ +//	std::cerr << "MediaPluginQuickTime::receiveMessage: received message: \"" << message_string << "\"" << std::endl; +	LLPluginMessage message_in; + +	if(message_in.parse(message_string) >= 0) +	{ +		std::string message_class = message_in.getClass(); +		std::string message_name = message_in.getName(); +		if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) +		{ +			if(message_name == "init") +			{ +				LLPluginMessage message("base", "init_response"); +				LLSD versions = LLSD::emptyMap(); +				versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; +				versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; +				// Normally a plugin would only specify one of these two subclasses, but this is a demo... +				versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; +				message.setValueLLSD("versions", versions); + +				#ifdef LL_WINDOWS + +				// QuickTime 7.6.4 has an issue (that was not present in 7.6.2) with initializing QuickTime +				// according to this article: http://lists.apple.com/archives/QuickTime-API/2009/Sep/msg00097.html +				// The solution presented there appears to work. +				QTLoadLibrary("qtcf.dll"); + +				// main initialization for QuickTime - only required on Windows +				OSErr result = InitializeQTML( 0L ); +				if ( result != noErr ) +				{ +					//TODO: If no QT on Windows, this fails - respond accordingly. +				} +				else +				{ +					//std::cerr << "QuickTime initialized" << std::endl; +				}; +				#endif + +				// required for both Windows and Mac +				EnterMovies(); + +				std::string plugin_version = "QuickTime media plugin, QuickTime version "; + +				long version = 0; +				Gestalt( gestaltQuickTimeVersion, &version ); +				std::ostringstream codec( "" ); +				codec << std::hex << version << std::dec; +				plugin_version += codec.str(); +				message.setValue("plugin_version", plugin_version); +				sendMessage(message); + +				// Plugin gets to decide the texture parameters to use. +				message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); +				#if defined(LL_WINDOWS) +					// Values for Windows +					mDepth = 3; +					message.setValueU32("format", GL_RGB); +					message.setValueU32("type", GL_UNSIGNED_BYTE); + +					// We really want to pad the texture width to a multiple of 32 bytes, but since we're using 3-byte pixels, it doesn't come out even. +					// Padding to a multiple of 3*32 guarantees it'll divide out properly. +					message.setValueU32("padding", 32 * 3); +				#else +					// Values for Mac +					mDepth = 4; +					message.setValueU32("format", GL_BGRA_EXT); +					#ifdef __BIG_ENDIAN__ +						message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV ); +					#else +						message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8); +					#endif + +					// Pad texture width to a multiple of 32 bytes, to line up with cache lines. +					message.setValueU32("padding", 32); +				#endif +				message.setValueS32("depth", mDepth); +				message.setValueU32("internalformat", GL_RGB); +				message.setValueBoolean("coords_opengl", true);	// true == use OpenGL-style coordinates, false == (0,0) is upper left. +				message.setValueBoolean("allow_downsample", true); +				sendMessage(message); +			} +			else if(message_name == "idle") +			{ +				// no response is necessary here. +				F64 time = message_in.getValueReal("time"); + +				// Convert time to milliseconds for update() +				update((int)(time * 1000.0f)); +			} +			else if(message_name == "cleanup") +			{ +				// TODO: clean up here +			} +			else if(message_name == "shm_added") +			{ +				SharedSegmentInfo info; +				info.mAddress = message_in.getValuePointer("address"); +				info.mSize = (size_t)message_in.getValueS32("size"); +				std::string name = message_in.getValue("name"); +//				std::cerr << "MediaPluginQuickTime::receiveMessage: shared memory added, name: " << name +//					<< ", size: " << info.mSize +//					<< ", address: " << info.mAddress +//					<< std::endl; + +				mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + +			} +			else if(message_name == "shm_remove") +			{ +				std::string name = message_in.getValue("name"); + +//				std::cerr << "MediaPluginQuickTime::receiveMessage: shared memory remove, name = " << name << std::endl; + +				SharedSegmentMap::iterator iter = mSharedSegments.find(name); +				if(iter != mSharedSegments.end()) +				{ +					if(mPixels == iter->second.mAddress) +					{ +						// This is the currently active pixel buffer.  Make sure we stop drawing to it. +						mPixels = NULL; +						mTextureSegmentName.clear(); + +						// Make sure the movie GWorld is no longer pointed at the shared segment. +						sizeChanged(); +					} +					mSharedSegments.erase(iter); +				} +				else +				{ +//					std::cerr << "MediaPluginQuickTime::receiveMessage: unknown shared memory region!" << std::endl; +				} + +				// Send the response so it can be cleaned up. +				LLPluginMessage message("base", "shm_remove_response"); +				message.setValue("name", name); +				sendMessage(message); +			} +			else +			{ +//				std::cerr << "MediaPluginQuickTime::receiveMessage: unknown base message: " << message_name << std::endl; +			} +		} +		else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) +		{ +			if(message_name == "size_change") +			{ +				std::string name = message_in.getValue("name"); +				S32 width = message_in.getValueS32("width"); +				S32 height = message_in.getValueS32("height"); +				S32 texture_width = message_in.getValueS32("texture_width"); +				S32 texture_height = message_in.getValueS32("texture_height"); + +				//std::cerr << "---->Got size change instruction from application with name: " << name << " - size is " << width << " x " << height << std::endl; + +				LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); +				message.setValue("name", name); +				message.setValueS32("width", width); +				message.setValueS32("height", height); +				message.setValueS32("texture_width", texture_width); +				message.setValueS32("texture_height", texture_height); +				sendMessage(message); + +				if(!name.empty()) +				{ +					// Find the shared memory region with this name +					SharedSegmentMap::iterator iter = mSharedSegments.find(name); +					if(iter != mSharedSegments.end()) +					{ +//						std::cerr << "%%% Got size change, new size is " << width << " by " << height << std::endl; +//						std::cerr << "%%%%  texture size is " << texture_width << " by " << texture_height << std::endl; + +						mPixels = (unsigned char*)iter->second.mAddress; +						mTextureSegmentName = name; +						mWidth = width; +						mHeight = height; + +						mTextureWidth = texture_width; +						mTextureHeight = texture_height; + +						mMediaSizeChanging = false; + +						sizeChanged(); + +						update(); +					}; +				}; +			} +			else if(message_name == "load_uri") +			{ +				std::string uri = message_in.getValue("uri"); +				load( uri ); +				sendStatus(); +			} +			else if(message_name == "mouse_event") +			{ +				std::string event = message_in.getValue("event"); +				S32 x = message_in.getValueS32("x"); +				S32 y = message_in.getValueS32("y"); + +				if(event == "down") +				{ +					mouseDown(x, y); +				} +				else if(event == "up") +				{ +					mouseUp(x, y); +				} +				else if(event == "move") +				{ +					mouseMove(x, y); +				}; +			}; +		} +		else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) +		{ +			if(message_name == "stop") +			{ +				stop(); +			} +			else if(message_name == "start") +			{ +				F64 rate = 0.0; +				if(message_in.hasValue("rate")) +				{ +					rate = message_in.getValueReal("rate"); +				} +				play(rate); +			} +			else if(message_name == "pause") +			{ +				pause(); +			} +			else if(message_name == "seek") +			{ +				F64 time = message_in.getValueReal("time"); +				seek(time); +			} +			else if(message_name == "set_loop") +			{ +				bool loop = message_in.getValueBoolean("loop"); +				mIsLooping = loop; +			} +			else if(message_name == "set_volume") +			{ +				F64 volume = message_in.getValueReal("volume"); +				setVolume(volume); +			} +		} +		else +		{ +//			std::cerr << "MediaPluginQuickTime::receiveMessage: unknown message class: " << message_class << std::endl; +		}; +	}; +} + +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ +	MediaPluginQuickTime *self = new MediaPluginQuickTime(host_send_func, host_user_data); +	*plugin_send_func = MediaPluginQuickTime::staticReceiveMessage; +	*plugin_user_data = (void*)self; + +	return 0; +} + +#else // LL_QUICKTIME_ENABLED + +// Stubbed-out class with constructor/destructor (necessary or windows linker +// will just think its dead code and optimize it all out) +class MediaPluginQuickTime : public MediaPluginBase +{ +public: +	MediaPluginQuickTime(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); +	~MediaPluginQuickTime(); +	/* virtual */ void receiveMessage(const char *message_string); +}; + +MediaPluginQuickTime::MediaPluginQuickTime( +	LLPluginInstance::sendMessageFunction host_send_func, +	void *host_user_data ) : +	MediaPluginBase(host_send_func, host_user_data) +{ +    // no-op +} + +MediaPluginQuickTime::~MediaPluginQuickTime() +{ +    // no-op +} + +void MediaPluginQuickTime::receiveMessage(const char *message_string) +{ +    // no-op +} + +// We're building without quicktime enabled.  Just refuse to initialize. +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ +    return -1; +} + +#endif // LL_QUICKTIME_ENABLED diff --git a/indra/newview/app_settings/ignorable_dialogs.xml b/indra/newview/app_settings/ignorable_dialogs.xml index 669235af1b..ab18febccc 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/installers/windows/FILES_ARE_UNICODE_UTF-16LE.txt b/indra/newview/installers/windows/FILES_ARE_UNICODE_UTF-16LE.txt index 185c0180fb..30f9349111 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/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 88658f7b9f..b01293d17c 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -1,343 +1,343 @@ -/** 
 - * @file llfloaterabout.cpp
 - * @author James Cook
 - * @brief The about box from Help->About
 - *
 - * $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 "llviewerprecompiledheaders.h"
 -
 -#include "llfloaterabout.h"
 -
 -// Viewer includes
 -#include "llagent.h"
 -#include "llappviewer.h" 
 -#include "llsecondlifeurls.h"
 -#include "llvoiceclient.h"
 -#include "lluictrlfactory.h"
 -#include "llviewertexteditor.h"
 -#include "llviewercontrol.h"
 -#include "llviewerstats.h"
 -#include "llviewerregion.h"
 -#include "llversionviewer.h"
 -#include "llviewerbuild.h"
 -#include "llweb.h"
 -
 -// Linden library includes
 -#include "llaudioengine.h"
 -#include "llbutton.h"
 -#include "llcurl.h"
 -#include "llglheaders.h"
 -#include "llfloater.h"
 -#include "llfloaterreg.h"
 -#include "llimagej2c.h"
 -#include "llsys.h"
 -#include "lltrans.h"
 -#include "lluri.h"
 -#include "v3dmath.h"
 -#include "llwindow.h"
 -#include "stringize.h"
 -#include "llsdutil_math.h"
 -#include "lleventdispatcher.h"
 -
 -#if LL_WINDOWS
 -#include "lldxhardware.h"
 -#endif
 -
 -extern LLMemoryInfo gSysMemory;
 -extern U32 gPacketsIn;
 -
 -static std::string get_viewer_release_notes_url();
 -
 -
 -///----------------------------------------------------------------------------
 -/// Class LLFloaterAbout
 -///----------------------------------------------------------------------------
 -class LLFloaterAbout 
 -	: public LLFloater
 -{
 -	friend class LLFloaterReg;
 -private:
 -	LLFloaterAbout(const LLSD& key);
 -	virtual ~LLFloaterAbout();
 -
 -public:
 -	/*virtual*/ BOOL postBuild();
 -
 -	/// Obtain the data used to fill out the contents string. This is
 -	/// separated so that we can programmatically access the same info.
 -	static LLSD getInfo();
 -	void onClickCopyToClipboard();
 -};
 -
 -
 -// Default constructor
 -LLFloaterAbout::LLFloaterAbout(const LLSD& key) 
 -:	LLFloater(key)
 -{
 -	//LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about.xml");
 -	
 -}
 -
 -// Destroys the object
 -LLFloaterAbout::~LLFloaterAbout()
 -{
 -}
 -
 -BOOL LLFloaterAbout::postBuild()
 -{
 -	center();
 -	LLViewerTextEditor *support_widget = 
 -		getChild<LLViewerTextEditor>("support_editor", true);
 -
 -	LLViewerTextEditor *credits_widget = 
 -		getChild<LLViewerTextEditor>("credits_editor", true);
 -
 -	getChild<LLUICtrl>("copy_btn")->setCommitCallback(
 -		boost::bind(&LLFloaterAbout::onClickCopyToClipboard, this));
 -
 -#if LL_WINDOWS
 -	getWindow()->incBusyCount();
 -	getWindow()->setCursor(UI_CURSOR_ARROW);
 -#endif
 -	LLSD info(getInfo());
 -#if LL_WINDOWS
 -	getWindow()->decBusyCount();
 -	getWindow()->setCursor(UI_CURSOR_ARROW);
 -#endif
 -
 -	std::ostringstream support;
 -
 -	// Render the LLSD from getInfo() as a format_map_t
 -	LLStringUtil::format_map_t args;
 -	// For reasons I don't yet understand, [ReleaseNotes] is not part of the
 -	// default substitution strings whereas [APP_NAME] is. But it works to
 -	// simply copy it into these specific args.
 -	args["ReleaseNotes"] = LLTrans::getString("ReleaseNotes");
 -	for (LLSD::map_const_iterator ii(info.beginMap()), iend(info.endMap());
 -		 ii != iend; ++ii)
 -	{
 -		if (! ii->second.isArray())
 -		{
 -			// Scalar value
 -			if (ii->second.isUndefined())
 -			{
 -				args[ii->first] = getString("none");
 -			}
 -			else
 -			{
 -				// don't forget to render value asString()
 -				args[ii->first] = ii->second.asString();
 -			}
 -		}
 -		else
 -		{
 -			// array value: build KEY_0, KEY_1 etc. entries
 -			for (LLSD::Integer n(0), size(ii->second.size()); n < size; ++n)
 -			{
 -				args[STRINGIZE(ii->first << '_' << n)] = ii->second[n].asString();
 -			}
 -		}
 -	}
 -
 -	// Now build the various pieces
 -	support << getString("AboutHeader", args);
 -	if (info.has("COMPILER"))
 -	{
 -		support << "\n\n" << getString("AboutCompiler", args);
 -	}
 -	if (info.has("REGION"))
 -	{
 -		support << "\n\n" << getString("AboutPosition", args);
 -	}
 -	support << "\n\n" << getString("AboutSystem", args);
 -	if (info.has("GRAPHICS_DRIVER_VERSION"))
 -	{
 -		support << "\n\n" << getString("AboutDriver", args);
 -	}
 -	support << "\n\n" << getString("AboutLibs", args);
 -	if (info.has("PACKETS_IN"))
 -	{
 -		support << '\n' << getString("AboutTraffic", args);
 -	}
 -
 -	support_widget->appendText(support.str(), 
 -								FALSE, 
 -								LLStyle::Params()
 -									.color(LLUIColorTable::instance().getColor("TextFgReadOnlyColor")));
 -	support_widget->blockUndo();
 -
 -	// Fix views
 -	support_widget->setCursorPos(0);
 -	support_widget->setEnabled(FALSE);
 -
 -	credits_widget->setCursorPos(0);
 -	credits_widget->setEnabled(FALSE);
 -
 -	return TRUE;
 -}
 -
 -// static
 -LLSD LLFloaterAbout::getInfo()
 -{
 -	// The point of having one method build an LLSD info block and the other
 -	// construct the user-visible About string is to ensure that the same info
 -	// is available to a getInfo() caller as to the user opening
 -	// LLFloaterAbout.
 -	LLSD info;
 -	LLSD version;
 -	version.append(LL_VERSION_MAJOR);
 -	version.append(LL_VERSION_MINOR);
 -	version.append(LL_VERSION_PATCH);
 -	version.append(LL_VERSION_BUILD);
 -	info["VIEWER_VERSION"] = version;
 -	info["VIEWER_VERSION_STR"] = STRINGIZE(version[0].asInteger() << '.' <<
 -										   version[1].asInteger() << '.' <<
 -										   version[2].asInteger() << '.' <<
 -										   version[3].asInteger());
 -	info["BUILD_DATE"] = __DATE__;
 -	info["BUILD_TIME"] = __TIME__;
 -	info["CHANNEL"] = gSavedSettings.getString("VersionChannelName");
 -
 -	info["VIEWER_RELEASE_NOTES_URL"] = get_viewer_release_notes_url();
 -
 -#if LL_MSVC
 -	info["COMPILER"] = "MSVC";
 -	info["COMPILER_VERSION"] = _MSC_VER;
 -#elif LL_GNUC
 -	info["COMPILER"] = "GCC";
 -	info["COMPILER_VERSION"] = GCC_VERSION;
 -#endif
 -
 -	// Position
 -	LLViewerRegion* region = gAgent.getRegion();
 -	if (region)
 -	{
 -		const LLVector3d &pos = gAgent.getPositionGlobal();
 -		info["POSITION"] = ll_sd_from_vector3d(pos);
 -		info["REGION"] = gAgent.getRegion()->getName();
 -		info["HOSTNAME"] = gAgent.getRegion()->getHost().getHostName();
 -		info["HOSTIP"] = gAgent.getRegion()->getHost().getString();
 -		info["SERVER_VERSION"] = gLastVersionChannel;
 -		info["SERVER_RELEASE_NOTES_URL"] = LLWeb::escapeURL(region->getCapability("ServerReleaseNotes"));
 -	}
 -
 -	// CPU
 -	info["CPU"] = gSysCPU.getCPUString();
 -	info["MEMORY_MB"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB() / 1024);
 -	// Moved hack adjustment to Windows memory size into llsys.cpp
 -	info["OS_VERSION"] = LLAppViewer::instance()->getOSInfo().getOSString();
 -	info["GRAPHICS_CARD_VENDOR"] = (const char*)(glGetString(GL_VENDOR));
 -	info["GRAPHICS_CARD"] = (const char*)(glGetString(GL_RENDERER));
 -
 -#if LL_WINDOWS
 -    LLSD driver_info = gDXHardware.getDisplayInfo();
 -    if (driver_info.has("DriverVersion"))
 -    {
 -        info["GRAPHICS_DRIVER_VERSION"] = driver_info["DriverVersion"];
 -    }
 -#endif
 -
 -	info["OPENGL_VERSION"] = (const char*)(glGetString(GL_VERSION));
 -	info["LIBCURL_VERSION"] = LLCurl::getVersionString();
 -	info["J2C_VERSION"] = LLImageJ2C::getEngineInfo();
 -	bool want_fullname = true;
 -	info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : LLSD();
 -	info["VIVOX_VERSION"] = gVoiceClient ? gVoiceClient->getAPIVersion() : "Unknown";
 -
 -	// TODO: Implement media plugin version query
 -	info["QT_WEBKIT_VERSION"] = "4.5.2";
 -
 -	if (gPacketsIn > 0)
 -	{
 -		info["PACKETS_LOST"] = LLViewerStats::getInstance()->mPacketsLostStat.getCurrent();
 -		info["PACKETS_IN"] = F32(gPacketsIn);
 -		info["PACKETS_PCT"] = 100.f*info["PACKETS_LOST"].asReal() / info["PACKETS_IN"].asReal();
 -	}
 -
 -    return info;
 -}
 -
 -static std::string get_viewer_release_notes_url()
 -{
 -	std::ostringstream version;
 -	version << LL_VERSION_MAJOR << "."
 -		<< LL_VERSION_MINOR << "."
 -		<< LL_VERSION_PATCH << "."
 -		<< LL_VERSION_BUILD;
 -
 -	LLSD query;
 -	query["channel"] = gSavedSettings.getString("VersionChannelName");
 -	query["version"] = version.str();
 -
 -	std::ostringstream url;
 -	url << LLTrans::getString("RELEASE_NOTES_BASE_URL") << LLURI::mapToQueryString(query);
 -
 -	return LLWeb::escapeURL(url.str());
 -}
 -
 -class LLFloaterAboutListener: public LLDispatchListener
 -{
 -public:
 -	LLFloaterAboutListener():
 -		LLDispatchListener("LLFloaterAbout", "op")
 -	{
 -		add("getInfo", &LLFloaterAboutListener::getInfo, LLSD().insert("reply", LLSD()));
 -	}
 -
 -private:
 -	void getInfo(const LLSD& request) const
 -	{
 -		LLReqID reqid(request);
 -		LLSD reply(LLFloaterAbout::getInfo());
 -		reqid.stamp(reply);
 -		LLEventPumps::instance().obtain(request["reply"]).post(reply);
 -	}
 -};
 -
 -static LLFloaterAboutListener floaterAboutListener;
 -
 -void LLFloaterAbout::onClickCopyToClipboard()
 -{
 -	LLViewerTextEditor *support_widget = 
 -		getChild<LLViewerTextEditor>("support_editor", true);
 -	support_widget->selectAll();
 -	support_widget->copy();
 -	support_widget->deselect();
 -}
 -
 -///----------------------------------------------------------------------------
 -/// LLFloaterAboutUtil
 -///----------------------------------------------------------------------------
 -void LLFloaterAboutUtil::registerFloater()
 -{
 -	LLFloaterReg::add("sl_about", "floater_about.xml",
 -		&LLFloaterReg::build<LLFloaterAbout>);
 -
 -}
 +/**  + * @file llfloaterabout.cpp + * @author James Cook + * @brief The about box from Help->About + * + * $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 "llviewerprecompiledheaders.h" + +#include "llfloaterabout.h" + +// Viewer includes +#include "llagent.h" +#include "llappviewer.h"  +#include "llsecondlifeurls.h" +#include "llvoiceclient.h" +#include "lluictrlfactory.h" +#include "llviewertexteditor.h" +#include "llviewercontrol.h" +#include "llviewerstats.h" +#include "llviewerregion.h" +#include "llversionviewer.h" +#include "llviewerbuild.h" +#include "llweb.h" + +// Linden library includes +#include "llaudioengine.h" +#include "llbutton.h" +#include "llcurl.h" +#include "llglheaders.h" +#include "llfloater.h" +#include "llfloaterreg.h" +#include "llimagej2c.h" +#include "llsys.h" +#include "lltrans.h" +#include "lluri.h" +#include "v3dmath.h" +#include "llwindow.h" +#include "stringize.h" +#include "llsdutil_math.h" +#include "lleventdispatcher.h" + +#if LL_WINDOWS +#include "lldxhardware.h" +#endif + +extern LLMemoryInfo gSysMemory; +extern U32 gPacketsIn; + +static std::string get_viewer_release_notes_url(); + + +///---------------------------------------------------------------------------- +/// Class LLFloaterAbout +///---------------------------------------------------------------------------- +class LLFloaterAbout  +	: public LLFloater +{ +	friend class LLFloaterReg; +private: +	LLFloaterAbout(const LLSD& key); +	virtual ~LLFloaterAbout(); + +public: +	/*virtual*/ BOOL postBuild(); + +	/// Obtain the data used to fill out the contents string. This is +	/// separated so that we can programmatically access the same info. +	static LLSD getInfo(); +	void onClickCopyToClipboard(); +}; + + +// Default constructor +LLFloaterAbout::LLFloaterAbout(const LLSD& key)  +:	LLFloater(key) +{ +	//LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about.xml"); +	 +} + +// Destroys the object +LLFloaterAbout::~LLFloaterAbout() +{ +} + +BOOL LLFloaterAbout::postBuild() +{ +	center(); +	LLViewerTextEditor *support_widget =  +		getChild<LLViewerTextEditor>("support_editor", true); + +	LLViewerTextEditor *credits_widget =  +		getChild<LLViewerTextEditor>("credits_editor", true); + +	getChild<LLUICtrl>("copy_btn")->setCommitCallback( +		boost::bind(&LLFloaterAbout::onClickCopyToClipboard, this)); + +#if LL_WINDOWS +	getWindow()->incBusyCount(); +	getWindow()->setCursor(UI_CURSOR_ARROW); +#endif +	LLSD info(getInfo()); +#if LL_WINDOWS +	getWindow()->decBusyCount(); +	getWindow()->setCursor(UI_CURSOR_ARROW); +#endif + +	std::ostringstream support; + +	// Render the LLSD from getInfo() as a format_map_t +	LLStringUtil::format_map_t args; +	// For reasons I don't yet understand, [ReleaseNotes] is not part of the +	// default substitution strings whereas [APP_NAME] is. But it works to +	// simply copy it into these specific args. +	args["ReleaseNotes"] = LLTrans::getString("ReleaseNotes"); +	for (LLSD::map_const_iterator ii(info.beginMap()), iend(info.endMap()); +		 ii != iend; ++ii) +	{ +		if (! ii->second.isArray()) +		{ +			// Scalar value +			if (ii->second.isUndefined()) +			{ +				args[ii->first] = getString("none"); +			} +			else +			{ +				// don't forget to render value asString() +				args[ii->first] = ii->second.asString(); +			} +		} +		else +		{ +			// array value: build KEY_0, KEY_1 etc. entries +			for (LLSD::Integer n(0), size(ii->second.size()); n < size; ++n) +			{ +				args[STRINGIZE(ii->first << '_' << n)] = ii->second[n].asString(); +			} +		} +	} + +	// Now build the various pieces +	support << getString("AboutHeader", args); +	if (info.has("COMPILER")) +	{ +		support << "\n\n" << getString("AboutCompiler", args); +	} +	if (info.has("REGION")) +	{ +		support << "\n\n" << getString("AboutPosition", args); +	} +	support << "\n\n" << getString("AboutSystem", args); +	if (info.has("GRAPHICS_DRIVER_VERSION")) +	{ +		support << "\n\n" << getString("AboutDriver", args); +	} +	support << "\n\n" << getString("AboutLibs", args); +	if (info.has("PACKETS_IN")) +	{ +		support << '\n' << getString("AboutTraffic", args); +	} + +	support_widget->appendText(support.str(),  +								FALSE,  +								LLStyle::Params() +									.color(LLUIColorTable::instance().getColor("TextFgReadOnlyColor"))); +	support_widget->blockUndo(); + +	// Fix views +	support_widget->setCursorPos(0); +	support_widget->setEnabled(FALSE); + +	credits_widget->setCursorPos(0); +	credits_widget->setEnabled(FALSE); + +	return TRUE; +} + +// static +LLSD LLFloaterAbout::getInfo() +{ +	// The point of having one method build an LLSD info block and the other +	// construct the user-visible About string is to ensure that the same info +	// is available to a getInfo() caller as to the user opening +	// LLFloaterAbout. +	LLSD info; +	LLSD version; +	version.append(LL_VERSION_MAJOR); +	version.append(LL_VERSION_MINOR); +	version.append(LL_VERSION_PATCH); +	version.append(LL_VERSION_BUILD); +	info["VIEWER_VERSION"] = version; +	info["VIEWER_VERSION_STR"] = STRINGIZE(version[0].asInteger() << '.' << +										   version[1].asInteger() << '.' << +										   version[2].asInteger() << '.' << +										   version[3].asInteger()); +	info["BUILD_DATE"] = __DATE__; +	info["BUILD_TIME"] = __TIME__; +	info["CHANNEL"] = gSavedSettings.getString("VersionChannelName"); + +	info["VIEWER_RELEASE_NOTES_URL"] = get_viewer_release_notes_url(); + +#if LL_MSVC +	info["COMPILER"] = "MSVC"; +	info["COMPILER_VERSION"] = _MSC_VER; +#elif LL_GNUC +	info["COMPILER"] = "GCC"; +	info["COMPILER_VERSION"] = GCC_VERSION; +#endif + +	// Position +	LLViewerRegion* region = gAgent.getRegion(); +	if (region) +	{ +		const LLVector3d &pos = gAgent.getPositionGlobal(); +		info["POSITION"] = ll_sd_from_vector3d(pos); +		info["REGION"] = gAgent.getRegion()->getName(); +		info["HOSTNAME"] = gAgent.getRegion()->getHost().getHostName(); +		info["HOSTIP"] = gAgent.getRegion()->getHost().getString(); +		info["SERVER_VERSION"] = gLastVersionChannel; +		info["SERVER_RELEASE_NOTES_URL"] = LLWeb::escapeURL(region->getCapability("ServerReleaseNotes")); +	} + +	// CPU +	info["CPU"] = gSysCPU.getCPUString(); +	info["MEMORY_MB"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB() / 1024); +	// Moved hack adjustment to Windows memory size into llsys.cpp +	info["OS_VERSION"] = LLAppViewer::instance()->getOSInfo().getOSString(); +	info["GRAPHICS_CARD_VENDOR"] = (const char*)(glGetString(GL_VENDOR)); +	info["GRAPHICS_CARD"] = (const char*)(glGetString(GL_RENDERER)); + +#if LL_WINDOWS +    LLSD driver_info = gDXHardware.getDisplayInfo(); +    if (driver_info.has("DriverVersion")) +    { +        info["GRAPHICS_DRIVER_VERSION"] = driver_info["DriverVersion"]; +    } +#endif + +	info["OPENGL_VERSION"] = (const char*)(glGetString(GL_VERSION)); +	info["LIBCURL_VERSION"] = LLCurl::getVersionString(); +	info["J2C_VERSION"] = LLImageJ2C::getEngineInfo(); +	bool want_fullname = true; +	info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : LLSD(); +	info["VIVOX_VERSION"] = gVoiceClient ? gVoiceClient->getAPIVersion() : "Unknown"; + +	// TODO: Implement media plugin version query +	info["QT_WEBKIT_VERSION"] = "4.5.2"; + +	if (gPacketsIn > 0) +	{ +		info["PACKETS_LOST"] = LLViewerStats::getInstance()->mPacketsLostStat.getCurrent(); +		info["PACKETS_IN"] = F32(gPacketsIn); +		info["PACKETS_PCT"] = 100.f*info["PACKETS_LOST"].asReal() / info["PACKETS_IN"].asReal(); +	} + +    return info; +} + +static std::string get_viewer_release_notes_url() +{ +	std::ostringstream version; +	version << LL_VERSION_MAJOR << "." +		<< LL_VERSION_MINOR << "." +		<< LL_VERSION_PATCH << "." +		<< LL_VERSION_BUILD; + +	LLSD query; +	query["channel"] = gSavedSettings.getString("VersionChannelName"); +	query["version"] = version.str(); + +	std::ostringstream url; +	url << LLTrans::getString("RELEASE_NOTES_BASE_URL") << LLURI::mapToQueryString(query); + +	return LLWeb::escapeURL(url.str()); +} + +class LLFloaterAboutListener: public LLDispatchListener +{ +public: +	LLFloaterAboutListener(): +		LLDispatchListener("LLFloaterAbout", "op") +	{ +		add("getInfo", &LLFloaterAboutListener::getInfo, LLSD().insert("reply", LLSD())); +	} + +private: +	void getInfo(const LLSD& request) const +	{ +		LLReqID reqid(request); +		LLSD reply(LLFloaterAbout::getInfo()); +		reqid.stamp(reply); +		LLEventPumps::instance().obtain(request["reply"]).post(reply); +	} +}; + +static LLFloaterAboutListener floaterAboutListener; + +void LLFloaterAbout::onClickCopyToClipboard() +{ +	LLViewerTextEditor *support_widget =  +		getChild<LLViewerTextEditor>("support_editor", true); +	support_widget->selectAll(); +	support_widget->copy(); +	support_widget->deselect(); +} + +///---------------------------------------------------------------------------- +/// LLFloaterAboutUtil +///---------------------------------------------------------------------------- +void LLFloaterAboutUtil::registerFloater() +{ +	LLFloaterReg::add("sl_about", "floater_about.xml", +		&LLFloaterReg::build<LLFloaterAbout>); + +} diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp index 89a9a317c2..8570b5eb4a 100644 --- a/indra/newview/llfloaterinventory.cpp +++ b/indra/newview/llfloaterinventory.cpp @@ -1,155 +1,155 @@ -/** 
 - * @file llfloaterinventory.cpp
 - * @brief Implementation of the inventory view and associated stuff.
 - *
 - * $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 "llviewerprecompiledheaders.h"
 -
 -#include "llfloaterinventory.h"
 -
 -#include "llagent.h"
 -#include "llfirstuse.h"
 -#include "llfloaterreg.h"
 -#include "llinventorymodel.h"
 -#include "llpanelmaininventory.h"
 -#include "llresmgr.h"
 -
 -///----------------------------------------------------------------------------
 -/// LLFloaterInventory
 -///----------------------------------------------------------------------------
 -
 -LLFloaterInventory::LLFloaterInventory(const LLSD& key)
 -	: LLFloater(key)
 -{
 -}
 -
 -LLFloaterInventory::~LLFloaterInventory()
 -{
 -}
 -
 -BOOL LLFloaterInventory::postBuild()
 -{
 -	mPanelMainInventory = getChild<LLPanelMainInventory>("Inventory Panel");
 -	return TRUE;
 -}
 -
 -
 -void LLFloaterInventory::draw()
 -{
 - 	if (LLInventoryModel::isEverythingFetched())
 -	{
 -		updateTitle();
 -	}
 -	LLFloater::draw();
 -}
 -
 -void LLFloaterInventory::updateTitle()
 -{
 -	LLLocale locale(LLLocale::USER_LOCALE);
 -	std::string item_count_string;
 -	LLResMgr::getInstance()->getIntegerString(item_count_string, gInventory.getItemCount());
 -
 -	LLStringUtil::format_map_t string_args;
 -	string_args["[ITEM_COUNT]"] = item_count_string;
 -	string_args["[FILTER]"] = mPanelMainInventory->getFilterText();
 -
 -	if (LLInventoryModel::backgroundFetchActive())
 -	{
 -		setTitle(getString("TitleFetching", string_args));
 -	}
 -	else
 -	{
 -		setTitle(getString("TitleCompleted", string_args));
 -	}
 -}
 -
 -void LLFloaterInventory::changed(U32 mask)
 -{
 -	updateTitle();
 -}
 -
 -LLInventoryPanel* LLFloaterInventory::getPanel()
 -{
 -	if (mPanelMainInventory)
 -		return mPanelMainInventory->getPanel();
 -	return NULL;
 -}
 -
 -// static
 -LLFloaterInventory* LLFloaterInventory::showAgentInventory()
 -{
 -	LLFloaterInventory* iv = NULL;
 -	if (!gAgent.cameraMouselook())
 -	{
 -		iv = LLFloaterReg::showTypedInstance<LLFloaterInventory>("inventory", LLSD());
 -	}
 -	return iv;
 -}
 -
 -// static
 -LLFloaterInventory* LLFloaterInventory::getActiveInventory()
 -{
 -	LLFloaterInventory* res = NULL;
 -	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
 -	S32 z_min = S32_MAX;
 -	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
 -	{
 -		LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter);
 -		if (iv)
 -		{
 -			S32 z_order = gFloaterView->getZOrder(iv);
 -			if (z_order < z_min)
 -			{
 -				res = iv;
 -				z_min = z_order;
 -			}
 -		}
 -	}
 -	return res;
 -}
 -
 -// static
 -void LLFloaterInventory::cleanup()
 -{
 -	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
 -	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end();)
 -	{
 -		LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter++);
 -		if (iv)
 -		{
 -			iv->destroy();
 -		}
 -	}
 -}
 -
 -void LLFloaterInventory::onOpen(const LLSD& key)
 -{
 -	LLFirstUse::useInventory();
 -}
 +/**  + * @file llfloaterinventory.cpp + * @brief Implementation of the inventory view and associated stuff. + * + * $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 "llviewerprecompiledheaders.h" + +#include "llfloaterinventory.h" + +#include "llagent.h" +#include "llfirstuse.h" +#include "llfloaterreg.h" +#include "llinventorymodel.h" +#include "llpanelmaininventory.h" +#include "llresmgr.h" + +///---------------------------------------------------------------------------- +/// LLFloaterInventory +///---------------------------------------------------------------------------- + +LLFloaterInventory::LLFloaterInventory(const LLSD& key) +	: LLFloater(key) +{ +} + +LLFloaterInventory::~LLFloaterInventory() +{ +} + +BOOL LLFloaterInventory::postBuild() +{ +	mPanelMainInventory = getChild<LLPanelMainInventory>("Inventory Panel"); +	return TRUE; +} + + +void LLFloaterInventory::draw() +{ + 	if (LLInventoryModel::isEverythingFetched()) +	{ +		updateTitle(); +	} +	LLFloater::draw(); +} + +void LLFloaterInventory::updateTitle() +{ +	LLLocale locale(LLLocale::USER_LOCALE); +	std::string item_count_string; +	LLResMgr::getInstance()->getIntegerString(item_count_string, gInventory.getItemCount()); + +	LLStringUtil::format_map_t string_args; +	string_args["[ITEM_COUNT]"] = item_count_string; +	string_args["[FILTER]"] = mPanelMainInventory->getFilterText(); + +	if (LLInventoryModel::backgroundFetchActive()) +	{ +		setTitle(getString("TitleFetching", string_args)); +	} +	else +	{ +		setTitle(getString("TitleCompleted", string_args)); +	} +} + +void LLFloaterInventory::changed(U32 mask) +{ +	updateTitle(); +} + +LLInventoryPanel* LLFloaterInventory::getPanel() +{ +	if (mPanelMainInventory) +		return mPanelMainInventory->getPanel(); +	return NULL; +} + +// static +LLFloaterInventory* LLFloaterInventory::showAgentInventory() +{ +	LLFloaterInventory* iv = NULL; +	if (!gAgent.cameraMouselook()) +	{ +		iv = LLFloaterReg::showTypedInstance<LLFloaterInventory>("inventory", LLSD()); +	} +	return iv; +} + +// static +LLFloaterInventory* LLFloaterInventory::getActiveInventory() +{ +	LLFloaterInventory* res = NULL; +	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); +	S32 z_min = S32_MAX; +	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) +	{ +		LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter); +		if (iv) +		{ +			S32 z_order = gFloaterView->getZOrder(iv); +			if (z_order < z_min) +			{ +				res = iv; +				z_min = z_order; +			} +		} +	} +	return res; +} + +// static +void LLFloaterInventory::cleanup() +{ +	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); +	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end();) +	{ +		LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter++); +		if (iv) +		{ +			iv->destroy(); +		} +	} +} + +void LLFloaterInventory::onOpen(const LLSD& key) +{ +	LLFirstUse::useInventory(); +} diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 336025e55e..b9775cf0e9 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -604,6 +604,12 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,  	{  		disabled_items.push_back(std::string("Delete"));  	} + +	// If multiple items are selected, disable properties (if it exists). +	if ((flags & FIRST_SELECTED_ITEM) == 0) +	{ +		disabled_items.push_back(std::string("Properties")); +	}  }  void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 694f702654..77121bd922 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1,344 +1,344 @@ -/** 
 - * @file llfloaterinventory.cpp
 - * @brief Implementation of the inventory view and associated stuff.
 - *
 - * $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 "llviewerprecompiledheaders.h"
 -
 -#include <utility> // for std::pair<>
 -
 -#include "llinventoryfunctions.h"
 -
 -// library includes
 -#include "llagent.h"
 -#include "llagentwearables.h"
 -#include "llcallingcard.h"
 -#include "llfloaterreg.h"
 -#include "llsdserialize.h"
 -#include "llfiltereditor.h"
 -#include "llspinctrl.h"
 -#include "llui.h"
 -#include "message.h"
 -
 -// newview includes
 -#include "llappearancemgr.h"
 -#include "llappviewer.h"
 -#include "llfirstuse.h"
 -#include "llfloaterchat.h"
 -#include "llfloatercustomize.h"
 -#include "llfocusmgr.h"
 -#include "llfolderview.h"
 -#include "llgesturemgr.h"
 -#include "lliconctrl.h"
 -#include "llimview.h"
 -#include "llinventorybridge.h"
 -#include "llinventoryclipboard.h"
 -#include "llinventorymodel.h"
 -#include "llinventorypanel.h"
 -#include "lllineeditor.h"
 -#include "llmenugl.h"
 -#include "llpreviewanim.h"
 -#include "llpreviewgesture.h"
 -#include "llpreviewnotecard.h"
 -#include "llpreviewscript.h"
 -#include "llpreviewsound.h"
 -#include "llpreviewtexture.h"
 -#include "llresmgr.h"
 -#include "llscrollbar.h"
 -#include "llscrollcontainer.h"
 -#include "llselectmgr.h"
 -#include "lltabcontainer.h"
 -#include "lltooldraganddrop.h"
 -#include "lluictrlfactory.h"
 -#include "llviewerinventory.h"
 -#include "llviewermessage.h"
 -#include "llviewerobjectlist.h"
 -#include "llviewerregion.h"
 -#include "llviewerwindow.h"
 -#include "llvoavatarself.h"
 -#include "llwearablelist.h"
 -
 -BOOL LLInventoryState::sWearNewClothing = FALSE;
 -LLUUID LLInventoryState::sWearNewClothingTransactionID;
 -
 -void LLSaveFolderState::setApply(BOOL apply)
 -{
 -	mApply = apply; 
 -	// before generating new list of open folders, clear the old one
 -	if(!apply) 
 -	{
 -		clearOpenFolders(); 
 -	}
 -}
 -
 -void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
 -{
 -	LLMemType mt(LLMemType::MTYPE_INVENTORY_DO_FOLDER);
 -	if(mApply)
 -	{
 -		// we're applying the open state
 -		LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
 -		if(!bridge) return;
 -		LLUUID id(bridge->getUUID());
 -		if(mOpenFolders.find(id) != mOpenFolders.end())
 -		{
 -			folder->setOpen(TRUE);
 -		}
 -		else
 -		{
 -			// keep selected filter in its current state, this is less jarring to user
 -			if (!folder->isSelected())
 -			{
 -				folder->setOpen(FALSE);
 -			}
 -		}
 -	}
 -	else
 -	{
 -		// we're recording state at this point
 -		if(folder->isOpen())
 -		{
 -			LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
 -			if(!bridge) return;
 -			mOpenFolders.insert(bridge->getUUID());
 -		}
 -	}
 -}
 -
 -void LLOpenFilteredFolders::doItem(LLFolderViewItem *item)
 -{
 -	if (item->getFiltered())
 -	{
 -		item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
 -	}
 -}
 -
 -void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder)
 -{
 -	if (folder->getFiltered() && folder->getParentFolder())
 -	{
 -		folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
 -	}
 -	// if this folder didn't pass the filter, and none of its descendants did
 -	else if (!folder->getFiltered() && !folder->hasFilteredDescendants())
 -	{
 -		folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_NO);
 -	}
 -}
 -
 -void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item)
 -{
 -	if (item->getFiltered() && !mItemSelected)
 -	{
 -		item->getRoot()->setSelection(item, FALSE, FALSE);
 -		if (item->getParentFolder())
 -		{
 -			item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
 -		}
 -		item->getRoot()->scrollToShowSelection();
 -		mItemSelected = TRUE;
 -	}
 -}
 -
 -void LLSelectFirstFilteredItem::doFolder(LLFolderViewFolder* folder)
 -{
 -	if (folder->getFiltered() && !mItemSelected)
 -	{
 -		folder->getRoot()->setSelection(folder, FALSE, FALSE);
 -		if (folder->getParentFolder())
 -		{
 -			folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
 -		}
 -		folder->getRoot()->scrollToShowSelection();
 -		mItemSelected = TRUE;
 -	}
 -}
 -
 -void LLOpenFoldersWithSelection::doItem(LLFolderViewItem *item)
 -{
 -	if (item->getParentFolder() && item->isSelected())
 -	{
 -		item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
 -	}
 -}
 -
 -void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder)
 -{
 -	if (folder->getParentFolder() && folder->isSelected())
 -	{
 -		folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
 -	}
 -}
 -
 -const std::string& get_item_icon_name(LLAssetType::EType asset_type,
 -							 LLInventoryType::EType inventory_type,
 -							 U32 attachment_point,
 -							 BOOL item_is_multi )
 -{
 -	EInventoryIcon idx = OBJECT_ICON_NAME;
 -	if ( item_is_multi )
 -	{
 -		idx = OBJECT_MULTI_ICON_NAME;
 -	}
 -	
 -	switch(asset_type)
 -	{
 -	case LLAssetType::AT_TEXTURE:
 -		if(LLInventoryType::IT_SNAPSHOT == inventory_type)
 -		{
 -			idx = SNAPSHOT_ICON_NAME;
 -		}
 -		else
 -		{
 -			idx = TEXTURE_ICON_NAME;
 -		}
 -		break;
 -
 -	case LLAssetType::AT_SOUND:
 -		idx = SOUND_ICON_NAME;
 -		break;
 -	case LLAssetType::AT_CALLINGCARD:
 -		if(attachment_point!= 0)
 -		{
 -			idx = CALLINGCARD_ONLINE_ICON_NAME;
 -		}
 -		else
 -		{
 -			idx = CALLINGCARD_OFFLINE_ICON_NAME;
 -		}
 -		break;
 -	case LLAssetType::AT_LANDMARK:
 -		if(attachment_point!= 0)
 -		{
 -			idx = LANDMARK_VISITED_ICON_NAME;
 -		}
 -		else
 -		{
 -			idx = LANDMARK_ICON_NAME;
 -		}
 -		break;
 -	case LLAssetType::AT_SCRIPT:
 -	case LLAssetType::AT_LSL_TEXT:
 -	case LLAssetType::AT_LSL_BYTECODE:
 -		idx = SCRIPT_ICON_NAME;
 -		break;
 -	case LLAssetType::AT_CLOTHING:
 -		idx = CLOTHING_ICON_NAME;
 -	case LLAssetType::AT_BODYPART :
 -		if(LLAssetType::AT_BODYPART == asset_type)
 -		{
 -			idx = BODYPART_ICON_NAME;
 -		}
 -		switch(LLInventoryItem::II_FLAGS_WEARABLES_MASK & attachment_point)
 -		{
 -		case WT_SHAPE:
 -			idx = BODYPART_SHAPE_ICON_NAME;
 -			break;
 -		case WT_SKIN:
 -			idx = BODYPART_SKIN_ICON_NAME;
 -			break;
 -		case WT_HAIR:
 -			idx = BODYPART_HAIR_ICON_NAME;
 -			break;
 -		case WT_EYES:
 -			idx = BODYPART_EYES_ICON_NAME;
 -			break;
 -		case WT_SHIRT:
 -			idx = CLOTHING_SHIRT_ICON_NAME;
 -			break;
 -		case WT_PANTS:
 -			idx = CLOTHING_PANTS_ICON_NAME;
 -			break;
 -		case WT_SHOES:
 -			idx = CLOTHING_SHOES_ICON_NAME;
 -			break;
 -		case WT_SOCKS:
 -			idx = CLOTHING_SOCKS_ICON_NAME;
 -			break;
 -		case WT_JACKET:
 -			idx = CLOTHING_JACKET_ICON_NAME;
 -			break;
 -		case WT_GLOVES:
 -			idx = CLOTHING_GLOVES_ICON_NAME;
 -			break;
 -		case WT_UNDERSHIRT:
 -			idx = CLOTHING_UNDERSHIRT_ICON_NAME;
 -			break;
 -		case WT_UNDERPANTS:
 -			idx = CLOTHING_UNDERPANTS_ICON_NAME;
 -			break;
 -		case WT_SKIRT:
 -			idx = CLOTHING_SKIRT_ICON_NAME;
 -			break;
 -		case WT_ALPHA:
 -			idx = CLOTHING_ALPHA_ICON_NAME;
 -			break;
 -		case WT_TATTOO:
 -			idx = CLOTHING_TATTOO_ICON_NAME;
 -			break;
 -		default:
 -			// no-op, go with choice above
 -			break;
 -		}
 -		break;
 -	case LLAssetType::AT_NOTECARD:
 -		idx = NOTECARD_ICON_NAME;
 -		break;
 -	case LLAssetType::AT_ANIMATION:
 -		idx = ANIMATION_ICON_NAME;
 -		break;
 -	case LLAssetType::AT_GESTURE:
 -		idx = GESTURE_ICON_NAME;
 -		break;
 -	case LLAssetType::AT_FAVORITE:
 -		//TODO - need bette idx
 -		idx = LANDMARK_ICON_NAME;
 -		break;
 -	case LLAssetType::AT_LINK:
 -		idx = LINKITEM_ICON_NAME;
 -		break;
 -	case LLAssetType::AT_LINK_FOLDER:
 -		idx = LINKFOLDER_ICON_NAME;
 -		break;
 -	default:
 -		break;
 -	}
 -	
 -	return ICON_NAME[idx];
 -}
 -
 -LLUIImagePtr get_item_icon(LLAssetType::EType asset_type,
 -							 LLInventoryType::EType inventory_type,
 -							 U32 attachment_point,
 -							 BOOL item_is_multi)
 -{
 -	const std::string& icon_name = get_item_icon_name(asset_type, inventory_type, attachment_point, item_is_multi );
 -	return LLUI::getUIImage(icon_name);
 -}
 +/**  + * @file llfloaterinventory.cpp + * @brief Implementation of the inventory view and associated stuff. + * + * $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 "llviewerprecompiledheaders.h" + +#include <utility> // for std::pair<> + +#include "llinventoryfunctions.h" + +// library includes +#include "llagent.h" +#include "llagentwearables.h" +#include "llcallingcard.h" +#include "llfloaterreg.h" +#include "llsdserialize.h" +#include "llfiltereditor.h" +#include "llspinctrl.h" +#include "llui.h" +#include "message.h" + +// newview includes +#include "llappearancemgr.h" +#include "llappviewer.h" +#include "llfirstuse.h" +#include "llfloaterchat.h" +#include "llfloatercustomize.h" +#include "llfocusmgr.h" +#include "llfolderview.h" +#include "llgesturemgr.h" +#include "lliconctrl.h" +#include "llimview.h" +#include "llinventorybridge.h" +#include "llinventoryclipboard.h" +#include "llinventorymodel.h" +#include "llinventorypanel.h" +#include "lllineeditor.h" +#include "llmenugl.h" +#include "llpreviewanim.h" +#include "llpreviewgesture.h" +#include "llpreviewnotecard.h" +#include "llpreviewscript.h" +#include "llpreviewsound.h" +#include "llpreviewtexture.h" +#include "llresmgr.h" +#include "llscrollbar.h" +#include "llscrollcontainer.h" +#include "llselectmgr.h" +#include "lltabcontainer.h" +#include "lltooldraganddrop.h" +#include "lluictrlfactory.h" +#include "llviewerinventory.h" +#include "llviewermessage.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llviewerwindow.h" +#include "llvoavatarself.h" +#include "llwearablelist.h" + +BOOL LLInventoryState::sWearNewClothing = FALSE; +LLUUID LLInventoryState::sWearNewClothingTransactionID; + +void LLSaveFolderState::setApply(BOOL apply) +{ +	mApply = apply;  +	// before generating new list of open folders, clear the old one +	if(!apply)  +	{ +		clearOpenFolders();  +	} +} + +void LLSaveFolderState::doFolder(LLFolderViewFolder* folder) +{ +	LLMemType mt(LLMemType::MTYPE_INVENTORY_DO_FOLDER); +	if(mApply) +	{ +		// we're applying the open state +		LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener(); +		if(!bridge) return; +		LLUUID id(bridge->getUUID()); +		if(mOpenFolders.find(id) != mOpenFolders.end()) +		{ +			folder->setOpen(TRUE); +		} +		else +		{ +			// keep selected filter in its current state, this is less jarring to user +			if (!folder->isSelected()) +			{ +				folder->setOpen(FALSE); +			} +		} +	} +	else +	{ +		// we're recording state at this point +		if(folder->isOpen()) +		{ +			LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener(); +			if(!bridge) return; +			mOpenFolders.insert(bridge->getUUID()); +		} +	} +} + +void LLOpenFilteredFolders::doItem(LLFolderViewItem *item) +{ +	if (item->getFiltered()) +	{ +		item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); +	} +} + +void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder) +{ +	if (folder->getFiltered() && folder->getParentFolder()) +	{ +		folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); +	} +	// if this folder didn't pass the filter, and none of its descendants did +	else if (!folder->getFiltered() && !folder->hasFilteredDescendants()) +	{ +		folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_NO); +	} +} + +void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item) +{ +	if (item->getFiltered() && !mItemSelected) +	{ +		item->getRoot()->setSelection(item, FALSE, FALSE); +		if (item->getParentFolder()) +		{ +			item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); +		} +		item->getRoot()->scrollToShowSelection(); +		mItemSelected = TRUE; +	} +} + +void LLSelectFirstFilteredItem::doFolder(LLFolderViewFolder* folder) +{ +	if (folder->getFiltered() && !mItemSelected) +	{ +		folder->getRoot()->setSelection(folder, FALSE, FALSE); +		if (folder->getParentFolder()) +		{ +			folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); +		} +		folder->getRoot()->scrollToShowSelection(); +		mItemSelected = TRUE; +	} +} + +void LLOpenFoldersWithSelection::doItem(LLFolderViewItem *item) +{ +	if (item->getParentFolder() && item->isSelected()) +	{ +		item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); +	} +} + +void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder) +{ +	if (folder->getParentFolder() && folder->isSelected()) +	{ +		folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); +	} +} + +const std::string& get_item_icon_name(LLAssetType::EType asset_type, +							 LLInventoryType::EType inventory_type, +							 U32 attachment_point, +							 BOOL item_is_multi ) +{ +	EInventoryIcon idx = OBJECT_ICON_NAME; +	if ( item_is_multi ) +	{ +		idx = OBJECT_MULTI_ICON_NAME; +	} +	 +	switch(asset_type) +	{ +	case LLAssetType::AT_TEXTURE: +		if(LLInventoryType::IT_SNAPSHOT == inventory_type) +		{ +			idx = SNAPSHOT_ICON_NAME; +		} +		else +		{ +			idx = TEXTURE_ICON_NAME; +		} +		break; + +	case LLAssetType::AT_SOUND: +		idx = SOUND_ICON_NAME; +		break; +	case LLAssetType::AT_CALLINGCARD: +		if(attachment_point!= 0) +		{ +			idx = CALLINGCARD_ONLINE_ICON_NAME; +		} +		else +		{ +			idx = CALLINGCARD_OFFLINE_ICON_NAME; +		} +		break; +	case LLAssetType::AT_LANDMARK: +		if(attachment_point!= 0) +		{ +			idx = LANDMARK_VISITED_ICON_NAME; +		} +		else +		{ +			idx = LANDMARK_ICON_NAME; +		} +		break; +	case LLAssetType::AT_SCRIPT: +	case LLAssetType::AT_LSL_TEXT: +	case LLAssetType::AT_LSL_BYTECODE: +		idx = SCRIPT_ICON_NAME; +		break; +	case LLAssetType::AT_CLOTHING: +		idx = CLOTHING_ICON_NAME; +	case LLAssetType::AT_BODYPART : +		if(LLAssetType::AT_BODYPART == asset_type) +		{ +			idx = BODYPART_ICON_NAME; +		} +		switch(LLInventoryItem::II_FLAGS_WEARABLES_MASK & attachment_point) +		{ +		case WT_SHAPE: +			idx = BODYPART_SHAPE_ICON_NAME; +			break; +		case WT_SKIN: +			idx = BODYPART_SKIN_ICON_NAME; +			break; +		case WT_HAIR: +			idx = BODYPART_HAIR_ICON_NAME; +			break; +		case WT_EYES: +			idx = BODYPART_EYES_ICON_NAME; +			break; +		case WT_SHIRT: +			idx = CLOTHING_SHIRT_ICON_NAME; +			break; +		case WT_PANTS: +			idx = CLOTHING_PANTS_ICON_NAME; +			break; +		case WT_SHOES: +			idx = CLOTHING_SHOES_ICON_NAME; +			break; +		case WT_SOCKS: +			idx = CLOTHING_SOCKS_ICON_NAME; +			break; +		case WT_JACKET: +			idx = CLOTHING_JACKET_ICON_NAME; +			break; +		case WT_GLOVES: +			idx = CLOTHING_GLOVES_ICON_NAME; +			break; +		case WT_UNDERSHIRT: +			idx = CLOTHING_UNDERSHIRT_ICON_NAME; +			break; +		case WT_UNDERPANTS: +			idx = CLOTHING_UNDERPANTS_ICON_NAME; +			break; +		case WT_SKIRT: +			idx = CLOTHING_SKIRT_ICON_NAME; +			break; +		case WT_ALPHA: +			idx = CLOTHING_ALPHA_ICON_NAME; +			break; +		case WT_TATTOO: +			idx = CLOTHING_TATTOO_ICON_NAME; +			break; +		default: +			// no-op, go with choice above +			break; +		} +		break; +	case LLAssetType::AT_NOTECARD: +		idx = NOTECARD_ICON_NAME; +		break; +	case LLAssetType::AT_ANIMATION: +		idx = ANIMATION_ICON_NAME; +		break; +	case LLAssetType::AT_GESTURE: +		idx = GESTURE_ICON_NAME; +		break; +	case LLAssetType::AT_FAVORITE: +		//TODO - need bette idx +		idx = LANDMARK_ICON_NAME; +		break; +	case LLAssetType::AT_LINK: +		idx = LINKITEM_ICON_NAME; +		break; +	case LLAssetType::AT_LINK_FOLDER: +		idx = LINKFOLDER_ICON_NAME; +		break; +	default: +		break; +	} +	 +	return ICON_NAME[idx]; +} + +LLUIImagePtr get_item_icon(LLAssetType::EType asset_type, +							 LLInventoryType::EType inventory_type, +							 U32 attachment_point, +							 BOOL item_is_multi) +{ +	const std::string& icon_name = get_item_icon_name(asset_type, inventory_type, attachment_point, item_is_multi ); +	return LLUI::getUIImage(icon_name); +} diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index efd40576a7..95cc68ddbe 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 c17a035503..d1ca0efed3 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -1,888 +1,888 @@ -/** 
 - * @file llfloaterinventory.cpp
 - * @brief Implementation of the inventory view and associated stuff.
 - *
 - * $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 "llviewerprecompiledheaders.h"
 -
 -#include <utility> // for std::pair<>
 -
 -#include "llinventorypanel.h"
 -
 -// Seraph TODO: Remove unnecessary headers
 -
 -// library includes
 -#include "llagent.h"
 -#include "llagentwearables.h"
 -#include "llcallingcard.h"
 -#include "llfloaterreg.h"
 -#include "llsdserialize.h"
 -#include "llfiltereditor.h"
 -#include "llspinctrl.h"
 -#include "llui.h"
 -#include "message.h"
 -
 -// newview includes
 -#include "llappearancemgr.h"
 -#include "llappviewer.h"
 -#include "llfirstuse.h"
 -#include "llfloaterchat.h"
 -#include "llfloatercustomize.h"
 -#include "llfocusmgr.h"
 -#include "llfolderview.h"
 -#include "llgesturemgr.h"
 -#include "lliconctrl.h"
 -#include "llimview.h"
 -#include "llinventorybridge.h"
 -#include "llinventoryclipboard.h"
 -#include "llinventorymodel.h"
 -#include "lllineeditor.h"
 -#include "llmenugl.h"
 -#include "llpreviewanim.h"
 -#include "llpreviewgesture.h"
 -#include "llpreviewnotecard.h"
 -#include "llpreviewscript.h"
 -#include "llpreviewsound.h"
 -#include "llpreviewtexture.h"
 -#include "llresmgr.h"
 -#include "llscrollbar.h"
 -#include "llscrollcontainer.h"
 -#include "llselectmgr.h"
 -#include "lltabcontainer.h"
 -#include "lltooldraganddrop.h"
 -#include "lluictrlfactory.h"
 -#include "llviewerinventory.h"
 -#include "llviewermessage.h"
 -#include "llviewerobjectlist.h"
 -#include "llviewerregion.h"
 -#include "llviewerwindow.h"
 -#include "llvoavatarself.h"
 -#include "llwearablelist.h"
 -
 -static LLDefaultChildRegistry::Register<LLInventoryPanel> r("inventory_panel");
 -
 -const std::string LLInventoryPanel::DEFAULT_SORT_ORDER = std::string("InventorySortOrder");
 -const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("RecentItemsSortOrder");
 -const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string("");
 -static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER;
 -
 -LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :	
 -	LLPanel(p),
 -	mInventoryObserver(NULL),
 -	mFolders(NULL),
 -	mScroller(NULL),
 -	mSortOrderSetting(p.sort_order_setting),
 -	mInventory(p.inventory),
 -	mAllowMultiSelect(p.allow_multi_select),
 -	mHasInventoryConnection(false),
 -	mStartFolderString(p.start_folder),	
 -	mBuildDefaultHierarchy(true),
 -	mInvFVBridgeBuilder(NULL)
 -{
 -	mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
 -
 -	// contex menu callbacks
 -	mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLInventoryPanel::doToSelected, this, _2));
 -	mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLAssetType::AT_TRASH));
 -	mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLAssetType::AT_LOST_AND_FOUND));
 -	mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLInventoryPanel::doCreate, this, _2));
 -	mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2));
 -	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));
 -	
 -	setBackgroundColor(LLUIColorTable::instance().getColor("InventoryBackgroundColor"));
 -	setBackgroundVisible(TRUE);
 -	setBackgroundOpaque(TRUE);
 -}
 -
 -BOOL LLInventoryPanel::postBuild()
 -{
 -	LLMemType mt(LLMemType::MTYPE_INVENTORY_POST_BUILD);
 -
 -	mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
 -	
 -	// create root folder
 -	{
 -		LLRect folder_rect(0,
 -						   0,
 -						   getRect().getWidth(),
 -						   0);
 -		LLFolderView::Params p;
 -		p.name = getName();
 -		p.rect = folder_rect;
 -		p.parent_panel = this;
 -		mFolders = LLUICtrlFactory::create<LLFolderView>(p);
 -		mFolders->setAllowMultiSelect(mAllowMultiSelect);
 -	}
 -
 -	mCommitCallbackRegistrar.popScope();
 -	
 -	mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
 -	
 -	// scroller
 -	{
 -		LLRect scroller_view_rect = getRect();
 -		scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
 -		LLScrollContainer::Params p;
 -		p.name("Inventory Scroller");
 -		p.rect(scroller_view_rect);
 -		p.follows.flags(FOLLOWS_ALL);
 -		p.reserve_scroll_corner(true);
 -		p.tab_stop(true);
 -		mScroller = LLUICtrlFactory::create<LLScrollContainer>(p);
 -	}
 -	addChild(mScroller);
 -	mScroller->addChild(mFolders);
 -	
 -	mFolders->setScrollContainer(mScroller);
 -
 -	// set up the callbacks from the inventory we're viewing, and then
 -	// build everything.
 -	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 LLAssetType::EType preferred_type = LLAssetType::lookupHumanReadable(mStartFolderString);
 -
 -	if ("inventory" == mStartFolderString)
 -	{
 -		mStartFolderID = gInventory.getRootFolderID();
 -	}
 -	else if ("library" == mStartFolderString)
 -	{
 -		mStartFolderID = gInventory.getLibraryRootFolderID();
 -	}
 -	else
 -	{
 -		mStartFolderID = (preferred_type != LLAssetType::AT_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);
 -		mHasInventoryConnection = true;
 -	}
 -
 -	// bit of a hack to make sure the inventory is open.
 -	mFolders->openFolder(preferred_type != LLAssetType::AT_NONE ? LLAssetType::lookupCategoryName(preferred_type) : "My Inventory");
 -
 -	if (mSortOrderSetting != INHERIT_SORT_ORDER)
 -	{
 -		setSortOrder(gSavedSettings.getU32(mSortOrderSetting));
 -	}
 -	else
 -	{
 -		setSortOrder(gSavedSettings.getU32(DEFAULT_SORT_ORDER));
 -	}
 -	mFolders->setSortOrder(mFolders->getFilter()->getSortOrder());
 -
 -	return TRUE;
 -}
 -
 -LLInventoryPanel::~LLInventoryPanel()
 -{
 -	// should this be a global setting?
 -	if (mFolders)
 -	{
 -		U32 sort_order = mFolders->getSortOrder();
 -		if (mSortOrderSetting != INHERIT_SORT_ORDER)
 -		{
 -			gSavedSettings.setU32(mSortOrderSetting, sort_order);
 -		}
 -	}
 -
 -	// LLView destructor will take care of the sub-views.
 -	mInventory->removeObserver(mInventoryObserver);
 -	delete mInventoryObserver;
 -	mScroller = NULL;
 -}
 -
 -LLMemType mt(LLMemType::MTYPE_INVENTORY_FROM_XML); // ! BUG ! Should this be removed?
 -void LLInventoryPanel::draw()
 -{
 -	// select the desired item (in case it wasn't loaded when the selection was requested)
 -	mFolders->updateSelection();
 -	LLPanel::draw();
 -}
 -
 -LLInventoryFilter* LLInventoryPanel::getFilter()
 -{
 -	if (mFolders) return mFolders->getFilter();
 -	return NULL;
 -}
 -
 -void LLInventoryPanel::setFilterTypes(U64 filter_types, BOOL filter_for_categories)
 -{
 -	mFolders->getFilter()->setFilterTypes(filter_types, filter_for_categories);
 -}	
 -
 -void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask)
 -{
 -	mFolders->getFilter()->setFilterPermissions(filter_perm_mask);
 -}
 -
 -void LLInventoryPanel::setFilterSubString(const std::string& string)
 -{
 -	mFolders->getFilter()->setFilterSubString(string);
 -}
 -
 -void LLInventoryPanel::setSortOrder(U32 order)
 -{
 -	mFolders->getFilter()->setSortOrder(order);
 -	if (mFolders->getFilter()->isModified())
 -	{
 -		mFolders->setSortOrder(order);
 -		// try to keep selection onscreen, even if it wasn't to start with
 -		mFolders->scrollToShowSelection();
 -	}
 -}
 -
 -void LLInventoryPanel::setSinceLogoff(BOOL sl)
 -{
 -	mFolders->getFilter()->setDateRangeLastLogoff(sl);
 -}
 -
 -void LLInventoryPanel::setHoursAgo(U32 hours)
 -{
 -	mFolders->getFilter()->setHoursAgo(hours);
 -}
 -
 -void LLInventoryPanel::setShowFolderState(LLInventoryFilter::EFolderShow show)
 -{
 -	mFolders->getFilter()->setShowFolderState(show);
 -}
 -
 -LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState()
 -{
 -	return mFolders->getFilter()->getShowFolderState();
 -}
 -
 -static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh");
 -
 -void LLInventoryPanel::modelChanged(U32 mask)
 -{
 -	LLFastTimer t2(FTM_REFRESH);
 -
 -	bool handled = false;
 -
 -	// inventory just initialized, do complete build
 -	if ((mask & LLInventoryObserver::ADD) && gInventory.getChangedIDs().empty() && !mHasInventoryConnection)
 -	{
 -		rebuildViewsFor(mStartFolderID);
 -		mHasInventoryConnection = true;
 -		return;
 -	}
 -
 -	if(mask & LLInventoryObserver::LABEL)
 -	{
 -		handled = true;
 -		// label change - empty out the display name for each object
 -		// in this change set.
 -		const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
 -		std::set<LLUUID>::const_iterator id_it = changed_items.begin();
 -		std::set<LLUUID>::const_iterator id_end = changed_items.end();
 -		LLFolderViewItem* view = NULL;
 -		LLInvFVBridge* bridge = NULL;
 -		for (;id_it != id_end; ++id_it)
 -		{
 -			view = mFolders->getItemByID(*id_it);
 -			if(view)
 -			{
 -				// request refresh on this item (also flags for filtering)
 -				bridge = (LLInvFVBridge*)view->getListener();
 -				if(bridge)
 -				{	// Clear the display name first, so it gets properly re-built during refresh()
 -					bridge->clearDisplayName();
 -				}
 -				view->refresh();
 -			}
 -		}
 -	}
 -	if((mask & (LLInventoryObserver::STRUCTURE
 -				| LLInventoryObserver::ADD
 -				| LLInventoryObserver::REMOVE)) != 0)
 -	{
 -		handled = true;
 -		// Record which folders are open by uuid.
 -		LLInventoryModel* model = getModel();
 -		if (model)
 -		{
 -			const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
 -
 -			std::set<LLUUID>::const_iterator id_it = changed_items.begin();
 -			std::set<LLUUID>::const_iterator id_end = changed_items.end();
 -			for (;id_it != id_end; ++id_it)
 -			{
 -				// sync view with model
 -				LLInventoryObject* model_item = model->getObject(*id_it);
 -				LLFolderViewItem* view_item = mFolders->getItemByID(*id_it);
 -
 -				if (model_item)
 -				{
 -					if (!view_item)
 -					{
 -						// this object was just created, need to build a view for it
 -						if ((mask & LLInventoryObserver::ADD) != LLInventoryObserver::ADD)
 -						{
 -							llwarns << *id_it << " is in model but not in view, but ADD flag not set" << llendl;
 -						}
 -						buildNewViews(*id_it);
 -						
 -						// select any newly created object
 -						// that has the auto rename at top of folder
 -						// root set
 -						if(mFolders->getRoot()->needsAutoRename())
 -						{
 -							setSelection(*id_it, FALSE);
 -						}
 -					}
 -					else
 -					{
 -						// this object was probably moved, check its parent
 -						if ((mask & LLInventoryObserver::STRUCTURE) != LLInventoryObserver::STRUCTURE)
 -						{
 -							llwarns << *id_it << " is in model and in view, but STRUCTURE flag not set" << llendl;
 -						}
 -
 -						LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolders->getItemByID(model_item->getParentUUID());
 -
 -						// added check against NULL for cases when Inventory panel contains startFolder.
 -						// in this case parent is LLFolderView (LLInventoryPanel::mFolders) itself.
 -						// this check is a fix for bug EXT-1859.
 -						if (NULL != new_parent && view_item->getParentFolder() != new_parent)
 -						{
 -							view_item->getParentFolder()->extractItem(view_item);
 -							view_item->addToFolder(new_parent, mFolders);
 -						}
 -					}
 -				}
 -				else
 -				{
 -					if (view_item)
 -					{
 -						if ((mask & LLInventoryObserver::REMOVE) != LLInventoryObserver::REMOVE)
 -						{
 -							llwarns << *id_it << " is not in model but in view, but REMOVE flag not set" << llendl;
 -						}
 -						// item in view but not model, need to delete view
 -						view_item->destroyView();
 -					}
 -					else
 -					{
 -						llwarns << *id_it << "Item does not exist in either view or model, but notification triggered" << llendl;
 -					}
 -				}
 -			}
 -		}
 -	}
 -
 -	if (!handled)
 -	{
 -		// it's a small change that only requires a refresh.
 -		// *TODO: figure out a more efficient way to do the refresh
 -		// since it is expensive on large inventories
 -		mFolders->refresh();
 -	}
 -}
 -
 -
 -void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
 -{
 -	LLFolderViewItem* old_view = NULL;
 -
 -	// get old LLFolderViewItem
 -	old_view = mFolders->getItemByID(id);
 -	if (old_view && id.notNull())
 -	{
 -		old_view->destroyView();
 -	}
 -
 -	buildNewViews(id);
 -}
 -
 -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)
 -	{
 -		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));
 -
 -			// 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()) << 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 (new_listener)
 -				{
 -					LLFolderViewFolder::Params p;
 -					p.name = new_listener->getDisplayName();
 -					p.icon = new_listener->getIcon();
 -					p.root = mFolders;
 -					p.listener = new_listener;
 -					LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(p);
 -				
 -					folderp->setItemSortOrder(mFolders->getSortOrder());
 -					itemp = folderp;
 -				}
 -			}
 -			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)
 -				{
 -					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));
 -					itemp = LLUICtrlFactory::create<LLFolderViewItem> (params);
 -				}
 -			}
 -
 -			if (itemp)
 -			{
 -				itemp->addToFolder(parent_folder, mFolders);
 -			}
 -		}
 -	}
 -
 -	// If this is a folder, add the children of the folder and recursively add any 
 -	// child folders.
 -	if ((id == mStartFolderID) ||
 -		(objectp && objectp->getType() == LLAssetType::AT_CATEGORY))
 -	{
 -		LLViewerInventoryCategory::cat_array_t* categories;
 -		LLViewerInventoryItem::item_array_t* items;
 -
 -		mInventory->lockDirectDescendentArrays(id, categories, items);
 -		if(categories)
 -		{
 -			S32 count = categories->count();
 -			for(S32 i = 0; i < count; ++i)
 -			{
 -				LLInventoryCategory* cat = categories->get(i);
 -				buildNewViews(cat->getUUID());
 -			}
 -		}
 -		if(items)
 -		{
 -			S32 count = items->count();
 -			for(S32 i = 0; i < count; ++i)
 -			{
 -				LLInventoryItem* item = items->get(i);
 -				buildNewViews(item->getUUID());
 -			}
 -		}
 -		mInventory->unlockDirectDescendentArrays(id);
 -	}
 -}
 -
 -struct LLConfirmPurgeData
 -{
 -	LLUUID mID;
 -	LLInventoryModel* mModel;
 -};
 -
 -class LLIsNotWorn : public LLInventoryCollectFunctor
 -{
 -public:
 -	LLIsNotWorn() {}
 -	virtual ~LLIsNotWorn() {}
 -	virtual bool operator()(LLInventoryCategory* cat,
 -							LLInventoryItem* item)
 -	{
 -		return !gAgentWearables.isWearingItem(item->getUUID());
 -	}
 -};
 -
 -class LLOpenFolderByID : public LLFolderViewFunctor
 -{
 -public:
 -	LLOpenFolderByID(const LLUUID& id) : mID(id) {}
 -	virtual ~LLOpenFolderByID() {}
 -	virtual void doFolder(LLFolderViewFolder* folder)
 -		{
 -			if (folder->getListener() && folder->getListener()->getUUID() == mID) folder->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
 -		}
 -	virtual void doItem(LLFolderViewItem* item) {}
 -protected:
 -	const LLUUID& mID;
 -};
 -
 -
 -void LLInventoryPanel::openSelected()
 -{
 -	LLFolderViewItem* folder_item = mFolders->getCurSelectedItem();
 -	if(!folder_item) return;
 -	LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
 -	if(!bridge) return;
 -	bridge->openItem();
 -}
 -
 -BOOL LLInventoryPanel::handleHover(S32 x, S32 y, MASK mask)
 -{
 -	BOOL handled = LLView::handleHover(x, y, mask);
 -	if(handled)
 -	{
 -		ECursorType cursor = getWindow()->getCursor();
 -		if (LLInventoryModel::backgroundFetchActive() && cursor == UI_CURSOR_ARROW)
 -		{
 -			// replace arrow cursor with arrow and hourglass cursor
 -			getWindow()->setCursor(UI_CURSOR_WORKING);
 -		}
 -	}
 -	else
 -	{
 -		getWindow()->setCursor(UI_CURSOR_ARROW);
 -	}
 -	return TRUE;
 -}
 -
 -BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 -								   EDragAndDropType cargo_type,
 -								   void* cargo_data,
 -								   EAcceptance* accept,
 -								   std::string& tooltip_msg)
 -{
 -
 -	BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
 -
 -	if (handled)
 -	{
 -		mFolders->setDragAndDropThisFrame();
 -	}
 -
 -	return handled;
 -}
 -
 -void LLInventoryPanel::onFocusLost()
 -{
 -	// inventory no longer handles cut/copy/paste/delete
 -	if (LLEditMenuHandler::gEditMenuHandler == mFolders)
 -	{
 -		LLEditMenuHandler::gEditMenuHandler = NULL;
 -	}
 -
 -	LLPanel::onFocusLost();
 -}
 -
 -void LLInventoryPanel::onFocusReceived()
 -{
 -	// inventory now handles cut/copy/paste/delete
 -	LLEditMenuHandler::gEditMenuHandler = mFolders;
 -
 -	LLPanel::onFocusReceived();
 -}
 -
 -
 -void LLInventoryPanel::openAllFolders()
 -{
 -	mFolders->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN);
 -	mFolders->arrangeAll();
 -}
 -
 -void LLInventoryPanel::openDefaultFolderForType(LLAssetType::EType type)
 -{
 -	LLUUID category_id = mInventory->findCategoryUUIDForType(type);
 -	LLOpenFolderByID opener(category_id);
 -	mFolders->applyFunctorRecursively(opener);
 -}
 -
 -void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus)
 -{
 -	// Don't select objects in COF (e.g. to prevent refocus when items are worn).
 -	const LLInventoryObject *obj = gInventory.getObject(obj_id);
 -	if (obj && obj->getParentUUID() == LLAppearanceManager::getCOF())
 -	{
 -		return;
 -	}
 -	mFolders->setSelectionByID(obj_id, take_keyboard_focus);
 -}
 -
 -void LLInventoryPanel::clearSelection()
 -{
 -	mFolders->clearSelection();
 -}
 -
 -void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action)
 -{
 -	LLFolderView* fv = getRootFolder();
 -	if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename
 -	{
 -		fv->setNeedsAutoRename(FALSE);
 -		if (items.size()) // new asset is visible and selected
 -		{
 -			fv->startRenamingSelectedItem();
 -		}
 -	}
 -	// Seraph - Put determineFolderType in here for ensemble typing?
 -}
 -
 -//----------------------------------------------------------------------------
 -
 -void LLInventoryPanel::doToSelected(const LLSD& userdata)
 -{
 -	mFolders->doToSelected(&gInventory, userdata);
 -}
 -
 -void LLInventoryPanel::doCreate(const LLSD& userdata)
 -{
 -	menu_create_inventory_item(mFolders, LLFolderBridge::sSelf, userdata);
 -}
 -
 -bool LLInventoryPanel::beginIMSession()
 -{
 -	std::set<LLUUID> selected_items;
 -	mFolders->getSelectionList(selected_items);
 -
 -	std::string name;
 -	static int session_num = 1;
 -
 -	LLDynamicArray<LLUUID> members;
 -	EInstantMessage type = IM_SESSION_CONFERENCE_START;
 -
 -	std::set<LLUUID>::const_iterator iter;
 -	for (iter = selected_items.begin(); iter != selected_items.end(); iter++)
 -	{
 -
 -		LLUUID item = *iter;
 -		LLFolderViewItem* folder_item = mFolders->getItemByID(item);
 -			
 -		if(folder_item) 
 -		{
 -			LLFolderViewEventListener* fve_listener = folder_item->getListener();
 -			if (fve_listener && (fve_listener->getInventoryType() == LLInventoryType::IT_CATEGORY))
 -			{
 -
 -				LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getListener();
 -				if(!bridge) return true;
 -				LLViewerInventoryCategory* cat = bridge->getCategory();
 -				if(!cat) return true;
 -				name = cat->getName();
 -				LLUniqueBuddyCollector is_buddy;
 -				LLInventoryModel::cat_array_t cat_array;
 -				LLInventoryModel::item_array_t item_array;
 -				gInventory.collectDescendentsIf(bridge->getUUID(),
 -												cat_array,
 -												item_array,
 -												LLInventoryModel::EXCLUDE_TRASH,
 -												is_buddy);
 -				S32 count = item_array.count();
 -				if(count > 0)
 -				{
 -					LLFloaterReg::showInstance("communicate");
 -					// create the session
 -					LLAvatarTracker& at = LLAvatarTracker::instance();
 -					LLUUID id;
 -					for(S32 i = 0; i < count; ++i)
 -					{
 -						id = item_array.get(i)->getCreatorUUID();
 -						if(at.isBuddyOnline(id))
 -						{
 -							members.put(id);
 -						}
 -					}
 -				}
 -			}
 -			else
 -			{
 -				LLFolderViewItem* folder_item = mFolders->getItemByID(item);
 -				if(!folder_item) return true;
 -				LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getListener();
 -
 -				if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD)
 -				{
 -					LLInventoryItem* inv_item = gInventory.getItem(listenerp->getUUID());
 -
 -					if (inv_item)
 -					{
 -						LLAvatarTracker& at = LLAvatarTracker::instance();
 -						LLUUID id = inv_item->getCreatorUUID();
 -
 -						if(at.isBuddyOnline(id))
 -						{
 -							members.put(id);
 -						}
 -					}
 -				} //if IT_CALLINGCARD
 -			} //if !IT_CATEGORY
 -		}
 -	} //for selected_items	
 -
 -	// the session_id is randomly generated UUID which will be replaced later
 -	// with a server side generated number
 -
 -	if (name.empty())
 -	{
 -		name = llformat("Session %d", session_num++);
 -	}
 -
 -	gIMMgr->addSession(name, type, members[0], members);
 -		
 -	return true;
 -}
 -
 -bool LLInventoryPanel::attachObject(const LLSD& userdata)
 -{
 -	std::set<LLUUID> selected_items;
 -	mFolders->getSelectionList(selected_items);
 -
 -	std::string joint_name = userdata.asString();
 -	LLVOAvatar *avatarp = static_cast<LLVOAvatar*>(gAgent.getAvatarObject());
 -	LLViewerJointAttachment* attachmentp = NULL;
 -	for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); 
 -		 iter != avatarp->mAttachmentPoints.end(); )
 -	{
 -		LLVOAvatar::attachment_map_t::iterator curiter = iter++;
 -		LLViewerJointAttachment* attachment = curiter->second;
 -		if (attachment->getName() == joint_name)
 -		{
 -			attachmentp = attachment;
 -			break;
 -		}
 -	}
 -	if (attachmentp == NULL)
 -	{
 -		return true;
 -	}
 -
 -	for (std::set<LLUUID>::const_iterator set_iter = selected_items.begin(); 
 -		 set_iter != selected_items.end(); 
 -		 ++set_iter)
 -	{
 -		const LLUUID &id = *set_iter;
 -		LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(id);
 -		if(item && gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID()))
 -		{
 -			rez_attachment(item, attachmentp);
 -		}
 -		else if(item && item->isComplete())
 -		{
 -			// must be in library. copy it to our inventory and put it on.
 -			LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(attachmentp);
 -			copy_inventory_item(gAgent.getID(),
 -								item->getPermissions().getOwner(),
 -								item->getUUID(),
 -								LLUUID::null,
 -								std::string(),
 -								cb);
 -		}
 -	}
 -	gFocusMgr.setKeyboardFocus(NULL);
 -
 -	return true;
 -}
 -
 -
 -//----------------------------------------------------------------------------
 -
 -// static DEBUG ONLY:
 -void LLInventoryPanel::dumpSelectionInformation(void* user_data)
 -{
 -	LLInventoryPanel* iv = (LLInventoryPanel*)user_data;
 -	iv->mFolders->dumpSelectionInformation();
 -}
 -
 -BOOL LLInventoryPanel::getSinceLogoff()
 -{
 -	return mFolders->getFilter()->isSinceLogoff();
 -}
 -
 -void example_param_block_usage()
 -{
 -	LLInventoryPanel::Params param_block;
 -	param_block.name(std::string("inventory"));
 -
 -	param_block.sort_order_setting(LLInventoryPanel::RECENTITEMS_SORT_ORDER);
 -	param_block.allow_multi_select(true);
 -	param_block.filter(LLInventoryPanel::Filter()
 -			.sort_order(1)
 -			.types(0xffff0000));
 -	param_block.inventory(&gInventory);
 -	param_block.has_border(true);
 -
 -	LLUICtrlFactory::create<LLInventoryPanel>(param_block);
 -
 -	param_block = LLInventoryPanel::Params();
 -	param_block.name(std::string("inventory"));
 -
 -	//LLSD param_block_sd;
 -	//param_block_sd["sort_order_setting"] = LLInventoryPanel::RECENTITEMS_SORT_ORDER;
 -	//param_block_sd["allow_multi_select"] = true;
 -	//param_block_sd["filter"]["sort_order"] = 1;
 -	//param_block_sd["filter"]["types"] = (S32)0xffff0000;
 -	//param_block_sd["has_border"] = true;
 -
 -	//LLInitParam::LLSDParser(param_block_sd).parse(param_block);
 -
 -	LLUICtrlFactory::create<LLInventoryPanel>(param_block);
 -}
 +/**  + * @file llfloaterinventory.cpp + * @brief Implementation of the inventory view and associated stuff. + * + * $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 "llviewerprecompiledheaders.h" + +#include <utility> // for std::pair<> + +#include "llinventorypanel.h" + +// Seraph TODO: Remove unnecessary headers + +// library includes +#include "llagent.h" +#include "llagentwearables.h" +#include "llcallingcard.h" +#include "llfloaterreg.h" +#include "llsdserialize.h" +#include "llfiltereditor.h" +#include "llspinctrl.h" +#include "llui.h" +#include "message.h" + +// newview includes +#include "llappearancemgr.h" +#include "llappviewer.h" +#include "llfirstuse.h" +#include "llfloaterchat.h" +#include "llfloatercustomize.h" +#include "llfocusmgr.h" +#include "llfolderview.h" +#include "llgesturemgr.h" +#include "lliconctrl.h" +#include "llimview.h" +#include "llinventorybridge.h" +#include "llinventoryclipboard.h" +#include "llinventorymodel.h" +#include "lllineeditor.h" +#include "llmenugl.h" +#include "llpreviewanim.h" +#include "llpreviewgesture.h" +#include "llpreviewnotecard.h" +#include "llpreviewscript.h" +#include "llpreviewsound.h" +#include "llpreviewtexture.h" +#include "llresmgr.h" +#include "llscrollbar.h" +#include "llscrollcontainer.h" +#include "llselectmgr.h" +#include "lltabcontainer.h" +#include "lltooldraganddrop.h" +#include "lluictrlfactory.h" +#include "llviewerinventory.h" +#include "llviewermessage.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llviewerwindow.h" +#include "llvoavatarself.h" +#include "llwearablelist.h" + +static LLDefaultChildRegistry::Register<LLInventoryPanel> r("inventory_panel"); + +const std::string LLInventoryPanel::DEFAULT_SORT_ORDER = std::string("InventorySortOrder"); +const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("RecentItemsSortOrder"); +const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string(""); +static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER; + +LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :	 +	LLPanel(p), +	mInventoryObserver(NULL), +	mFolders(NULL), +	mScroller(NULL), +	mSortOrderSetting(p.sort_order_setting), +	mInventory(p.inventory), +	mAllowMultiSelect(p.allow_multi_select), +	mHasInventoryConnection(false), +	mStartFolderString(p.start_folder),	 +	mBuildDefaultHierarchy(true), +	mInvFVBridgeBuilder(NULL) +{ +	mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER; + +	// contex menu callbacks +	mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLInventoryPanel::doToSelected, this, _2)); +	mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLAssetType::AT_TRASH)); +	mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLAssetType::AT_LOST_AND_FOUND)); +	mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLInventoryPanel::doCreate, this, _2)); +	mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2)); +	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this)); +	 +	setBackgroundColor(LLUIColorTable::instance().getColor("InventoryBackgroundColor")); +	setBackgroundVisible(TRUE); +	setBackgroundOpaque(TRUE); +} + +BOOL LLInventoryPanel::postBuild() +{ +	LLMemType mt(LLMemType::MTYPE_INVENTORY_POST_BUILD); + +	mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves +	 +	// create root folder +	{ +		LLRect folder_rect(0, +						   0, +						   getRect().getWidth(), +						   0); +		LLFolderView::Params p; +		p.name = getName(); +		p.rect = folder_rect; +		p.parent_panel = this; +		mFolders = LLUICtrlFactory::create<LLFolderView>(p); +		mFolders->setAllowMultiSelect(mAllowMultiSelect); +	} + +	mCommitCallbackRegistrar.popScope(); +	 +	mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar); +	 +	// scroller +	{ +		LLRect scroller_view_rect = getRect(); +		scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); +		LLScrollContainer::Params p; +		p.name("Inventory Scroller"); +		p.rect(scroller_view_rect); +		p.follows.flags(FOLLOWS_ALL); +		p.reserve_scroll_corner(true); +		p.tab_stop(true); +		mScroller = LLUICtrlFactory::create<LLScrollContainer>(p); +	} +	addChild(mScroller); +	mScroller->addChild(mFolders); +	 +	mFolders->setScrollContainer(mScroller); + +	// set up the callbacks from the inventory we're viewing, and then +	// build everything. +	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 LLAssetType::EType preferred_type = LLAssetType::lookupHumanReadable(mStartFolderString); + +	if ("inventory" == mStartFolderString) +	{ +		mStartFolderID = gInventory.getRootFolderID(); +	} +	else if ("library" == mStartFolderString) +	{ +		mStartFolderID = gInventory.getLibraryRootFolderID(); +	} +	else +	{ +		mStartFolderID = (preferred_type != LLAssetType::AT_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); +		mHasInventoryConnection = true; +	} + +	// bit of a hack to make sure the inventory is open. +	mFolders->openFolder(preferred_type != LLAssetType::AT_NONE ? LLAssetType::lookupCategoryName(preferred_type) : "My Inventory"); + +	if (mSortOrderSetting != INHERIT_SORT_ORDER) +	{ +		setSortOrder(gSavedSettings.getU32(mSortOrderSetting)); +	} +	else +	{ +		setSortOrder(gSavedSettings.getU32(DEFAULT_SORT_ORDER)); +	} +	mFolders->setSortOrder(mFolders->getFilter()->getSortOrder()); + +	return TRUE; +} + +LLInventoryPanel::~LLInventoryPanel() +{ +	// should this be a global setting? +	if (mFolders) +	{ +		U32 sort_order = mFolders->getSortOrder(); +		if (mSortOrderSetting != INHERIT_SORT_ORDER) +		{ +			gSavedSettings.setU32(mSortOrderSetting, sort_order); +		} +	} + +	// LLView destructor will take care of the sub-views. +	mInventory->removeObserver(mInventoryObserver); +	delete mInventoryObserver; +	mScroller = NULL; +} + +LLMemType mt(LLMemType::MTYPE_INVENTORY_FROM_XML); // ! BUG ! Should this be removed? +void LLInventoryPanel::draw() +{ +	// select the desired item (in case it wasn't loaded when the selection was requested) +	mFolders->updateSelection(); +	LLPanel::draw(); +} + +LLInventoryFilter* LLInventoryPanel::getFilter() +{ +	if (mFolders) return mFolders->getFilter(); +	return NULL; +} + +void LLInventoryPanel::setFilterTypes(U64 filter_types, BOOL filter_for_categories) +{ +	mFolders->getFilter()->setFilterTypes(filter_types, filter_for_categories); +}	 + +void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask) +{ +	mFolders->getFilter()->setFilterPermissions(filter_perm_mask); +} + +void LLInventoryPanel::setFilterSubString(const std::string& string) +{ +	mFolders->getFilter()->setFilterSubString(string); +} + +void LLInventoryPanel::setSortOrder(U32 order) +{ +	mFolders->getFilter()->setSortOrder(order); +	if (mFolders->getFilter()->isModified()) +	{ +		mFolders->setSortOrder(order); +		// try to keep selection onscreen, even if it wasn't to start with +		mFolders->scrollToShowSelection(); +	} +} + +void LLInventoryPanel::setSinceLogoff(BOOL sl) +{ +	mFolders->getFilter()->setDateRangeLastLogoff(sl); +} + +void LLInventoryPanel::setHoursAgo(U32 hours) +{ +	mFolders->getFilter()->setHoursAgo(hours); +} + +void LLInventoryPanel::setShowFolderState(LLInventoryFilter::EFolderShow show) +{ +	mFolders->getFilter()->setShowFolderState(show); +} + +LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState() +{ +	return mFolders->getFilter()->getShowFolderState(); +} + +static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh"); + +void LLInventoryPanel::modelChanged(U32 mask) +{ +	LLFastTimer t2(FTM_REFRESH); + +	bool handled = false; + +	// inventory just initialized, do complete build +	if ((mask & LLInventoryObserver::ADD) && gInventory.getChangedIDs().empty() && !mHasInventoryConnection) +	{ +		rebuildViewsFor(mStartFolderID); +		mHasInventoryConnection = true; +		return; +	} + +	if(mask & LLInventoryObserver::LABEL) +	{ +		handled = true; +		// label change - empty out the display name for each object +		// in this change set. +		const std::set<LLUUID>& changed_items = gInventory.getChangedIDs(); +		std::set<LLUUID>::const_iterator id_it = changed_items.begin(); +		std::set<LLUUID>::const_iterator id_end = changed_items.end(); +		LLFolderViewItem* view = NULL; +		LLInvFVBridge* bridge = NULL; +		for (;id_it != id_end; ++id_it) +		{ +			view = mFolders->getItemByID(*id_it); +			if(view) +			{ +				// request refresh on this item (also flags for filtering) +				bridge = (LLInvFVBridge*)view->getListener(); +				if(bridge) +				{	// Clear the display name first, so it gets properly re-built during refresh() +					bridge->clearDisplayName(); +				} +				view->refresh(); +			} +		} +	} +	if((mask & (LLInventoryObserver::STRUCTURE +				| LLInventoryObserver::ADD +				| LLInventoryObserver::REMOVE)) != 0) +	{ +		handled = true; +		// Record which folders are open by uuid. +		LLInventoryModel* model = getModel(); +		if (model) +		{ +			const std::set<LLUUID>& changed_items = gInventory.getChangedIDs(); + +			std::set<LLUUID>::const_iterator id_it = changed_items.begin(); +			std::set<LLUUID>::const_iterator id_end = changed_items.end(); +			for (;id_it != id_end; ++id_it) +			{ +				// sync view with model +				LLInventoryObject* model_item = model->getObject(*id_it); +				LLFolderViewItem* view_item = mFolders->getItemByID(*id_it); + +				if (model_item) +				{ +					if (!view_item) +					{ +						// this object was just created, need to build a view for it +						if ((mask & LLInventoryObserver::ADD) != LLInventoryObserver::ADD) +						{ +							llwarns << *id_it << " is in model but not in view, but ADD flag not set" << llendl; +						} +						buildNewViews(*id_it); +						 +						// select any newly created object +						// that has the auto rename at top of folder +						// root set +						if(mFolders->getRoot()->needsAutoRename()) +						{ +							setSelection(*id_it, FALSE); +						} +					} +					else +					{ +						// this object was probably moved, check its parent +						if ((mask & LLInventoryObserver::STRUCTURE) != LLInventoryObserver::STRUCTURE) +						{ +							llwarns << *id_it << " is in model and in view, but STRUCTURE flag not set" << llendl; +						} + +						LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolders->getItemByID(model_item->getParentUUID()); + +						// added check against NULL for cases when Inventory panel contains startFolder. +						// in this case parent is LLFolderView (LLInventoryPanel::mFolders) itself. +						// this check is a fix for bug EXT-1859. +						if (NULL != new_parent && view_item->getParentFolder() != new_parent) +						{ +							view_item->getParentFolder()->extractItem(view_item); +							view_item->addToFolder(new_parent, mFolders); +						} +					} +				} +				else +				{ +					if (view_item) +					{ +						if ((mask & LLInventoryObserver::REMOVE) != LLInventoryObserver::REMOVE) +						{ +							llwarns << *id_it << " is not in model but in view, but REMOVE flag not set" << llendl; +						} +						// item in view but not model, need to delete view +						view_item->destroyView(); +					} +					else +					{ +						llwarns << *id_it << "Item does not exist in either view or model, but notification triggered" << llendl; +					} +				} +			} +		} +	} + +	if (!handled) +	{ +		// it's a small change that only requires a refresh. +		// *TODO: figure out a more efficient way to do the refresh +		// since it is expensive on large inventories +		mFolders->refresh(); +	} +} + + +void LLInventoryPanel::rebuildViewsFor(const LLUUID& id) +{ +	LLFolderViewItem* old_view = NULL; + +	// get old LLFolderViewItem +	old_view = mFolders->getItemByID(id); +	if (old_view && id.notNull()) +	{ +		old_view->destroyView(); +	} + +	buildNewViews(id); +} + +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) +	{ +		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)); + +			// 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()) << 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 (new_listener) +				{ +					LLFolderViewFolder::Params p; +					p.name = new_listener->getDisplayName(); +					p.icon = new_listener->getIcon(); +					p.root = mFolders; +					p.listener = new_listener; +					LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(p); +				 +					folderp->setItemSortOrder(mFolders->getSortOrder()); +					itemp = folderp; +				} +			} +			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) +				{ +					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)); +					itemp = LLUICtrlFactory::create<LLFolderViewItem> (params); +				} +			} + +			if (itemp) +			{ +				itemp->addToFolder(parent_folder, mFolders); +			} +		} +	} + +	// If this is a folder, add the children of the folder and recursively add any  +	// child folders. +	if ((id == mStartFolderID) || +		(objectp && objectp->getType() == LLAssetType::AT_CATEGORY)) +	{ +		LLViewerInventoryCategory::cat_array_t* categories; +		LLViewerInventoryItem::item_array_t* items; + +		mInventory->lockDirectDescendentArrays(id, categories, items); +		if(categories) +		{ +			S32 count = categories->count(); +			for(S32 i = 0; i < count; ++i) +			{ +				LLInventoryCategory* cat = categories->get(i); +				buildNewViews(cat->getUUID()); +			} +		} +		if(items) +		{ +			S32 count = items->count(); +			for(S32 i = 0; i < count; ++i) +			{ +				LLInventoryItem* item = items->get(i); +				buildNewViews(item->getUUID()); +			} +		} +		mInventory->unlockDirectDescendentArrays(id); +	} +} + +struct LLConfirmPurgeData +{ +	LLUUID mID; +	LLInventoryModel* mModel; +}; + +class LLIsNotWorn : public LLInventoryCollectFunctor +{ +public: +	LLIsNotWorn() {} +	virtual ~LLIsNotWorn() {} +	virtual bool operator()(LLInventoryCategory* cat, +							LLInventoryItem* item) +	{ +		return !gAgentWearables.isWearingItem(item->getUUID()); +	} +}; + +class LLOpenFolderByID : public LLFolderViewFunctor +{ +public: +	LLOpenFolderByID(const LLUUID& id) : mID(id) {} +	virtual ~LLOpenFolderByID() {} +	virtual void doFolder(LLFolderViewFolder* folder) +		{ +			if (folder->getListener() && folder->getListener()->getUUID() == mID) folder->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); +		} +	virtual void doItem(LLFolderViewItem* item) {} +protected: +	const LLUUID& mID; +}; + + +void LLInventoryPanel::openSelected() +{ +	LLFolderViewItem* folder_item = mFolders->getCurSelectedItem(); +	if(!folder_item) return; +	LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener(); +	if(!bridge) return; +	bridge->openItem(); +} + +BOOL LLInventoryPanel::handleHover(S32 x, S32 y, MASK mask) +{ +	BOOL handled = LLView::handleHover(x, y, mask); +	if(handled) +	{ +		ECursorType cursor = getWindow()->getCursor(); +		if (LLInventoryModel::backgroundFetchActive() && cursor == UI_CURSOR_ARROW) +		{ +			// replace arrow cursor with arrow and hourglass cursor +			getWindow()->setCursor(UI_CURSOR_WORKING); +		} +	} +	else +	{ +		getWindow()->setCursor(UI_CURSOR_ARROW); +	} +	return TRUE; +} + +BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, +								   EDragAndDropType cargo_type, +								   void* cargo_data, +								   EAcceptance* accept, +								   std::string& tooltip_msg) +{ + +	BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + +	if (handled) +	{ +		mFolders->setDragAndDropThisFrame(); +	} + +	return handled; +} + +void LLInventoryPanel::onFocusLost() +{ +	// inventory no longer handles cut/copy/paste/delete +	if (LLEditMenuHandler::gEditMenuHandler == mFolders) +	{ +		LLEditMenuHandler::gEditMenuHandler = NULL; +	} + +	LLPanel::onFocusLost(); +} + +void LLInventoryPanel::onFocusReceived() +{ +	// inventory now handles cut/copy/paste/delete +	LLEditMenuHandler::gEditMenuHandler = mFolders; + +	LLPanel::onFocusReceived(); +} + + +void LLInventoryPanel::openAllFolders() +{ +	mFolders->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN); +	mFolders->arrangeAll(); +} + +void LLInventoryPanel::openDefaultFolderForType(LLAssetType::EType type) +{ +	LLUUID category_id = mInventory->findCategoryUUIDForType(type); +	LLOpenFolderByID opener(category_id); +	mFolders->applyFunctorRecursively(opener); +} + +void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus) +{ +	// Don't select objects in COF (e.g. to prevent refocus when items are worn). +	const LLInventoryObject *obj = gInventory.getObject(obj_id); +	if (obj && obj->getParentUUID() == LLAppearanceManager::getCOF()) +	{ +		return; +	} +	mFolders->setSelectionByID(obj_id, take_keyboard_focus); +} + +void LLInventoryPanel::clearSelection() +{ +	mFolders->clearSelection(); +} + +void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action) +{ +	LLFolderView* fv = getRootFolder(); +	if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename +	{ +		fv->setNeedsAutoRename(FALSE); +		if (items.size()) // new asset is visible and selected +		{ +			fv->startRenamingSelectedItem(); +		} +	} +	// Seraph - Put determineFolderType in here for ensemble typing? +} + +//---------------------------------------------------------------------------- + +void LLInventoryPanel::doToSelected(const LLSD& userdata) +{ +	mFolders->doToSelected(&gInventory, userdata); +} + +void LLInventoryPanel::doCreate(const LLSD& userdata) +{ +	menu_create_inventory_item(mFolders, LLFolderBridge::sSelf, userdata); +} + +bool LLInventoryPanel::beginIMSession() +{ +	std::set<LLUUID> selected_items; +	mFolders->getSelectionList(selected_items); + +	std::string name; +	static int session_num = 1; + +	LLDynamicArray<LLUUID> members; +	EInstantMessage type = IM_SESSION_CONFERENCE_START; + +	std::set<LLUUID>::const_iterator iter; +	for (iter = selected_items.begin(); iter != selected_items.end(); iter++) +	{ + +		LLUUID item = *iter; +		LLFolderViewItem* folder_item = mFolders->getItemByID(item); +			 +		if(folder_item)  +		{ +			LLFolderViewEventListener* fve_listener = folder_item->getListener(); +			if (fve_listener && (fve_listener->getInventoryType() == LLInventoryType::IT_CATEGORY)) +			{ + +				LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getListener(); +				if(!bridge) return true; +				LLViewerInventoryCategory* cat = bridge->getCategory(); +				if(!cat) return true; +				name = cat->getName(); +				LLUniqueBuddyCollector is_buddy; +				LLInventoryModel::cat_array_t cat_array; +				LLInventoryModel::item_array_t item_array; +				gInventory.collectDescendentsIf(bridge->getUUID(), +												cat_array, +												item_array, +												LLInventoryModel::EXCLUDE_TRASH, +												is_buddy); +				S32 count = item_array.count(); +				if(count > 0) +				{ +					LLFloaterReg::showInstance("communicate"); +					// create the session +					LLAvatarTracker& at = LLAvatarTracker::instance(); +					LLUUID id; +					for(S32 i = 0; i < count; ++i) +					{ +						id = item_array.get(i)->getCreatorUUID(); +						if(at.isBuddyOnline(id)) +						{ +							members.put(id); +						} +					} +				} +			} +			else +			{ +				LLFolderViewItem* folder_item = mFolders->getItemByID(item); +				if(!folder_item) return true; +				LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getListener(); + +				if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD) +				{ +					LLInventoryItem* inv_item = gInventory.getItem(listenerp->getUUID()); + +					if (inv_item) +					{ +						LLAvatarTracker& at = LLAvatarTracker::instance(); +						LLUUID id = inv_item->getCreatorUUID(); + +						if(at.isBuddyOnline(id)) +						{ +							members.put(id); +						} +					} +				} //if IT_CALLINGCARD +			} //if !IT_CATEGORY +		} +	} //for selected_items	 + +	// the session_id is randomly generated UUID which will be replaced later +	// with a server side generated number + +	if (name.empty()) +	{ +		name = llformat("Session %d", session_num++); +	} + +	gIMMgr->addSession(name, type, members[0], members); +		 +	return true; +} + +bool LLInventoryPanel::attachObject(const LLSD& userdata) +{ +	std::set<LLUUID> selected_items; +	mFolders->getSelectionList(selected_items); + +	std::string joint_name = userdata.asString(); +	LLVOAvatar *avatarp = static_cast<LLVOAvatar*>(gAgent.getAvatarObject()); +	LLViewerJointAttachment* attachmentp = NULL; +	for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();  +		 iter != avatarp->mAttachmentPoints.end(); ) +	{ +		LLVOAvatar::attachment_map_t::iterator curiter = iter++; +		LLViewerJointAttachment* attachment = curiter->second; +		if (attachment->getName() == joint_name) +		{ +			attachmentp = attachment; +			break; +		} +	} +	if (attachmentp == NULL) +	{ +		return true; +	} + +	for (std::set<LLUUID>::const_iterator set_iter = selected_items.begin();  +		 set_iter != selected_items.end();  +		 ++set_iter) +	{ +		const LLUUID &id = *set_iter; +		LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(id); +		if(item && gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID())) +		{ +			rez_attachment(item, attachmentp); +		} +		else if(item && item->isComplete()) +		{ +			// must be in library. copy it to our inventory and put it on. +			LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(attachmentp); +			copy_inventory_item(gAgent.getID(), +								item->getPermissions().getOwner(), +								item->getUUID(), +								LLUUID::null, +								std::string(), +								cb); +		} +	} +	gFocusMgr.setKeyboardFocus(NULL); + +	return true; +} + + +//---------------------------------------------------------------------------- + +// static DEBUG ONLY: +void LLInventoryPanel::dumpSelectionInformation(void* user_data) +{ +	LLInventoryPanel* iv = (LLInventoryPanel*)user_data; +	iv->mFolders->dumpSelectionInformation(); +} + +BOOL LLInventoryPanel::getSinceLogoff() +{ +	return mFolders->getFilter()->isSinceLogoff(); +} + +void example_param_block_usage() +{ +	LLInventoryPanel::Params param_block; +	param_block.name(std::string("inventory")); + +	param_block.sort_order_setting(LLInventoryPanel::RECENTITEMS_SORT_ORDER); +	param_block.allow_multi_select(true); +	param_block.filter(LLInventoryPanel::Filter() +			.sort_order(1) +			.types(0xffff0000)); +	param_block.inventory(&gInventory); +	param_block.has_border(true); + +	LLUICtrlFactory::create<LLInventoryPanel>(param_block); + +	param_block = LLInventoryPanel::Params(); +	param_block.name(std::string("inventory")); + +	//LLSD param_block_sd; +	//param_block_sd["sort_order_setting"] = LLInventoryPanel::RECENTITEMS_SORT_ORDER; +	//param_block_sd["allow_multi_select"] = true; +	//param_block_sd["filter"]["sort_order"] = 1; +	//param_block_sd["filter"]["types"] = (S32)0xffff0000; +	//param_block_sd["has_border"] = true; + +	//LLInitParam::LLSDParser(param_block_sd).parse(param_block); + +	LLUICtrlFactory::create<LLInventoryPanel>(param_block); +} diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index f958aaf839..997678a478 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -1,206 +1,206 @@ -/** 
 - * @file llinventorypanel.h
 - * @brief LLInventoryPanel
 - * 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_LLINVENTORYPANEL_H
 -#define LL_LLINVENTORYPANEL_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 LLInvFVBridge;
 -class LLInventoryFVBridgeBuilder;
 -class LLMenuBarGL;
 -class LLCheckBoxCtrl;
 -class LLSpinCtrl;
 -class LLScrollContainer;
 -class LLTextBox;
 -class LLIconCtrl;
 -class LLSaveFolderState;
 -class LLFilterEditor;
 -class LLTabContainer;
 -
 -class LLInventoryPanel : public LLPanel
 -{
 -public:
 -	static const std::string DEFAULT_SORT_ORDER;
 -	static const std::string RECENTITEMS_SORT_ORDER;
 -	static const std::string INHERIT_SORT_ORDER;
 -
 -	struct Filter : public LLInitParam::Block<Filter>
 -	{
 -		Optional<U32>			sort_order;
 -		Optional<U32>			types;
 -		Optional<std::string>	search_string;
 -
 -		Filter()
 -		:	sort_order("sort_order"),
 -			types("types", 0xffffffff),
 -			search_string("search_string")
 -		{}
 -	};
 -
 -	struct Params 
 -	:	public LLInitParam::Block<Params, LLPanel::Params>
 -	{
 -		Optional<std::string>				sort_order_setting;
 -		Optional<LLInventoryModel*>			inventory;
 -		Optional<bool>						allow_multi_select;
 -		Optional<Filter>					filter;
 -		Optional<std::string>               start_folder;
 -
 -		Params()
 -		:	sort_order_setting("sort_order_setting"),
 -			inventory("", &gInventory),
 -			allow_multi_select("allow_multi_select", true),
 -			filter("filter"),
 -			start_folder("start_folder")
 -		{}
 -	};
 -
 -protected:
 -	LLInventoryPanel(const Params&);
 -	friend class LLUICtrlFactory;
 -
 -public:
 -	virtual ~LLInventoryPanel();
 -
 -	LLInventoryModel* getModel() { return mInventory; }
 -
 -	BOOL postBuild();
 -
 -	// LLView methods
 -	void draw();
 -	BOOL handleHover(S32 x, S32 y, MASK mask);
 -	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 -								   EDragAndDropType cargo_type,
 -								   void* cargo_data,
 -								   EAcceptance* accept,
 -								   std::string& tooltip_msg);
 -	// LLUICtrl methods
 -	 /*virtual*/ void onFocusLost();
 -	 /*virtual*/ void onFocusReceived();
 -
 -	// Call this method to set the selection.
 -	void openAllFolders();
 -	void openDefaultFolderForType(LLAssetType::EType);
 -	void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);
 -	void setSelectCallback(const LLFolderView::signal_t::slot_type& cb) { if (mFolders) mFolders->setSelectCallback(cb); }
 -	void clearSelection();
 -	LLInventoryFilter* getFilter();
 -	void setFilterTypes(U64 filter, BOOL filter_for_categories = FALSE); // if filter_for_categories is true, operate on folder preferred asset type
 -	U32 getFilterTypes() const { return mFolders->getFilterTypes(); }
 -	void setFilterPermMask(PermissionMask filter_perm_mask);
 -	U32 getFilterPermMask() const { return mFolders->getFilterPermissions(); }
 -	void setFilterSubString(const std::string& string);
 -	const std::string getFilterSubString() { return mFolders->getFilterSubString(); }
 -	void setSortOrder(U32 order);
 -	U32 getSortOrder() { return mFolders->getSortOrder(); }
 -	void setSinceLogoff(BOOL sl);
 -	void setHoursAgo(U32 hours);
 -	BOOL getSinceLogoff();
 -	
 -	void setShowFolderState(LLInventoryFilter::EFolderShow show);
 -	LLInventoryFilter::EFolderShow getShowFolderState();
 -	void setAllowMultiSelect(BOOL allow) { mFolders->setAllowMultiSelect(allow); }
 -	// This method is called when something has changed about the inventory.
 -	void modelChanged(U32 mask);
 -	LLFolderView* getRootFolder() { return mFolders; }
 -	LLScrollContainer* getScrollableContainer() { return mScroller; }
 -	
 -	void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
 -	
 -	// Callbacks
 -	void doToSelected(const LLSD& userdata);
 -	void doCreate(const LLSD& userdata);
 -	bool beginIMSession();
 -	bool attachObject(const LLSD& userdata);
 -	
 -	// DEBUG ONLY:
 -	static void dumpSelectionInformation(void* user_data);
 -
 -	void openSelected();
 -	void unSelectAll()	{ mFolders->setSelection(NULL, FALSE, FALSE); }
 -	
 -protected:
 -	// 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
 -
 -protected:
 -	LLInventoryModel*			mInventory;
 -	LLInventoryObserver*		mInventoryObserver;
 -	BOOL 						mAllowMultiSelect;
 -	std::string					mSortOrderSetting;
 -
 -//private: // Can not make these private - needed by llinventorysubtreepanel
 -	LLFolderView*				mFolders;
 -	std::string                 mStartFolderString;
 -
 -	/**
 -	 * Contains UUID of Inventory item from which hierarchy should be built.
 -	 * Can be set with the "start_folder" xml property.
 -	 * Default is LLUUID::null that means total Inventory hierarchy.
 -	 */
 -	LLUUID						mStartFolderID;
 -	LLScrollContainer*			mScroller;
 -	bool						mHasInventoryConnection;
 -
 -	/**
 -	 * Flag specified if default inventory hierarchy should be created in postBuild()
 -	 */
 -	bool						mBuildDefaultHierarchy;
 -
 -	LLUUID						mRootInventoryItemUUID;
 -
 -	/**
 -	 * Pointer to LLInventoryFVBridgeBuilder.
 -	 *
 -	 * It is set in LLInventoryPanel's constructor and can be overridden in derived classes with 
 -	 * another implementation.
 -	 * Take into account it will not be deleted by LLInventoryPanel itself.
 -	 */
 -	const LLInventoryFVBridgeBuilder* mInvFVBridgeBuilder;
 -
 -};
 -
 -#endif // LL_LLINVENTORYPANEL_H
 +/**  + * @file llinventorypanel.h + * @brief LLInventoryPanel + * 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_LLINVENTORYPANEL_H +#define LL_LLINVENTORYPANEL_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 LLInvFVBridge; +class LLInventoryFVBridgeBuilder; +class LLMenuBarGL; +class LLCheckBoxCtrl; +class LLSpinCtrl; +class LLScrollContainer; +class LLTextBox; +class LLIconCtrl; +class LLSaveFolderState; +class LLFilterEditor; +class LLTabContainer; + +class LLInventoryPanel : public LLPanel +{ +public: +	static const std::string DEFAULT_SORT_ORDER; +	static const std::string RECENTITEMS_SORT_ORDER; +	static const std::string INHERIT_SORT_ORDER; + +	struct Filter : public LLInitParam::Block<Filter> +	{ +		Optional<U32>			sort_order; +		Optional<U32>			types; +		Optional<std::string>	search_string; + +		Filter() +		:	sort_order("sort_order"), +			types("types", 0xffffffff), +			search_string("search_string") +		{} +	}; + +	struct Params  +	:	public LLInitParam::Block<Params, LLPanel::Params> +	{ +		Optional<std::string>				sort_order_setting; +		Optional<LLInventoryModel*>			inventory; +		Optional<bool>						allow_multi_select; +		Optional<Filter>					filter; +		Optional<std::string>               start_folder; + +		Params() +		:	sort_order_setting("sort_order_setting"), +			inventory("", &gInventory), +			allow_multi_select("allow_multi_select", true), +			filter("filter"), +			start_folder("start_folder") +		{} +	}; + +protected: +	LLInventoryPanel(const Params&); +	friend class LLUICtrlFactory; + +public: +	virtual ~LLInventoryPanel(); + +	LLInventoryModel* getModel() { return mInventory; } + +	BOOL postBuild(); + +	// LLView methods +	void draw(); +	BOOL handleHover(S32 x, S32 y, MASK mask); +	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, +								   EDragAndDropType cargo_type, +								   void* cargo_data, +								   EAcceptance* accept, +								   std::string& tooltip_msg); +	// LLUICtrl methods +	 /*virtual*/ void onFocusLost(); +	 /*virtual*/ void onFocusReceived(); + +	// Call this method to set the selection. +	void openAllFolders(); +	void openDefaultFolderForType(LLAssetType::EType); +	void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus); +	void setSelectCallback(const LLFolderView::signal_t::slot_type& cb) { if (mFolders) mFolders->setSelectCallback(cb); } +	void clearSelection(); +	LLInventoryFilter* getFilter(); +	void setFilterTypes(U64 filter, BOOL filter_for_categories = FALSE); // if filter_for_categories is true, operate on folder preferred asset type +	U32 getFilterTypes() const { return mFolders->getFilterTypes(); } +	void setFilterPermMask(PermissionMask filter_perm_mask); +	U32 getFilterPermMask() const { return mFolders->getFilterPermissions(); } +	void setFilterSubString(const std::string& string); +	const std::string getFilterSubString() { return mFolders->getFilterSubString(); } +	void setSortOrder(U32 order); +	U32 getSortOrder() { return mFolders->getSortOrder(); } +	void setSinceLogoff(BOOL sl); +	void setHoursAgo(U32 hours); +	BOOL getSinceLogoff(); +	 +	void setShowFolderState(LLInventoryFilter::EFolderShow show); +	LLInventoryFilter::EFolderShow getShowFolderState(); +	void setAllowMultiSelect(BOOL allow) { mFolders->setAllowMultiSelect(allow); } +	// This method is called when something has changed about the inventory. +	void modelChanged(U32 mask); +	LLFolderView* getRootFolder() { return mFolders; } +	LLScrollContainer* getScrollableContainer() { return mScroller; } +	 +	void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action); +	 +	// Callbacks +	void doToSelected(const LLSD& userdata); +	void doCreate(const LLSD& userdata); +	bool beginIMSession(); +	bool attachObject(const LLSD& userdata); +	 +	// DEBUG ONLY: +	static void dumpSelectionInformation(void* user_data); + +	void openSelected(); +	void unSelectAll()	{ mFolders->setSelection(NULL, FALSE, FALSE); } +	 +protected: +	// 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 + +protected: +	LLInventoryModel*			mInventory; +	LLInventoryObserver*		mInventoryObserver; +	BOOL 						mAllowMultiSelect; +	std::string					mSortOrderSetting; + +//private: // Can not make these private - needed by llinventorysubtreepanel +	LLFolderView*				mFolders; +	std::string                 mStartFolderString; + +	/** +	 * Contains UUID of Inventory item from which hierarchy should be built. +	 * Can be set with the "start_folder" xml property. +	 * Default is LLUUID::null that means total Inventory hierarchy. +	 */ +	LLUUID						mStartFolderID; +	LLScrollContainer*			mScroller; +	bool						mHasInventoryConnection; + +	/** +	 * Flag specified if default inventory hierarchy should be created in postBuild() +	 */ +	bool						mBuildDefaultHierarchy; + +	LLUUID						mRootInventoryItemUUID; + +	/** +	 * Pointer to LLInventoryFVBridgeBuilder. +	 * +	 * It is set in LLInventoryPanel's constructor and can be overridden in derived classes with  +	 * another implementation. +	 * Take into account it will not be deleted by LLInventoryPanel itself. +	 */ +	const LLInventoryFVBridgeBuilder* mInvFVBridgeBuilder; + +}; + +#endif // LL_LLINVENTORYPANEL_H diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index ca567018e7..617445a27f 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -1,818 +1,818 @@ -/** 
 - * @file llsidepanelmaininventory.cpp
 - * @brief Implementation of llsidepanelmaininventory.
 - *
 - * $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 "llviewerprecompiledheaders.h"
 -#include "llpanelmaininventory.h"
 -
 -#include "llfloaterinventory.h"
 -#include "llinventorybridge.h"
 -#include "llinventoryfunctions.h"
 -#include "llinventorypanel.h"
 -#include "llfiltereditor.h"
 -#include "llfloaterreg.h"
 -#include "llscrollcontainer.h"
 -#include "llsdserialize.h"
 -#include "llspinctrl.h"
 -#include "lltooldraganddrop.h"
 -
 -static LLRegisterPanelClassWrapper<LLPanelMainInventory> t_inventory("panel_main_inventory"); // Seraph is this redundant with constructor?
 -
 -///----------------------------------------------------------------------------
 -/// LLFloaterInventoryFinder
 -///----------------------------------------------------------------------------
 -
 -class LLFloaterInventoryFinder : public LLFloater
 -{
 -public:
 -	LLFloaterInventoryFinder( LLPanelMainInventory* inventory_view);
 -	virtual void draw();
 -	/*virtual*/	BOOL	postBuild();
 -	void changeFilter(LLInventoryFilter* filter);
 -	void updateElementsFromFilter();
 -	BOOL getCheckShowEmpty();
 -	BOOL getCheckSinceLogoff();
 -
 -	static void onTimeAgo(LLUICtrl*, void *);
 -	static void onCheckSinceLogoff(LLUICtrl*, void *);
 -	static void onCloseBtn(void* user_data);
 -	static void selectAllTypes(void* user_data);
 -	static void selectNoTypes(void* user_data);
 -private:
 -	LLPanelMainInventory*	mPanelInventoryDecorated;
 -	LLSpinCtrl*			mSpinSinceDays;
 -	LLSpinCtrl*			mSpinSinceHours;
 -	LLInventoryFilter*	mFilter;
 -};
 -
 -///----------------------------------------------------------------------------
 -/// LLPanelMainInventory
 -///----------------------------------------------------------------------------
 -
 -LLPanelMainInventory::LLPanelMainInventory()
 -	: LLPanel()
 -{
 -	LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_INIT);
 -	// Menu Callbacks (non contex menus)
 -	mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelMainInventory::doToSelected, this, _2));
 -	mCommitCallbackRegistrar.add("Inventory.CloseAllFolders", boost::bind(&LLPanelMainInventory::closeAllFolders, this));
 -	mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLAssetType::AT_TRASH));
 -	mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLAssetType::AT_LOST_AND_FOUND));
 -	mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLPanelMainInventory::doCreate, this, _2));
 - 	mCommitCallbackRegistrar.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow, this));
 -	mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this));
 -	mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this));
 -	mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2));
 -
 -	// Controls
 -	// *TODO: Just use persistant settings for each of these
 -	U32 sort_order = gSavedSettings.getU32("InventorySortOrder");
 -	BOOL sort_by_name = ! ( sort_order & LLInventoryFilter::SO_DATE );
 -	BOOL sort_folders_by_name = ( sort_order & LLInventoryFilter::SO_FOLDERS_BY_NAME );
 -	BOOL sort_system_folders_to_top = ( sort_order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP );
 -	
 -	gSavedSettings.declareBOOL("Inventory.SortByName", sort_by_name, "Declared in code", FALSE);
 -	gSavedSettings.declareBOOL("Inventory.SortByDate", !sort_by_name, "Declared in code", FALSE);
 -	gSavedSettings.declareBOOL("Inventory.FoldersAlwaysByName", sort_folders_by_name, "Declared in code", FALSE);
 -	gSavedSettings.declareBOOL("Inventory.SystemFoldersToTop", sort_system_folders_to_top, "Declared in code", FALSE);
 -	
 -	mSavedFolderState = new LLSaveFolderState();
 -	mSavedFolderState->setApply(FALSE);
 -}
 -
 -BOOL LLPanelMainInventory::postBuild()
 -{
 -	gInventory.addObserver(this);
 -	
 -	mFilterTabs = getChild<LLTabContainer>("inventory filter tabs");
 -	mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this));
 -	
 -	//panel->getFilter()->markDefault();
 -
 -	// Set up the default inv. panel/filter settings.
 -	mActivePanel = getChild<LLInventoryPanel>("All Items");
 -	if (mActivePanel)
 -	{
 -		// "All Items" is the previous only view, so it gets the InventorySortOrder
 -		mActivePanel->setSortOrder(gSavedSettings.getU32("InventorySortOrder"));
 -		mActivePanel->getFilter()->markDefault();
 -		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
 -		mActivePanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mActivePanel, _1, _2));
 -	}
 -	LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
 -	if (recent_items_panel)
 -	{
 -		recent_items_panel->setSinceLogoff(TRUE);
 -		recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
 -		recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
 -		recent_items_panel->getFilter()->markDefault();
 -		recent_items_panel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, recent_items_panel, _1, _2));
 -	}
 -
 -	// Now load the stored settings from disk, if available.
 -	std::ostringstream filterSaveName;
 -	filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml");
 -	llinfos << "LLPanelMainInventory::init: reading from " << filterSaveName << llendl;
 -	llifstream file(filterSaveName.str());
 -	LLSD savedFilterState;
 -	if (file.is_open())
 -	{
 -		LLSDSerialize::fromXML(savedFilterState, file);
 -		file.close();
 -
 -		// Load the persistent "Recent Items" settings.
 -		// Note that the "All Items" settings do not persist.
 -		if(recent_items_panel)
 -		{
 -			if(savedFilterState.has(recent_items_panel->getFilter()->getName()))
 -			{
 -				LLSD recent_items = savedFilterState.get(
 -					recent_items_panel->getFilter()->getName());
 -				recent_items_panel->getFilter()->fromLLSD(recent_items);
 -			}
 -		}
 -
 -	}
 -
 -
 -	mFilterEditor = getChild<LLFilterEditor>("inventory search editor");
 -	if (mFilterEditor)
 -	{
 -		mFilterEditor->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterEdit, this, _2));
 -	}
 -
 -	// *TODO:Get the cost info from the server
 -	const std::string upload_cost("10");
 -	childSetLabelArg("Upload Image", "[COST]", upload_cost);
 -	childSetLabelArg("Upload Sound", "[COST]", upload_cost);
 -	childSetLabelArg("Upload Animation", "[COST]", upload_cost);
 -	childSetLabelArg("Bulk Upload", "[COST]", upload_cost);
 -	
 -	return TRUE;
 -}
 -
 -// Destroys the object
 -LLPanelMainInventory::~LLPanelMainInventory( void )
 -{
 -	// Save the filters state.
 -	LLSD filterRoot;
 -	LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items");
 -	if (all_items_panel)
 -	{
 -		LLInventoryFilter* filter = all_items_panel->getFilter();
 -		if (filter)
 -		{
 -			LLSD filterState;
 -			filter->toLLSD(filterState);
 -			filterRoot[filter->getName()] = filterState;
 -		}
 -	}
 -
 -	LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
 -	if (recent_items_panel)
 -	{
 -		LLInventoryFilter* filter = recent_items_panel->getFilter();
 -		if (filter)
 -		{
 -			LLSD filterState;
 -			filter->toLLSD(filterState);
 -			filterRoot[filter->getName()] = filterState;
 -		}
 -	}
 -
 -	std::ostringstream filterSaveName;
 -	filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml");
 -	llofstream filtersFile(filterSaveName.str());
 -	if(!LLSDSerialize::toPrettyXML(filterRoot, filtersFile))
 -	{
 -		llwarns << "Could not write to filters save file " << filterSaveName << llendl;
 -	}
 -	else
 -		filtersFile.close();
 -
 -	gInventory.removeObserver(this);
 -	delete mSavedFolderState;
 -}
 -
 -void LLPanelMainInventory::startSearch()
 -{
 -	// this forces focus to line editor portion of search editor
 -	if (mFilterEditor)
 -	{
 -		mFilterEditor->focusFirstItem(TRUE);
 -	}
 -}
 -
 -BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask)
 -{
 -	LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL;
 -	if (root_folder)
 -	{
 -		// first check for user accepting current search results
 -		if (mFilterEditor 
 -			&& mFilterEditor->hasFocus()
 -		    && (key == KEY_RETURN 
 -		    	|| key == KEY_DOWN)
 -		    && mask == MASK_NONE)
 -		{
 -			// move focus to inventory proper
 -			mActivePanel->setFocus(TRUE);
 -			root_folder->scrollToShowSelection();
 -			return TRUE;
 -		}
 -
 -		if (mActivePanel->hasFocus() && key == KEY_UP)
 -		{
 -			startSearch();
 -		}
 -	}
 -
 -	return LLPanel::handleKeyHere(key, mask);
 -
 -}
 -
 -//----------------------------------------------------------------------------
 -// menu callbacks
 -
 -void LLPanelMainInventory::doToSelected(const LLSD& userdata)
 -{
 -	getPanel()->getRootFolder()->doToSelected(&gInventory, userdata);
 -}
 -
 -void LLPanelMainInventory::closeAllFolders()
 -{
 -	getPanel()->getRootFolder()->closeAllFolders();
 -}
 -
 -void LLPanelMainInventory::newWindow()
 -{
 -	LLFloaterInventory::showAgentInventory();
 -}
 -
 -void LLPanelMainInventory::doCreate(const LLSD& userdata)
 -{
 -	menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata);
 -}
 -
 -void LLPanelMainInventory::resetFilters()
 -{
 -	LLFloaterInventoryFinder *finder = getFinder();
 -	getActivePanel()->getFilter()->resetDefault();
 -	if (finder)
 -	{
 -		finder->updateElementsFromFilter();
 -	}
 -
 -	setFilterTextFromFilter();
 -}
 -
 -void LLPanelMainInventory::setSortBy(const LLSD& userdata)
 -{
 -	std::string sort_field = userdata.asString();
 -	if (sort_field == "name")
 -	{
 -		U32 order = getActivePanel()->getSortOrder();
 -		getActivePanel()->setSortOrder( order & ~LLInventoryFilter::SO_DATE );
 -			
 -		gSavedSettings.setBOOL("Inventory.SortByName", TRUE );
 -		gSavedSettings.setBOOL("Inventory.SortByDate", FALSE );
 -	}
 -	else if (sort_field == "date")
 -	{
 -		U32 order = getActivePanel()->getSortOrder();
 -		getActivePanel()->setSortOrder( order | LLInventoryFilter::SO_DATE );
 -
 -		gSavedSettings.setBOOL("Inventory.SortByName", FALSE );
 -		gSavedSettings.setBOOL("Inventory.SortByDate", TRUE );
 -	}
 -	else if (sort_field == "foldersalwaysbyname")
 -	{
 -		U32 order = getActivePanel()->getSortOrder();
 -		if ( order & LLInventoryFilter::SO_FOLDERS_BY_NAME )
 -		{
 -			order &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME;
 -
 -			gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", FALSE );
 -		}
 -		else
 -		{
 -			order |= LLInventoryFilter::SO_FOLDERS_BY_NAME;
 -
 -			gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", TRUE );
 -		}
 -		getActivePanel()->setSortOrder( order );
 -	}
 -	else if (sort_field == "systemfolderstotop")
 -	{
 -		U32 order = getActivePanel()->getSortOrder();
 -		if ( order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP )
 -		{
 -			order &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
 -
 -			gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", FALSE );
 -		}
 -		else
 -		{
 -			order |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
 -
 -			gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", TRUE );
 -		}
 -		getActivePanel()->setSortOrder( order );
 -	}
 -}
 -
 -// static
 -BOOL LLPanelMainInventory::filtersVisible(void* user_data)
 -{
 -	LLPanelMainInventory* self = (LLPanelMainInventory*)user_data;
 -	if(!self) return FALSE;
 -
 -	return self->getFinder() != NULL;
 -}
 -
 -void LLPanelMainInventory::onClearSearch()
 -{
 -	LLFloater *finder = getFinder();
 -	if (mActivePanel)
 -	{
 -		mActivePanel->setFilterSubString(LLStringUtil::null);
 -		mActivePanel->setFilterTypes(0xffffffff);
 -	}
 -
 -	if (finder)
 -	{
 -		LLFloaterInventoryFinder::selectAllTypes(finder);
 -	}
 -
 -	// re-open folders that were initially open
 -	if (mActivePanel)
 -	{
 -		mSavedFolderState->setApply(TRUE);
 -		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
 -		LLOpenFoldersWithSelection opener;
 -		mActivePanel->getRootFolder()->applyFunctorRecursively(opener);
 -		mActivePanel->getRootFolder()->scrollToShowSelection();
 -	}
 -}
 -
 -void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
 -{
 -	if (search_string == "")
 -	{
 -		onClearSearch();
 -	}
 -	if (!mActivePanel)
 -	{
 -		return;
 -	}
 -
 -	gInventory.startBackgroundFetch();
 -
 -	std::string uppercase_search_string = search_string;
 -	LLStringUtil::toUpper(uppercase_search_string);
 -	if (mActivePanel->getFilterSubString().empty() && uppercase_search_string.empty())
 -	{
 -			// current filter and new filter empty, do nothing
 -			return;
 -	}
 -
 -	// save current folder open state if no filter currently applied
 -	if (!mActivePanel->getRootFolder()->isFilterModified())
 -	{
 -		mSavedFolderState->setApply(FALSE);
 -		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
 -	}
 -
 -	// set new filter string
 -	mActivePanel->setFilterSubString(uppercase_search_string);
 -}
 -
 -
 - //static
 - BOOL LLPanelMainInventory::incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward)
 - {
 - 	LLPanelMainInventory* active_view = NULL;
 -	
 -	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
 -	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
 -	{
 -		LLPanelMainInventory* iv = dynamic_cast<LLPanelMainInventory*>(*iter);
 -		if (iv)
 -		{
 -			if (gFocusMgr.childHasKeyboardFocus(iv))
 -			{
 -				active_view = iv;
 -				break;
 -			}
 - 		}
 - 	}
 -
 - 	if (!active_view)
 - 	{
 - 		return FALSE;
 - 	}
 -
 - 	std::string search_string(find_text);
 -
 - 	if (search_string.empty())
 - 	{
 - 		return FALSE;
 - 	}
 -
 - 	if (active_view->getPanel() &&
 - 		active_view->getPanel()->getRootFolder()->search(first_item, search_string, backward))
 - 	{
 - 		return TRUE;
 - 	}
 -
 - 	return FALSE;
 - }
 -
 -void LLPanelMainInventory::onFilterSelected()
 -{
 -	// Find my index
 -	mActivePanel = (LLInventoryPanel*)childGetVisibleTab("inventory filter tabs");
 -
 -	if (!mActivePanel)
 -	{
 -		return;
 -	}
 -	LLInventoryFilter* filter = mActivePanel->getFilter();
 -	LLFloaterInventoryFinder *finder = getFinder();
 -	if (finder)
 -	{
 -		finder->changeFilter(filter);
 -	}
 -	if (filter->isActive())
 -	{
 -		// If our filter is active we may be the first thing requiring a fetch so we better start it here.
 -		gInventory.startBackgroundFetch();
 -	}
 -	setFilterTextFromFilter();
 -}
 -
 -const std::string LLPanelMainInventory::getFilterSubString() 
 -{ 
 -	return mActivePanel->getFilterSubString(); 
 -}
 -
 -void LLPanelMainInventory::setFilterSubString(const std::string& string) 
 -{ 
 -	mActivePanel->setFilterSubString(string); 
 -}
 -
 -BOOL LLPanelMainInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 -										 EDragAndDropType cargo_type,
 -										 void* cargo_data,
 -										 EAcceptance* accept,
 -										 std::string& tooltip_msg)
 -{
 -	// Check to see if we are auto scrolling from the last frame
 -	LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel();
 -	BOOL needsToScroll = panel->getScrollableContainer()->autoScroll(x, y);
 -	if(mFilterTabs)
 -	{
 -		if(needsToScroll)
 -		{
 -			mFilterTabs->startDragAndDropDelayTimer();
 -		}
 -	}
 -	
 -	BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
 -
 -	return handled;
 -}
 -
 -void LLPanelMainInventory::changed(U32 mask)
 -{
 -}
 -
 -
 -void LLPanelMainInventory::setFilterTextFromFilter() 
 -{ 
 -	mFilterText = mActivePanel->getFilter()->getFilterText(); 
 -}
 -
 -void LLPanelMainInventory::toggleFindOptions()
 -{
 -	LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_TOGGLE);
 -	LLFloater *floater = getFinder();
 -	if (!floater)
 -	{
 -		LLFloaterInventoryFinder * finder = new LLFloaterInventoryFinder(this);
 -		mFinderHandle = finder->getHandle();
 -		finder->openFloater();
 -
 -		LLFloater* parent_floater = gFloaterView->getParentFloater(this);
 -		if (parent_floater) // Seraph: Fix this, shouldn't be null even for sidepanel
 -			parent_floater->addDependentFloater(mFinderHandle);
 -		// start background fetch of folders
 -		gInventory.startBackgroundFetch();
 -	}
 -	else
 -	{
 -		floater->closeFloater();
 -	}
 -}
 -
 -void LLPanelMainInventory::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)
 -{
 -	getChild<LLInventoryPanel>("All Items")->setSelectCallback(cb);
 -	getChild<LLInventoryPanel>("Recent Items")->setSelectCallback(cb);
 -}
 -
 -///----------------------------------------------------------------------------
 -/// LLFloaterInventoryFinder
 -///----------------------------------------------------------------------------
 -
 -LLFloaterInventoryFinder* LLPanelMainInventory::getFinder() 
 -{ 
 -	return (LLFloaterInventoryFinder*)mFinderHandle.get();
 -}
 -
 -
 -LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view) :	
 -	LLFloater(LLSD()),
 -	mPanelInventoryDecorated(inventory_view),
 -	mFilter(inventory_view->getPanel()->getFilter())
 -{
 -	LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory_view_finder.xml", NULL);
 -	updateElementsFromFilter();
 -}
 -
 -
 -void LLFloaterInventoryFinder::onCheckSinceLogoff(LLUICtrl *ctrl, void *user_data)
 -{
 -	LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
 -	if (!self) return;
 -
 -	bool since_logoff= self->childGetValue("check_since_logoff");
 -	
 -	if (!since_logoff && 
 -	    !(  self->mSpinSinceDays->get() ||  self->mSpinSinceHours->get() ) )
 -	{
 -		self->mSpinSinceHours->set(1.0f);
 -	}	
 -}
 -BOOL LLFloaterInventoryFinder::postBuild()
 -{
 -	const LLRect& viewrect = mPanelInventoryDecorated->getRect();
 -	setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight()));
 -
 -	childSetAction("All", selectAllTypes, this);
 -	childSetAction("None", selectNoTypes, this);
 -
 -	mSpinSinceHours = getChild<LLSpinCtrl>("spin_hours_ago");
 -	childSetCommitCallback("spin_hours_ago", onTimeAgo, this);
 -
 -	mSpinSinceDays = getChild<LLSpinCtrl>("spin_days_ago");
 -	childSetCommitCallback("spin_days_ago", onTimeAgo, this);
 -
 -	//	mCheckSinceLogoff   = getChild<LLSpinCtrl>("check_since_logoff");
 -	childSetCommitCallback("check_since_logoff", onCheckSinceLogoff, this);
 -
 -	childSetAction("Close", onCloseBtn, this);
 -
 -	updateElementsFromFilter();
 -	return TRUE;
 -}
 -void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data)
 -{
 -	LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
 -	if (!self) return;
 -	
 -	bool since_logoff=true;
 -	if ( self->mSpinSinceDays->get() ||  self->mSpinSinceHours->get() )
 -	{
 -		since_logoff = false;
 -	}
 -	self->childSetValue("check_since_logoff", since_logoff);
 -}
 -
 -void LLFloaterInventoryFinder::changeFilter(LLInventoryFilter* filter)
 -{
 -	mFilter = filter;
 -	updateElementsFromFilter();
 -}
 -
 -void LLFloaterInventoryFinder::updateElementsFromFilter()
 -{
 -	if (!mFilter)
 -		return;
 -
 -	// Get data needed for filter display
 -	U32 filter_types = mFilter->getFilterTypes();
 -	std::string filter_string = mFilter->getFilterSubString();
 -	LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState();
 -	U32 hours = mFilter->getHoursAgo();
 -
 -	// update the ui elements
 -	setTitle(mFilter->getName());
 -
 -	childSetValue("check_animation", (S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION));
 -
 -	childSetValue("check_calling_card", (S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD));
 -	childSetValue("check_clothing", (S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
 -	childSetValue("check_gesture", (S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
 -	childSetValue("check_landmark", (S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
 -	childSetValue("check_notecard", (S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
 -	childSetValue("check_object", (S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
 -	childSetValue("check_script", (S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
 -	childSetValue("check_sound", (S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND));
 -	childSetValue("check_texture", (S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE));
 -	childSetValue("check_snapshot", (S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT));
 -	childSetValue("check_show_empty", show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS);
 -	childSetValue("check_since_logoff", mFilter->isSinceLogoff());
 -	mSpinSinceHours->set((F32)(hours % 24));
 -	mSpinSinceDays->set((F32)(hours / 24));
 -}
 -
 -void LLFloaterInventoryFinder::draw()
 -{
 -	LLMemType mt(LLMemType::MTYPE_INVENTORY_DRAW);
 -	U32 filter = 0xffffffff;
 -	BOOL filtered_by_all_types = TRUE;
 -
 -	if (!childGetValue("check_animation"))
 -	{
 -		filter &= ~(0x1 << LLInventoryType::IT_ANIMATION);
 -		filtered_by_all_types = FALSE;
 -	}
 -
 -
 -	if (!childGetValue("check_calling_card"))
 -	{
 -		filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD);
 -		filtered_by_all_types = FALSE;
 -	}
 -
 -	if (!childGetValue("check_clothing"))
 -	{
 -		filter &= ~(0x1 << LLInventoryType::IT_WEARABLE);
 -		filtered_by_all_types = FALSE;
 -	}
 -
 -	if (!childGetValue("check_gesture"))
 -	{
 -		filter &= ~(0x1 << LLInventoryType::IT_GESTURE);
 -		filtered_by_all_types = FALSE;
 -	}
 -
 -	if (!childGetValue("check_landmark"))
 -
 -
 -	{
 -		filter &= ~(0x1 << LLInventoryType::IT_LANDMARK);
 -		filtered_by_all_types = FALSE;
 -	}
 -
 -	if (!childGetValue("check_notecard"))
 -	{
 -		filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
 -		filtered_by_all_types = FALSE;
 -	}
 -
 -	if (!childGetValue("check_object"))
 -	{
 -		filter &= ~(0x1 << LLInventoryType::IT_OBJECT);
 -		filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT);
 -		filtered_by_all_types = FALSE;
 -	}
 -
 -	if (!childGetValue("check_script"))
 -	{
 -		filter &= ~(0x1 << LLInventoryType::IT_LSL);
 -		filtered_by_all_types = FALSE;
 -	}
 -
 -	if (!childGetValue("check_sound"))
 -	{
 -		filter &= ~(0x1 << LLInventoryType::IT_SOUND);
 -		filtered_by_all_types = FALSE;
 -	}
 -
 -	if (!childGetValue("check_texture"))
 -	{
 -		filter &= ~(0x1 << LLInventoryType::IT_TEXTURE);
 -		filtered_by_all_types = FALSE;
 -	}
 -
 -	if (!childGetValue("check_snapshot"))
 -	{
 -		filter &= ~(0x1 << LLInventoryType::IT_SNAPSHOT);
 -		filtered_by_all_types = FALSE;
 -	}
 -
 -	if (!filtered_by_all_types)
 -	{
 -		// don't include folders in filter, unless I've selected everything
 -		filter &= ~(0x1 << LLInventoryType::IT_CATEGORY);
 -	}
 -
 -	// update the panel, panel will update the filter
 -	mPanelInventoryDecorated->getPanel()->setShowFolderState(getCheckShowEmpty() ?
 -		LLInventoryFilter::SHOW_ALL_FOLDERS : LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
 -	mPanelInventoryDecorated->getPanel()->setFilterTypes(filter);
 -	if (getCheckSinceLogoff())
 -	{
 -		mSpinSinceDays->set(0);
 -		mSpinSinceHours->set(0);
 -	}
 -	U32 days = (U32)mSpinSinceDays->get();
 -	U32 hours = (U32)mSpinSinceHours->get();
 -	if (hours > 24)
 -	{
 -		days += hours / 24;
 -		hours = (U32)hours % 24;
 -		mSpinSinceDays->set((F32)days);
 -		mSpinSinceHours->set((F32)hours);
 -	}
 -	hours += days * 24;
 -	mPanelInventoryDecorated->getPanel()->setHoursAgo(hours);
 -	mPanelInventoryDecorated->getPanel()->setSinceLogoff(getCheckSinceLogoff());
 -	mPanelInventoryDecorated->setFilterTextFromFilter();
 -
 -	LLPanel::draw();
 -}
 -
 -BOOL LLFloaterInventoryFinder::getCheckShowEmpty()
 -{
 -	return childGetValue("check_show_empty");
 -}
 -
 -BOOL LLFloaterInventoryFinder::getCheckSinceLogoff()
 -{
 -	return childGetValue("check_since_logoff");
 -}
 -
 -void LLFloaterInventoryFinder::onCloseBtn(void* user_data)
 -{
 -	LLFloaterInventoryFinder* finderp = (LLFloaterInventoryFinder*)user_data;
 -	finderp->closeFloater();
 -}
 -
 -// static
 -void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
 -{
 -	LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
 -	if(!self) return;
 -
 -	self->childSetValue("check_animation", TRUE);
 -	self->childSetValue("check_calling_card", TRUE);
 -	self->childSetValue("check_clothing", TRUE);
 -	self->childSetValue("check_gesture", TRUE);
 -	self->childSetValue("check_landmark", TRUE);
 -	self->childSetValue("check_notecard", TRUE);
 -	self->childSetValue("check_object", TRUE);
 -	self->childSetValue("check_script", TRUE);
 -	self->childSetValue("check_sound", TRUE);
 -	self->childSetValue("check_texture", TRUE);
 -	self->childSetValue("check_snapshot", TRUE);
 -}
 -
 -//static
 -void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
 -{
 -	LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
 -	if(!self) return;
 -
 -	self->childSetValue("check_animation", FALSE);
 -	self->childSetValue("check_calling_card", FALSE);
 -	self->childSetValue("check_clothing", FALSE);
 -	self->childSetValue("check_gesture", FALSE);
 -	self->childSetValue("check_landmark", FALSE);
 -	self->childSetValue("check_notecard", FALSE);
 -	self->childSetValue("check_object", FALSE);
 -	self->childSetValue("check_script", FALSE);
 -	self->childSetValue("check_sound", FALSE);
 -	self->childSetValue("check_texture", FALSE);
 -	self->childSetValue("check_snapshot", FALSE);
 -}
 +/**  + * @file llsidepanelmaininventory.cpp + * @brief Implementation of llsidepanelmaininventory. + * + * $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 "llviewerprecompiledheaders.h" +#include "llpanelmaininventory.h" + +#include "llfloaterinventory.h" +#include "llinventorybridge.h" +#include "llinventoryfunctions.h" +#include "llinventorypanel.h" +#include "llfiltereditor.h" +#include "llfloaterreg.h" +#include "llscrollcontainer.h" +#include "llsdserialize.h" +#include "llspinctrl.h" +#include "lltooldraganddrop.h" + +static LLRegisterPanelClassWrapper<LLPanelMainInventory> t_inventory("panel_main_inventory"); // Seraph is this redundant with constructor? + +///---------------------------------------------------------------------------- +/// LLFloaterInventoryFinder +///---------------------------------------------------------------------------- + +class LLFloaterInventoryFinder : public LLFloater +{ +public: +	LLFloaterInventoryFinder( LLPanelMainInventory* inventory_view); +	virtual void draw(); +	/*virtual*/	BOOL	postBuild(); +	void changeFilter(LLInventoryFilter* filter); +	void updateElementsFromFilter(); +	BOOL getCheckShowEmpty(); +	BOOL getCheckSinceLogoff(); + +	static void onTimeAgo(LLUICtrl*, void *); +	static void onCheckSinceLogoff(LLUICtrl*, void *); +	static void onCloseBtn(void* user_data); +	static void selectAllTypes(void* user_data); +	static void selectNoTypes(void* user_data); +private: +	LLPanelMainInventory*	mPanelInventoryDecorated; +	LLSpinCtrl*			mSpinSinceDays; +	LLSpinCtrl*			mSpinSinceHours; +	LLInventoryFilter*	mFilter; +}; + +///---------------------------------------------------------------------------- +/// LLPanelMainInventory +///---------------------------------------------------------------------------- + +LLPanelMainInventory::LLPanelMainInventory() +	: LLPanel() +{ +	LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_INIT); +	// Menu Callbacks (non contex menus) +	mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelMainInventory::doToSelected, this, _2)); +	mCommitCallbackRegistrar.add("Inventory.CloseAllFolders", boost::bind(&LLPanelMainInventory::closeAllFolders, this)); +	mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLAssetType::AT_TRASH)); +	mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLAssetType::AT_LOST_AND_FOUND)); +	mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLPanelMainInventory::doCreate, this, _2)); + 	mCommitCallbackRegistrar.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow, this)); +	mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this)); +	mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this)); +	mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2)); + +	// Controls +	// *TODO: Just use persistant settings for each of these +	U32 sort_order = gSavedSettings.getU32("InventorySortOrder"); +	BOOL sort_by_name = ! ( sort_order & LLInventoryFilter::SO_DATE ); +	BOOL sort_folders_by_name = ( sort_order & LLInventoryFilter::SO_FOLDERS_BY_NAME ); +	BOOL sort_system_folders_to_top = ( sort_order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP ); +	 +	gSavedSettings.declareBOOL("Inventory.SortByName", sort_by_name, "Declared in code", FALSE); +	gSavedSettings.declareBOOL("Inventory.SortByDate", !sort_by_name, "Declared in code", FALSE); +	gSavedSettings.declareBOOL("Inventory.FoldersAlwaysByName", sort_folders_by_name, "Declared in code", FALSE); +	gSavedSettings.declareBOOL("Inventory.SystemFoldersToTop", sort_system_folders_to_top, "Declared in code", FALSE); +	 +	mSavedFolderState = new LLSaveFolderState(); +	mSavedFolderState->setApply(FALSE); +} + +BOOL LLPanelMainInventory::postBuild() +{ +	gInventory.addObserver(this); +	 +	mFilterTabs = getChild<LLTabContainer>("inventory filter tabs"); +	mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this)); +	 +	//panel->getFilter()->markDefault(); + +	// Set up the default inv. panel/filter settings. +	mActivePanel = getChild<LLInventoryPanel>("All Items"); +	if (mActivePanel) +	{ +		// "All Items" is the previous only view, so it gets the InventorySortOrder +		mActivePanel->setSortOrder(gSavedSettings.getU32("InventorySortOrder")); +		mActivePanel->getFilter()->markDefault(); +		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); +		mActivePanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mActivePanel, _1, _2)); +	} +	LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items"); +	if (recent_items_panel) +	{ +		recent_items_panel->setSinceLogoff(TRUE); +		recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE); +		recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); +		recent_items_panel->getFilter()->markDefault(); +		recent_items_panel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, recent_items_panel, _1, _2)); +	} + +	// Now load the stored settings from disk, if available. +	std::ostringstream filterSaveName; +	filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml"); +	llinfos << "LLPanelMainInventory::init: reading from " << filterSaveName << llendl; +	llifstream file(filterSaveName.str()); +	LLSD savedFilterState; +	if (file.is_open()) +	{ +		LLSDSerialize::fromXML(savedFilterState, file); +		file.close(); + +		// Load the persistent "Recent Items" settings. +		// Note that the "All Items" settings do not persist. +		if(recent_items_panel) +		{ +			if(savedFilterState.has(recent_items_panel->getFilter()->getName())) +			{ +				LLSD recent_items = savedFilterState.get( +					recent_items_panel->getFilter()->getName()); +				recent_items_panel->getFilter()->fromLLSD(recent_items); +			} +		} + +	} + + +	mFilterEditor = getChild<LLFilterEditor>("inventory search editor"); +	if (mFilterEditor) +	{ +		mFilterEditor->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterEdit, this, _2)); +	} + +	// *TODO:Get the cost info from the server +	const std::string upload_cost("10"); +	childSetLabelArg("Upload Image", "[COST]", upload_cost); +	childSetLabelArg("Upload Sound", "[COST]", upload_cost); +	childSetLabelArg("Upload Animation", "[COST]", upload_cost); +	childSetLabelArg("Bulk Upload", "[COST]", upload_cost); +	 +	return TRUE; +} + +// Destroys the object +LLPanelMainInventory::~LLPanelMainInventory( void ) +{ +	// Save the filters state. +	LLSD filterRoot; +	LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items"); +	if (all_items_panel) +	{ +		LLInventoryFilter* filter = all_items_panel->getFilter(); +		if (filter) +		{ +			LLSD filterState; +			filter->toLLSD(filterState); +			filterRoot[filter->getName()] = filterState; +		} +	} + +	LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items"); +	if (recent_items_panel) +	{ +		LLInventoryFilter* filter = recent_items_panel->getFilter(); +		if (filter) +		{ +			LLSD filterState; +			filter->toLLSD(filterState); +			filterRoot[filter->getName()] = filterState; +		} +	} + +	std::ostringstream filterSaveName; +	filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml"); +	llofstream filtersFile(filterSaveName.str()); +	if(!LLSDSerialize::toPrettyXML(filterRoot, filtersFile)) +	{ +		llwarns << "Could not write to filters save file " << filterSaveName << llendl; +	} +	else +		filtersFile.close(); + +	gInventory.removeObserver(this); +	delete mSavedFolderState; +} + +void LLPanelMainInventory::startSearch() +{ +	// this forces focus to line editor portion of search editor +	if (mFilterEditor) +	{ +		mFilterEditor->focusFirstItem(TRUE); +	} +} + +BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask) +{ +	LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL; +	if (root_folder) +	{ +		// first check for user accepting current search results +		if (mFilterEditor  +			&& mFilterEditor->hasFocus() +		    && (key == KEY_RETURN  +		    	|| key == KEY_DOWN) +		    && mask == MASK_NONE) +		{ +			// move focus to inventory proper +			mActivePanel->setFocus(TRUE); +			root_folder->scrollToShowSelection(); +			return TRUE; +		} + +		if (mActivePanel->hasFocus() && key == KEY_UP) +		{ +			startSearch(); +		} +	} + +	return LLPanel::handleKeyHere(key, mask); + +} + +//---------------------------------------------------------------------------- +// menu callbacks + +void LLPanelMainInventory::doToSelected(const LLSD& userdata) +{ +	getPanel()->getRootFolder()->doToSelected(&gInventory, userdata); +} + +void LLPanelMainInventory::closeAllFolders() +{ +	getPanel()->getRootFolder()->closeAllFolders(); +} + +void LLPanelMainInventory::newWindow() +{ +	LLFloaterInventory::showAgentInventory(); +} + +void LLPanelMainInventory::doCreate(const LLSD& userdata) +{ +	menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata); +} + +void LLPanelMainInventory::resetFilters() +{ +	LLFloaterInventoryFinder *finder = getFinder(); +	getActivePanel()->getFilter()->resetDefault(); +	if (finder) +	{ +		finder->updateElementsFromFilter(); +	} + +	setFilterTextFromFilter(); +} + +void LLPanelMainInventory::setSortBy(const LLSD& userdata) +{ +	std::string sort_field = userdata.asString(); +	if (sort_field == "name") +	{ +		U32 order = getActivePanel()->getSortOrder(); +		getActivePanel()->setSortOrder( order & ~LLInventoryFilter::SO_DATE ); +			 +		gSavedSettings.setBOOL("Inventory.SortByName", TRUE ); +		gSavedSettings.setBOOL("Inventory.SortByDate", FALSE ); +	} +	else if (sort_field == "date") +	{ +		U32 order = getActivePanel()->getSortOrder(); +		getActivePanel()->setSortOrder( order | LLInventoryFilter::SO_DATE ); + +		gSavedSettings.setBOOL("Inventory.SortByName", FALSE ); +		gSavedSettings.setBOOL("Inventory.SortByDate", TRUE ); +	} +	else if (sort_field == "foldersalwaysbyname") +	{ +		U32 order = getActivePanel()->getSortOrder(); +		if ( order & LLInventoryFilter::SO_FOLDERS_BY_NAME ) +		{ +			order &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME; + +			gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", FALSE ); +		} +		else +		{ +			order |= LLInventoryFilter::SO_FOLDERS_BY_NAME; + +			gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", TRUE ); +		} +		getActivePanel()->setSortOrder( order ); +	} +	else if (sort_field == "systemfolderstotop") +	{ +		U32 order = getActivePanel()->getSortOrder(); +		if ( order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP ) +		{ +			order &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; + +			gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", FALSE ); +		} +		else +		{ +			order |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; + +			gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", TRUE ); +		} +		getActivePanel()->setSortOrder( order ); +	} +} + +// static +BOOL LLPanelMainInventory::filtersVisible(void* user_data) +{ +	LLPanelMainInventory* self = (LLPanelMainInventory*)user_data; +	if(!self) return FALSE; + +	return self->getFinder() != NULL; +} + +void LLPanelMainInventory::onClearSearch() +{ +	LLFloater *finder = getFinder(); +	if (mActivePanel) +	{ +		mActivePanel->setFilterSubString(LLStringUtil::null); +		mActivePanel->setFilterTypes(0xffffffff); +	} + +	if (finder) +	{ +		LLFloaterInventoryFinder::selectAllTypes(finder); +	} + +	// re-open folders that were initially open +	if (mActivePanel) +	{ +		mSavedFolderState->setApply(TRUE); +		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); +		LLOpenFoldersWithSelection opener; +		mActivePanel->getRootFolder()->applyFunctorRecursively(opener); +		mActivePanel->getRootFolder()->scrollToShowSelection(); +	} +} + +void LLPanelMainInventory::onFilterEdit(const std::string& search_string ) +{ +	if (search_string == "") +	{ +		onClearSearch(); +	} +	if (!mActivePanel) +	{ +		return; +	} + +	gInventory.startBackgroundFetch(); + +	std::string uppercase_search_string = search_string; +	LLStringUtil::toUpper(uppercase_search_string); +	if (mActivePanel->getFilterSubString().empty() && uppercase_search_string.empty()) +	{ +			// current filter and new filter empty, do nothing +			return; +	} + +	// save current folder open state if no filter currently applied +	if (!mActivePanel->getRootFolder()->isFilterModified()) +	{ +		mSavedFolderState->setApply(FALSE); +		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); +	} + +	// set new filter string +	mActivePanel->setFilterSubString(uppercase_search_string); +} + + + //static + BOOL LLPanelMainInventory::incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward) + { + 	LLPanelMainInventory* active_view = NULL; +	 +	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); +	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) +	{ +		LLPanelMainInventory* iv = dynamic_cast<LLPanelMainInventory*>(*iter); +		if (iv) +		{ +			if (gFocusMgr.childHasKeyboardFocus(iv)) +			{ +				active_view = iv; +				break; +			} + 		} + 	} + + 	if (!active_view) + 	{ + 		return FALSE; + 	} + + 	std::string search_string(find_text); + + 	if (search_string.empty()) + 	{ + 		return FALSE; + 	} + + 	if (active_view->getPanel() && + 		active_view->getPanel()->getRootFolder()->search(first_item, search_string, backward)) + 	{ + 		return TRUE; + 	} + + 	return FALSE; + } + +void LLPanelMainInventory::onFilterSelected() +{ +	// Find my index +	mActivePanel = (LLInventoryPanel*)childGetVisibleTab("inventory filter tabs"); + +	if (!mActivePanel) +	{ +		return; +	} +	LLInventoryFilter* filter = mActivePanel->getFilter(); +	LLFloaterInventoryFinder *finder = getFinder(); +	if (finder) +	{ +		finder->changeFilter(filter); +	} +	if (filter->isActive()) +	{ +		// If our filter is active we may be the first thing requiring a fetch so we better start it here. +		gInventory.startBackgroundFetch(); +	} +	setFilterTextFromFilter(); +} + +const std::string LLPanelMainInventory::getFilterSubString()  +{  +	return mActivePanel->getFilterSubString();  +} + +void LLPanelMainInventory::setFilterSubString(const std::string& string)  +{  +	mActivePanel->setFilterSubString(string);  +} + +BOOL LLPanelMainInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, +										 EDragAndDropType cargo_type, +										 void* cargo_data, +										 EAcceptance* accept, +										 std::string& tooltip_msg) +{ +	// Check to see if we are auto scrolling from the last frame +	LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel(); +	BOOL needsToScroll = panel->getScrollableContainer()->autoScroll(x, y); +	if(mFilterTabs) +	{ +		if(needsToScroll) +		{ +			mFilterTabs->startDragAndDropDelayTimer(); +		} +	} +	 +	BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + +	return handled; +} + +void LLPanelMainInventory::changed(U32 mask) +{ +} + + +void LLPanelMainInventory::setFilterTextFromFilter()  +{  +	mFilterText = mActivePanel->getFilter()->getFilterText();  +} + +void LLPanelMainInventory::toggleFindOptions() +{ +	LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_TOGGLE); +	LLFloater *floater = getFinder(); +	if (!floater) +	{ +		LLFloaterInventoryFinder * finder = new LLFloaterInventoryFinder(this); +		mFinderHandle = finder->getHandle(); +		finder->openFloater(); + +		LLFloater* parent_floater = gFloaterView->getParentFloater(this); +		if (parent_floater) // Seraph: Fix this, shouldn't be null even for sidepanel +			parent_floater->addDependentFloater(mFinderHandle); +		// start background fetch of folders +		gInventory.startBackgroundFetch(); +	} +	else +	{ +		floater->closeFloater(); +	} +} + +void LLPanelMainInventory::setSelectCallback(const LLFolderView::signal_t::slot_type& cb) +{ +	getChild<LLInventoryPanel>("All Items")->setSelectCallback(cb); +	getChild<LLInventoryPanel>("Recent Items")->setSelectCallback(cb); +} + +///---------------------------------------------------------------------------- +/// LLFloaterInventoryFinder +///---------------------------------------------------------------------------- + +LLFloaterInventoryFinder* LLPanelMainInventory::getFinder()  +{  +	return (LLFloaterInventoryFinder*)mFinderHandle.get(); +} + + +LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view) :	 +	LLFloater(LLSD()), +	mPanelInventoryDecorated(inventory_view), +	mFilter(inventory_view->getPanel()->getFilter()) +{ +	LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory_view_finder.xml", NULL); +	updateElementsFromFilter(); +} + + +void LLFloaterInventoryFinder::onCheckSinceLogoff(LLUICtrl *ctrl, void *user_data) +{ +	LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data; +	if (!self) return; + +	bool since_logoff= self->childGetValue("check_since_logoff"); +	 +	if (!since_logoff &&  +	    !(  self->mSpinSinceDays->get() ||  self->mSpinSinceHours->get() ) ) +	{ +		self->mSpinSinceHours->set(1.0f); +	}	 +} +BOOL LLFloaterInventoryFinder::postBuild() +{ +	const LLRect& viewrect = mPanelInventoryDecorated->getRect(); +	setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight())); + +	childSetAction("All", selectAllTypes, this); +	childSetAction("None", selectNoTypes, this); + +	mSpinSinceHours = getChild<LLSpinCtrl>("spin_hours_ago"); +	childSetCommitCallback("spin_hours_ago", onTimeAgo, this); + +	mSpinSinceDays = getChild<LLSpinCtrl>("spin_days_ago"); +	childSetCommitCallback("spin_days_ago", onTimeAgo, this); + +	//	mCheckSinceLogoff   = getChild<LLSpinCtrl>("check_since_logoff"); +	childSetCommitCallback("check_since_logoff", onCheckSinceLogoff, this); + +	childSetAction("Close", onCloseBtn, this); + +	updateElementsFromFilter(); +	return TRUE; +} +void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data) +{ +	LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data; +	if (!self) return; +	 +	bool since_logoff=true; +	if ( self->mSpinSinceDays->get() ||  self->mSpinSinceHours->get() ) +	{ +		since_logoff = false; +	} +	self->childSetValue("check_since_logoff", since_logoff); +} + +void LLFloaterInventoryFinder::changeFilter(LLInventoryFilter* filter) +{ +	mFilter = filter; +	updateElementsFromFilter(); +} + +void LLFloaterInventoryFinder::updateElementsFromFilter() +{ +	if (!mFilter) +		return; + +	// Get data needed for filter display +	U32 filter_types = mFilter->getFilterTypes(); +	std::string filter_string = mFilter->getFilterSubString(); +	LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState(); +	U32 hours = mFilter->getHoursAgo(); + +	// update the ui elements +	setTitle(mFilter->getName()); + +	childSetValue("check_animation", (S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION)); + +	childSetValue("check_calling_card", (S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD)); +	childSetValue("check_clothing", (S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE)); +	childSetValue("check_gesture", (S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE)); +	childSetValue("check_landmark", (S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK)); +	childSetValue("check_notecard", (S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD)); +	childSetValue("check_object", (S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT)); +	childSetValue("check_script", (S32) (filter_types & 0x1 << LLInventoryType::IT_LSL)); +	childSetValue("check_sound", (S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND)); +	childSetValue("check_texture", (S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE)); +	childSetValue("check_snapshot", (S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT)); +	childSetValue("check_show_empty", show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS); +	childSetValue("check_since_logoff", mFilter->isSinceLogoff()); +	mSpinSinceHours->set((F32)(hours % 24)); +	mSpinSinceDays->set((F32)(hours / 24)); +} + +void LLFloaterInventoryFinder::draw() +{ +	LLMemType mt(LLMemType::MTYPE_INVENTORY_DRAW); +	U32 filter = 0xffffffff; +	BOOL filtered_by_all_types = TRUE; + +	if (!childGetValue("check_animation")) +	{ +		filter &= ~(0x1 << LLInventoryType::IT_ANIMATION); +		filtered_by_all_types = FALSE; +	} + + +	if (!childGetValue("check_calling_card")) +	{ +		filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD); +		filtered_by_all_types = FALSE; +	} + +	if (!childGetValue("check_clothing")) +	{ +		filter &= ~(0x1 << LLInventoryType::IT_WEARABLE); +		filtered_by_all_types = FALSE; +	} + +	if (!childGetValue("check_gesture")) +	{ +		filter &= ~(0x1 << LLInventoryType::IT_GESTURE); +		filtered_by_all_types = FALSE; +	} + +	if (!childGetValue("check_landmark")) + + +	{ +		filter &= ~(0x1 << LLInventoryType::IT_LANDMARK); +		filtered_by_all_types = FALSE; +	} + +	if (!childGetValue("check_notecard")) +	{ +		filter &= ~(0x1 << LLInventoryType::IT_NOTECARD); +		filtered_by_all_types = FALSE; +	} + +	if (!childGetValue("check_object")) +	{ +		filter &= ~(0x1 << LLInventoryType::IT_OBJECT); +		filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT); +		filtered_by_all_types = FALSE; +	} + +	if (!childGetValue("check_script")) +	{ +		filter &= ~(0x1 << LLInventoryType::IT_LSL); +		filtered_by_all_types = FALSE; +	} + +	if (!childGetValue("check_sound")) +	{ +		filter &= ~(0x1 << LLInventoryType::IT_SOUND); +		filtered_by_all_types = FALSE; +	} + +	if (!childGetValue("check_texture")) +	{ +		filter &= ~(0x1 << LLInventoryType::IT_TEXTURE); +		filtered_by_all_types = FALSE; +	} + +	if (!childGetValue("check_snapshot")) +	{ +		filter &= ~(0x1 << LLInventoryType::IT_SNAPSHOT); +		filtered_by_all_types = FALSE; +	} + +	if (!filtered_by_all_types) +	{ +		// don't include folders in filter, unless I've selected everything +		filter &= ~(0x1 << LLInventoryType::IT_CATEGORY); +	} + +	// update the panel, panel will update the filter +	mPanelInventoryDecorated->getPanel()->setShowFolderState(getCheckShowEmpty() ? +		LLInventoryFilter::SHOW_ALL_FOLDERS : LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); +	mPanelInventoryDecorated->getPanel()->setFilterTypes(filter); +	if (getCheckSinceLogoff()) +	{ +		mSpinSinceDays->set(0); +		mSpinSinceHours->set(0); +	} +	U32 days = (U32)mSpinSinceDays->get(); +	U32 hours = (U32)mSpinSinceHours->get(); +	if (hours > 24) +	{ +		days += hours / 24; +		hours = (U32)hours % 24; +		mSpinSinceDays->set((F32)days); +		mSpinSinceHours->set((F32)hours); +	} +	hours += days * 24; +	mPanelInventoryDecorated->getPanel()->setHoursAgo(hours); +	mPanelInventoryDecorated->getPanel()->setSinceLogoff(getCheckSinceLogoff()); +	mPanelInventoryDecorated->setFilterTextFromFilter(); + +	LLPanel::draw(); +} + +BOOL LLFloaterInventoryFinder::getCheckShowEmpty() +{ +	return childGetValue("check_show_empty"); +} + +BOOL LLFloaterInventoryFinder::getCheckSinceLogoff() +{ +	return childGetValue("check_since_logoff"); +} + +void LLFloaterInventoryFinder::onCloseBtn(void* user_data) +{ +	LLFloaterInventoryFinder* finderp = (LLFloaterInventoryFinder*)user_data; +	finderp->closeFloater(); +} + +// static +void LLFloaterInventoryFinder::selectAllTypes(void* user_data) +{ +	LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data; +	if(!self) return; + +	self->childSetValue("check_animation", TRUE); +	self->childSetValue("check_calling_card", TRUE); +	self->childSetValue("check_clothing", TRUE); +	self->childSetValue("check_gesture", TRUE); +	self->childSetValue("check_landmark", TRUE); +	self->childSetValue("check_notecard", TRUE); +	self->childSetValue("check_object", TRUE); +	self->childSetValue("check_script", TRUE); +	self->childSetValue("check_sound", TRUE); +	self->childSetValue("check_texture", TRUE); +	self->childSetValue("check_snapshot", TRUE); +} + +//static +void LLFloaterInventoryFinder::selectNoTypes(void* user_data) +{ +	LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data; +	if(!self) return; + +	self->childSetValue("check_animation", FALSE); +	self->childSetValue("check_calling_card", FALSE); +	self->childSetValue("check_clothing", FALSE); +	self->childSetValue("check_gesture", FALSE); +	self->childSetValue("check_landmark", FALSE); +	self->childSetValue("check_notecard", FALSE); +	self->childSetValue("check_object", FALSE); +	self->childSetValue("check_script", FALSE); +	self->childSetValue("check_sound", FALSE); +	self->childSetValue("check_texture", FALSE); +	self->childSetValue("check_snapshot", FALSE); +} diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index 75526a3c98..a2b988e80c 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -1,125 +1,125 @@ -/** 
 - * @file llpanelmaininventory.h
 - * @brief llpanelmaininventory.h
 - * 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_LLPANELMAININVENTORY_H
 -#define LL_LLPANELMAININVENTORY_H
 -
 -#include "llpanel.h"
 -#include "llinventorymodel.h"
 -#include "llfolderview.h"
 -
 -class LLFolderViewItem;
 -class LLInventoryPanel;
 -class LLSaveFolderState;
 -class LLFilterEditor;
 -class LLTabContainer;
 -class LLFloaterInventoryFinder;
 -
 -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 -// Class LLPanelMainInventory
 -//
 -// This is a panel used to view and control an agent's inventory,
 -// including all the fixin's (e.g. AllItems/RecentItems tabs, filter floaters).
 -//
 -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 -class LLPanelMainInventory : public LLPanel, LLInventoryObserver
 -{
 -public:
 -	friend class LLFloaterInventoryFinder;
 -
 -	LLPanelMainInventory();
 -	~LLPanelMainInventory();
 -
 -	BOOL postBuild();
 -
 -	virtual BOOL handleKeyHere(KEY key, MASK mask);
 -
 -	// Inherited functionality
 -	/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 -									   EDragAndDropType cargo_type,
 -									   void* cargo_data,
 -									   EAcceptance* accept,
 -									   std::string& tooltip_msg);
 -	/*virtual*/ void changed(U32 mask);
 -
 -	LLInventoryPanel* getPanel() { return mActivePanel; }
 -	LLInventoryPanel* getActivePanel() { return mActivePanel; }
 -
 -	const std::string& getFilterText() const { return mFilterText; }
 -	
 -	void setSelectCallback(const LLFolderView::signal_t::slot_type& cb);
 -
 -protected:
 -	//
 -	// Misc functions
 -	//
 -	void setFilterTextFromFilter();
 -	void startSearch();
 -	
 -	void toggleFindOptions();
 -
 -	static BOOL filtersVisible(void* user_data);
 -	void onClearSearch();
 -	static void onFoldersByName(void *user_data);
 -	static BOOL checkFoldersByName(void *user_data);
 -	void onFilterEdit(const std::string& search_string );
 -	static BOOL incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward);
 -	void onFilterSelected();
 -
 -	const std::string getFilterSubString();
 -	void setFilterSubString(const std::string& string);
 -	
 -	// menu callbacks
 -	void doToSelected(const LLSD& userdata);
 -	void closeAllFolders();
 -	void newWindow();
 -	void doCreate(const LLSD& userdata);
 -	void resetFilters();
 -	void setSortBy(const LLSD& userdata);
 -	
 -private:
 -	LLFloaterInventoryFinder* getFinder();
 -
 -	LLFilterEditor*				mFilterEditor;
 -	LLTabContainer*				mFilterTabs;
 -	LLHandle<LLFloater>			mFinderHandle;
 -	LLInventoryPanel*			mActivePanel;
 -	LLSaveFolderState*			mSavedFolderState;
 -
 -	std::string					mFilterText;
 -};
 -
 -#endif // LL_LLPANELMAININVENTORY_H
 -
 -
 -
 +/**  + * @file llpanelmaininventory.h + * @brief llpanelmaininventory.h + * 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_LLPANELMAININVENTORY_H +#define LL_LLPANELMAININVENTORY_H + +#include "llpanel.h" +#include "llinventorymodel.h" +#include "llfolderview.h" + +class LLFolderViewItem; +class LLInventoryPanel; +class LLSaveFolderState; +class LLFilterEditor; +class LLTabContainer; +class LLFloaterInventoryFinder; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLPanelMainInventory +// +// This is a panel used to view and control an agent's inventory, +// including all the fixin's (e.g. AllItems/RecentItems tabs, filter floaters). +// +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLPanelMainInventory : public LLPanel, LLInventoryObserver +{ +public: +	friend class LLFloaterInventoryFinder; + +	LLPanelMainInventory(); +	~LLPanelMainInventory(); + +	BOOL postBuild(); + +	virtual BOOL handleKeyHere(KEY key, MASK mask); + +	// Inherited functionality +	/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, +									   EDragAndDropType cargo_type, +									   void* cargo_data, +									   EAcceptance* accept, +									   std::string& tooltip_msg); +	/*virtual*/ void changed(U32 mask); + +	LLInventoryPanel* getPanel() { return mActivePanel; } +	LLInventoryPanel* getActivePanel() { return mActivePanel; } + +	const std::string& getFilterText() const { return mFilterText; } +	 +	void setSelectCallback(const LLFolderView::signal_t::slot_type& cb); + +protected: +	// +	// Misc functions +	// +	void setFilterTextFromFilter(); +	void startSearch(); +	 +	void toggleFindOptions(); + +	static BOOL filtersVisible(void* user_data); +	void onClearSearch(); +	static void onFoldersByName(void *user_data); +	static BOOL checkFoldersByName(void *user_data); +	void onFilterEdit(const std::string& search_string ); +	static BOOL incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward); +	void onFilterSelected(); + +	const std::string getFilterSubString(); +	void setFilterSubString(const std::string& string); +	 +	// menu callbacks +	void doToSelected(const LLSD& userdata); +	void closeAllFolders(); +	void newWindow(); +	void doCreate(const LLSD& userdata); +	void resetFilters(); +	void setSortBy(const LLSD& userdata); +	 +private: +	LLFloaterInventoryFinder* getFinder(); + +	LLFilterEditor*				mFilterEditor; +	LLTabContainer*				mFilterTabs; +	LLHandle<LLFloater>			mFinderHandle; +	LLInventoryPanel*			mActivePanel; +	LLSaveFolderState*			mSavedFolderState; + +	std::string					mFilterText; +}; + +#endif // LL_LLPANELMAININVENTORY_H + + + diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp index a198499b47..85efe0f93e 100644 --- a/indra/newview/llpanelmediasettingsgeneral.cpp +++ b/indra/newview/llpanelmediasettingsgeneral.cpp @@ -1,453 +1,453 @@ -/**
 - * @file llpanelmediasettingsgeneral.cpp
 - * @brief LLPanelMediaSettingsGeneral class implementation
 - *
 - * $LicenseInfo:firstyear=2009&license=viewergpl$
 - * 
 - * Copyright (c) 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 "llagent.h"
 -#include "llpanelmediasettingsgeneral.h"
 -#include "llcombobox.h"
 -#include "llcheckboxctrl.h"
 -#include "llspinctrl.h"
 -#include "lluictrlfactory.h"
 -#include "llviewerwindow.h"
 -#include "llviewermedia.h"
 -#include "llsdutil.h"
 -#include "llselectmgr.h"
 -#include "llbutton.h"
 -#include "lltexturectrl.h"
 -#include "llurl.h"
 -#include "llwindow.h"
 -#include "llmediaentry.h"
 -#include "llmediactrl.h"
 -#include "llpanelcontents.h"
 -#include "llpermissions.h"
 -#include "llpluginclassmedia.h"
 -#include "llfloatermediasettings.h"
 -#include "llfloatertools.h"
 -#include "lltrans.h"
 -
 -////////////////////////////////////////////////////////////////////////////////
 -//
 -LLPanelMediaSettingsGeneral::LLPanelMediaSettingsGeneral() :
 -	mControls( NULL ),
 -	mAutoLoop( NULL ),
 -	mFirstClick( NULL ),
 -	mAutoZoom( NULL ),
 -	mAutoPlay( NULL ),
 -	mAutoScale( NULL ),
 -	mWidthPixels( NULL ),
 -	mHeightPixels( NULL ),
 -	mHomeURL( NULL ),
 -	mCurrentURL( NULL ),
 -	mParent( NULL ),
 -	mMediaEditable(false)
 -{
 -	// build dialog from XML
 -	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_general.xml");
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -//
 -BOOL LLPanelMediaSettingsGeneral::postBuild()
 -{
 -	// connect member vars with UI widgets
 -	mAutoLoop = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_LOOP_KEY );
 -	mAutoPlay = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_PLAY_KEY );
 -	mAutoScale = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_SCALE_KEY );
 -	mAutoZoom = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_ZOOM_KEY );
 -	mControls = getChild< LLComboBox >( LLMediaEntry::CONTROLS_KEY );
 -	mCurrentURL = getChild< LLLineEditor >( LLMediaEntry::CURRENT_URL_KEY );
 -	mFirstClick = getChild< LLCheckBoxCtrl >( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
 -	mHeightPixels = getChild< LLSpinCtrl >( LLMediaEntry::HEIGHT_PIXELS_KEY );
 -	mHomeURL = getChild< LLLineEditor >( LLMediaEntry::HOME_URL_KEY );
 -	mWidthPixels = getChild< LLSpinCtrl >( LLMediaEntry::WIDTH_PIXELS_KEY );
 -	mPreviewMedia = getChild<LLMediaCtrl>("preview_media");
 -
 -	// watch commit action for HOME URL
 -	childSetCommitCallback( LLMediaEntry::HOME_URL_KEY, onCommitHomeURL, this);
 -	childSetCommitCallback( "current_url_reset_btn",onBtnResetCurrentUrl, this);
 -	// interrogates controls and updates widgets as required
 -	updateMediaPreview();
 -	updateCurrentURL();
 -
 -	return true;
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// virtual
 -LLPanelMediaSettingsGeneral::~LLPanelMediaSettingsGeneral()
 -{
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLPanelMediaSettingsGeneral::draw()
 -{
 -	// housekeeping
 -	LLPanel::draw();
 -
 -	// enable/disable pixel values image entry based on auto scale checkbox 
 -	if ( mAutoScale->getValue().asBoolean() == false )
 -	{
 -		childSetEnabled( LLMediaEntry::WIDTH_PIXELS_KEY, true );
 -		childSetEnabled( LLMediaEntry::HEIGHT_PIXELS_KEY, true );
 -	}
 -	else
 -	{
 -		childSetEnabled( LLMediaEntry::WIDTH_PIXELS_KEY, false );
 -		childSetEnabled( LLMediaEntry::HEIGHT_PIXELS_KEY, false );
 -	};
 -
 -	// enable/disable UI based on type of media
 -	bool reset_button_is_active = true;
 -	if( mPreviewMedia )
 -	{
 -		LLPluginClassMedia* media_plugin = mPreviewMedia->getMediaPlugin();
 -		if( media_plugin )
 -		{
 -			// turn off volume (if we can) for preview. Note: this really only
 -			// works for QuickTime movies right now - no way to control the 
 -			// volume of a flash app embedded in a page for example
 -			media_plugin->setVolume( 0 );
 -
 -			// some controls are only appropriate for time or browser type plugins
 -			// so we selectively enable/disable them - need to do it in draw
 -			// because the information from plugins arrives assynchronously
 -			bool show_time_controls = media_plugin->pluginSupportsMediaTime();
 -			if ( show_time_controls )
 -			{
 -				childSetEnabled( LLMediaEntry::CURRENT_URL_KEY, false );
 -				reset_button_is_active = false;
 -				childSetEnabled( "current_url_label", false );
 -				childSetEnabled( LLMediaEntry::AUTO_LOOP_KEY, true );
 -			}
 -			else
 -			{
 -				childSetEnabled( LLMediaEntry::CURRENT_URL_KEY, true );
 -				reset_button_is_active = true;
 -				childSetEnabled( "current_url_label", true );
 -				childSetEnabled( LLMediaEntry::AUTO_LOOP_KEY, false );
 -			};
 -		};
 -	};
 -
 -	// current URL can change over time.
 -//	updateCurrentURL();
 -
 -	LLPermissions perm;
 -	bool user_can_press_reset = mMediaEditable;
 -
 -	// several places modify this widget so we must collect states in one place
 -	if ( reset_button_is_active )
 -	{
 -		// user has perms to press reset button and it is active
 -		if ( user_can_press_reset )
 -		{
 -			childSetEnabled( "current_url_reset_btn", true );
 -		}
 -		// user does not has perms to press reset button and it is active
 -		else
 -		{
 -			childSetEnabled( "current_url_reset_btn", false );
 -		};
 -	}
 -	else
 -	// reset button is inactive so we just slam it to off - other states don't matter
 -	{
 -		childSetEnabled( "current_url_reset_btn", false );
 -	};
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// static 
 -void LLPanelMediaSettingsGeneral::clearValues( void* userdata, bool editable)
 -{	
 -	LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;
 -	self->mAutoLoop->clear();
 -	self->mAutoPlay->clear();
 -	self->mAutoScale->clear();
 -	self->mAutoZoom ->clear();
 -	self->mControls->clear();
 -	self->mCurrentURL->clear();
 -	self->mFirstClick->clear();
 -	self->mHeightPixels->clear();
 -	self->mHomeURL->clear();
 -	self->mWidthPixels->clear();
 -	self->mAutoLoop ->setEnabled(editable);
 -	self->mAutoPlay ->setEnabled(editable);
 -	self->mAutoScale ->setEnabled(editable);
 -	self->mAutoZoom  ->setEnabled(editable);
 -	self->mControls ->setEnabled(editable);
 -	self->mCurrentURL ->setEnabled(editable);
 -	self->mFirstClick ->setEnabled(editable);
 -	self->mHeightPixels ->setEnabled(editable);
 -	self->mHomeURL ->setEnabled(editable);
 -	self->mWidthPixels ->setEnabled(editable);
 -	self->updateMediaPreview();
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// static 
 -void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_settings ,bool editable)
 -{
 -	LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;
 -	self->mMediaEditable = editable;
 -
 -	//llinfos << "---------------" << llendl;
 -	//llinfos << ll_pretty_print_sd(media_settings) << llendl;
 -	//llinfos << "---------------" << llendl;
 -
 -	// IF all the faces have media (or all dont have media)
 -	if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo )
 -	{
 -		if(LLFloaterMediaSettings::getInstance()->mMultipleMedia) 
 -		{
 -			self->clearValues(self, self->mMediaEditable);
 -			// only show multiple 
 -			self->mHomeURL ->setText(LLTrans::getString("Multiple Media"));
 -			return;
 -		}
 -		
 -	}
 -	else
 -	{
 -		if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia) 
 -		{
 -			self->clearValues(self, self->mMediaEditable);
 -			// only show multiple 
 -			self->mHomeURL ->setText(LLTrans::getString("Multiple Media"));
 -			return;
 -		}			
 -		
 -	}
 -	std::string base_key( "" );
 -	std::string tentative_key( "" );
 -
 -	struct 
 -	{
 -		std::string key_name;
 -		LLUICtrl* ctrl_ptr;
 -		std::string ctrl_type;
 -
 -	} data_set [] = 
 -	{ 
 -        { LLMediaEntry::AUTO_LOOP_KEY,				self->mAutoLoop,		"LLCheckBoxCtrl" },
 -		{ LLMediaEntry::AUTO_PLAY_KEY,				self->mAutoPlay,		"LLCheckBoxCtrl" },
 -		{ LLMediaEntry::AUTO_SCALE_KEY,				self->mAutoScale,		"LLCheckBoxCtrl" },
 -		{ LLMediaEntry::AUTO_ZOOM_KEY,				self->mAutoZoom,		"LLCheckBoxCtrl" },
 -		{ LLMediaEntry::CONTROLS_KEY,				self->mControls,		"LLComboBox" },
 -		{ LLMediaEntry::CURRENT_URL_KEY,			self->mCurrentURL,		"LLLineEditor" },
 -		{ LLMediaEntry::HEIGHT_PIXELS_KEY,			self->mHeightPixels,	"LLSpinCtrl" },
 -		{ LLMediaEntry::HOME_URL_KEY,				self->mHomeURL,			"LLLineEditor" },
 -		{ LLMediaEntry::FIRST_CLICK_INTERACT_KEY,	self->mFirstClick,		"LLCheckBoxCtrl" },
 -		{ LLMediaEntry::WIDTH_PIXELS_KEY,			self->mWidthPixels,		"LLSpinCtrl" },
 -		{ "", NULL , "" }
 -	};
 -
 -	for( int i = 0; data_set[ i ].key_name.length() > 0; ++i )
 -	{
 -		base_key = std::string( data_set[ i ].key_name );
 -		tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX );
 -		// TODO: CP - I bet there is a better way to do this using Boost
 -		if ( media_settings[ base_key ].isDefined() )
 -		{
 -			if ( data_set[ i ].ctrl_type == "LLLineEditor" )
 -			{
 -				static_cast< LLLineEditor* >( data_set[ i ].ctrl_ptr )->
 -					setText( media_settings[ base_key ].asString() );
 -			}
 -			else
 -			if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" )
 -				static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )->
 -					setValue( media_settings[ base_key ].asBoolean() );
 -			else
 -			if ( data_set[ i ].ctrl_type == "LLComboBox" )
 -				static_cast< LLComboBox* >( data_set[ i ].ctrl_ptr )->
 -					setCurrentByIndex( media_settings[ base_key ].asInteger() );
 -			else
 -			if ( data_set[ i ].ctrl_type == "LLSpinCtrl" )
 -				static_cast< LLSpinCtrl* >( data_set[ i ].ctrl_ptr )->
 -					setValue( media_settings[ base_key ].asInteger() );
 -
 -			data_set[ i ].ctrl_ptr->setEnabled(self->mMediaEditable);
 -			data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
 -		};
 -	};
 -	
 -	// interrogates controls and updates widgets as required
 -	self->updateMediaPreview();
 -	self->updateCurrentURL();
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// Helper to set media control to media URL as required
 -void LLPanelMediaSettingsGeneral::updateMediaPreview()
 -{
 -	if ( mHomeURL->getValue().asString().length() > 0 )
 -	{
 -		mPreviewMedia->navigateTo( mHomeURL->getValue().asString() );
 -	}
 -	else
 -	// new home URL will be empty if media is deleted so display a 
 -	// "preview goes here" data url page
 -	{
 -		mPreviewMedia->navigateTo( "data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%22100%%22 height=%22100%%22 %3E%3Cdefs%3E%3Cpattern id=%22checker%22 patternUnits=%22userSpaceOnUse%22 x=%220%22 y=%220%22 width=%22128%22 height=%22128%22 viewBox=%220 0 128 128%22 %3E%3Crect x=%220%22 y=%220%22 width=%2264%22 height=%2264%22 fill=%22#ddddff%22 /%3E%3Crect x=%2264%22 y=%2264%22 width=%2264%22 height=%2264%22 fill=%22#ddddff%22 /%3E%3C/pattern%3E%3C/defs%3E%3Crect x=%220%22 y=%220%22 width=%22100%%22 height=%22100%%22 fill=%22url(#checker)%22 /%3E%3C/svg%3E" );
 -	};
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// Helper to set current URL
 -void LLPanelMediaSettingsGeneral::updateCurrentURL()
 -{
 -	if( mCurrentURL->getText().empty() )
 -	{
 -		childSetText( "current_url", mHomeURL->getText() );
 -	}
 -	
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -
 -// virtual
 -void LLPanelMediaSettingsGeneral::onClose(bool app_quitting)
 -{
 -	if(mPreviewMedia)
 -	{
 -		mPreviewMedia->unloadMediaSource();
 -	}
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLPanelMediaSettingsGeneral::onCommitHomeURL( LLUICtrl* ctrl, void *userdata )
 -{
 -	LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata;
 -
 -	// check url user is trying to enter for home URL will pass whitelist 
 -	// and decline to accept it if it doesn't.
 -	std::string home_url = self->mHomeURL->getValue().asString();
 -	if ( ! self->mParent->passesWhiteList( home_url ) )
 -	{
 -		LLNotifications::instance().add("WhiteListInvalidatesHomeUrl");		
 -		return;
 -	};
 -	
 -	self->updateMediaPreview();
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLPanelMediaSettingsGeneral::onBtnResetCurrentUrl(LLUICtrl* ctrl, void *userdata)
 -{
 -	LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata;
 -	self->navigateHomeSelectedFace();
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLPanelMediaSettingsGeneral::apply( void* userdata )
 -{
 -	LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;
 -	self->mHomeURL->onCommit();
 -	// build LLSD Fragment
 -	LLSD media_data_general;
 -	self->getValues(media_data_general);
 -
 -	// this merges contents of LLSD passed in with what's there so this is ok
 -	LLSelectMgr::getInstance()->selectionSetMediaData( media_data_general );
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -//
 -void LLPanelMediaSettingsGeneral::getValues( LLSD &fill_me_in )
 -{
 -    fill_me_in[LLMediaEntry::AUTO_LOOP_KEY] = mAutoLoop->getValue();
 -    fill_me_in[LLMediaEntry::AUTO_PLAY_KEY] = mAutoPlay->getValue();
 -    fill_me_in[LLMediaEntry::AUTO_SCALE_KEY] = mAutoScale->getValue();
 -    fill_me_in[LLMediaEntry::AUTO_ZOOM_KEY] = mAutoZoom->getValue();
 -    fill_me_in[LLMediaEntry::CONTROLS_KEY] = mControls->getCurrentIndex();
 -    fill_me_in[LLMediaEntry::CURRENT_URL_KEY] = mCurrentURL->getValue();
 -    fill_me_in[LLMediaEntry::HEIGHT_PIXELS_KEY] = mHeightPixels->getValue();
 -    fill_me_in[LLMediaEntry::HOME_URL_KEY] = mHomeURL->getValue();
 -    fill_me_in[LLMediaEntry::FIRST_CLICK_INTERACT_KEY] = mFirstClick->getValue();
 -    fill_me_in[LLMediaEntry::WIDTH_PIXELS_KEY] = mWidthPixels->getValue();
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -//
 -void LLPanelMediaSettingsGeneral::setParent( LLFloaterMediaSettings* parent )
 -{
 -	mParent = parent;
 -};
 -
 -bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace()
 -{
 -	// HACK: This is directly referencing an impl name.  BAD!
 -	// This can be removed when we have a truly generic media browser that only 
 -	// builds an impl based on the type of url it is passed.
 -	struct functor_navigate_media : public LLSelectedTEGetFunctor< bool>
 -	{
 -		bool get( LLViewerObject* object, S32 face )
 -		{
 -			if ( object )
 -				if ( object->getTE(face) )
 -					if ( object->getTE(face)->getMediaData() )
 -					{
 -						if(object->permModify())
 -						{
 -							viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(object->getTE(face)->getMediaData()->getMediaID());
 -							if(media_impl)
 -							{
 -								media_impl->navigateHome();
 -								return true;
 -							}
 -						}	
 -					}
 -		   return false;
 -		 };
 -				
 -	} functor_navigate_media;
 -	
 -	bool all_face_media_navigated = false;
 -	LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
 -	selected_objects->getSelectedTEValue( &functor_navigate_media, all_face_media_navigated );
 -	
 -	return all_face_media_navigated;
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -//
 -const std::string LLPanelMediaSettingsGeneral::getHomeUrl()
 -{
 -	return mHomeURL->getValue().asString(); 
 -}
 -
 +/** + * @file llpanelmediasettingsgeneral.cpp + * @brief LLPanelMediaSettingsGeneral class implementation + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 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 "llagent.h" +#include "llpanelmediasettingsgeneral.h" +#include "llcombobox.h" +#include "llcheckboxctrl.h" +#include "llspinctrl.h" +#include "lluictrlfactory.h" +#include "llviewerwindow.h" +#include "llviewermedia.h" +#include "llsdutil.h" +#include "llselectmgr.h" +#include "llbutton.h" +#include "lltexturectrl.h" +#include "llurl.h" +#include "llwindow.h" +#include "llmediaentry.h" +#include "llmediactrl.h" +#include "llpanelcontents.h" +#include "llpermissions.h" +#include "llpluginclassmedia.h" +#include "llfloatermediasettings.h" +#include "llfloatertools.h" +#include "lltrans.h" + +//////////////////////////////////////////////////////////////////////////////// +// +LLPanelMediaSettingsGeneral::LLPanelMediaSettingsGeneral() : +	mControls( NULL ), +	mAutoLoop( NULL ), +	mFirstClick( NULL ), +	mAutoZoom( NULL ), +	mAutoPlay( NULL ), +	mAutoScale( NULL ), +	mWidthPixels( NULL ), +	mHeightPixels( NULL ), +	mHomeURL( NULL ), +	mCurrentURL( NULL ), +	mParent( NULL ), +	mMediaEditable(false) +{ +	// build dialog from XML +	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_general.xml"); +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLPanelMediaSettingsGeneral::postBuild() +{ +	// connect member vars with UI widgets +	mAutoLoop = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_LOOP_KEY ); +	mAutoPlay = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_PLAY_KEY ); +	mAutoScale = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_SCALE_KEY ); +	mAutoZoom = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_ZOOM_KEY ); +	mControls = getChild< LLComboBox >( LLMediaEntry::CONTROLS_KEY ); +	mCurrentURL = getChild< LLLineEditor >( LLMediaEntry::CURRENT_URL_KEY ); +	mFirstClick = getChild< LLCheckBoxCtrl >( LLMediaEntry::FIRST_CLICK_INTERACT_KEY ); +	mHeightPixels = getChild< LLSpinCtrl >( LLMediaEntry::HEIGHT_PIXELS_KEY ); +	mHomeURL = getChild< LLLineEditor >( LLMediaEntry::HOME_URL_KEY ); +	mWidthPixels = getChild< LLSpinCtrl >( LLMediaEntry::WIDTH_PIXELS_KEY ); +	mPreviewMedia = getChild<LLMediaCtrl>("preview_media"); + +	// watch commit action for HOME URL +	childSetCommitCallback( LLMediaEntry::HOME_URL_KEY, onCommitHomeURL, this); +	childSetCommitCallback( "current_url_reset_btn",onBtnResetCurrentUrl, this); +	// interrogates controls and updates widgets as required +	updateMediaPreview(); +	updateCurrentURL(); + +	return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +LLPanelMediaSettingsGeneral::~LLPanelMediaSettingsGeneral() +{ +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsGeneral::draw() +{ +	// housekeeping +	LLPanel::draw(); + +	// enable/disable pixel values image entry based on auto scale checkbox  +	if ( mAutoScale->getValue().asBoolean() == false ) +	{ +		childSetEnabled( LLMediaEntry::WIDTH_PIXELS_KEY, true ); +		childSetEnabled( LLMediaEntry::HEIGHT_PIXELS_KEY, true ); +	} +	else +	{ +		childSetEnabled( LLMediaEntry::WIDTH_PIXELS_KEY, false ); +		childSetEnabled( LLMediaEntry::HEIGHT_PIXELS_KEY, false ); +	}; + +	// enable/disable UI based on type of media +	bool reset_button_is_active = true; +	if( mPreviewMedia ) +	{ +		LLPluginClassMedia* media_plugin = mPreviewMedia->getMediaPlugin(); +		if( media_plugin ) +		{ +			// turn off volume (if we can) for preview. Note: this really only +			// works for QuickTime movies right now - no way to control the  +			// volume of a flash app embedded in a page for example +			media_plugin->setVolume( 0 ); + +			// some controls are only appropriate for time or browser type plugins +			// so we selectively enable/disable them - need to do it in draw +			// because the information from plugins arrives assynchronously +			bool show_time_controls = media_plugin->pluginSupportsMediaTime(); +			if ( show_time_controls ) +			{ +				childSetEnabled( LLMediaEntry::CURRENT_URL_KEY, false ); +				reset_button_is_active = false; +				childSetEnabled( "current_url_label", false ); +				childSetEnabled( LLMediaEntry::AUTO_LOOP_KEY, true ); +			} +			else +			{ +				childSetEnabled( LLMediaEntry::CURRENT_URL_KEY, true ); +				reset_button_is_active = true; +				childSetEnabled( "current_url_label", true ); +				childSetEnabled( LLMediaEntry::AUTO_LOOP_KEY, false ); +			}; +		}; +	}; + +	// current URL can change over time. +//	updateCurrentURL(); + +	LLPermissions perm; +	bool user_can_press_reset = mMediaEditable; + +	// several places modify this widget so we must collect states in one place +	if ( reset_button_is_active ) +	{ +		// user has perms to press reset button and it is active +		if ( user_can_press_reset ) +		{ +			childSetEnabled( "current_url_reset_btn", true ); +		} +		// user does not has perms to press reset button and it is active +		else +		{ +			childSetEnabled( "current_url_reset_btn", false ); +		}; +	} +	else +	// reset button is inactive so we just slam it to off - other states don't matter +	{ +		childSetEnabled( "current_url_reset_btn", false ); +	}; +} + +//////////////////////////////////////////////////////////////////////////////// +// static  +void LLPanelMediaSettingsGeneral::clearValues( void* userdata, bool editable) +{	 +	LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata; +	self->mAutoLoop->clear(); +	self->mAutoPlay->clear(); +	self->mAutoScale->clear(); +	self->mAutoZoom ->clear(); +	self->mControls->clear(); +	self->mCurrentURL->clear(); +	self->mFirstClick->clear(); +	self->mHeightPixels->clear(); +	self->mHomeURL->clear(); +	self->mWidthPixels->clear(); +	self->mAutoLoop ->setEnabled(editable); +	self->mAutoPlay ->setEnabled(editable); +	self->mAutoScale ->setEnabled(editable); +	self->mAutoZoom  ->setEnabled(editable); +	self->mControls ->setEnabled(editable); +	self->mCurrentURL ->setEnabled(editable); +	self->mFirstClick ->setEnabled(editable); +	self->mHeightPixels ->setEnabled(editable); +	self->mHomeURL ->setEnabled(editable); +	self->mWidthPixels ->setEnabled(editable); +	self->updateMediaPreview(); +} + +//////////////////////////////////////////////////////////////////////////////// +// static  +void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_settings ,bool editable) +{ +	LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata; +	self->mMediaEditable = editable; + +	//llinfos << "---------------" << llendl; +	//llinfos << ll_pretty_print_sd(media_settings) << llendl; +	//llinfos << "---------------" << llendl; + +	// IF all the faces have media (or all dont have media) +	if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo ) +	{ +		if(LLFloaterMediaSettings::getInstance()->mMultipleMedia)  +		{ +			self->clearValues(self, self->mMediaEditable); +			// only show multiple  +			self->mHomeURL ->setText(LLTrans::getString("Multiple Media")); +			return; +		} +		 +	} +	else +	{ +		if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)  +		{ +			self->clearValues(self, self->mMediaEditable); +			// only show multiple  +			self->mHomeURL ->setText(LLTrans::getString("Multiple Media")); +			return; +		}			 +		 +	} +	std::string base_key( "" ); +	std::string tentative_key( "" ); + +	struct  +	{ +		std::string key_name; +		LLUICtrl* ctrl_ptr; +		std::string ctrl_type; + +	} data_set [] =  +	{  +        { LLMediaEntry::AUTO_LOOP_KEY,				self->mAutoLoop,		"LLCheckBoxCtrl" }, +		{ LLMediaEntry::AUTO_PLAY_KEY,				self->mAutoPlay,		"LLCheckBoxCtrl" }, +		{ LLMediaEntry::AUTO_SCALE_KEY,				self->mAutoScale,		"LLCheckBoxCtrl" }, +		{ LLMediaEntry::AUTO_ZOOM_KEY,				self->mAutoZoom,		"LLCheckBoxCtrl" }, +		{ LLMediaEntry::CONTROLS_KEY,				self->mControls,		"LLComboBox" }, +		{ LLMediaEntry::CURRENT_URL_KEY,			self->mCurrentURL,		"LLLineEditor" }, +		{ LLMediaEntry::HEIGHT_PIXELS_KEY,			self->mHeightPixels,	"LLSpinCtrl" }, +		{ LLMediaEntry::HOME_URL_KEY,				self->mHomeURL,			"LLLineEditor" }, +		{ LLMediaEntry::FIRST_CLICK_INTERACT_KEY,	self->mFirstClick,		"LLCheckBoxCtrl" }, +		{ LLMediaEntry::WIDTH_PIXELS_KEY,			self->mWidthPixels,		"LLSpinCtrl" }, +		{ "", NULL , "" } +	}; + +	for( int i = 0; data_set[ i ].key_name.length() > 0; ++i ) +	{ +		base_key = std::string( data_set[ i ].key_name ); +		tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ); +		// TODO: CP - I bet there is a better way to do this using Boost +		if ( media_settings[ base_key ].isDefined() ) +		{ +			if ( data_set[ i ].ctrl_type == "LLLineEditor" ) +			{ +				static_cast< LLLineEditor* >( data_set[ i ].ctrl_ptr )-> +					setText( media_settings[ base_key ].asString() ); +			} +			else +			if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" ) +				static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )-> +					setValue( media_settings[ base_key ].asBoolean() ); +			else +			if ( data_set[ i ].ctrl_type == "LLComboBox" ) +				static_cast< LLComboBox* >( data_set[ i ].ctrl_ptr )-> +					setCurrentByIndex( media_settings[ base_key ].asInteger() ); +			else +			if ( data_set[ i ].ctrl_type == "LLSpinCtrl" ) +				static_cast< LLSpinCtrl* >( data_set[ i ].ctrl_ptr )-> +					setValue( media_settings[ base_key ].asInteger() ); + +			data_set[ i ].ctrl_ptr->setEnabled(self->mMediaEditable); +			data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() ); +		}; +	}; +	 +	// interrogates controls and updates widgets as required +	self->updateMediaPreview(); +	self->updateCurrentURL(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Helper to set media control to media URL as required +void LLPanelMediaSettingsGeneral::updateMediaPreview() +{ +	if ( mHomeURL->getValue().asString().length() > 0 ) +	{ +		mPreviewMedia->navigateTo( mHomeURL->getValue().asString() ); +	} +	else +	// new home URL will be empty if media is deleted so display a  +	// "preview goes here" data url page +	{ +		mPreviewMedia->navigateTo( "data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%22100%%22 height=%22100%%22 %3E%3Cdefs%3E%3Cpattern id=%22checker%22 patternUnits=%22userSpaceOnUse%22 x=%220%22 y=%220%22 width=%22128%22 height=%22128%22 viewBox=%220 0 128 128%22 %3E%3Crect x=%220%22 y=%220%22 width=%2264%22 height=%2264%22 fill=%22#ddddff%22 /%3E%3Crect x=%2264%22 y=%2264%22 width=%2264%22 height=%2264%22 fill=%22#ddddff%22 /%3E%3C/pattern%3E%3C/defs%3E%3Crect x=%220%22 y=%220%22 width=%22100%%22 height=%22100%%22 fill=%22url(#checker)%22 /%3E%3C/svg%3E" ); +	}; +} + +//////////////////////////////////////////////////////////////////////////////// +// Helper to set current URL +void LLPanelMediaSettingsGeneral::updateCurrentURL() +{ +	if( mCurrentURL->getText().empty() ) +	{ +		childSetText( "current_url", mHomeURL->getText() ); +	} +	 +} + +//////////////////////////////////////////////////////////////////////////////// + +// virtual +void LLPanelMediaSettingsGeneral::onClose(bool app_quitting) +{ +	if(mPreviewMedia) +	{ +		mPreviewMedia->unloadMediaSource(); +	} +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsGeneral::onCommitHomeURL( LLUICtrl* ctrl, void *userdata ) +{ +	LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata; + +	// check url user is trying to enter for home URL will pass whitelist  +	// and decline to accept it if it doesn't. +	std::string home_url = self->mHomeURL->getValue().asString(); +	if ( ! self->mParent->passesWhiteList( home_url ) ) +	{ +		LLNotifications::instance().add("WhiteListInvalidatesHomeUrl");		 +		return; +	}; +	 +	self->updateMediaPreview(); +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsGeneral::onBtnResetCurrentUrl(LLUICtrl* ctrl, void *userdata) +{ +	LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata; +	self->navigateHomeSelectedFace(); +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsGeneral::apply( void* userdata ) +{ +	LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata; +	self->mHomeURL->onCommit(); +	// build LLSD Fragment +	LLSD media_data_general; +	self->getValues(media_data_general); + +	// this merges contents of LLSD passed in with what's there so this is ok +	LLSelectMgr::getInstance()->selectionSetMediaData( media_data_general ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsGeneral::getValues( LLSD &fill_me_in ) +{ +    fill_me_in[LLMediaEntry::AUTO_LOOP_KEY] = mAutoLoop->getValue(); +    fill_me_in[LLMediaEntry::AUTO_PLAY_KEY] = mAutoPlay->getValue(); +    fill_me_in[LLMediaEntry::AUTO_SCALE_KEY] = mAutoScale->getValue(); +    fill_me_in[LLMediaEntry::AUTO_ZOOM_KEY] = mAutoZoom->getValue(); +    fill_me_in[LLMediaEntry::CONTROLS_KEY] = mControls->getCurrentIndex(); +    fill_me_in[LLMediaEntry::CURRENT_URL_KEY] = mCurrentURL->getValue(); +    fill_me_in[LLMediaEntry::HEIGHT_PIXELS_KEY] = mHeightPixels->getValue(); +    fill_me_in[LLMediaEntry::HOME_URL_KEY] = mHomeURL->getValue(); +    fill_me_in[LLMediaEntry::FIRST_CLICK_INTERACT_KEY] = mFirstClick->getValue(); +    fill_me_in[LLMediaEntry::WIDTH_PIXELS_KEY] = mWidthPixels->getValue(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsGeneral::setParent( LLFloaterMediaSettings* parent ) +{ +	mParent = parent; +}; + +bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace() +{ +	// HACK: This is directly referencing an impl name.  BAD! +	// This can be removed when we have a truly generic media browser that only  +	// builds an impl based on the type of url it is passed. +	struct functor_navigate_media : public LLSelectedTEGetFunctor< bool> +	{ +		bool get( LLViewerObject* object, S32 face ) +		{ +			if ( object ) +				if ( object->getTE(face) ) +					if ( object->getTE(face)->getMediaData() ) +					{ +						if(object->permModify()) +						{ +							viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(object->getTE(face)->getMediaData()->getMediaID()); +							if(media_impl) +							{ +								media_impl->navigateHome(); +								return true; +							} +						}	 +					} +		   return false; +		 }; +				 +	} functor_navigate_media; +	 +	bool all_face_media_navigated = false; +	LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection(); +	selected_objects->getSelectedTEValue( &functor_navigate_media, all_face_media_navigated ); +	 +	return all_face_media_navigated; +} + +//////////////////////////////////////////////////////////////////////////////// +// +const std::string LLPanelMediaSettingsGeneral::getHomeUrl() +{ +	return mHomeURL->getValue().asString();  +} + diff --git a/indra/newview/llpanelmediasettingssecurity.cpp b/indra/newview/llpanelmediasettingssecurity.cpp index f5607aa287..3fe436e915 100644 --- a/indra/newview/llpanelmediasettingssecurity.cpp +++ b/indra/newview/llpanelmediasettingssecurity.cpp @@ -1,339 +1,339 @@ -/**
 - * @file llpanelmediasettingssecurity.cpp
 - * @brief LLPanelMediaSettingsSecurity class implementation
 - *
 - * $LicenseInfo:firstyear=2009&license=viewergpl$
 - * 
 - * Copyright (c) 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 "llfloaterreg.h"
 -#include "llpanelmediasettingssecurity.h"
 -#include "llpanelcontents.h"
 -#include "llcheckboxctrl.h"
 -#include "llscrolllistctrl.h"
 -#include "llscrolllistitem.h"
 -#include "lluictrlfactory.h"
 -#include "llwindow.h"
 -#include "llviewerwindow.h"
 -#include "llsdutil.h"
 -#include "llselectmgr.h"
 -#include "llmediaentry.h"
 -#include "llfloaterwhitelistentry.h"
 -#include "llfloatermediasettings.h"
 -////////////////////////////////////////////////////////////////////////////////
 -//
 -LLPanelMediaSettingsSecurity::LLPanelMediaSettingsSecurity() :
 -	mParent( NULL )
 -{
 -	// build dialog from XML
 -	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_security.xml");
 -	mCommitCallbackRegistrar.add("Media.whitelistAdd",		boost::bind(&LLPanelMediaSettingsSecurity::onBtnAdd, this));
 -	mCommitCallbackRegistrar.add("Media.whitelistDelete",	boost::bind(&LLPanelMediaSettingsSecurity::onBtnDel, this));	
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -//
 -BOOL LLPanelMediaSettingsSecurity::postBuild()
 -{
 -	mEnableWhiteList = getChild< LLCheckBoxCtrl >( LLMediaEntry::WHITELIST_ENABLE_KEY );
 -	mWhiteListList = getChild< LLScrollListCtrl >( LLMediaEntry::WHITELIST_KEY );
 -
 -	childSetAction("whitelist_add", onBtnAdd, this);
 -	childSetAction("whitelist_del", onBtnDel, this);
 -
 -	setDefaultBtn("whitelist_add");
 -
 -	return true;
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// virtual
 -LLPanelMediaSettingsSecurity::~LLPanelMediaSettingsSecurity()
 -{
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// 
 -void LLPanelMediaSettingsSecurity::draw()
 -{
 -	// housekeeping
 -	LLPanel::draw();
 -
 -	// if list is empty, disable DEL button and checkbox to enable use of list
 -	if ( mWhiteListList->isEmpty() )
 -	{
 -		childSetEnabled( "whitelist_del", false );
 -		childSetEnabled( LLMediaEntry::WHITELIST_KEY, false );
 -		childSetEnabled( LLMediaEntry::WHITELIST_ENABLE_KEY, false );
 -	}
 -	else
 -	{
 -		childSetEnabled( "whitelist_del", true );
 -		childSetEnabled( LLMediaEntry::WHITELIST_KEY, true );
 -		childSetEnabled( LLMediaEntry::WHITELIST_ENABLE_KEY, true );
 -	};
 -
 -	// if nothing is selected, disable DEL button
 -	if ( mWhiteListList->getSelectedValue().asString().empty() )
 -	{
 -		childSetEnabled( "whitelist_del", false );
 -	}
 -	else
 -	{
 -		childSetEnabled( "whitelist_del", true );
 -	};
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// static 
 -void LLPanelMediaSettingsSecurity::initValues( void* userdata, const LLSD& media_settings , bool editable)
 -{
 -	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
 -
 -	if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo )
 -	{
 -		if(LLFloaterMediaSettings::getInstance()->mMultipleMedia) 
 -		{
 -			self->clearValues(self, editable);
 -			// only show multiple 
 -			return;
 -		}
 -		
 -	}
 -	else
 -	{
 -		if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia) 
 -		{
 -			self->clearValues(self, editable);
 -			// only show multiple 
 -			return;
 -		}			
 -		
 -	}
 -	std::string base_key( "" );
 -	std::string tentative_key( "" );
 -
 -	struct 
 -	{
 -		std::string key_name;
 -		LLUICtrl* ctrl_ptr;
 -		std::string ctrl_type;
 -
 -	} data_set [] = 
 -	{
 -		{ LLMediaEntry::WHITELIST_ENABLE_KEY,	self->mEnableWhiteList,		"LLCheckBoxCtrl" },
 -		{ LLMediaEntry::WHITELIST_KEY,			self->mWhiteListList,		"LLScrollListCtrl" },
 -		{ "", NULL , "" }
 -	};
 -
 -	for( int i = 0; data_set[ i ].key_name.length() > 0; ++i )
 -	{
 -		base_key = std::string( data_set[ i ].key_name );
 -        tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX );
 -
 -		// TODO: CP - I bet there is a better way to do this using Boost
 -		if ( media_settings[ base_key ].isDefined() )
 -		{
 -			if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" )
 -			{
 -				static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )->
 -					setValue( media_settings[ base_key ].asBoolean() );
 -			}
 -			else
 -			if ( data_set[ i ].ctrl_type == "LLScrollListCtrl" )
 -			{
 -				// get control 
 -				LLScrollListCtrl* list = static_cast< LLScrollListCtrl* >( data_set[ i ].ctrl_ptr );
 -				list->deleteAllItems();
 -
 -				// points to list of white list URLs
 -				LLSD url_list = media_settings[ base_key ];
 -
 -				// iterate over them and add to scroll list
 -				LLSD::array_iterator iter = url_list.beginArray();
 -				while( iter != url_list.endArray() )
 -				{
 -					// TODO: is iter guaranteed to be valid here?
 -					std::string url = *iter;
 -					list->addSimpleElement( url );
 -					++iter;
 -				};
 -			};
 -			data_set[ i ].ctrl_ptr->setEnabled(editable);
 -			data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
 -		};
 -	};
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// static 
 -void LLPanelMediaSettingsSecurity::clearValues( void* userdata , bool editable)
 -{
 -	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
 -	self->mEnableWhiteList->clear();
 -	self->mWhiteListList->deleteAllItems();
 -	self->mEnableWhiteList->setEnabled(editable);
 -	self->mWhiteListList->setEnabled(editable);
 -}
 -////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLPanelMediaSettingsSecurity::apply( void* userdata )
 -{
 -	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
 -
 -	// build LLSD Fragment
 -	LLSD media_data_security;
 -	self->getValues(media_data_security);
 -	// this merges contents of LLSD passed in with what's there so this is ok
 -	LLSelectMgr::getInstance()->selectionSetMediaData( media_data_security );
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -//
 -void LLPanelMediaSettingsSecurity::getValues( LLSD &fill_me_in )
 -{
 -    fill_me_in[LLMediaEntry::WHITELIST_ENABLE_KEY] = mEnableWhiteList->getValue();
 -
 -    // iterate over white list and extract items
 -    std::vector< LLScrollListItem* > white_list_items = mWhiteListList->getAllData();
 -    std::vector< LLScrollListItem* >::iterator iter = white_list_items.begin();
 -    fill_me_in[LLMediaEntry::WHITELIST_KEY].clear();
 -    while( iter != white_list_items.end() )
 -    {
 -        std::string white_list_url = (*iter)->getValue().asString();
 -        fill_me_in[ LLMediaEntry::WHITELIST_KEY ].append( white_list_url );
 -        ++iter;
 -    };
 -}
 -
 -///////////////////////////////////////////////////////////////////////////////
 -// Try to make a valid URL if a fragment (
 -// white list list box widget and build a list to test against. Can also
 -const std::string LLPanelMediaSettingsSecurity::makeValidUrl( const std::string& src_url )
 -{
 -	// use LLURI to determine if we have a valid scheme
 +/** + * @file llpanelmediasettingssecurity.cpp + * @brief LLPanelMediaSettingsSecurity class implementation + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 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 "llfloaterreg.h" +#include "llpanelmediasettingssecurity.h" +#include "llpanelcontents.h" +#include "llcheckboxctrl.h" +#include "llscrolllistctrl.h" +#include "llscrolllistitem.h" +#include "lluictrlfactory.h" +#include "llwindow.h" +#include "llviewerwindow.h" +#include "llsdutil.h" +#include "llselectmgr.h" +#include "llmediaentry.h" +#include "llfloaterwhitelistentry.h" +#include "llfloatermediasettings.h" +//////////////////////////////////////////////////////////////////////////////// +// +LLPanelMediaSettingsSecurity::LLPanelMediaSettingsSecurity() : +	mParent( NULL ) +{ +	// build dialog from XML +	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_security.xml"); +	mCommitCallbackRegistrar.add("Media.whitelistAdd",		boost::bind(&LLPanelMediaSettingsSecurity::onBtnAdd, this)); +	mCommitCallbackRegistrar.add("Media.whitelistDelete",	boost::bind(&LLPanelMediaSettingsSecurity::onBtnDel, this));	 +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLPanelMediaSettingsSecurity::postBuild() +{ +	mEnableWhiteList = getChild< LLCheckBoxCtrl >( LLMediaEntry::WHITELIST_ENABLE_KEY ); +	mWhiteListList = getChild< LLScrollListCtrl >( LLMediaEntry::WHITELIST_KEY ); + +	childSetAction("whitelist_add", onBtnAdd, this); +	childSetAction("whitelist_del", onBtnDel, this); + +	setDefaultBtn("whitelist_add"); + +	return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +LLPanelMediaSettingsSecurity::~LLPanelMediaSettingsSecurity() +{ +} + +//////////////////////////////////////////////////////////////////////////////// +//  +void LLPanelMediaSettingsSecurity::draw() +{ +	// housekeeping +	LLPanel::draw(); + +	// if list is empty, disable DEL button and checkbox to enable use of list +	if ( mWhiteListList->isEmpty() ) +	{ +		childSetEnabled( "whitelist_del", false ); +		childSetEnabled( LLMediaEntry::WHITELIST_KEY, false ); +		childSetEnabled( LLMediaEntry::WHITELIST_ENABLE_KEY, false ); +	} +	else +	{ +		childSetEnabled( "whitelist_del", true ); +		childSetEnabled( LLMediaEntry::WHITELIST_KEY, true ); +		childSetEnabled( LLMediaEntry::WHITELIST_ENABLE_KEY, true ); +	}; + +	// if nothing is selected, disable DEL button +	if ( mWhiteListList->getSelectedValue().asString().empty() ) +	{ +		childSetEnabled( "whitelist_del", false ); +	} +	else +	{ +		childSetEnabled( "whitelist_del", true ); +	}; +} + +//////////////////////////////////////////////////////////////////////////////// +// static  +void LLPanelMediaSettingsSecurity::initValues( void* userdata, const LLSD& media_settings , bool editable) +{ +	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata; + +	if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo ) +	{ +		if(LLFloaterMediaSettings::getInstance()->mMultipleMedia)  +		{ +			self->clearValues(self, editable); +			// only show multiple  +			return; +		} +		 +	} +	else +	{ +		if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)  +		{ +			self->clearValues(self, editable); +			// only show multiple  +			return; +		}			 +		 +	} +	std::string base_key( "" ); +	std::string tentative_key( "" ); + +	struct  +	{ +		std::string key_name; +		LLUICtrl* ctrl_ptr; +		std::string ctrl_type; + +	} data_set [] =  +	{ +		{ LLMediaEntry::WHITELIST_ENABLE_KEY,	self->mEnableWhiteList,		"LLCheckBoxCtrl" }, +		{ LLMediaEntry::WHITELIST_KEY,			self->mWhiteListList,		"LLScrollListCtrl" }, +		{ "", NULL , "" } +	}; + +	for( int i = 0; data_set[ i ].key_name.length() > 0; ++i ) +	{ +		base_key = std::string( data_set[ i ].key_name ); +        tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ); + +		// TODO: CP - I bet there is a better way to do this using Boost +		if ( media_settings[ base_key ].isDefined() ) +		{ +			if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" ) +			{ +				static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )-> +					setValue( media_settings[ base_key ].asBoolean() ); +			} +			else +			if ( data_set[ i ].ctrl_type == "LLScrollListCtrl" ) +			{ +				// get control  +				LLScrollListCtrl* list = static_cast< LLScrollListCtrl* >( data_set[ i ].ctrl_ptr ); +				list->deleteAllItems(); + +				// points to list of white list URLs +				LLSD url_list = media_settings[ base_key ]; + +				// iterate over them and add to scroll list +				LLSD::array_iterator iter = url_list.beginArray(); +				while( iter != url_list.endArray() ) +				{ +					// TODO: is iter guaranteed to be valid here? +					std::string url = *iter; +					list->addSimpleElement( url ); +					++iter; +				}; +			}; +			data_set[ i ].ctrl_ptr->setEnabled(editable); +			data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() ); +		}; +	}; +} + +//////////////////////////////////////////////////////////////////////////////// +// static  +void LLPanelMediaSettingsSecurity::clearValues( void* userdata , bool editable) +{ +	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata; +	self->mEnableWhiteList->clear(); +	self->mWhiteListList->deleteAllItems(); +	self->mEnableWhiteList->setEnabled(editable); +	self->mWhiteListList->setEnabled(editable); +} +//////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsSecurity::apply( void* userdata ) +{ +	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata; + +	// build LLSD Fragment +	LLSD media_data_security; +	self->getValues(media_data_security); +	// this merges contents of LLSD passed in with what's there so this is ok +	LLSelectMgr::getInstance()->selectionSetMediaData( media_data_security ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsSecurity::getValues( LLSD &fill_me_in ) +{ +    fill_me_in[LLMediaEntry::WHITELIST_ENABLE_KEY] = mEnableWhiteList->getValue(); + +    // iterate over white list and extract items +    std::vector< LLScrollListItem* > white_list_items = mWhiteListList->getAllData(); +    std::vector< LLScrollListItem* >::iterator iter = white_list_items.begin(); +    fill_me_in[LLMediaEntry::WHITELIST_KEY].clear(); +    while( iter != white_list_items.end() ) +    { +        std::string white_list_url = (*iter)->getValue().asString(); +        fill_me_in[ LLMediaEntry::WHITELIST_KEY ].append( white_list_url ); +        ++iter; +    }; +} + +/////////////////////////////////////////////////////////////////////////////// +// Try to make a valid URL if a fragment ( +// white list list box widget and build a list to test against. Can also +const std::string LLPanelMediaSettingsSecurity::makeValidUrl( const std::string& src_url ) +{ +	// use LLURI to determine if we have a valid scheme  	LLURI candidate_url( src_url );  	if ( candidate_url.scheme().empty() )  	{ -		// build a URL comprised of default scheme and the original fragment 
 -		const std::string default_scheme( "http://" );
 -		return default_scheme + src_url;
 +		// build a URL comprised of default scheme and the original fragment  +		const std::string default_scheme( "http://" ); +		return default_scheme + src_url;  	};  	// we *could* test the "default scheme" + "original fragment" URL again  	// using LLURI to see if it's valid but I think the outcome is the same  	// in either case - our only option is to return the original URL -
 -	// we *think* the original url passed in was valid
 -	return src_url;
 -}
 -
 -///////////////////////////////////////////////////////////////////////////////
 -// wrapper for testing a URL against the whitelist. We grab entries from
 -// white list list box widget and build a list to test against. Can also
 -// optionally pass the URL that you are trying to add to the widget since
 -// it won't be added until this call returns.
 -bool LLPanelMediaSettingsSecurity::passesWhiteList( const std::string& added_url,
 -													const std::string& test_url )
 -{
 -	// the checkUrlAgainstWhitelist(..) function works on a vector
 -	// of strings for the white list entries - in this panel, the white list
 -	// is stored in the widgets themselves so we need to build something compatible.
 -	std::vector< std::string > whitelist_strings;
 -	whitelist_strings.clear();	// may not be required - I forget what the spec says.
 -
 -	// step through whitelist widget entries and grab them as strings
 -    std::vector< LLScrollListItem* > white_list_items = mWhiteListList->getAllData();
 -    std::vector< LLScrollListItem* >::iterator iter = white_list_items.begin(); 
 -	while( iter != white_list_items.end()  )
 -    {
 -        const std::string whitelist_url = (*iter)->getValue().asString();
 -		whitelist_strings.push_back( whitelist_url );
 -
 -		++iter;
 -    };
 -
 -	// add in the URL that might be added to the whitelist so we can test that too
 -	if ( added_url.length() )
 -		whitelist_strings.push_back( added_url );
 -
 -	// possible the URL is just a fragment so we validize it
 -	const std::string valid_url = makeValidUrl( test_url );
 -
 -	// indicate if the URL passes whitelist
 -	return LLMediaEntry::checkUrlAgainstWhitelist( valid_url, whitelist_strings );
 -}
 -
 -///////////////////////////////////////////////////////////////////////////////
 -//
 -void LLPanelMediaSettingsSecurity::addWhiteListItem(const std::string& url)
 -{
 -	// grab home URL from the general panel (via the parent floater)
 -	std::string home_url( "" );
 -	if ( mParent )
 -		home_url = mParent->getHomeUrl();
 -
 -	// if the home URL is blank (user hasn't entered it yet) then
 -	// don't bother to check if it passes the white list
 -	if ( home_url.empty() )
 -	{
 -		mWhiteListList->addSimpleElement( url );
 -		return;
 -	};
 -
 -	// if the URL passes the white list, add it
 -	if ( passesWhiteList( url, home_url ) )
 -	{
 -		mWhiteListList->addSimpleElement( url );
 -	}
 -	else
 -	// display a message indicating you can't do that
 -	{
 -		LLNotifications::instance().add("WhiteListInvalidatesHomeUrl");
 -	};
 -}
 -
 -///////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLPanelMediaSettingsSecurity::onBtnAdd( void* userdata )
 -{
 -	LLFloaterReg::showInstance("whitelist_entry");
 -}
 -
 -///////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLPanelMediaSettingsSecurity::onBtnDel( void* userdata )
 -{
 -	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
 -
 -	self->mWhiteListList->deleteSelectedItems();
 -}
 -
 + +	// we *think* the original url passed in was valid +	return src_url; +} + +/////////////////////////////////////////////////////////////////////////////// +// wrapper for testing a URL against the whitelist. We grab entries from +// white list list box widget and build a list to test against. Can also +// optionally pass the URL that you are trying to add to the widget since +// it won't be added until this call returns. +bool LLPanelMediaSettingsSecurity::passesWhiteList( const std::string& added_url, +													const std::string& test_url ) +{ +	// the checkUrlAgainstWhitelist(..) function works on a vector +	// of strings for the white list entries - in this panel, the white list +	// is stored in the widgets themselves so we need to build something compatible. +	std::vector< std::string > whitelist_strings; +	whitelist_strings.clear();	// may not be required - I forget what the spec says. + +	// step through whitelist widget entries and grab them as strings +    std::vector< LLScrollListItem* > white_list_items = mWhiteListList->getAllData(); +    std::vector< LLScrollListItem* >::iterator iter = white_list_items.begin();  +	while( iter != white_list_items.end()  ) +    { +        const std::string whitelist_url = (*iter)->getValue().asString(); +		whitelist_strings.push_back( whitelist_url ); + +		++iter; +    }; + +	// add in the URL that might be added to the whitelist so we can test that too +	if ( added_url.length() ) +		whitelist_strings.push_back( added_url ); + +	// possible the URL is just a fragment so we validize it +	const std::string valid_url = makeValidUrl( test_url ); + +	// indicate if the URL passes whitelist +	return LLMediaEntry::checkUrlAgainstWhitelist( valid_url, whitelist_strings ); +} + +/////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsSecurity::addWhiteListItem(const std::string& url) +{ +	// grab home URL from the general panel (via the parent floater) +	std::string home_url( "" ); +	if ( mParent ) +		home_url = mParent->getHomeUrl(); + +	// if the home URL is blank (user hasn't entered it yet) then +	// don't bother to check if it passes the white list +	if ( home_url.empty() ) +	{ +		mWhiteListList->addSimpleElement( url ); +		return; +	}; + +	// if the URL passes the white list, add it +	if ( passesWhiteList( url, home_url ) ) +	{ +		mWhiteListList->addSimpleElement( url ); +	} +	else +	// display a message indicating you can't do that +	{ +		LLNotifications::instance().add("WhiteListInvalidatesHomeUrl"); +	}; +} + +/////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsSecurity::onBtnAdd( void* userdata ) +{ +	LLFloaterReg::showInstance("whitelist_entry"); +} + +/////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsSecurity::onBtnDel( void* userdata ) +{ +	LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata; + +	self->mWhiteListList->deleteSelectedItems(); +} +  ////////////////////////////////////////////////////////////////////////////////  //  void LLPanelMediaSettingsSecurity::setParent( LLFloaterMediaSettings* parent ) diff --git a/indra/newview/llpanelmediasettingssecurity.h b/indra/newview/llpanelmediasettingssecurity.h index b78ee92193..2555bb8dc8 100644 --- a/indra/newview/llpanelmediasettingssecurity.h +++ b/indra/newview/llpanelmediasettingssecurity.h @@ -55,7 +55,7 @@ class LLPanelMediaSettingsSecurity : public LLPanel  		void addWhiteListItem(const std::string& url);  		void setParent( LLFloaterMediaSettings* parent );  		const std::string makeValidUrl( const std::string& src_url ); -		bool passesWhiteList( const std::string& added_url, const std::string& test_url );
 +		bool passesWhiteList( const std::string& added_url, const std::string& test_url );  	protected:  		LLFloaterMediaSettings* mParent; diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 365a6e632f..63fad7ddfd 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -1,1905 +1,1913 @@ -/**
 - * @file llsidepanelinventory.cpp
 - * @brief LLPanelObjectInventory class implementation
 - *
 - * $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$
 - */
 -
 -//*****************************************************************************
 -//
 -// Implementation of the panel inventory - used to view and control a
 -// task's inventory.
 -//
 -//*****************************************************************************
 -
 -#include "llviewerprecompiledheaders.h"
 -
 -#include "llpanelobjectinventory.h"
 -
 -#include "roles_constants.h"
 -
 -#include "llagent.h"
 -#include "llcallbacklist.h"
 -#include "llfloaterbuycurrency.h"
 -#include "llfloaterreg.h"
 -#include "llinventorybridge.h"
 -#include "llinventoryfunctions.h"
 -#include "llpreviewanim.h"
 -#include "llpreviewgesture.h"
 -#include "llpreviewnotecard.h"
 -#include "llpreviewscript.h"
 -#include "llpreviewsound.h"
 -#include "llpreviewtexture.h"
 -#include "llscrollcontainer.h"
 -#include "llselectmgr.h"
 -#include "llstatusbar.h"
 -#include "lltrans.h"
 -#include "llviewerregion.h"
 -#include "llviewerobjectlist.h"
 -#include "llviewermessage.h"
 -
 -
 -///----------------------------------------------------------------------------
 -/// Class LLTaskInvFVBridge
 -///----------------------------------------------------------------------------
 -
 -class LLTaskInvFVBridge : public LLFolderViewEventListener
 -{
 -protected:
 -	LLUUID mUUID;
 -	std::string mName;
 -	mutable std::string mDisplayName;
 -	LLPanelObjectInventory* mPanel;
 -	U32 mFlags;
 -
 -	LLInventoryItem* findItem() const;
 -
 -public:
 -	LLTaskInvFVBridge(
 -		LLPanelObjectInventory* panel,
 -		const LLUUID& uuid,
 -		const std::string& name,
 -		U32 flags=0);
 -	virtual ~LLTaskInvFVBridge( void ) {}
 -
 -	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
 -	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
 -
 -	static LLTaskInvFVBridge* createObjectBridge(LLPanelObjectInventory* panel,
 -												 LLInventoryObject* object);
 -	void showProperties();
 -	void buyItem();
 -	S32 getPrice();
 -	static bool commitBuyItem(const LLSD& notification, const LLSD& response);
 -
 -	// LLFolderViewEventListener functionality
 -	virtual const std::string& getName() const;
 -	virtual const std::string& getDisplayName() const;
 -	virtual PermissionMask getPermissionMask() const { return PERM_NONE; }
 -	/*virtual*/ LLAssetType::EType getPreferredType() const { return LLAssetType::AT_NONE; }
 -	virtual const LLUUID& getUUID() const { return mUUID; }
 -	virtual time_t getCreationDate() const;
 -	virtual LLUIImagePtr getIcon() const;
 -	virtual void openItem();
 -	virtual void closeItem() {}
 -	virtual void previewItem();
 -	virtual void selectItem() {}
 -	virtual BOOL isItemRenameable() const;
 -	virtual BOOL renameItem(const std::string& new_name);
 -	virtual BOOL isItemMovable() const;
 -	virtual BOOL isItemRemovable();
 -	virtual BOOL removeItem();
 -	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
 -	virtual void move(LLFolderViewEventListener* parent_listener);
 -	virtual BOOL isItemCopyable() const;
 -	virtual BOOL copyToClipboard() const;
 -	virtual void cutToClipboard();
 -	virtual BOOL isClipboardPasteable() const;
 -	virtual void pasteFromClipboard();
 -	virtual void pasteLinkFromClipboard();
 -	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
 -	virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
 -	virtual BOOL isUpToDate() const { return TRUE; }
 -	virtual BOOL hasChildren() const { return FALSE; }
 -	virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
 -	// LLDragAndDropBridge functionality
 -	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
 -	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 -							EDragAndDropType cargo_type,
 -							void* cargo_data);
 -};
 -
 -LLTaskInvFVBridge::LLTaskInvFVBridge(
 -	LLPanelObjectInventory* panel,
 -	const LLUUID& uuid,
 -	const std::string& name,
 -	U32 flags):
 -	mUUID(uuid),
 -	mName(name),
 -	mPanel(panel),
 -	mFlags(flags)
 -{
 -
 -}
 -
 -LLInventoryItem* LLTaskInvFVBridge::findItem() const
 -{
 -	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 -	if(object)
 -	{
 -		return (LLInventoryItem*)(object->getInventoryObject(mUUID));
 -	}
 -	return NULL;
 -}
 -
 -void LLTaskInvFVBridge::showProperties()
 -{
 -	LLFloaterProperties* floater = LLFloaterReg::showTypedInstance<LLFloaterProperties>("properties", mUUID);
 -	if (floater)
 -	{
 -		floater->setObjectID(mPanel->getTaskUUID());
 -	}
 -}
 -
 -struct LLBuyInvItemData
 -{
 -	LLUUID mTaskID;
 -	LLUUID mItemID;
 -	LLAssetType::EType mType;
 -
 -	LLBuyInvItemData(const LLUUID& task,
 -					 const LLUUID& item,
 -					 LLAssetType::EType type) :
 -		mTaskID(task), mItemID(item), mType(type)
 -	{}
 -};
 -
 -void LLTaskInvFVBridge::buyItem()
 -{
 -	llinfos << "LLTaskInvFVBridge::buyItem()" << llendl;
 -	LLInventoryItem* item = findItem();
 -	if(!item || !item->getSaleInfo().isForSale()) return;
 -	LLBuyInvItemData* inv = new LLBuyInvItemData(mPanel->getTaskUUID(),
 -												 mUUID,
 -												 item->getType());
 -
 -	const LLSaleInfo& sale_info = item->getSaleInfo();
 -	const LLPermissions& perm = item->getPermissions();
 -	const std::string owner_name; // no owner name currently... FIXME?
 -
 -	LLViewerObject* obj;
 -	if( ( obj = gObjectList.findObject( mPanel->getTaskUUID() ) ) && obj->isAttachment() )
 -	{
 -		LLNotifications::instance().add("Cannot_Purchase_an_Attachment");
 -		llinfos << "Attempt to purchase an attachment" << llendl;
 -		delete inv;
 -	}
 -	else
 -	{
 -        LLSD args;
 -        args["PRICE"] = llformat("%d",sale_info.getSalePrice());
 -        args["OWNER"] = owner_name;
 -        if (sale_info.getSaleType() != LLSaleInfo::FS_CONTENTS)
 -        {
 -        	U32 next_owner_mask = perm.getMaskNextOwner();
 -        	args["MODIFYPERM"] = LLNotifications::instance().getGlobalString((next_owner_mask & PERM_MODIFY) ? "PermYes" : "PermNo");
 -        	args["COPYPERM"] = LLNotifications::instance().getGlobalString((next_owner_mask & PERM_COPY) ? "PermYes" : "PermNo");
 -        	args["RESELLPERM"] = LLNotifications::instance().getGlobalString((next_owner_mask & PERM_TRANSFER) ? "PermYes" : "PermNo");
 -        }
 -
 -		std::string alertdesc;
 -       	switch(sale_info.getSaleType())
 -       	{
 -       	  case LLSaleInfo::FS_ORIGINAL:
 -       		alertdesc = owner_name.empty() ? "BuyOriginalNoOwner" : "BuyOriginal";
 -       		break;
 -       	  case LLSaleInfo::FS_CONTENTS:
 -       		alertdesc = owner_name.empty() ? "BuyContentsNoOwner" : "BuyContents";
 -       		break;
 -		  case LLSaleInfo::FS_COPY:
 -       	  default:
 -       		alertdesc = owner_name.empty() ? "BuyCopyNoOwner" : "BuyCopy";
 -       		break;
 -       	}
 -
 -		LLSD payload;
 -		payload["task_id"] = inv->mTaskID;
 -		payload["item_id"] = inv->mItemID;
 -		payload["type"] = inv->mType;
 -		LLNotifications::instance().add(alertdesc, args, payload, LLTaskInvFVBridge::commitBuyItem);
 -	}
 -}
 -
 -S32 LLTaskInvFVBridge::getPrice()
 -{
 -	LLInventoryItem* item = findItem();
 -	if(item)
 -	{
 -		return item->getSaleInfo().getSalePrice();
 -	}
 -	else
 -	{
 -		return -1;
 -	}
 -}
 -
 -// static
 -bool LLTaskInvFVBridge::commitBuyItem(const LLSD& notification, const LLSD& response)
 -{
 -	S32 option = LLNotification::getSelectedOption(notification, response);
 -	if(0 == option)
 -	{
 -		LLViewerObject* object = gObjectList.findObject(notification["payload"]["task_id"].asUUID());
 -		if(!object || !object->getRegion()) return false;
 -
 -
 -		LLMessageSystem* msg = gMessageSystem;
 -		msg->newMessageFast(_PREHASH_BuyObjectInventory);
 -		msg->nextBlockFast(_PREHASH_AgentData);
 -		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 -		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 -		msg->nextBlockFast(_PREHASH_Data);
 -		msg->addUUIDFast(_PREHASH_ObjectID, notification["payload"]["task_id"].asUUID());
 -		msg->addUUIDFast(_PREHASH_ItemID, notification["payload"]["item_id"].asUUID());
 -		msg->addUUIDFast(_PREHASH_FolderID,
 -			gInventory.findCategoryUUIDForType((LLAssetType::EType)notification["payload"]["type"].asInteger()));
 -		msg->sendReliable(object->getRegion()->getHost());
 -	}
 -	return false;
 -}
 -
 -const std::string& LLTaskInvFVBridge::getName() const
 -{
 -	return mName;
 -}
 -
 -const std::string& LLTaskInvFVBridge::getDisplayName() const
 -{
 -	LLInventoryItem* item = findItem();
 -	if(item)
 -	{
 -		mDisplayName.assign(item->getName());
 -
 -		const LLPermissions& perm(item->getPermissions());
 -		BOOL copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE);
 -		BOOL mod  = gAgent.allowOperation(PERM_MODIFY, perm, GP_OBJECT_MANIPULATE);
 -		BOOL xfer = gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE);
 -
 -		if(!copy)
 -		{
 -			mDisplayName.append(" (no copy)");
 -		}
 -		if(!mod)
 -		{
 -			mDisplayName.append(" (no modify)");
 -		}
 -		if(!xfer)
 -		{
 -			mDisplayName.append(" (no transfer)");
 -		}
 -	}
 -
 -	return mDisplayName;
 -}
 -
 -// BUG: No creation dates for task inventory
 -time_t LLTaskInvFVBridge::getCreationDate() const
 -{
 -	return 0;
 -}
 -
 -LLUIImagePtr LLTaskInvFVBridge::getIcon() const
 -{
 -	BOOL item_is_multi = FALSE;
 -	if ( mFlags & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS )
 -	{
 -		item_is_multi = TRUE;
 -	}
 -
 -	return get_item_icon(LLAssetType::AT_OBJECT, LLInventoryType::IT_OBJECT, 0, item_is_multi );
 -}
 -
 -void LLTaskInvFVBridge::openItem()
 -{
 -	// no-op.
 -	lldebugs << "LLTaskInvFVBridge::openItem()" << llendl;
 -}
 -
 -void LLTaskInvFVBridge::previewItem()
 -{
 -	openItem();
 -}
 -
 -BOOL LLTaskInvFVBridge::isItemRenameable() const
 -{
 -	if(gAgent.isGodlike()) return TRUE;
 -	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 -	if(object)
 -	{
 -		LLInventoryItem* item;
 -		item = (LLInventoryItem*)(object->getInventoryObject(mUUID));
 -		if(item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
 -										 GP_OBJECT_MANIPULATE, GOD_LIKE))
 -		{
 -			return TRUE;
 -		}
 -	}
 -	return FALSE;
 -}
 -
 -BOOL LLTaskInvFVBridge::renameItem(const std::string& new_name)
 -{
 -	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 -	if(object)
 -	{
 -		LLViewerInventoryItem* item = NULL;
 -		item = (LLViewerInventoryItem*)object->getInventoryObject(mUUID);
 -		if(item && (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
 -										GP_OBJECT_MANIPULATE, GOD_LIKE)))
 -		{
 -			LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
 -			new_item->rename(new_name);
 -			object->updateInventory(
 -				new_item,
 -				TASK_INVENTORY_ITEM_KEY,
 -				false);
 -		}
 -	}
 -	return TRUE;
 -}
 -
 -BOOL LLTaskInvFVBridge::isItemMovable() const
 -{
 -	//LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 -	//if(object && (object->permModify() || gAgent.isGodlike()))
 -	//{
 -	//	return TRUE;
 -	//}
 -	//return FALSE;
 -	return TRUE;
 -}
 -
 -BOOL LLTaskInvFVBridge::isItemRemovable()
 -{
 -	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 -	if(object
 -	   && (object->permModify() || object->permYouOwner()))
 -	{
 -		return TRUE;
 -	}
 -	return FALSE;
 -}
 -
 -bool remove_task_inventory_callback(const LLSD& notification, const LLSD& response, LLPanelObjectInventory* panel)
 -{
 -	S32 option = LLNotification::getSelectedOption(notification, response);
 -	LLViewerObject* object = gObjectList.findObject(notification["payload"]["task_id"].asUUID());
 -	if(option == 0 && object)
 -	{
 -		// yes
 -		LLSD::array_const_iterator list_end = notification["payload"]["inventory_ids"].endArray();
 -		for (LLSD::array_const_iterator list_it = notification["payload"]["inventory_ids"].beginArray();
 -			list_it != list_end; 
 -			++list_it)
 -		{
 -			object->removeInventory(list_it->asUUID());
 -		}
 -
 -		// refresh the UI.
 -		panel->refresh();
 -	}
 -	return false;
 -}
 -
 -// helper for remove
 -// ! REFACTOR ! two_uuids_list_t is also defined in llinevntorybridge.h, but differently.
 -typedef std::pair<LLUUID, std::list<LLUUID> > panel_two_uuids_list_t;
 -typedef std::pair<LLPanelObjectInventory*, panel_two_uuids_list_t> remove_data_t;
 -BOOL LLTaskInvFVBridge::removeItem()
 -{
 -	if(isItemRemovable() && mPanel)
 -	{
 -		LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 -		if(object)
 -		{
 -			if(object->permModify())
 -			{
 -				// just do it.
 -				object->removeInventory(mUUID);
 -				return TRUE;
 -			}
 -			else
 -			{
 -				remove_data_t* data = new remove_data_t;
 -				data->first = mPanel;
 -				data->second.first = mPanel->getTaskUUID();
 -				data->second.second.push_back(mUUID);
 -				LLSD payload;
 -				payload["task_id"] = mPanel->getTaskUUID();
 -				payload["inventory_ids"].append(mUUID);
 -				LLNotifications::instance().add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel));
 -				return FALSE;
 -			}
 -		}
 -	}
 -	return FALSE;
 -}
 -
 -void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
 -{
 -	if (!mPanel)
 -	{
 -		return;
 -	}
 -
 -	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 -	if (!object)
 -	{
 -		return;
 -	}
 -
 -	if (!object->permModify())
 -	{
 -		LLSD payload;
 -		payload["task_id"] = mPanel->getTaskUUID();
 -		for (S32 i = 0; i < (S32)batch.size(); i++)
 -		{
 -			LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i];
 -			payload["inventory_ids"].append(itemp->getUUID());
 -		}
 -		LLNotifications::instance().add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel));
 -		
 -	}
 -	else
 -	{
 -		for (S32 i = 0; i < (S32)batch.size(); i++)
 -		{
 -			LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i];
 -
 -			if(itemp->isItemRemovable())
 -			{
 -				// just do it.
 -				object->removeInventory(itemp->getUUID());
 -			}
 -		}
 -	}
 -}
 -
 -void LLTaskInvFVBridge::move(LLFolderViewEventListener* parent_listener)
 -{
 -}
 -
 -BOOL LLTaskInvFVBridge::isItemCopyable() const
 -{
 -	LLInventoryItem* item = findItem();
 -	if(!item) return FALSE;
 -	return gAgent.allowOperation(PERM_COPY, item->getPermissions(),
 -								GP_OBJECT_MANIPULATE);
 -}
 -
 -BOOL LLTaskInvFVBridge::copyToClipboard() const
 -{
 -	return FALSE;
 -}
 -
 -void LLTaskInvFVBridge::cutToClipboard()
 -{
 -}
 -
 -BOOL LLTaskInvFVBridge::isClipboardPasteable() const
 -{
 -	return FALSE;
 -}
 -
 -void LLTaskInvFVBridge::pasteFromClipboard()
 -{
 -}
 -
 -void LLTaskInvFVBridge::pasteLinkFromClipboard()
 -{
 -}
 -
 -BOOL LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
 -{
 -	//llinfos << "LLTaskInvFVBridge::startDrag()" << llendl;
 -	if(mPanel)
 -	{
 -		LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 -		if(object)
 -		{
 -			LLInventoryItem* inv = NULL;
 -			if((inv = (LLInventoryItem*)object->getInventoryObject(mUUID)))
 -			{
 -				const LLPermissions& perm = inv->getPermissions();
 -				bool can_copy = gAgent.allowOperation(PERM_COPY, perm,
 -														GP_OBJECT_MANIPULATE);
 -				if (object->isAttachment() && !can_copy)
 -				{
 -                    //RN: no copy contents of attachments cannot be dragged out
 -                    // due to a race condition and possible exploit where
 -                    // attached objects do not update their inventory items
 -                    // when their contents are manipulated
 -                    return FALSE;
 -				}
 -				if((can_copy && perm.allowTransferTo(gAgent.getID()))
 -				   || object->permYouOwner())
 -//				   || gAgent.isGodlike())
 -
 -				{
 -					*type = LLAssetType::lookupDragAndDropType(inv->getType());
 -
 -					*id = inv->getUUID();
 -					return TRUE;
 -				}
 -			}
 -		}
 -	}
 -	return FALSE;
 -}
 -
 -BOOL LLTaskInvFVBridge::dragOrDrop(MASK mask, BOOL drop,
 -								   EDragAndDropType cargo_type,
 -								   void* cargo_data)
 -{
 -	//llinfos << "LLTaskInvFVBridge::dragOrDrop()" << llendl;
 -	return FALSE;
 -}
 -
 -// virtual
 -void LLTaskInvFVBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
 -{
 -	if (action == "task_buy")
 -	{
 -		// Check the price of the item.
 -		S32 price = getPrice();
 -		if (-1 == price)
 -		{
 -			llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
 -		}
 -		else
 -		{
 -			if (price > 0 && price > gStatusBar->getBalance())
 -			{
 -				LLFloaterBuyCurrency::buyCurrency("This costs", price);
 -			}
 -			else
 -			{
 -				buyItem();
 -			}
 -		}
 -	}
 -	else if (action == "task_open")
 -	{
 -		openItem();
 -	}
 -	else if (action == "task_properties")
 -	{
 -		showProperties();
 -	}
 -}
 -
 -void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 -{
 -	LLInventoryItem* item = findItem();
 -	std::vector<std::string> items;
 -	std::vector<std::string> disabled_items;
 -	
 -	if (!item)
 -	{
 -		hide_context_entries(menu, items, disabled_items);
 -		return;
 -	}
 -
 -	if(gAgent.allowOperation(PERM_OWNER, item->getPermissions(),
 -							 GP_OBJECT_MANIPULATE)
 -	   && item->getSaleInfo().isForSale())
 -	{
 -		items.push_back(std::string("Task Buy"));
 -
 -		std::string label= LLTrans::getString("Buy");
 -		// Check the price of the item.
 -		S32 price = getPrice();
 -		if (-1 == price)
 -		{
 -			llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
 -		}
 -		else
 -		{
 -			std::ostringstream info;
 -			info << LLTrans::getString("BuyforL$") << price;
 -			label.assign(info.str());
 -		}
 -
 -		const LLView::child_list_t *list = menu.getChildList();
 -		LLView::child_list_t::const_iterator itor;
 -		for (itor = list->begin(); itor != list->end(); ++itor)
 -		{
 -			std::string name = (*itor)->getName();
 -			LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor);
 -			if (name == "Task Buy" && menu_itemp)
 -			{
 -				menu_itemp->setLabel(label);
 -			}
 -		}
 -	}
 -	else
 -	{
 -		items.push_back(std::string("Task Open"));
 -		if (!isItemCopyable())
 -		{
 -			disabled_items.push_back(std::string("Task Open"));
 -		}
 -	}
 -	items.push_back(std::string("Task Properties"));
 -	if(isItemRenameable())
 -	{
 -		items.push_back(std::string("Task Rename"));
 -	}
 -	if(isItemRemovable())
 -	{
 -		items.push_back(std::string("Task Remove"));
 -	}
 -
 -	hide_context_entries(menu, items, disabled_items);
 -}
 -
 -
 -///----------------------------------------------------------------------------
 -/// Class LLTaskFolderBridge
 -///----------------------------------------------------------------------------
 -
 -class LLTaskCategoryBridge : public LLTaskInvFVBridge
 -{
 -public:
 -	LLTaskCategoryBridge(
 -		LLPanelObjectInventory* panel,
 -		const LLUUID& uuid,
 -		const std::string& name);
 -
 -	virtual LLUIImagePtr getIcon() const;
 -	virtual const std::string& getDisplayName() const { return getName(); }
 -	virtual BOOL isItemRenameable() const;
 -	virtual BOOL renameItem(const std::string& new_name);
 -	virtual BOOL isItemRemovable();
 -	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
 -	virtual BOOL hasChildren() const;
 -	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
 -	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 -							EDragAndDropType cargo_type,
 -							void* cargo_data);
 -};
 -
 -LLTaskCategoryBridge::LLTaskCategoryBridge(
 -	LLPanelObjectInventory* panel,
 -	const LLUUID& uuid,
 -	const std::string& name) :
 -	LLTaskInvFVBridge(panel, uuid, name)
 -{
 -}
 -
 -LLUIImagePtr LLTaskCategoryBridge::getIcon() const
 -{
 -	return LLUI::getUIImage("Inv_FolderClosed");
 -}
 -
 -BOOL LLTaskCategoryBridge::isItemRenameable() const
 -{
 -	return FALSE;
 -}
 -
 -BOOL LLTaskCategoryBridge::renameItem(const std::string& new_name)
 -{
 -	return FALSE;
 -}
 -
 -BOOL LLTaskCategoryBridge::isItemRemovable()
 -{
 -	return FALSE;
 -}
 -
 -void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 -{
 -	std::vector<std::string> items;
 -	std::vector<std::string> disabled_items;
 -	items.push_back(std::string("Task Open"));
 -	hide_context_entries(menu, items, disabled_items);
 -}
 -
 -BOOL LLTaskCategoryBridge::hasChildren() const
 -{
 -	// return TRUE if we have or do know know if we have children.
 -	// *FIX: For now, return FALSE - we will know for sure soon enough.
 -	return FALSE;
 -}
 -
 -BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
 -{
 -	//llinfos << "LLTaskInvFVBridge::startDrag()" << llendl;
 -	if(mPanel)
 -	{
 -		LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 -		if(object)
 -		{
 -			LLInventoryItem* inv = NULL;
 -			if((inv = (LLInventoryItem*)object->getInventoryObject(mUUID)))
 -			{
 -				const LLPermissions& perm = inv->getPermissions();
 -				bool can_copy = gAgent.allowOperation(PERM_COPY, perm,
 -														GP_OBJECT_MANIPULATE);
 -				if((can_copy && perm.allowTransferTo(gAgent.getID()))
 -				   || object->permYouOwner())
 -//				   || gAgent.isGodlike())
 -
 -				{
 -					*type = LLAssetType::lookupDragAndDropType(inv->getType());
 -
 -					*id = inv->getUUID();
 -					return TRUE;
 -				}
 -			}
 -		}
 -	}
 -	return FALSE;
 -}
 -
 -BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop,
 -									  EDragAndDropType cargo_type,
 -									  void* cargo_data)
 -{
 -	//llinfos << "LLTaskCategoryBridge::dragOrDrop()" << llendl;
 -	BOOL accept = FALSE;
 -	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 -	if(object)
 -	{
 -		switch(cargo_type)
 -		{
 -		case DAD_CATEGORY:
 -			accept = LLToolDragAndDrop::getInstance()->dadUpdateInventoryCategory(object,drop);
 -			break;
 -		case DAD_TEXTURE:
 -		case DAD_SOUND:
 -		case DAD_LANDMARK:
 -		case DAD_OBJECT:
 -		case DAD_NOTECARD:
 -		case DAD_CLOTHING:
 -		case DAD_BODYPART:
 -		case DAD_ANIMATION:
 -		case DAD_GESTURE:
 -		case DAD_CALLINGCARD:
 -			accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
 -			if(accept && drop)
 -			{
 -				LLToolDragAndDrop::dropInventory(object,
 -												 (LLViewerInventoryItem*)cargo_data,
 -												 LLToolDragAndDrop::getInstance()->getSource(),
 -												 LLToolDragAndDrop::getInstance()->getSourceID());
 -			}
 -			break;
 -		case DAD_SCRIPT:
 -			// *HACK: In order to resolve SL-22177, we need to block
 -			// drags from notecards and objects onto other
 -			// objects. uncomment the simpler version when we have
 -			// that right.
 -			//accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
 -			if(LLToolDragAndDrop::isInventoryDropAcceptable(
 -				   object, (LLViewerInventoryItem*)cargo_data)
 -			   && (LLToolDragAndDrop::SOURCE_WORLD != LLToolDragAndDrop::getInstance()->getSource())
 -			   && (LLToolDragAndDrop::SOURCE_NOTECARD != LLToolDragAndDrop::getInstance()->getSource()))
 -			{
 -				accept = TRUE;
 -			}
 -			if(accept && drop)
 -			{
 -				LLViewerInventoryItem* item = (LLViewerInventoryItem*)cargo_data;
 -				// rez in the script active by default, rez in
 -				// inactive if the control key is being held down.
 -				BOOL active = ((mask & MASK_CONTROL) == 0);
 -				LLToolDragAndDrop::dropScript(object, item, active,
 -											  LLToolDragAndDrop::getInstance()->getSource(),
 -											  LLToolDragAndDrop::getInstance()->getSourceID());
 -			}
 -			break;
 -		default:
 -			break;
 -		}
 -	}
 -	return accept;
 -}
 -
 -///----------------------------------------------------------------------------
 -/// Class LLTaskTextureBridge
 -///----------------------------------------------------------------------------
 -
 -class LLTaskTextureBridge : public LLTaskInvFVBridge
 -{
 -public:
 -	LLTaskTextureBridge(
 -		LLPanelObjectInventory* panel,
 -		const LLUUID& uuid,
 -		const std::string& name,
 -		LLInventoryType::EType it);
 -
 -	virtual LLUIImagePtr getIcon() const;
 -	virtual void openItem();
 -protected:
 -	LLInventoryType::EType mInventoryType;
 -};
 -
 -LLTaskTextureBridge::LLTaskTextureBridge(
 -	LLPanelObjectInventory* panel,
 -	const LLUUID& uuid,
 -	const std::string& name,
 -	LLInventoryType::EType it) :
 -	LLTaskInvFVBridge(panel, uuid, name),
 -	mInventoryType(it)
 -{
 -}
 -
 -LLUIImagePtr LLTaskTextureBridge::getIcon() const
 -{
 -	return get_item_icon(LLAssetType::AT_TEXTURE, mInventoryType, 0, FALSE);
 -}
 -
 -void LLTaskTextureBridge::openItem()
 -{
 -	llinfos << "LLTaskTextureBridge::openItem()" << llendl;
 -	LLPreviewTexture* preview = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES);
 -	if(preview)
 -	{
 -		preview->setObjectID(mPanel->getTaskUUID());
 -	}
 -}
 -
 -
 -///----------------------------------------------------------------------------
 -/// Class LLTaskSoundBridge
 -///----------------------------------------------------------------------------
 -
 -class LLTaskSoundBridge : public LLTaskInvFVBridge
 -{
 -public:
 -	LLTaskSoundBridge(
 -		LLPanelObjectInventory* panel,
 -		const LLUUID& uuid,
 -		const std::string& name);
 -
 -	virtual LLUIImagePtr getIcon() const;
 -	virtual void openItem();
 -	virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
 -	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
 -	static void openSoundPreview(void* data);
 -};
 -
 -LLTaskSoundBridge::LLTaskSoundBridge(
 -	LLPanelObjectInventory* panel,
 -	const LLUUID& uuid,
 -	const std::string& name) :
 -	LLTaskInvFVBridge(panel, uuid, name)
 -{
 -}
 -
 -LLUIImagePtr LLTaskSoundBridge::getIcon() const
 -{
 -	return get_item_icon(LLAssetType::AT_SOUND, LLInventoryType::IT_SOUND, 0, FALSE);
 -}
 -
 -void LLTaskSoundBridge::openItem()
 -{
 -	openSoundPreview((void*)this);
 -}
 -
 -void LLTaskSoundBridge::openSoundPreview(void* data)
 -{
 -	LLTaskSoundBridge* self = (LLTaskSoundBridge*)data;
 -	if(!self)
 -		return;
 -
 -	LLPreviewSound* preview = LLFloaterReg::showTypedInstance<LLPreviewSound>("preview_sound", LLSD(self->mUUID), TAKE_FOCUS_YES);
 -	if (preview)
 -	{
 -		preview->setObjectID(self->mPanel->getTaskUUID());
 -	}
 -}
 -
 -// virtual
 -void LLTaskSoundBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
 -{
 -	if (action == "task_play")
 -	{
 -		LLInventoryItem* item = findItem();
 -		if(item)
 -		{
 -			send_sound_trigger(item->getAssetUUID(), 1.0);
 -		}
 -	}
 -	LLTaskInvFVBridge::performAction(folder, model, action);
 -}
 -
 -void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 -{
 -	LLInventoryItem* item = findItem();
 -	if(!item) return;
 -	std::vector<std::string> items;
 -	std::vector<std::string> disabled_items;
 -
 -	if(item->getPermissions().getOwner() != gAgent.getID()
 -	   && item->getSaleInfo().isForSale())
 -	{
 -		items.push_back(std::string("Task Buy"));
 -
 -		std::string label= LLTrans::getString("Buy");
 -		// Check the price of the item.
 -		S32 price = getPrice();
 -		if (-1 == price)
 -		{
 -			llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
 -		}
 -		else
 -		{
 -			std::ostringstream info;
 -			info <<  LLTrans::getString("BuyforL$") << price;
 -			label.assign(info.str());
 -		}
 -
 -		const LLView::child_list_t *list = menu.getChildList();
 -		LLView::child_list_t::const_iterator itor;
 -		for (itor = list->begin(); itor != list->end(); ++itor)
 -		{
 -			std::string name = (*itor)->getName();
 -			LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor);
 -			if (name == "Task Buy" && menu_itemp)
 -			{
 -				menu_itemp->setLabel(label);
 -			}
 -		}
 -	}
 -	else
 -	{
 -		items.push_back(std::string("Task Open")); 
 -		if (!isItemCopyable())
 -		{
 -			disabled_items.push_back(std::string("Task Open"));
 -		}
 -	}
 -	items.push_back(std::string("Task Properties"));
 -	if(isItemRenameable())
 -	{
 -		items.push_back(std::string("Task Rename"));
 -	}
 -	if(isItemRemovable())
 -	{
 -		items.push_back(std::string("Task Remove"));
 -	}
 -
 -	items.push_back(std::string("Task Play"));
 -
 -
 -	hide_context_entries(menu, items, disabled_items);
 -}
 -
 -///----------------------------------------------------------------------------
 -/// Class LLTaskLandmarkBridge
 -///----------------------------------------------------------------------------
 -
 -class LLTaskLandmarkBridge : public LLTaskInvFVBridge
 -{
 -public:
 -	LLTaskLandmarkBridge(
 -		LLPanelObjectInventory* panel,
 -		const LLUUID& uuid,
 -		const std::string& name);
 -
 -	virtual LLUIImagePtr getIcon() const;
 -};
 -
 -LLTaskLandmarkBridge::LLTaskLandmarkBridge(
 -	LLPanelObjectInventory* panel,
 -	const LLUUID& uuid,
 -	const std::string& name) :
 -	LLTaskInvFVBridge(panel, uuid, name)
 -{
 -}
 -
 -LLUIImagePtr LLTaskLandmarkBridge::getIcon() const
 -{
 -	return get_item_icon(LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, 0, FALSE);
 -}
 -
 -
 -///----------------------------------------------------------------------------
 -/// Class LLTaskCallingCardBridge
 -///----------------------------------------------------------------------------
 -
 -class LLTaskCallingCardBridge : public LLTaskInvFVBridge
 -{
 -public:
 -	LLTaskCallingCardBridge(
 -		LLPanelObjectInventory* panel,
 -		const LLUUID& uuid,
 -		const std::string& name);
 -
 -	virtual LLUIImagePtr getIcon() const;
 -	virtual BOOL isItemRenameable() const;
 -	virtual BOOL renameItem(const std::string& new_name);
 -};
 -
 -LLTaskCallingCardBridge::LLTaskCallingCardBridge(
 -	LLPanelObjectInventory* panel,
 -	const LLUUID& uuid,
 -	const std::string& name) :
 -	LLTaskInvFVBridge(panel, uuid, name)
 -{
 -}
 -
 -LLUIImagePtr LLTaskCallingCardBridge::getIcon() const
 -{
 -	return get_item_icon(LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, 0, FALSE);
 -}
 -
 -BOOL LLTaskCallingCardBridge::isItemRenameable() const
 -{
 -	return FALSE;
 -}
 -
 -BOOL LLTaskCallingCardBridge::renameItem(const std::string& new_name)
 -{
 -	return FALSE;
 -}
 -
 -
 -///----------------------------------------------------------------------------
 -/// Class LLTaskScriptBridge
 -///----------------------------------------------------------------------------
 -
 -class LLTaskScriptBridge : public LLTaskInvFVBridge
 -{
 -public:
 -	LLTaskScriptBridge(
 -		LLPanelObjectInventory* panel,
 -		const LLUUID& uuid,
 -		const std::string& name);
 -
 -	virtual LLUIImagePtr getIcon() const;
 -	//static BOOL enableIfCopyable( void* userdata );
 -};
 -
 -LLTaskScriptBridge::LLTaskScriptBridge(
 -	LLPanelObjectInventory* panel,
 -	const LLUUID& uuid,
 -	const std::string& name) :
 -	LLTaskInvFVBridge(panel, uuid, name)
 -{
 -}
 -
 -LLUIImagePtr LLTaskScriptBridge::getIcon() const
 -{
 -	return get_item_icon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0, FALSE);
 -}
 -
 -
 -class LLTaskLSLBridge : public LLTaskScriptBridge
 -{
 -public:
 -	LLTaskLSLBridge(
 -		LLPanelObjectInventory* panel,
 -		const LLUUID& uuid,
 -		const std::string& name);
 -
 -	virtual void openItem();
 -	virtual BOOL removeItem();
 -	//virtual void buildContextMenu(LLMenuGL& menu);
 -
 -	//static void copyToInventory(void* userdata);
 -};
 -
 -LLTaskLSLBridge::LLTaskLSLBridge(
 -	LLPanelObjectInventory* panel,
 -	const LLUUID& uuid,
 -	const std::string& name) :
 -	LLTaskScriptBridge(panel, uuid, name)
 -{
 -}
 -
 -void LLTaskLSLBridge::openItem()
 -{
 -	llinfos << "LLTaskLSLBridge::openItem() " << mUUID << llendl;
 -	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 -	if(!object || object->isInventoryPending())
 -	{
 -		return;
 -	}
 -	LLLiveLSLEditor* preview = LLFloaterReg::showTypedInstance<LLLiveLSLEditor>("preview_scriptedit", LLSD(mUUID), TAKE_FOCUS_YES);
 -	if (preview && (object->permModify() || gAgent.isGodlike()))
 -	{
 -		preview->setObjectID(mPanel->getTaskUUID());
 -	}
 -}
 -
 -BOOL LLTaskLSLBridge::removeItem()
 -{
 -	LLFloaterReg::hideInstance("preview_scriptedit", LLSD(mUUID));
 -	return LLTaskInvFVBridge::removeItem();
 -}
 -
 -///----------------------------------------------------------------------------
 -/// Class LLTaskObjectBridge
 -///----------------------------------------------------------------------------
 -
 -class LLTaskObjectBridge : public LLTaskInvFVBridge
 -{
 -public:
 -	LLTaskObjectBridge(
 -		LLPanelObjectInventory* panel,
 -		const LLUUID& uuid,
 -		const std::string& name);
 -
 -	virtual LLUIImagePtr getIcon() const;
 -};
 -
 -LLTaskObjectBridge::LLTaskObjectBridge(
 -	LLPanelObjectInventory* panel,
 -	const LLUUID& uuid,
 -	const std::string& name) :
 -	LLTaskInvFVBridge(panel, uuid, name)
 -{
 -}
 -
 -LLUIImagePtr LLTaskObjectBridge::getIcon() const
 -{
 -	BOOL item_is_multi = FALSE;
 -	if ( mFlags & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS )
 -	{
 -		item_is_multi = TRUE;
 -	}
 -
 -	return get_item_icon(LLAssetType::AT_OBJECT, LLInventoryType::IT_OBJECT, 0, item_is_multi);
 -}
 -
 -///----------------------------------------------------------------------------
 -/// Class LLTaskNotecardBridge
 -///----------------------------------------------------------------------------
 -
 -class LLTaskNotecardBridge : public LLTaskInvFVBridge
 -{
 -public:
 -	LLTaskNotecardBridge(
 -		LLPanelObjectInventory* panel,
 -		const LLUUID& uuid,
 -		const std::string& name);
 -
 -	virtual LLUIImagePtr getIcon() const;
 -	virtual void openItem();
 -	virtual BOOL removeItem();
 -};
 -
 -LLTaskNotecardBridge::LLTaskNotecardBridge(
 -	LLPanelObjectInventory* panel,
 -	const LLUUID& uuid,
 -	const std::string& name) :
 -	LLTaskInvFVBridge(panel, uuid, name)
 -{
 -}
 -
 -LLUIImagePtr LLTaskNotecardBridge::getIcon() const
 -{
 -	return get_item_icon(LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, 0, FALSE);
 -}
 -
 -void LLTaskNotecardBridge::openItem()
 -{
 -	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 -	if(!object || object->isInventoryPending())
 -	{
 -		return;
 -	}
 -	if(object->permModify() || gAgent.isGodlike())
 -	{
 -		LLPreviewNotecard* preview = LLFloaterReg::showTypedInstance<LLPreviewNotecard>("preview_notecard", LLSD(mUUID), TAKE_FOCUS_YES);
 -		if (preview)
 -		{
 -			preview->setObjectID(mPanel->getTaskUUID());
 -		}
 -	}
 -}
 -
 -BOOL LLTaskNotecardBridge::removeItem()
 -{
 -	LLFloaterReg::hideInstance("preview_notecard", LLSD(mUUID));
 -	return LLTaskInvFVBridge::removeItem();
 -}
 -
 -///----------------------------------------------------------------------------
 -/// Class LLTaskGestureBridge
 -///----------------------------------------------------------------------------
 -
 -class LLTaskGestureBridge : public LLTaskInvFVBridge
 -{
 -public:
 -	LLTaskGestureBridge(
 -		LLPanelObjectInventory* panel,
 -		const LLUUID& uuid,
 -		const std::string& name);
 -
 -	virtual LLUIImagePtr getIcon() const;
 -	virtual void openItem();
 -	virtual BOOL removeItem();
 -};
 -
 -LLTaskGestureBridge::LLTaskGestureBridge(
 -	LLPanelObjectInventory* panel,
 -	const LLUUID& uuid,
 -	const std::string& name) :
 -	LLTaskInvFVBridge(panel, uuid, name)
 -{
 -}
 -
 -LLUIImagePtr LLTaskGestureBridge::getIcon() const
 -{
 -	return get_item_icon(LLAssetType::AT_GESTURE, LLInventoryType::IT_GESTURE, 0, FALSE);
 -}
 -
 -void LLTaskGestureBridge::openItem()
 -{
 -	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 -	if(!object || object->isInventoryPending())
 -	{
 -		return;
 -	}
 -	LLPreviewGesture::show(mUUID, mPanel->getTaskUUID());
 -}
 -
 -BOOL LLTaskGestureBridge::removeItem()
 -{
 -	// Don't need to deactivate gesture because gestures inside objects can never be active.
 -	LLFloaterReg::hideInstance("preview_gesture", LLSD(mUUID));
 -	return LLTaskInvFVBridge::removeItem();
 -}
 -
 -///----------------------------------------------------------------------------
 -/// Class LLTaskAnimationBridge
 -///----------------------------------------------------------------------------
 -
 -class LLTaskAnimationBridge : public LLTaskInvFVBridge
 -{
 -public:
 -	LLTaskAnimationBridge(
 -		LLPanelObjectInventory* panel,
 -		const LLUUID& uuid,
 -		const std::string& name);
 -
 -	virtual LLUIImagePtr getIcon() const;
 -	virtual void openItem();
 -	virtual BOOL removeItem();
 -};
 -
 -LLTaskAnimationBridge::LLTaskAnimationBridge(
 -	LLPanelObjectInventory* panel,
 -	const LLUUID& uuid,
 -	const std::string& name) :
 -	LLTaskInvFVBridge(panel, uuid, name)
 -{
 -}
 -
 -LLUIImagePtr LLTaskAnimationBridge::getIcon() const
 -{
 -	return get_item_icon(LLAssetType::AT_ANIMATION, LLInventoryType::IT_ANIMATION, 0, FALSE);
 -}
 -
 -void LLTaskAnimationBridge::openItem()
 -{
 -	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
 -	if(!object || object->isInventoryPending())
 -	{
 -		return;
 -	}
 -
 -	LLPreviewAnim* preview = LLFloaterReg::showTypedInstance<LLPreviewAnim>("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES);
 -	if (preview && (object->permModify() || gAgent.isGodlike()))
 -	{
 -		preview->setObjectID(mPanel->getTaskUUID());
 -	}
 -}
 -
 -BOOL LLTaskAnimationBridge::removeItem()
 -{
 -	LLFloaterReg::hideInstance("preview_anim", LLSD(mUUID));
 -	return LLTaskInvFVBridge::removeItem();
 -}
 -
 -///----------------------------------------------------------------------------
 -/// Class LLTaskWearableBridge
 -///----------------------------------------------------------------------------
 -
 -class LLTaskWearableBridge : public LLTaskInvFVBridge
 -{
 -public:
 -	LLTaskWearableBridge(
 -		LLPanelObjectInventory* panel,
 -		const LLUUID& uuid,
 -		const std::string& name,
 -		LLAssetType::EType asset_type,
 -		U32 flags);
 -
 -	virtual LLUIImagePtr getIcon() const;
 -
 -protected:
 -	LLAssetType::EType		mAssetType;
 -};
 -
 -LLTaskWearableBridge::LLTaskWearableBridge(
 -	LLPanelObjectInventory* panel,
 -	const LLUUID& uuid,
 -	const std::string& name,
 -	LLAssetType::EType asset_type,
 -	U32 flags) :
 -	LLTaskInvFVBridge(panel, uuid, name, flags),
 -	mAssetType( asset_type )
 -{
 -}
 -
 -LLUIImagePtr LLTaskWearableBridge::getIcon() const
 -{
 -	return get_item_icon(mAssetType, LLInventoryType::IT_WEARABLE, mFlags, FALSE );
 -}
 -
 -
 -///----------------------------------------------------------------------------
 -/// LLTaskInvFVBridge impl
 -//----------------------------------------------------------------------------
 -
 -LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory* panel,
 -														 LLInventoryObject* object)
 -{
 -	LLTaskInvFVBridge* new_bridge = NULL;
 -	LLAssetType::EType type = object->getType();
 -	LLInventoryItem* item = NULL;
 -	switch(type)
 -	{
 -	case LLAssetType::AT_TEXTURE:
 -		item = (LLInventoryItem*)object;
 -		new_bridge = new LLTaskTextureBridge(panel,
 -											 object->getUUID(),
 -											 object->getName(),
 -											 item->getInventoryType());
 -		break;
 -	case LLAssetType::AT_SOUND:
 -		new_bridge = new LLTaskSoundBridge(panel,
 -										   object->getUUID(),
 -										   object->getName());
 -		break;
 -	case LLAssetType::AT_LANDMARK:
 -		new_bridge = new LLTaskLandmarkBridge(panel,
 -											  object->getUUID(),
 -											  object->getName());
 -		break;
 -	case LLAssetType::AT_CALLINGCARD:
 -		new_bridge = new LLTaskCallingCardBridge(panel,
 -												 object->getUUID(),
 -												 object->getName());
 -		break;
 -	case LLAssetType::AT_SCRIPT:
 -		// OLD SCRIPTS DEPRECATED - JC
 -		llwarns << "Old script" << llendl;
 -		//new_bridge = new LLTaskOldScriptBridge(panel,
 -		//									   object->getUUID(),
 -		//									   object->getName());
 -		break;
 -	case LLAssetType::AT_OBJECT:
 -		new_bridge = new LLTaskObjectBridge(panel,
 -											object->getUUID(),
 -											object->getName());
 -		break;
 -	case LLAssetType::AT_NOTECARD:
 -		new_bridge = new LLTaskNotecardBridge(panel,
 -											  object->getUUID(),
 -											  object->getName());
 -		break;
 -	case LLAssetType::AT_ANIMATION:
 -		new_bridge = new LLTaskAnimationBridge(panel,
 -											  object->getUUID(),
 -											  object->getName());
 -		break;
 -	case LLAssetType::AT_GESTURE:
 -		new_bridge = new LLTaskGestureBridge(panel,
 -											  object->getUUID(),
 -											  object->getName());
 -		break;
 -	case LLAssetType::AT_CLOTHING:
 -	case LLAssetType::AT_BODYPART:
 -		item = (LLInventoryItem*)object;
 -		new_bridge = new LLTaskWearableBridge(panel,
 -											  object->getUUID(),
 -											  object->getName(),
 -											  type,
 -											  item->getFlags());
 -		break;
 -	case LLAssetType::AT_CATEGORY:
 -	case LLAssetType::AT_FAVORITE:
 -		new_bridge = new LLTaskCategoryBridge(panel,
 -											  object->getUUID(),
 -											  object->getName());
 -		break;
 -	case LLAssetType::AT_LSL_TEXT:
 -		new_bridge = new LLTaskLSLBridge(panel,
 -										 object->getUUID(),
 -										 object->getName());
 -		break;
 -	
 -		break;
 -	default:
 -		llinfos << "Unhandled inventory type (llassetstorage.h): "
 -				<< (S32)type << llendl;
 -		break;
 -	}
 -	return new_bridge;
 -}
 -
 -
 -///----------------------------------------------------------------------------
 -/// Class LLPanelObjectInventory
 -///----------------------------------------------------------------------------
 -
 -static LLDefaultChildRegistry::Register<LLPanelObjectInventory> r("panel_inventory_object");
 -
 -void do_nothing()
 -{
 -}
 -
 -// Default constructor
 -LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Params& p) :
 -	LLPanel(p),
 -	mScroller(NULL),
 -	mFolders(NULL),
 -	mHaveInventory(FALSE),
 -	mIsInventoryEmpty(TRUE),
 -	mInventoryNeedsUpdate(FALSE)
 -{
 -	// Setup context menu callbacks
 -	mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelObjectInventory::doToSelected, this, _2));
 -	mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLAssetType::AT_TRASH));
 -	mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLAssetType::AT_LOST_AND_FOUND));
 -	mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&do_nothing));
 -	mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&do_nothing));
 -	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&do_nothing));
 -}
 -
 -// Destroys the object
 -LLPanelObjectInventory::~LLPanelObjectInventory()
 -{
 -	if (!gIdleCallbacks.deleteFunction(idle, this))
 -	{
 -		llwarns << "LLPanelObjectInventory::~LLPanelObjectInventory() failed to delete callback" << llendl;
 -	}
 -}
 -
 -BOOL LLPanelObjectInventory::postBuild()
 -{
 -	// clear contents and initialize menus, sets up mFolders
 -	reset();
 -
 -	// Register an idle update callback
 -	gIdleCallbacks.addFunction(idle, this);
 -
 -	return TRUE;
 -}
 -
 -void LLPanelObjectInventory::doToSelected(const LLSD& userdata)
 -{
 -	mFolders->doToSelected(&gInventory, userdata);
 -}
 -
 -void LLPanelObjectInventory::clearContents()
 -{
 -	mHaveInventory = FALSE;
 -	mIsInventoryEmpty = TRUE;
 -	if (LLToolDragAndDrop::getInstance() && LLToolDragAndDrop::getInstance()->getSource() == LLToolDragAndDrop::SOURCE_WORLD)
 -	{
 -		LLToolDragAndDrop::getInstance()->endDrag();
 -	}
 -
 -	if( mScroller )
 -	{
 -		// removes mFolders
 -		removeChild( mScroller ); //*TODO: Really shouldn't do this during draw()/refresh()
 -		mScroller->die();
 -		mScroller = NULL;
 -		mFolders = NULL;
 -	}
 -}
 -
 -
 -void LLPanelObjectInventory::reset()
 -{
 -	clearContents();
 -
 -	setBorderVisible(FALSE);
 -	
 -	mCommitCallbackRegistrar.pushScope(); // push local callbacks
 -	
 -	LLRect dummy_rect(0, 1, 1, 0);
 -	LLFolderView::Params p;
 -	p.name = "task inventory";
 -	p.task_id = getTaskUUID();
 -	p.parent_panel = this;
 -	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
 -	// this ensures that we never say "searching..." or "no items found"
 -	mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
 -	mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
 -
 -	LLRect scroller_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
 -	LLScrollContainer::Params scroll_p;
 -	scroll_p.name("task inventory scroller");
 -	scroll_p.rect(scroller_rect);
 -	scroll_p.follows.flags(FOLLOWS_ALL);
 -	mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroll_p);
 -	addChild(mScroller);
 -	mScroller->addChild(mFolders);
 -	
 -	mFolders->setScrollContainer( mScroller );
 -	
 -	mCommitCallbackRegistrar.popScope();
 -}
 -
 -void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object,
 -										InventoryObjectList* inventory,
 -										S32 serial_num,
 -										void* data)
 -{
 -	if(!object) return;
 -
 -	//llinfos << "invetnory arrived: \n"
 -	//		<< " panel UUID: " << panel->mTaskUUID << "\n"
 -	//		<< " task  UUID: " << object->mID << llendl;
 -	if(mTaskUUID == object->mID)
 -	{
 -		mInventoryNeedsUpdate = TRUE;
 -	}
 -
 -	// refresh any properties floaters that are hanging around.
 -	if(inventory)
 -	{
 -		for (InventoryObjectList::const_iterator iter = inventory->begin();
 -			 iter != inventory->end(); )
 -		{
 -			LLInventoryObject* item = *iter++;
 -			LLFloaterProperties* floater = LLFloaterReg::findTypedInstance<LLFloaterProperties>("properites", item->getUUID());
 -			if(floater)
 -			{
 -				floater->refresh();
 -			}
 -		}
 -	}
 -}
 -
 -void LLPanelObjectInventory::updateInventory()
 -{
 -	//llinfos << "inventory arrived: \n"
 -	//		<< " panel UUID: " << panel->mTaskUUID << "\n"
 -	//		<< " task  UUID: " << object->mID << llendl;
 -	// We're still interested in this task's inventory.
 -	std::set<LLUUID> selected_items;
 -	BOOL inventory_has_focus = FALSE;
 -	if (mHaveInventory && mFolders->getNumSelectedDescendants())
 -	{
 -		mFolders->getSelectionList(selected_items);
 -		inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders);
 -	}
 -
 -	reset();
 -
 -	LLViewerObject* objectp = gObjectList.findObject(mTaskUUID);
 -	if (objectp)
 -	{
 -		LLInventoryObject* inventory_root = objectp->getInventoryRoot();
 -		InventoryObjectList contents;
 -		objectp->getInventoryContents(contents);
 -		if (inventory_root)
 -		{
 -			createFolderViews(inventory_root, contents);
 -			mHaveInventory = TRUE;
 -			mIsInventoryEmpty = FALSE;
 -			mFolders->setEnabled(TRUE);
 -		}
 -		else
 -		{
 -			// TODO: create an empty inventory
 -			mIsInventoryEmpty = TRUE;
 -			mHaveInventory = TRUE;
 -		}
 -	}
 -	else
 -	{
 -		// TODO: create an empty inventory
 -		mIsInventoryEmpty = TRUE;
 -		mHaveInventory = TRUE;
 -	}
 -
 -	// restore previous selection
 -	std::set<LLUUID>::iterator selection_it;
 -	BOOL first_item = TRUE;
 -	for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it)
 -	{
 -		LLFolderViewItem* selected_item = mFolders->getItemByID(*selection_it);
 -		if (selected_item)
 -		{
 -			//HACK: "set" first item then "change" each other one to get keyboard focus right
 -			if (first_item)
 -			{
 -				mFolders->setSelection(selected_item, TRUE, inventory_has_focus);
 -				first_item = FALSE;
 -			}
 -			else
 -			{
 -				mFolders->changeSelection(selected_item, TRUE);
 -			}
 -		}
 -	}
 -
 -	mFolders->requestArrange();
 -	mInventoryNeedsUpdate = FALSE;
 -}
 -
 -// *FIX: This is currently a very expensive operation, because we have
 -// to iterate through the inventory one time for each category. This
 -// leads to an N^2 based on the category count. This could be greatly
 -// speeded with an efficient multimap implementation, but we don't
 -// have that in our current arsenal.
 -void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root, InventoryObjectList& contents)
 -{
 -	if (!inventory_root)
 -	{
 -		return;
 -	}
 -	// Create a visible root category.
 -	LLTaskInvFVBridge* bridge = NULL;
 -	bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root);
 -	if(bridge)
 -	{
 -		LLFolderViewFolder* new_folder = NULL;
 -		LLFolderViewFolder::Params p;
 -		p.name = inventory_root->getName();
 -		p.icon = LLUI::getUIImage("Inv_FolderClosed");
 -		p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
 -		p.root = mFolders;
 -		p.listener = bridge;
 -		new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
 -		new_folder->addToFolder(mFolders, mFolders);
 -		new_folder->toggleOpen();
 -
 -		createViewsForCategory(&contents, inventory_root, new_folder);
 -	}
 -}
 -
 -typedef std::pair<LLInventoryObject*, LLFolderViewFolder*> obj_folder_pair;
 -
 -void LLPanelObjectInventory::createViewsForCategory(InventoryObjectList* inventory, 
 -											  LLInventoryObject* parent,
 -											  LLFolderViewFolder* folder)
 -{
 -	// Find all in the first pass
 -	LLDynamicArray<obj_folder_pair*> child_categories;
 -	LLTaskInvFVBridge* bridge;
 -	LLFolderViewItem* view;
 -
 -	InventoryObjectList::iterator it = inventory->begin();
 -	InventoryObjectList::iterator end = inventory->end();
 -	for( ; it != end; ++it)
 -	{
 -		LLInventoryObject* obj = *it;
 -
 -		if(parent->getUUID() == obj->getParentUUID())
 -		{
 -			bridge = LLTaskInvFVBridge::createObjectBridge(this, obj);
 -			if(!bridge)
 -			{
 -				continue;
 -			}
 -			if(LLAssetType::AT_CATEGORY == obj->getType())
 -			{
 -				LLFolderViewFolder::Params p;
 -				p.name = obj->getName();
 -				p.icon = LLUI::getUIImage("Inv_FolderClosed");
 -				p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
 -				p.root = mFolders;
 -				p.listener = bridge;
 -				view = LLUICtrlFactory::create<LLFolderViewFolder>(p);
 -				child_categories.put(new obj_folder_pair(obj,
 -														 (LLFolderViewFolder*)view));
 -			}
 -			else
 -			{
 -				LLFolderViewItem::Params params;
 -				params.name(obj->getName());
 -				params.icon(bridge->getIcon());
 -				params.creation_date(bridge->getCreationDate());
 -				params.root(mFolders);
 -				params.listener(bridge);
 -				params.rect(LLRect());
 -				view = LLUICtrlFactory::create<LLFolderViewItem> (params);
 -			}
 -			view->addToFolder(folder, mFolders);
 -		}
 -	}
 -
 -	// now, for each category, do the second pass
 -	for(S32 i = 0; i < child_categories.count(); i++)
 -	{
 -		createViewsForCategory(inventory, child_categories[i]->first,
 -							   child_categories[i]->second );
 -		delete child_categories[i];
 -	}
 -}
 -
 -void LLPanelObjectInventory::refresh()
 -{
 -	//llinfos << "LLPanelObjectInventory::refresh()" << llendl;
 -	BOOL has_inventory = FALSE;
 -	const BOOL non_root_ok = TRUE;
 -	LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(NULL, non_root_ok);
 -	if(node)
 -	{
 -		LLViewerObject* object = node->getObject();
 -		if(object && ((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1)
 -					  || (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)))
 -		{
 -			// determine if we need to make a request. Start with a
 -			// default based on if we have inventory at all.
 -			BOOL make_request = !mHaveInventory;
 -
 -			// If the task id is different than what we've stored,
 -			// then make the request.
 -			if(mTaskUUID != object->mID)
 -			{
 -				mTaskUUID = object->mID;
 -				make_request = TRUE;
 -
 -				// This is a new object so pre-emptively clear the contents
 -				// Otherwise we show the old stuff until the update comes in
 -				clearContents();
 -
 -				// Register for updates from this object,
 -				registerVOInventoryListener(object,NULL);
 -			}
 -
 -			// Based on the node information, we may need to dirty the
 -			// object inventory and get it again.
 -			if(node->mValid)
 -			{
 -				if(node->mInventorySerial != object->getInventorySerial() || object->isInventoryDirty())
 -				{
 -					make_request = TRUE;
 -				}
 -			}
 -
 -			// do the request if necessary.
 -			if(make_request)
 -			{
 -				requestVOInventory();
 -			}
 -			has_inventory = TRUE;
 -		}
 -	}
 -	if(!has_inventory)
 -	{
 -		mTaskUUID = LLUUID::null;
 -		removeVOInventoryListener();
 -		clearContents();
 -	}
 -	//llinfos << "LLPanelObjectInventory::refresh() " << mTaskUUID << llendl;
 -}
 -
 -void LLPanelObjectInventory::removeSelectedItem()
 -{
 -	if(mFolders)
 -	{
 -		mFolders->removeSelectedItems();
 -	}
 -}
 -
 -void LLPanelObjectInventory::startRenamingSelectedItem()
 -{
 -	if(mFolders)
 -	{
 -		mFolders->startRenamingSelectedItem();
 -	}
 -}
 -
 -void LLPanelObjectInventory::draw()
 -{
 -	LLPanel::draw();
 -
 -	if(mIsInventoryEmpty)
 -	{
 -		if((LLUUID::null != mTaskUUID) && (!mHaveInventory))
 -		{
 -			LLFontGL::getFontSansSerif()->renderUTF8(LLTrans::getString("LoadingContents"), 0,
 -													 (S32)(getRect().getWidth() * 0.5f),
 -													 10,
 -													 LLColor4( 1, 1, 1, 1 ),
 -													 LLFontGL::HCENTER,
 -													 LLFontGL::BOTTOM);
 -		}
 -		else if(mHaveInventory)
 -		{
 -			LLFontGL::getFontSansSerif()->renderUTF8(LLTrans::getString("NoContents"), 0,
 -													 (S32)(getRect().getWidth() * 0.5f),
 -													 10,
 -													 LLColor4( 1, 1, 1, 1 ),
 -													 LLFontGL::HCENTER,
 -													 LLFontGL::BOTTOM);
 -		}
 -	}
 -}
 -
 -void LLPanelObjectInventory::deleteAllChildren()
 -{
 -	mScroller = NULL;
 -	mFolders = NULL;
 -	LLView::deleteAllChildren();
 -}
 -
 -BOOL LLPanelObjectInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg)
 -{
 -	if (mFolders && mHaveInventory)
 -	{
 -		LLFolderViewItem* folderp = mFolders->getNextFromChild(NULL);
 -		if (!folderp)
 -		{
 -			return FALSE;
 -		}
 -		// Try to pass on unmodified mouse coordinates
 -		S32 local_x = x - mFolders->getRect().mLeft;
 -		S32 local_y = y - mFolders->getRect().mBottom;
 -
 -		if (mFolders->pointInView(local_x, local_y))
 -		{
 -			return mFolders->handleDragAndDrop(local_x, local_y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
 -		}
 -		else
 -		{
 -			//force mouse coordinates to be inside folder rectangle
 -			return mFolders->handleDragAndDrop(5, 1, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
 -		}
 -	}
 -	else
 -	{
 -		return FALSE;
 -	}
 -}
 -
 -//static
 -void LLPanelObjectInventory::idle(void* user_data)
 -{
 -	LLPanelObjectInventory* self = (LLPanelObjectInventory*)user_data;
 -
 -
 -	if (self->mInventoryNeedsUpdate)
 -	{
 -		self->updateInventory();
 -	}
 -}
 +/** + * @file llsidepanelinventory.cpp + * @brief LLPanelObjectInventory class implementation + * + * $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$ + */ + +//***************************************************************************** +// +// Implementation of the panel inventory - used to view and control a +// task's inventory. +// +//***************************************************************************** + +#include "llviewerprecompiledheaders.h" + +#include "llpanelobjectinventory.h" + +#include "roles_constants.h" + +#include "llagent.h" +#include "llcallbacklist.h" +#include "llfloaterbuycurrency.h" +#include "llfloaterreg.h" +#include "llinventorybridge.h" +#include "llinventoryfunctions.h" +#include "llpreviewanim.h" +#include "llpreviewgesture.h" +#include "llpreviewnotecard.h" +#include "llpreviewscript.h" +#include "llpreviewsound.h" +#include "llpreviewtexture.h" +#include "llscrollcontainer.h" +#include "llselectmgr.h" +#include "llsidetray.h" +#include "llstatusbar.h" +#include "lltrans.h" +#include "llviewerregion.h" +#include "llviewerobjectlist.h" +#include "llviewermessage.h" + + +///---------------------------------------------------------------------------- +/// Class LLTaskInvFVBridge +///---------------------------------------------------------------------------- + +class LLTaskInvFVBridge : public LLFolderViewEventListener +{ +protected: +	LLUUID mUUID; +	std::string mName; +	mutable std::string mDisplayName; +	LLPanelObjectInventory* mPanel; +	U32 mFlags; + +	LLInventoryItem* findItem() const; + +public: +	LLTaskInvFVBridge( +		LLPanelObjectInventory* panel, +		const LLUUID& uuid, +		const std::string& name, +		U32 flags=0); +	virtual ~LLTaskInvFVBridge( void ) {} + +	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; } +	virtual std::string getLabelSuffix() const { return LLStringUtil::null; } + +	static LLTaskInvFVBridge* createObjectBridge(LLPanelObjectInventory* panel, +												 LLInventoryObject* object); +	void showProperties(); +	void buyItem(); +	S32 getPrice(); +	static bool commitBuyItem(const LLSD& notification, const LLSD& response); + +	// LLFolderViewEventListener functionality +	virtual const std::string& getName() const; +	virtual const std::string& getDisplayName() const; +	virtual PermissionMask getPermissionMask() const { return PERM_NONE; } +	/*virtual*/ LLAssetType::EType getPreferredType() const { return LLAssetType::AT_NONE; } +	virtual const LLUUID& getUUID() const { return mUUID; } +	virtual time_t getCreationDate() const; +	virtual LLUIImagePtr getIcon() const; +	virtual void openItem(); +	virtual void closeItem() {} +	virtual void previewItem(); +	virtual void selectItem() {} +	virtual BOOL isItemRenameable() const; +	virtual BOOL renameItem(const std::string& new_name); +	virtual BOOL isItemMovable() const; +	virtual BOOL isItemRemovable(); +	virtual BOOL removeItem(); +	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch); +	virtual void move(LLFolderViewEventListener* parent_listener); +	virtual BOOL isItemCopyable() const; +	virtual BOOL copyToClipboard() const; +	virtual void cutToClipboard(); +	virtual BOOL isClipboardPasteable() const; +	virtual void pasteFromClipboard(); +	virtual void pasteLinkFromClipboard(); +	virtual void buildContextMenu(LLMenuGL& menu, U32 flags); +	virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action); +	virtual BOOL isUpToDate() const { return TRUE; } +	virtual BOOL hasChildren() const { return FALSE; } +	virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; } +	// LLDragAndDropBridge functionality +	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const; +	virtual BOOL dragOrDrop(MASK mask, BOOL drop, +							EDragAndDropType cargo_type, +							void* cargo_data); +}; + +LLTaskInvFVBridge::LLTaskInvFVBridge( +	LLPanelObjectInventory* panel, +	const LLUUID& uuid, +	const std::string& name, +	U32 flags): +	mUUID(uuid), +	mName(name), +	mPanel(panel), +	mFlags(flags) +{ + +} + +LLInventoryItem* LLTaskInvFVBridge::findItem() const +{ +	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); +	if(object) +	{ +		return (LLInventoryItem*)(object->getInventoryObject(mUUID)); +	} +	return NULL; +} + +void LLTaskInvFVBridge::showProperties() +{ +	LLSD key; +	key["object"] = mPanel->getTaskUUID(); +	key["id"] = mUUID; +	LLSideTray::getInstance()->showPanel("sidepanel_inventory", key); +	 +	/* +	LLFloaterProperties* floater = LLFloaterReg::showTypedInstance<LLFloaterProperties>("properties", mUUID); +	if (floater) +	{ +		floater->setObjectID(mPanel->getTaskUUID()); +	} +	*/ +} + +struct LLBuyInvItemData +{ +	LLUUID mTaskID; +	LLUUID mItemID; +	LLAssetType::EType mType; + +	LLBuyInvItemData(const LLUUID& task, +					 const LLUUID& item, +					 LLAssetType::EType type) : +		mTaskID(task), mItemID(item), mType(type) +	{} +}; + +void LLTaskInvFVBridge::buyItem() +{ +	llinfos << "LLTaskInvFVBridge::buyItem()" << llendl; +	LLInventoryItem* item = findItem(); +	if(!item || !item->getSaleInfo().isForSale()) return; +	LLBuyInvItemData* inv = new LLBuyInvItemData(mPanel->getTaskUUID(), +												 mUUID, +												 item->getType()); + +	const LLSaleInfo& sale_info = item->getSaleInfo(); +	const LLPermissions& perm = item->getPermissions(); +	const std::string owner_name; // no owner name currently... FIXME? + +	LLViewerObject* obj; +	if( ( obj = gObjectList.findObject( mPanel->getTaskUUID() ) ) && obj->isAttachment() ) +	{ +		LLNotifications::instance().add("Cannot_Purchase_an_Attachment"); +		llinfos << "Attempt to purchase an attachment" << llendl; +		delete inv; +	} +	else +	{ +        LLSD args; +        args["PRICE"] = llformat("%d",sale_info.getSalePrice()); +        args["OWNER"] = owner_name; +        if (sale_info.getSaleType() != LLSaleInfo::FS_CONTENTS) +        { +        	U32 next_owner_mask = perm.getMaskNextOwner(); +        	args["MODIFYPERM"] = LLNotifications::instance().getGlobalString((next_owner_mask & PERM_MODIFY) ? "PermYes" : "PermNo"); +        	args["COPYPERM"] = LLNotifications::instance().getGlobalString((next_owner_mask & PERM_COPY) ? "PermYes" : "PermNo"); +        	args["RESELLPERM"] = LLNotifications::instance().getGlobalString((next_owner_mask & PERM_TRANSFER) ? "PermYes" : "PermNo"); +        } + +		std::string alertdesc; +       	switch(sale_info.getSaleType()) +       	{ +       	  case LLSaleInfo::FS_ORIGINAL: +       		alertdesc = owner_name.empty() ? "BuyOriginalNoOwner" : "BuyOriginal"; +       		break; +       	  case LLSaleInfo::FS_CONTENTS: +       		alertdesc = owner_name.empty() ? "BuyContentsNoOwner" : "BuyContents"; +       		break; +		  case LLSaleInfo::FS_COPY: +       	  default: +       		alertdesc = owner_name.empty() ? "BuyCopyNoOwner" : "BuyCopy"; +       		break; +       	} + +		LLSD payload; +		payload["task_id"] = inv->mTaskID; +		payload["item_id"] = inv->mItemID; +		payload["type"] = inv->mType; +		LLNotifications::instance().add(alertdesc, args, payload, LLTaskInvFVBridge::commitBuyItem); +	} +} + +S32 LLTaskInvFVBridge::getPrice() +{ +	LLInventoryItem* item = findItem(); +	if(item) +	{ +		return item->getSaleInfo().getSalePrice(); +	} +	else +	{ +		return -1; +	} +} + +// static +bool LLTaskInvFVBridge::commitBuyItem(const LLSD& notification, const LLSD& response) +{ +	S32 option = LLNotification::getSelectedOption(notification, response); +	if(0 == option) +	{ +		LLViewerObject* object = gObjectList.findObject(notification["payload"]["task_id"].asUUID()); +		if(!object || !object->getRegion()) return false; + + +		LLMessageSystem* msg = gMessageSystem; +		msg->newMessageFast(_PREHASH_BuyObjectInventory); +		msg->nextBlockFast(_PREHASH_AgentData); +		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +		msg->nextBlockFast(_PREHASH_Data); +		msg->addUUIDFast(_PREHASH_ObjectID, notification["payload"]["task_id"].asUUID()); +		msg->addUUIDFast(_PREHASH_ItemID, notification["payload"]["item_id"].asUUID()); +		msg->addUUIDFast(_PREHASH_FolderID, +			gInventory.findCategoryUUIDForType((LLAssetType::EType)notification["payload"]["type"].asInteger())); +		msg->sendReliable(object->getRegion()->getHost()); +	} +	return false; +} + +const std::string& LLTaskInvFVBridge::getName() const +{ +	return mName; +} + +const std::string& LLTaskInvFVBridge::getDisplayName() const +{ +	LLInventoryItem* item = findItem(); +	if(item) +	{ +		mDisplayName.assign(item->getName()); + +		const LLPermissions& perm(item->getPermissions()); +		BOOL copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE); +		BOOL mod  = gAgent.allowOperation(PERM_MODIFY, perm, GP_OBJECT_MANIPULATE); +		BOOL xfer = gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE); + +		if(!copy) +		{ +			mDisplayName.append(" (no copy)"); +		} +		if(!mod) +		{ +			mDisplayName.append(" (no modify)"); +		} +		if(!xfer) +		{ +			mDisplayName.append(" (no transfer)"); +		} +	} + +	return mDisplayName; +} + +// BUG: No creation dates for task inventory +time_t LLTaskInvFVBridge::getCreationDate() const +{ +	return 0; +} + +LLUIImagePtr LLTaskInvFVBridge::getIcon() const +{ +	BOOL item_is_multi = FALSE; +	if ( mFlags & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS ) +	{ +		item_is_multi = TRUE; +	} + +	return get_item_icon(LLAssetType::AT_OBJECT, LLInventoryType::IT_OBJECT, 0, item_is_multi ); +} + +void LLTaskInvFVBridge::openItem() +{ +	// no-op. +	lldebugs << "LLTaskInvFVBridge::openItem()" << llendl; +} + +void LLTaskInvFVBridge::previewItem() +{ +	openItem(); +} + +BOOL LLTaskInvFVBridge::isItemRenameable() const +{ +	if(gAgent.isGodlike()) return TRUE; +	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); +	if(object) +	{ +		LLInventoryItem* item; +		item = (LLInventoryItem*)(object->getInventoryObject(mUUID)); +		if(item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), +										 GP_OBJECT_MANIPULATE, GOD_LIKE)) +		{ +			return TRUE; +		} +	} +	return FALSE; +} + +BOOL LLTaskInvFVBridge::renameItem(const std::string& new_name) +{ +	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); +	if(object) +	{ +		LLViewerInventoryItem* item = NULL; +		item = (LLViewerInventoryItem*)object->getInventoryObject(mUUID); +		if(item && (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), +										GP_OBJECT_MANIPULATE, GOD_LIKE))) +		{ +			LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); +			new_item->rename(new_name); +			object->updateInventory( +				new_item, +				TASK_INVENTORY_ITEM_KEY, +				false); +		} +	} +	return TRUE; +} + +BOOL LLTaskInvFVBridge::isItemMovable() const +{ +	//LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); +	//if(object && (object->permModify() || gAgent.isGodlike())) +	//{ +	//	return TRUE; +	//} +	//return FALSE; +	return TRUE; +} + +BOOL LLTaskInvFVBridge::isItemRemovable() +{ +	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); +	if(object +	   && (object->permModify() || object->permYouOwner())) +	{ +		return TRUE; +	} +	return FALSE; +} + +bool remove_task_inventory_callback(const LLSD& notification, const LLSD& response, LLPanelObjectInventory* panel) +{ +	S32 option = LLNotification::getSelectedOption(notification, response); +	LLViewerObject* object = gObjectList.findObject(notification["payload"]["task_id"].asUUID()); +	if(option == 0 && object) +	{ +		// yes +		LLSD::array_const_iterator list_end = notification["payload"]["inventory_ids"].endArray(); +		for (LLSD::array_const_iterator list_it = notification["payload"]["inventory_ids"].beginArray(); +			list_it != list_end;  +			++list_it) +		{ +			object->removeInventory(list_it->asUUID()); +		} + +		// refresh the UI. +		panel->refresh(); +	} +	return false; +} + +// helper for remove +// ! REFACTOR ! two_uuids_list_t is also defined in llinevntorybridge.h, but differently. +typedef std::pair<LLUUID, std::list<LLUUID> > panel_two_uuids_list_t; +typedef std::pair<LLPanelObjectInventory*, panel_two_uuids_list_t> remove_data_t; +BOOL LLTaskInvFVBridge::removeItem() +{ +	if(isItemRemovable() && mPanel) +	{ +		LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); +		if(object) +		{ +			if(object->permModify()) +			{ +				// just do it. +				object->removeInventory(mUUID); +				return TRUE; +			} +			else +			{ +				remove_data_t* data = new remove_data_t; +				data->first = mPanel; +				data->second.first = mPanel->getTaskUUID(); +				data->second.second.push_back(mUUID); +				LLSD payload; +				payload["task_id"] = mPanel->getTaskUUID(); +				payload["inventory_ids"].append(mUUID); +				LLNotifications::instance().add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel)); +				return FALSE; +			} +		} +	} +	return FALSE; +} + +void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) +{ +	if (!mPanel) +	{ +		return; +	} + +	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); +	if (!object) +	{ +		return; +	} + +	if (!object->permModify()) +	{ +		LLSD payload; +		payload["task_id"] = mPanel->getTaskUUID(); +		for (S32 i = 0; i < (S32)batch.size(); i++) +		{ +			LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i]; +			payload["inventory_ids"].append(itemp->getUUID()); +		} +		LLNotifications::instance().add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel)); +		 +	} +	else +	{ +		for (S32 i = 0; i < (S32)batch.size(); i++) +		{ +			LLTaskInvFVBridge* itemp = (LLTaskInvFVBridge*)batch[i]; + +			if(itemp->isItemRemovable()) +			{ +				// just do it. +				object->removeInventory(itemp->getUUID()); +			} +		} +	} +} + +void LLTaskInvFVBridge::move(LLFolderViewEventListener* parent_listener) +{ +} + +BOOL LLTaskInvFVBridge::isItemCopyable() const +{ +	LLInventoryItem* item = findItem(); +	if(!item) return FALSE; +	return gAgent.allowOperation(PERM_COPY, item->getPermissions(), +								GP_OBJECT_MANIPULATE); +} + +BOOL LLTaskInvFVBridge::copyToClipboard() const +{ +	return FALSE; +} + +void LLTaskInvFVBridge::cutToClipboard() +{ +} + +BOOL LLTaskInvFVBridge::isClipboardPasteable() const +{ +	return FALSE; +} + +void LLTaskInvFVBridge::pasteFromClipboard() +{ +} + +void LLTaskInvFVBridge::pasteLinkFromClipboard() +{ +} + +BOOL LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const +{ +	//llinfos << "LLTaskInvFVBridge::startDrag()" << llendl; +	if(mPanel) +	{ +		LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); +		if(object) +		{ +			LLInventoryItem* inv = NULL; +			if((inv = (LLInventoryItem*)object->getInventoryObject(mUUID))) +			{ +				const LLPermissions& perm = inv->getPermissions(); +				bool can_copy = gAgent.allowOperation(PERM_COPY, perm, +														GP_OBJECT_MANIPULATE); +				if (object->isAttachment() && !can_copy) +				{ +                    //RN: no copy contents of attachments cannot be dragged out +                    // due to a race condition and possible exploit where +                    // attached objects do not update their inventory items +                    // when their contents are manipulated +                    return FALSE; +				} +				if((can_copy && perm.allowTransferTo(gAgent.getID())) +				   || object->permYouOwner()) +//				   || gAgent.isGodlike()) + +				{ +					*type = LLAssetType::lookupDragAndDropType(inv->getType()); + +					*id = inv->getUUID(); +					return TRUE; +				} +			} +		} +	} +	return FALSE; +} + +BOOL LLTaskInvFVBridge::dragOrDrop(MASK mask, BOOL drop, +								   EDragAndDropType cargo_type, +								   void* cargo_data) +{ +	//llinfos << "LLTaskInvFVBridge::dragOrDrop()" << llendl; +	return FALSE; +} + +// virtual +void LLTaskInvFVBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) +{ +	if (action == "task_buy") +	{ +		// Check the price of the item. +		S32 price = getPrice(); +		if (-1 == price) +		{ +			llwarns << "label_buy_task_bridged_item: Invalid price" << llendl; +		} +		else +		{ +			if (price > 0 && price > gStatusBar->getBalance()) +			{ +				LLFloaterBuyCurrency::buyCurrency("This costs", price); +			} +			else +			{ +				buyItem(); +			} +		} +	} +	else if (action == "task_open") +	{ +		openItem(); +	} +	else if (action == "task_properties") +	{ +		showProperties(); +	} +} + +void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ +	LLInventoryItem* item = findItem(); +	std::vector<std::string> items; +	std::vector<std::string> disabled_items; +	 +	if (!item) +	{ +		hide_context_entries(menu, items, disabled_items); +		return; +	} + +	if(gAgent.allowOperation(PERM_OWNER, item->getPermissions(), +							 GP_OBJECT_MANIPULATE) +	   && item->getSaleInfo().isForSale()) +	{ +		items.push_back(std::string("Task Buy")); + +		std::string label= LLTrans::getString("Buy"); +		// Check the price of the item. +		S32 price = getPrice(); +		if (-1 == price) +		{ +			llwarns << "label_buy_task_bridged_item: Invalid price" << llendl; +		} +		else +		{ +			std::ostringstream info; +			info << LLTrans::getString("BuyforL$") << price; +			label.assign(info.str()); +		} + +		const LLView::child_list_t *list = menu.getChildList(); +		LLView::child_list_t::const_iterator itor; +		for (itor = list->begin(); itor != list->end(); ++itor) +		{ +			std::string name = (*itor)->getName(); +			LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor); +			if (name == "Task Buy" && menu_itemp) +			{ +				menu_itemp->setLabel(label); +			} +		} +	} +	else +	{ +		items.push_back(std::string("Task Open")); +		if (!isItemCopyable()) +		{ +			disabled_items.push_back(std::string("Task Open")); +		} +	} +	items.push_back(std::string("Task Properties")); +	if(isItemRenameable()) +	{ +		items.push_back(std::string("Task Rename")); +	} +	if(isItemRemovable()) +	{ +		items.push_back(std::string("Task Remove")); +	} + +	hide_context_entries(menu, items, disabled_items); +} + + +///---------------------------------------------------------------------------- +/// Class LLTaskFolderBridge +///---------------------------------------------------------------------------- + +class LLTaskCategoryBridge : public LLTaskInvFVBridge +{ +public: +	LLTaskCategoryBridge( +		LLPanelObjectInventory* panel, +		const LLUUID& uuid, +		const std::string& name); + +	virtual LLUIImagePtr getIcon() const; +	virtual const std::string& getDisplayName() const { return getName(); } +	virtual BOOL isItemRenameable() const; +	virtual BOOL renameItem(const std::string& new_name); +	virtual BOOL isItemRemovable(); +	virtual void buildContextMenu(LLMenuGL& menu, U32 flags); +	virtual BOOL hasChildren() const; +	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const; +	virtual BOOL dragOrDrop(MASK mask, BOOL drop, +							EDragAndDropType cargo_type, +							void* cargo_data); +}; + +LLTaskCategoryBridge::LLTaskCategoryBridge( +	LLPanelObjectInventory* panel, +	const LLUUID& uuid, +	const std::string& name) : +	LLTaskInvFVBridge(panel, uuid, name) +{ +} + +LLUIImagePtr LLTaskCategoryBridge::getIcon() const +{ +	return LLUI::getUIImage("Inv_FolderClosed"); +} + +BOOL LLTaskCategoryBridge::isItemRenameable() const +{ +	return FALSE; +} + +BOOL LLTaskCategoryBridge::renameItem(const std::string& new_name) +{ +	return FALSE; +} + +BOOL LLTaskCategoryBridge::isItemRemovable() +{ +	return FALSE; +} + +void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ +	std::vector<std::string> items; +	std::vector<std::string> disabled_items; +	items.push_back(std::string("Task Open")); +	hide_context_entries(menu, items, disabled_items); +} + +BOOL LLTaskCategoryBridge::hasChildren() const +{ +	// return TRUE if we have or do know know if we have children. +	// *FIX: For now, return FALSE - we will know for sure soon enough. +	return FALSE; +} + +BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const +{ +	//llinfos << "LLTaskInvFVBridge::startDrag()" << llendl; +	if(mPanel) +	{ +		LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); +		if(object) +		{ +			LLInventoryItem* inv = NULL; +			if((inv = (LLInventoryItem*)object->getInventoryObject(mUUID))) +			{ +				const LLPermissions& perm = inv->getPermissions(); +				bool can_copy = gAgent.allowOperation(PERM_COPY, perm, +														GP_OBJECT_MANIPULATE); +				if((can_copy && perm.allowTransferTo(gAgent.getID())) +				   || object->permYouOwner()) +//				   || gAgent.isGodlike()) + +				{ +					*type = LLAssetType::lookupDragAndDropType(inv->getType()); + +					*id = inv->getUUID(); +					return TRUE; +				} +			} +		} +	} +	return FALSE; +} + +BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop, +									  EDragAndDropType cargo_type, +									  void* cargo_data) +{ +	//llinfos << "LLTaskCategoryBridge::dragOrDrop()" << llendl; +	BOOL accept = FALSE; +	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); +	if(object) +	{ +		switch(cargo_type) +		{ +		case DAD_CATEGORY: +			accept = LLToolDragAndDrop::getInstance()->dadUpdateInventoryCategory(object,drop); +			break; +		case DAD_TEXTURE: +		case DAD_SOUND: +		case DAD_LANDMARK: +		case DAD_OBJECT: +		case DAD_NOTECARD: +		case DAD_CLOTHING: +		case DAD_BODYPART: +		case DAD_ANIMATION: +		case DAD_GESTURE: +		case DAD_CALLINGCARD: +			accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data); +			if(accept && drop) +			{ +				LLToolDragAndDrop::dropInventory(object, +												 (LLViewerInventoryItem*)cargo_data, +												 LLToolDragAndDrop::getInstance()->getSource(), +												 LLToolDragAndDrop::getInstance()->getSourceID()); +			} +			break; +		case DAD_SCRIPT: +			// *HACK: In order to resolve SL-22177, we need to block +			// drags from notecards and objects onto other +			// objects. uncomment the simpler version when we have +			// that right. +			//accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data); +			if(LLToolDragAndDrop::isInventoryDropAcceptable( +				   object, (LLViewerInventoryItem*)cargo_data) +			   && (LLToolDragAndDrop::SOURCE_WORLD != LLToolDragAndDrop::getInstance()->getSource()) +			   && (LLToolDragAndDrop::SOURCE_NOTECARD != LLToolDragAndDrop::getInstance()->getSource())) +			{ +				accept = TRUE; +			} +			if(accept && drop) +			{ +				LLViewerInventoryItem* item = (LLViewerInventoryItem*)cargo_data; +				// rez in the script active by default, rez in +				// inactive if the control key is being held down. +				BOOL active = ((mask & MASK_CONTROL) == 0); +				LLToolDragAndDrop::dropScript(object, item, active, +											  LLToolDragAndDrop::getInstance()->getSource(), +											  LLToolDragAndDrop::getInstance()->getSourceID()); +			} +			break; +		default: +			break; +		} +	} +	return accept; +} + +///---------------------------------------------------------------------------- +/// Class LLTaskTextureBridge +///---------------------------------------------------------------------------- + +class LLTaskTextureBridge : public LLTaskInvFVBridge +{ +public: +	LLTaskTextureBridge( +		LLPanelObjectInventory* panel, +		const LLUUID& uuid, +		const std::string& name, +		LLInventoryType::EType it); + +	virtual LLUIImagePtr getIcon() const; +	virtual void openItem(); +protected: +	LLInventoryType::EType mInventoryType; +}; + +LLTaskTextureBridge::LLTaskTextureBridge( +	LLPanelObjectInventory* panel, +	const LLUUID& uuid, +	const std::string& name, +	LLInventoryType::EType it) : +	LLTaskInvFVBridge(panel, uuid, name), +	mInventoryType(it) +{ +} + +LLUIImagePtr LLTaskTextureBridge::getIcon() const +{ +	return get_item_icon(LLAssetType::AT_TEXTURE, mInventoryType, 0, FALSE); +} + +void LLTaskTextureBridge::openItem() +{ +	llinfos << "LLTaskTextureBridge::openItem()" << llendl; +	LLPreviewTexture* preview = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES); +	if(preview) +	{ +		preview->setObjectID(mPanel->getTaskUUID()); +	} +} + + +///---------------------------------------------------------------------------- +/// Class LLTaskSoundBridge +///---------------------------------------------------------------------------- + +class LLTaskSoundBridge : public LLTaskInvFVBridge +{ +public: +	LLTaskSoundBridge( +		LLPanelObjectInventory* panel, +		const LLUUID& uuid, +		const std::string& name); + +	virtual LLUIImagePtr getIcon() const; +	virtual void openItem(); +	virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action); +	virtual void buildContextMenu(LLMenuGL& menu, U32 flags); +	static void openSoundPreview(void* data); +}; + +LLTaskSoundBridge::LLTaskSoundBridge( +	LLPanelObjectInventory* panel, +	const LLUUID& uuid, +	const std::string& name) : +	LLTaskInvFVBridge(panel, uuid, name) +{ +} + +LLUIImagePtr LLTaskSoundBridge::getIcon() const +{ +	return get_item_icon(LLAssetType::AT_SOUND, LLInventoryType::IT_SOUND, 0, FALSE); +} + +void LLTaskSoundBridge::openItem() +{ +	openSoundPreview((void*)this); +} + +void LLTaskSoundBridge::openSoundPreview(void* data) +{ +	LLTaskSoundBridge* self = (LLTaskSoundBridge*)data; +	if(!self) +		return; + +	LLPreviewSound* preview = LLFloaterReg::showTypedInstance<LLPreviewSound>("preview_sound", LLSD(self->mUUID), TAKE_FOCUS_YES); +	if (preview) +	{ +		preview->setObjectID(self->mPanel->getTaskUUID()); +	} +} + +// virtual +void LLTaskSoundBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) +{ +	if (action == "task_play") +	{ +		LLInventoryItem* item = findItem(); +		if(item) +		{ +			send_sound_trigger(item->getAssetUUID(), 1.0); +		} +	} +	LLTaskInvFVBridge::performAction(folder, model, action); +} + +void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ +	LLInventoryItem* item = findItem(); +	if(!item) return; +	std::vector<std::string> items; +	std::vector<std::string> disabled_items; + +	if(item->getPermissions().getOwner() != gAgent.getID() +	   && item->getSaleInfo().isForSale()) +	{ +		items.push_back(std::string("Task Buy")); + +		std::string label= LLTrans::getString("Buy"); +		// Check the price of the item. +		S32 price = getPrice(); +		if (-1 == price) +		{ +			llwarns << "label_buy_task_bridged_item: Invalid price" << llendl; +		} +		else +		{ +			std::ostringstream info; +			info <<  LLTrans::getString("BuyforL$") << price; +			label.assign(info.str()); +		} + +		const LLView::child_list_t *list = menu.getChildList(); +		LLView::child_list_t::const_iterator itor; +		for (itor = list->begin(); itor != list->end(); ++itor) +		{ +			std::string name = (*itor)->getName(); +			LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor); +			if (name == "Task Buy" && menu_itemp) +			{ +				menu_itemp->setLabel(label); +			} +		} +	} +	else +	{ +		items.push_back(std::string("Task Open"));  +		if (!isItemCopyable()) +		{ +			disabled_items.push_back(std::string("Task Open")); +		} +	} +	items.push_back(std::string("Task Properties")); +	if(isItemRenameable()) +	{ +		items.push_back(std::string("Task Rename")); +	} +	if(isItemRemovable()) +	{ +		items.push_back(std::string("Task Remove")); +	} + +	items.push_back(std::string("Task Play")); + + +	hide_context_entries(menu, items, disabled_items); +} + +///---------------------------------------------------------------------------- +/// Class LLTaskLandmarkBridge +///---------------------------------------------------------------------------- + +class LLTaskLandmarkBridge : public LLTaskInvFVBridge +{ +public: +	LLTaskLandmarkBridge( +		LLPanelObjectInventory* panel, +		const LLUUID& uuid, +		const std::string& name); + +	virtual LLUIImagePtr getIcon() const; +}; + +LLTaskLandmarkBridge::LLTaskLandmarkBridge( +	LLPanelObjectInventory* panel, +	const LLUUID& uuid, +	const std::string& name) : +	LLTaskInvFVBridge(panel, uuid, name) +{ +} + +LLUIImagePtr LLTaskLandmarkBridge::getIcon() const +{ +	return get_item_icon(LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, 0, FALSE); +} + + +///---------------------------------------------------------------------------- +/// Class LLTaskCallingCardBridge +///---------------------------------------------------------------------------- + +class LLTaskCallingCardBridge : public LLTaskInvFVBridge +{ +public: +	LLTaskCallingCardBridge( +		LLPanelObjectInventory* panel, +		const LLUUID& uuid, +		const std::string& name); + +	virtual LLUIImagePtr getIcon() const; +	virtual BOOL isItemRenameable() const; +	virtual BOOL renameItem(const std::string& new_name); +}; + +LLTaskCallingCardBridge::LLTaskCallingCardBridge( +	LLPanelObjectInventory* panel, +	const LLUUID& uuid, +	const std::string& name) : +	LLTaskInvFVBridge(panel, uuid, name) +{ +} + +LLUIImagePtr LLTaskCallingCardBridge::getIcon() const +{ +	return get_item_icon(LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, 0, FALSE); +} + +BOOL LLTaskCallingCardBridge::isItemRenameable() const +{ +	return FALSE; +} + +BOOL LLTaskCallingCardBridge::renameItem(const std::string& new_name) +{ +	return FALSE; +} + + +///---------------------------------------------------------------------------- +/// Class LLTaskScriptBridge +///---------------------------------------------------------------------------- + +class LLTaskScriptBridge : public LLTaskInvFVBridge +{ +public: +	LLTaskScriptBridge( +		LLPanelObjectInventory* panel, +		const LLUUID& uuid, +		const std::string& name); + +	virtual LLUIImagePtr getIcon() const; +	//static BOOL enableIfCopyable( void* userdata ); +}; + +LLTaskScriptBridge::LLTaskScriptBridge( +	LLPanelObjectInventory* panel, +	const LLUUID& uuid, +	const std::string& name) : +	LLTaskInvFVBridge(panel, uuid, name) +{ +} + +LLUIImagePtr LLTaskScriptBridge::getIcon() const +{ +	return get_item_icon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0, FALSE); +} + + +class LLTaskLSLBridge : public LLTaskScriptBridge +{ +public: +	LLTaskLSLBridge( +		LLPanelObjectInventory* panel, +		const LLUUID& uuid, +		const std::string& name); + +	virtual void openItem(); +	virtual BOOL removeItem(); +	//virtual void buildContextMenu(LLMenuGL& menu); + +	//static void copyToInventory(void* userdata); +}; + +LLTaskLSLBridge::LLTaskLSLBridge( +	LLPanelObjectInventory* panel, +	const LLUUID& uuid, +	const std::string& name) : +	LLTaskScriptBridge(panel, uuid, name) +{ +} + +void LLTaskLSLBridge::openItem() +{ +	llinfos << "LLTaskLSLBridge::openItem() " << mUUID << llendl; +	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); +	if(!object || object->isInventoryPending()) +	{ +		return; +	} +	LLLiveLSLEditor* preview = LLFloaterReg::showTypedInstance<LLLiveLSLEditor>("preview_scriptedit", LLSD(mUUID), TAKE_FOCUS_YES); +	if (preview && (object->permModify() || gAgent.isGodlike())) +	{ +		preview->setObjectID(mPanel->getTaskUUID()); +	} +} + +BOOL LLTaskLSLBridge::removeItem() +{ +	LLFloaterReg::hideInstance("preview_scriptedit", LLSD(mUUID)); +	return LLTaskInvFVBridge::removeItem(); +} + +///---------------------------------------------------------------------------- +/// Class LLTaskObjectBridge +///---------------------------------------------------------------------------- + +class LLTaskObjectBridge : public LLTaskInvFVBridge +{ +public: +	LLTaskObjectBridge( +		LLPanelObjectInventory* panel, +		const LLUUID& uuid, +		const std::string& name); + +	virtual LLUIImagePtr getIcon() const; +}; + +LLTaskObjectBridge::LLTaskObjectBridge( +	LLPanelObjectInventory* panel, +	const LLUUID& uuid, +	const std::string& name) : +	LLTaskInvFVBridge(panel, uuid, name) +{ +} + +LLUIImagePtr LLTaskObjectBridge::getIcon() const +{ +	BOOL item_is_multi = FALSE; +	if ( mFlags & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS ) +	{ +		item_is_multi = TRUE; +	} + +	return get_item_icon(LLAssetType::AT_OBJECT, LLInventoryType::IT_OBJECT, 0, item_is_multi); +} + +///---------------------------------------------------------------------------- +/// Class LLTaskNotecardBridge +///---------------------------------------------------------------------------- + +class LLTaskNotecardBridge : public LLTaskInvFVBridge +{ +public: +	LLTaskNotecardBridge( +		LLPanelObjectInventory* panel, +		const LLUUID& uuid, +		const std::string& name); + +	virtual LLUIImagePtr getIcon() const; +	virtual void openItem(); +	virtual BOOL removeItem(); +}; + +LLTaskNotecardBridge::LLTaskNotecardBridge( +	LLPanelObjectInventory* panel, +	const LLUUID& uuid, +	const std::string& name) : +	LLTaskInvFVBridge(panel, uuid, name) +{ +} + +LLUIImagePtr LLTaskNotecardBridge::getIcon() const +{ +	return get_item_icon(LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, 0, FALSE); +} + +void LLTaskNotecardBridge::openItem() +{ +	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); +	if(!object || object->isInventoryPending()) +	{ +		return; +	} +	if(object->permModify() || gAgent.isGodlike()) +	{ +		LLPreviewNotecard* preview = LLFloaterReg::showTypedInstance<LLPreviewNotecard>("preview_notecard", LLSD(mUUID), TAKE_FOCUS_YES); +		if (preview) +		{ +			preview->setObjectID(mPanel->getTaskUUID()); +		} +	} +} + +BOOL LLTaskNotecardBridge::removeItem() +{ +	LLFloaterReg::hideInstance("preview_notecard", LLSD(mUUID)); +	return LLTaskInvFVBridge::removeItem(); +} + +///---------------------------------------------------------------------------- +/// Class LLTaskGestureBridge +///---------------------------------------------------------------------------- + +class LLTaskGestureBridge : public LLTaskInvFVBridge +{ +public: +	LLTaskGestureBridge( +		LLPanelObjectInventory* panel, +		const LLUUID& uuid, +		const std::string& name); + +	virtual LLUIImagePtr getIcon() const; +	virtual void openItem(); +	virtual BOOL removeItem(); +}; + +LLTaskGestureBridge::LLTaskGestureBridge( +	LLPanelObjectInventory* panel, +	const LLUUID& uuid, +	const std::string& name) : +	LLTaskInvFVBridge(panel, uuid, name) +{ +} + +LLUIImagePtr LLTaskGestureBridge::getIcon() const +{ +	return get_item_icon(LLAssetType::AT_GESTURE, LLInventoryType::IT_GESTURE, 0, FALSE); +} + +void LLTaskGestureBridge::openItem() +{ +	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); +	if(!object || object->isInventoryPending()) +	{ +		return; +	} +	LLPreviewGesture::show(mUUID, mPanel->getTaskUUID()); +} + +BOOL LLTaskGestureBridge::removeItem() +{ +	// Don't need to deactivate gesture because gestures inside objects can never be active. +	LLFloaterReg::hideInstance("preview_gesture", LLSD(mUUID)); +	return LLTaskInvFVBridge::removeItem(); +} + +///---------------------------------------------------------------------------- +/// Class LLTaskAnimationBridge +///---------------------------------------------------------------------------- + +class LLTaskAnimationBridge : public LLTaskInvFVBridge +{ +public: +	LLTaskAnimationBridge( +		LLPanelObjectInventory* panel, +		const LLUUID& uuid, +		const std::string& name); + +	virtual LLUIImagePtr getIcon() const; +	virtual void openItem(); +	virtual BOOL removeItem(); +}; + +LLTaskAnimationBridge::LLTaskAnimationBridge( +	LLPanelObjectInventory* panel, +	const LLUUID& uuid, +	const std::string& name) : +	LLTaskInvFVBridge(panel, uuid, name) +{ +} + +LLUIImagePtr LLTaskAnimationBridge::getIcon() const +{ +	return get_item_icon(LLAssetType::AT_ANIMATION, LLInventoryType::IT_ANIMATION, 0, FALSE); +} + +void LLTaskAnimationBridge::openItem() +{ +	LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); +	if(!object || object->isInventoryPending()) +	{ +		return; +	} + +	LLPreviewAnim* preview = LLFloaterReg::showTypedInstance<LLPreviewAnim>("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES); +	if (preview && (object->permModify() || gAgent.isGodlike())) +	{ +		preview->setObjectID(mPanel->getTaskUUID()); +	} +} + +BOOL LLTaskAnimationBridge::removeItem() +{ +	LLFloaterReg::hideInstance("preview_anim", LLSD(mUUID)); +	return LLTaskInvFVBridge::removeItem(); +} + +///---------------------------------------------------------------------------- +/// Class LLTaskWearableBridge +///---------------------------------------------------------------------------- + +class LLTaskWearableBridge : public LLTaskInvFVBridge +{ +public: +	LLTaskWearableBridge( +		LLPanelObjectInventory* panel, +		const LLUUID& uuid, +		const std::string& name, +		LLAssetType::EType asset_type, +		U32 flags); + +	virtual LLUIImagePtr getIcon() const; + +protected: +	LLAssetType::EType		mAssetType; +}; + +LLTaskWearableBridge::LLTaskWearableBridge( +	LLPanelObjectInventory* panel, +	const LLUUID& uuid, +	const std::string& name, +	LLAssetType::EType asset_type, +	U32 flags) : +	LLTaskInvFVBridge(panel, uuid, name, flags), +	mAssetType( asset_type ) +{ +} + +LLUIImagePtr LLTaskWearableBridge::getIcon() const +{ +	return get_item_icon(mAssetType, LLInventoryType::IT_WEARABLE, mFlags, FALSE ); +} + + +///---------------------------------------------------------------------------- +/// LLTaskInvFVBridge impl +//---------------------------------------------------------------------------- + +LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory* panel, +														 LLInventoryObject* object) +{ +	LLTaskInvFVBridge* new_bridge = NULL; +	LLAssetType::EType type = object->getType(); +	LLInventoryItem* item = NULL; +	switch(type) +	{ +	case LLAssetType::AT_TEXTURE: +		item = (LLInventoryItem*)object; +		new_bridge = new LLTaskTextureBridge(panel, +											 object->getUUID(), +											 object->getName(), +											 item->getInventoryType()); +		break; +	case LLAssetType::AT_SOUND: +		new_bridge = new LLTaskSoundBridge(panel, +										   object->getUUID(), +										   object->getName()); +		break; +	case LLAssetType::AT_LANDMARK: +		new_bridge = new LLTaskLandmarkBridge(panel, +											  object->getUUID(), +											  object->getName()); +		break; +	case LLAssetType::AT_CALLINGCARD: +		new_bridge = new LLTaskCallingCardBridge(panel, +												 object->getUUID(), +												 object->getName()); +		break; +	case LLAssetType::AT_SCRIPT: +		// OLD SCRIPTS DEPRECATED - JC +		llwarns << "Old script" << llendl; +		//new_bridge = new LLTaskOldScriptBridge(panel, +		//									   object->getUUID(), +		//									   object->getName()); +		break; +	case LLAssetType::AT_OBJECT: +		new_bridge = new LLTaskObjectBridge(panel, +											object->getUUID(), +											object->getName()); +		break; +	case LLAssetType::AT_NOTECARD: +		new_bridge = new LLTaskNotecardBridge(panel, +											  object->getUUID(), +											  object->getName()); +		break; +	case LLAssetType::AT_ANIMATION: +		new_bridge = new LLTaskAnimationBridge(panel, +											  object->getUUID(), +											  object->getName()); +		break; +	case LLAssetType::AT_GESTURE: +		new_bridge = new LLTaskGestureBridge(panel, +											  object->getUUID(), +											  object->getName()); +		break; +	case LLAssetType::AT_CLOTHING: +	case LLAssetType::AT_BODYPART: +		item = (LLInventoryItem*)object; +		new_bridge = new LLTaskWearableBridge(panel, +											  object->getUUID(), +											  object->getName(), +											  type, +											  item->getFlags()); +		break; +	case LLAssetType::AT_CATEGORY: +	case LLAssetType::AT_FAVORITE: +		new_bridge = new LLTaskCategoryBridge(panel, +											  object->getUUID(), +											  object->getName()); +		break; +	case LLAssetType::AT_LSL_TEXT: +		new_bridge = new LLTaskLSLBridge(panel, +										 object->getUUID(), +										 object->getName()); +		break; +	 +		break; +	default: +		llinfos << "Unhandled inventory type (llassetstorage.h): " +				<< (S32)type << llendl; +		break; +	} +	return new_bridge; +} + + +///---------------------------------------------------------------------------- +/// Class LLPanelObjectInventory +///---------------------------------------------------------------------------- + +static LLDefaultChildRegistry::Register<LLPanelObjectInventory> r("panel_inventory_object"); + +void do_nothing() +{ +} + +// Default constructor +LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Params& p) : +	LLPanel(p), +	mScroller(NULL), +	mFolders(NULL), +	mHaveInventory(FALSE), +	mIsInventoryEmpty(TRUE), +	mInventoryNeedsUpdate(FALSE) +{ +	// Setup context menu callbacks +	mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelObjectInventory::doToSelected, this, _2)); +	mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLAssetType::AT_TRASH)); +	mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLAssetType::AT_LOST_AND_FOUND)); +	mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&do_nothing)); +	mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&do_nothing)); +	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&do_nothing)); +} + +// Destroys the object +LLPanelObjectInventory::~LLPanelObjectInventory() +{ +	if (!gIdleCallbacks.deleteFunction(idle, this)) +	{ +		llwarns << "LLPanelObjectInventory::~LLPanelObjectInventory() failed to delete callback" << llendl; +	} +} + +BOOL LLPanelObjectInventory::postBuild() +{ +	// clear contents and initialize menus, sets up mFolders +	reset(); + +	// Register an idle update callback +	gIdleCallbacks.addFunction(idle, this); + +	return TRUE; +} + +void LLPanelObjectInventory::doToSelected(const LLSD& userdata) +{ +	mFolders->doToSelected(&gInventory, userdata); +} + +void LLPanelObjectInventory::clearContents() +{ +	mHaveInventory = FALSE; +	mIsInventoryEmpty = TRUE; +	if (LLToolDragAndDrop::getInstance() && LLToolDragAndDrop::getInstance()->getSource() == LLToolDragAndDrop::SOURCE_WORLD) +	{ +		LLToolDragAndDrop::getInstance()->endDrag(); +	} + +	if( mScroller ) +	{ +		// removes mFolders +		removeChild( mScroller ); //*TODO: Really shouldn't do this during draw()/refresh() +		mScroller->die(); +		mScroller = NULL; +		mFolders = NULL; +	} +} + + +void LLPanelObjectInventory::reset() +{ +	clearContents(); + +	setBorderVisible(FALSE); +	 +	mCommitCallbackRegistrar.pushScope(); // push local callbacks +	 +	LLRect dummy_rect(0, 1, 1, 0); +	LLFolderView::Params p; +	p.name = "task inventory"; +	p.task_id = getTaskUUID(); +	p.parent_panel = this; +	mFolders = LLUICtrlFactory::create<LLFolderView>(p); +	// this ensures that we never say "searching..." or "no items found" +	mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS); +	mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar); + +	LLRect scroller_rect(0, getRect().getHeight(), getRect().getWidth(), 0); +	LLScrollContainer::Params scroll_p; +	scroll_p.name("task inventory scroller"); +	scroll_p.rect(scroller_rect); +	scroll_p.follows.flags(FOLLOWS_ALL); +	mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroll_p); +	addChild(mScroller); +	mScroller->addChild(mFolders); +	 +	mFolders->setScrollContainer( mScroller ); +	 +	mCommitCallbackRegistrar.popScope(); +} + +void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object, +										InventoryObjectList* inventory, +										S32 serial_num, +										void* data) +{ +	if(!object) return; + +	//llinfos << "invetnory arrived: \n" +	//		<< " panel UUID: " << panel->mTaskUUID << "\n" +	//		<< " task  UUID: " << object->mID << llendl; +	if(mTaskUUID == object->mID) +	{ +		mInventoryNeedsUpdate = TRUE; +	} + +	// refresh any properties floaters that are hanging around. +	if(inventory) +	{ +		for (InventoryObjectList::const_iterator iter = inventory->begin(); +			 iter != inventory->end(); ) +		{ +			LLInventoryObject* item = *iter++; +			LLFloaterProperties* floater = LLFloaterReg::findTypedInstance<LLFloaterProperties>("properites", item->getUUID()); +			if(floater) +			{ +				floater->refresh(); +			} +		} +	} +} + +void LLPanelObjectInventory::updateInventory() +{ +	//llinfos << "inventory arrived: \n" +	//		<< " panel UUID: " << panel->mTaskUUID << "\n" +	//		<< " task  UUID: " << object->mID << llendl; +	// We're still interested in this task's inventory. +	std::set<LLUUID> selected_items; +	BOOL inventory_has_focus = FALSE; +	if (mHaveInventory && mFolders->getNumSelectedDescendants()) +	{ +		mFolders->getSelectionList(selected_items); +		inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders); +	} + +	reset(); + +	LLViewerObject* objectp = gObjectList.findObject(mTaskUUID); +	if (objectp) +	{ +		LLInventoryObject* inventory_root = objectp->getInventoryRoot(); +		InventoryObjectList contents; +		objectp->getInventoryContents(contents); +		if (inventory_root) +		{ +			createFolderViews(inventory_root, contents); +			mHaveInventory = TRUE; +			mIsInventoryEmpty = FALSE; +			mFolders->setEnabled(TRUE); +		} +		else +		{ +			// TODO: create an empty inventory +			mIsInventoryEmpty = TRUE; +			mHaveInventory = TRUE; +		} +	} +	else +	{ +		// TODO: create an empty inventory +		mIsInventoryEmpty = TRUE; +		mHaveInventory = TRUE; +	} + +	// restore previous selection +	std::set<LLUUID>::iterator selection_it; +	BOOL first_item = TRUE; +	for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it) +	{ +		LLFolderViewItem* selected_item = mFolders->getItemByID(*selection_it); +		if (selected_item) +		{ +			//HACK: "set" first item then "change" each other one to get keyboard focus right +			if (first_item) +			{ +				mFolders->setSelection(selected_item, TRUE, inventory_has_focus); +				first_item = FALSE; +			} +			else +			{ +				mFolders->changeSelection(selected_item, TRUE); +			} +		} +	} + +	mFolders->requestArrange(); +	mInventoryNeedsUpdate = FALSE; +} + +// *FIX: This is currently a very expensive operation, because we have +// to iterate through the inventory one time for each category. This +// leads to an N^2 based on the category count. This could be greatly +// speeded with an efficient multimap implementation, but we don't +// have that in our current arsenal. +void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root, InventoryObjectList& contents) +{ +	if (!inventory_root) +	{ +		return; +	} +	// Create a visible root category. +	LLTaskInvFVBridge* bridge = NULL; +	bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root); +	if(bridge) +	{ +		LLFolderViewFolder* new_folder = NULL; +		LLFolderViewFolder::Params p; +		p.name = inventory_root->getName(); +		p.icon = LLUI::getUIImage("Inv_FolderClosed"); +		p.icon_open = LLUI::getUIImage("Inv_FolderOpen"); +		p.root = mFolders; +		p.listener = bridge; +		new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p); +		new_folder->addToFolder(mFolders, mFolders); +		new_folder->toggleOpen(); + +		createViewsForCategory(&contents, inventory_root, new_folder); +	} +} + +typedef std::pair<LLInventoryObject*, LLFolderViewFolder*> obj_folder_pair; + +void LLPanelObjectInventory::createViewsForCategory(InventoryObjectList* inventory,  +											  LLInventoryObject* parent, +											  LLFolderViewFolder* folder) +{ +	// Find all in the first pass +	LLDynamicArray<obj_folder_pair*> child_categories; +	LLTaskInvFVBridge* bridge; +	LLFolderViewItem* view; + +	InventoryObjectList::iterator it = inventory->begin(); +	InventoryObjectList::iterator end = inventory->end(); +	for( ; it != end; ++it) +	{ +		LLInventoryObject* obj = *it; + +		if(parent->getUUID() == obj->getParentUUID()) +		{ +			bridge = LLTaskInvFVBridge::createObjectBridge(this, obj); +			if(!bridge) +			{ +				continue; +			} +			if(LLAssetType::AT_CATEGORY == obj->getType()) +			{ +				LLFolderViewFolder::Params p; +				p.name = obj->getName(); +				p.icon = LLUI::getUIImage("Inv_FolderClosed"); +				p.icon_open = LLUI::getUIImage("Inv_FolderOpen"); +				p.root = mFolders; +				p.listener = bridge; +				view = LLUICtrlFactory::create<LLFolderViewFolder>(p); +				child_categories.put(new obj_folder_pair(obj, +														 (LLFolderViewFolder*)view)); +			} +			else +			{ +				LLFolderViewItem::Params params; +				params.name(obj->getName()); +				params.icon(bridge->getIcon()); +				params.creation_date(bridge->getCreationDate()); +				params.root(mFolders); +				params.listener(bridge); +				params.rect(LLRect()); +				view = LLUICtrlFactory::create<LLFolderViewItem> (params); +			} +			view->addToFolder(folder, mFolders); +		} +	} + +	// now, for each category, do the second pass +	for(S32 i = 0; i < child_categories.count(); i++) +	{ +		createViewsForCategory(inventory, child_categories[i]->first, +							   child_categories[i]->second ); +		delete child_categories[i]; +	} +} + +void LLPanelObjectInventory::refresh() +{ +	//llinfos << "LLPanelObjectInventory::refresh()" << llendl; +	BOOL has_inventory = FALSE; +	const BOOL non_root_ok = TRUE; +	LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(NULL, non_root_ok); +	if(node) +	{ +		LLViewerObject* object = node->getObject(); +		if(object && ((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1) +					  || (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1))) +		{ +			// determine if we need to make a request. Start with a +			// default based on if we have inventory at all. +			BOOL make_request = !mHaveInventory; + +			// If the task id is different than what we've stored, +			// then make the request. +			if(mTaskUUID != object->mID) +			{ +				mTaskUUID = object->mID; +				make_request = TRUE; + +				// This is a new object so pre-emptively clear the contents +				// Otherwise we show the old stuff until the update comes in +				clearContents(); + +				// Register for updates from this object, +				registerVOInventoryListener(object,NULL); +			} + +			// Based on the node information, we may need to dirty the +			// object inventory and get it again. +			if(node->mValid) +			{ +				if(node->mInventorySerial != object->getInventorySerial() || object->isInventoryDirty()) +				{ +					make_request = TRUE; +				} +			} + +			// do the request if necessary. +			if(make_request) +			{ +				requestVOInventory(); +			} +			has_inventory = TRUE; +		} +	} +	if(!has_inventory) +	{ +		mTaskUUID = LLUUID::null; +		removeVOInventoryListener(); +		clearContents(); +	} +	//llinfos << "LLPanelObjectInventory::refresh() " << mTaskUUID << llendl; +} + +void LLPanelObjectInventory::removeSelectedItem() +{ +	if(mFolders) +	{ +		mFolders->removeSelectedItems(); +	} +} + +void LLPanelObjectInventory::startRenamingSelectedItem() +{ +	if(mFolders) +	{ +		mFolders->startRenamingSelectedItem(); +	} +} + +void LLPanelObjectInventory::draw() +{ +	LLPanel::draw(); + +	if(mIsInventoryEmpty) +	{ +		if((LLUUID::null != mTaskUUID) && (!mHaveInventory)) +		{ +			LLFontGL::getFontSansSerif()->renderUTF8(LLTrans::getString("LoadingContents"), 0, +													 (S32)(getRect().getWidth() * 0.5f), +													 10, +													 LLColor4( 1, 1, 1, 1 ), +													 LLFontGL::HCENTER, +													 LLFontGL::BOTTOM); +		} +		else if(mHaveInventory) +		{ +			LLFontGL::getFontSansSerif()->renderUTF8(LLTrans::getString("NoContents"), 0, +													 (S32)(getRect().getWidth() * 0.5f), +													 10, +													 LLColor4( 1, 1, 1, 1 ), +													 LLFontGL::HCENTER, +													 LLFontGL::BOTTOM); +		} +	} +} + +void LLPanelObjectInventory::deleteAllChildren() +{ +	mScroller = NULL; +	mFolders = NULL; +	LLView::deleteAllChildren(); +} + +BOOL LLPanelObjectInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg) +{ +	if (mFolders && mHaveInventory) +	{ +		LLFolderViewItem* folderp = mFolders->getNextFromChild(NULL); +		if (!folderp) +		{ +			return FALSE; +		} +		// Try to pass on unmodified mouse coordinates +		S32 local_x = x - mFolders->getRect().mLeft; +		S32 local_y = y - mFolders->getRect().mBottom; + +		if (mFolders->pointInView(local_x, local_y)) +		{ +			return mFolders->handleDragAndDrop(local_x, local_y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); +		} +		else +		{ +			//force mouse coordinates to be inside folder rectangle +			return mFolders->handleDragAndDrop(5, 1, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); +		} +	} +	else +	{ +		return FALSE; +	} +} + +//static +void LLPanelObjectInventory::idle(void* user_data) +{ +	LLPanelObjectInventory* self = (LLPanelObjectInventory*)user_data; + + +	if (self->mInventoryNeedsUpdate) +	{ +		self->updateInventory(); +	} +} diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h index 7a39d8fabc..6722bb212e 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/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 5197a9bbc3..3cf17fb7f2 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -1,273 +1,244 @@ -/**
 - * @file LLSidepanelInventory.cpp
 - * @brief Side Bar "Inventory" 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 "llsidepanelinventory.h"
 -
 -#include "llagent.h"
 -#include "llbutton.h"
 -#include "llinventorybridge.h"
 -#include "llinventorypanel.h"
 -#include "llpanelmaininventory.h"
 -#include "llsidepanelobjectinfo.h"
 -#include "lltabcontainer.h"
 -
 -static const S32 LANDMARK_FOLDERS_MENU_WIDTH = 250;
 -static const std::string AGENT_INFO_TYPE			= "agent";
 -static const std::string CREATE_LANDMARK_INFO_TYPE	= "create_landmark";
 -static const std::string LANDMARK_INFO_TYPE			= "landmark";
 -static const std::string REMOTE_PLACE_INFO_TYPE		= "remote_place";
 -static const std::string TELEPORT_HISTORY_INFO_TYPE	= "teleport_history";
 -
 -static LLRegisterPanelClassWrapper<LLSidepanelInventory> t_inventory("sidepanel_inventory");
 -
 -LLSidepanelInventory::LLSidepanelInventory()
 -	:	LLPanel(),
 -		mSidepanelObjectInfo(NULL),
 -		mItem(NULL)
 -{
 -
 -	//LLUICtrlFactory::getInstance()->buildPanel(this, "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()
 -}
 -
 -LLSidepanelInventory::~LLSidepanelInventory()
 -{
 -}
 -
 -BOOL LLSidepanelInventory::postBuild()
 -{
 -	mInfoBtn = getChild<LLButton>("info_btn");
 -	mInfoBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onInfoButtonClicked, this));
 -
 -	mShareBtn = getChild<LLButton>("share_btn");
 -	mShareBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onShareButtonClicked, this));
 -
 -	mShareBtn = getChild<LLButton>("share_btn");
 -	mShareBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onShareButtonClicked, this));
 -
 -	mWearBtn = getChild<LLButton>("wear_btn");
 -	mWearBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onWearButtonClicked, this));
 -
 -	mPlayBtn = getChild<LLButton>("play_btn");
 -	mPlayBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onPlayButtonClicked, this));
 -
 -	mTeleportBtn = getChild<LLButton>("teleport_btn");
 -	mTeleportBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onTeleportButtonClicked, this));
 -
 -	mOverflowBtn = getChild<LLButton>("overflow_btn");
 -	mOverflowBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onOverflowButtonClicked, this));
 -
 -	mTabContainer = getChild<LLTabContainer>("Inventory Tabs");
 -	mSidepanelObjectInfo = getChild<LLSidepanelObjectInfo>("sidepanel_object_info");
 -
 -	mPanelMainInventory = getChild<LLPanelMainInventory>("panel_main_inventory");
 -	mPanelMainInventory->setSelectCallback(boost::bind(&LLSidepanelInventory::onSelectionChange, this, _1, _2));
 -
 -	LLButton* back_btn = mSidepanelObjectInfo->getChild<LLButton>("back_btn");
 -	back_btn->setClickedCallback(boost::bind(&LLSidepanelInventory::onBackButtonClicked, this));
 -
 -	return TRUE;
 -}
 -
 -void LLSidepanelInventory::onOpen(const LLSD& key)
 -{
 -	if(mSidepanelObjectInfo == NULL || key.size() == 0)
 -		return;
 -
 -	mItem = NULL;
 -
 -	LLInventoryItem* item = gInventory.getItem(key["id"].asUUID());
 -	if (!item)
 -	{
 -		return;
 -	}
 -	setItem(item);
 -	toggleObjectInfoPanel(TRUE);
 -}
 -
 -void LLSidepanelInventory::setItem(LLInventoryItem* item)
 -{
 -	if (!mSidepanelObjectInfo || !item)
 -		return;
 -
 -	mItem = item;
 -
 -	LLAssetType::EType item_type = mItem->getActualType();
 -	if (item_type == LLAssetType::AT_LINK)
 -	{
 -		mItem = gInventory.getItem(mItem->getLinkedUUID());
 -		if (mItem.isNull())
 -			return;
 -	}
 -
 -	// Check if item is in agent's inventory and he has the permission to modify it.
 -	BOOL is_object_editable = gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.getRootFolderID()) &&
 -		mItem->getPermissions().allowModifyBy(gAgent.getID());
 -
 -	mInfoBtn->setEnabled(is_object_editable);
 -	// mSaveBtn->setEnabled(is_object_editable);
 -
 -	mSidepanelObjectInfo->displayItemInfo(mItem);
 -}
 -
 -void LLSidepanelInventory::onInfoButtonClicked()
 -{
 -	LLInventoryItem *item = getSelectedItem();
 -	if (item)
 -	{
 -		setItem(item);
 -		toggleObjectInfoPanel(TRUE);
 -	}
 -}
 -
 -void LLSidepanelInventory::onShareButtonClicked()
 -{
 -}
 -
 -void LLSidepanelInventory::performActionOnSelection(const std::string &action)
 -{
 -	LLInventoryPanel *panel = mPanelMainInventory->getActivePanel();
 -	LLFolderViewItem* current_item = panel->getRootFolder()->getCurSelectedItem();
 -	if (!current_item)
 -	{
 -		return;
 -	}
 -	current_item->getListener()->performAction(panel->getRootFolder(), panel->getModel(), action);
 -}
 -
 -void LLSidepanelInventory::onWearButtonClicked()
 -{
 -	performActionOnSelection("wear");
 -	performActionOnSelection("attach");
 -}
 -
 -void LLSidepanelInventory::onPlayButtonClicked()
 -{
 -	performActionOnSelection("activate");
 -}
 -
 -void LLSidepanelInventory::onTeleportButtonClicked()
 -{
 -	performActionOnSelection("teleport");
 -}
 -
 -void LLSidepanelInventory::onOverflowButtonClicked()
 -{
 -}
 -
 -void LLSidepanelInventory::onBackButtonClicked()
 -{
 -	if (!mSidepanelObjectInfo)
 -		return;
 -	
 -	toggleObjectInfoPanel(FALSE);
 -
 -	
 -	updateVerbs();
 -}
 -
 -void LLSidepanelInventory::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)
 -{
 -	updateVerbs();
 -}
 -
 -void LLSidepanelInventory::toggleObjectInfoPanel(BOOL visible)
 -{
 -	if (!mSidepanelObjectInfo)
 -		return;
 -
 -	mSidepanelObjectInfo->setVisible(visible);
 -	mTabContainer->setVisible(!visible);
 -
 -	if (visible)
 -	{
 -		mSidepanelObjectInfo->reset();
 -		mSidepanelObjectInfo->setEditMode(FALSE);
 -
 -		LLRect rect = getRect();
 -		LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom);
 -		mSidepanelObjectInfo->reshape(new_rect.getWidth(),new_rect.getHeight());
 -	}
 -}
 -
 -void LLSidepanelInventory::updateVerbs()
 -{
 -	mInfoBtn->setEnabled(FALSE);
 -	mShareBtn->setEnabled(FALSE);
 -
 -	mWearBtn->setVisible(FALSE);
 -	mWearBtn->setEnabled(FALSE);
 -	mPlayBtn->setVisible(FALSE);
 -	mPlayBtn->setEnabled(FALSE);
 - 	mTeleportBtn->setVisible(FALSE);
 - 	mTeleportBtn->setEnabled(FALSE);
 -	
 -	const LLInventoryItem *item = getSelectedItem();
 -	if (!item)
 -		return;
 -
 -	mInfoBtn->setEnabled(TRUE);
 -	mShareBtn->setEnabled(TRUE);
 -
 -	switch(item->getInventoryType())
 -	{
 -		case LLInventoryType::IT_WEARABLE:
 -		case LLInventoryType::IT_OBJECT:
 -		case LLInventoryType::IT_ATTACHMENT:
 -			mWearBtn->setVisible(TRUE);
 -			mWearBtn->setEnabled(TRUE);
 -			break;
 -		case LLInventoryType::IT_SOUND:
 -		case LLInventoryType::IT_GESTURE:
 -		case LLInventoryType::IT_ANIMATION:
 -			mPlayBtn->setVisible(TRUE);
 -			mPlayBtn->setEnabled(TRUE);
 -			break;
 -		case LLInventoryType::IT_LANDMARK:
 -			mTeleportBtn->setVisible(TRUE);
 -			mTeleportBtn->setEnabled(TRUE);
 -			break;
 -		default:
 -			break;
 -	}
 -}
 -
 -LLInventoryItem *LLSidepanelInventory::getSelectedItem()
 -{
 -	LLFolderViewItem* current_item = mPanelMainInventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
 -	if (!current_item)
 -	{
 -		return NULL;
 -	}
 -	const LLUUID &item_id = current_item->getListener()->getUUID();
 -	LLInventoryItem *item = gInventory.getItem(item_id);
 -	return item;
 -}
 +/** + * @file LLSidepanelInventory.cpp + * @brief Side Bar "Inventory" 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 "llsidepanelinventory.h" + +#include "llagent.h" +#include "llbutton.h" +#include "llinventorybridge.h" +#include "llinventorypanel.h" +#include "llpanelmaininventory.h" +#include "llsidepanelobjectinfo.h" +#include "lltabcontainer.h" + +static const S32 LANDMARK_FOLDERS_MENU_WIDTH = 250; +static const std::string AGENT_INFO_TYPE			= "agent"; +static const std::string CREATE_LANDMARK_INFO_TYPE	= "create_landmark"; +static const std::string LANDMARK_INFO_TYPE			= "landmark"; +static const std::string REMOTE_PLACE_INFO_TYPE		= "remote_place"; +static const std::string TELEPORT_HISTORY_INFO_TYPE	= "teleport_history"; + +static LLRegisterPanelClassWrapper<LLSidepanelInventory> t_inventory("sidepanel_inventory"); + +LLSidepanelInventory::LLSidepanelInventory() +	:	LLPanel(), +		mSidepanelObjectInfo(NULL) +{ + +	//LLUICtrlFactory::getInstance()->buildPanel(this, "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() +} + +LLSidepanelInventory::~LLSidepanelInventory() +{ +} + +BOOL LLSidepanelInventory::postBuild() +{ +	mInfoBtn = getChild<LLButton>("info_btn"); +	mInfoBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onInfoButtonClicked, this)); + +	mShareBtn = getChild<LLButton>("share_btn"); +	mShareBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onShareButtonClicked, this)); + +	mShareBtn = getChild<LLButton>("share_btn"); +	mShareBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onShareButtonClicked, this)); + +	mWearBtn = getChild<LLButton>("wear_btn"); +	mWearBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onWearButtonClicked, this)); + +	mPlayBtn = getChild<LLButton>("play_btn"); +	mPlayBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onPlayButtonClicked, this)); + +	mTeleportBtn = getChild<LLButton>("teleport_btn"); +	mTeleportBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onTeleportButtonClicked, this)); + +	mOverflowBtn = getChild<LLButton>("overflow_btn"); +	mOverflowBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onOverflowButtonClicked, this)); + +	mTabContainer = getChild<LLTabContainer>("Inventory Tabs"); +	mSidepanelObjectInfo = getChild<LLSidepanelObjectInfo>("sidepanel_object_info"); + +	mPanelMainInventory = getChild<LLPanelMainInventory>("panel_main_inventory"); +	mPanelMainInventory->setSelectCallback(boost::bind(&LLSidepanelInventory::onSelectionChange, this, _1, _2)); + +	LLButton* back_btn = mSidepanelObjectInfo->getChild<LLButton>("back_btn"); +	back_btn->setClickedCallback(boost::bind(&LLSidepanelInventory::onBackButtonClicked, this)); + +	return TRUE; +} + +void LLSidepanelInventory::onOpen(const LLSD& key) +{ +	if(key.size() == 0) +		return; + +	mSidepanelObjectInfo->reset(); + +	if (key.has("id")) +	{ +		mSidepanelObjectInfo->setItemID(key["id"].asUUID()); +	} +	 +	if (key.has("object")) +	{ +		mSidepanelObjectInfo->setObjectID(key["object"].asUUID()); +	} + +	toggleObjectInfoPanel(TRUE); +} + +void LLSidepanelInventory::onInfoButtonClicked() +{ +	LLInventoryItem *item = getSelectedItem(); +	if (item) +	{ +		mSidepanelObjectInfo->reset(); +		mSidepanelObjectInfo->setItemID(item->getUUID()); +		toggleObjectInfoPanel(TRUE); +	} +} + +void LLSidepanelInventory::onShareButtonClicked() +{ +} + +void LLSidepanelInventory::performActionOnSelection(const std::string &action) +{ +	LLInventoryPanel *panel = mPanelMainInventory->getActivePanel(); +	LLFolderViewItem* current_item = panel->getRootFolder()->getCurSelectedItem(); +	if (!current_item) +	{ +		return; +	} +	current_item->getListener()->performAction(panel->getRootFolder(), panel->getModel(), action); +} + +void LLSidepanelInventory::onWearButtonClicked() +{ +	performActionOnSelection("wear"); +	performActionOnSelection("attach"); +} + +void LLSidepanelInventory::onPlayButtonClicked() +{ +	performActionOnSelection("activate"); +} + +void LLSidepanelInventory::onTeleportButtonClicked() +{ +	performActionOnSelection("teleport"); +} + +void LLSidepanelInventory::onOverflowButtonClicked() +{ +} + +void LLSidepanelInventory::onBackButtonClicked() +{ +	toggleObjectInfoPanel(FALSE); +	updateVerbs(); +} + +void LLSidepanelInventory::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action) +{ +	updateVerbs(); +} + +void LLSidepanelInventory::toggleObjectInfoPanel(BOOL visible) +{ +	mSidepanelObjectInfo->setVisible(visible); +	mTabContainer->setVisible(!visible); + +	if (visible) +	{ +		mSidepanelObjectInfo->reset(); +		mSidepanelObjectInfo->setEditMode(FALSE); + +		LLRect rect = getRect(); +		LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom); +		mSidepanelObjectInfo->reshape(new_rect.getWidth(),new_rect.getHeight()); +	} +} + +void LLSidepanelInventory::updateVerbs() +{ +	mInfoBtn->setEnabled(FALSE); +	mShareBtn->setEnabled(FALSE); + +	mWearBtn->setVisible(FALSE); +	mWearBtn->setEnabled(FALSE); +	mPlayBtn->setVisible(FALSE); +	mPlayBtn->setEnabled(FALSE); + 	mTeleportBtn->setVisible(FALSE); + 	mTeleportBtn->setEnabled(FALSE); +	 +	const LLInventoryItem *item = getSelectedItem(); +	if (!item) +		return; + +	mInfoBtn->setEnabled(TRUE); +	mShareBtn->setEnabled(TRUE); + +	switch(item->getInventoryType()) +	{ +		case LLInventoryType::IT_WEARABLE: +		case LLInventoryType::IT_OBJECT: +		case LLInventoryType::IT_ATTACHMENT: +			mWearBtn->setVisible(TRUE); +			mWearBtn->setEnabled(TRUE); +			break; +		case LLInventoryType::IT_SOUND: +		case LLInventoryType::IT_GESTURE: +		case LLInventoryType::IT_ANIMATION: +			mPlayBtn->setVisible(TRUE); +			mPlayBtn->setEnabled(TRUE); +			break; +		case LLInventoryType::IT_LANDMARK: +			mTeleportBtn->setVisible(TRUE); +			mTeleportBtn->setEnabled(TRUE); +			break; +		default: +			break; +	} +} + +LLInventoryItem *LLSidepanelInventory::getSelectedItem() +{ +	LLFolderViewItem* current_item = mPanelMainInventory->getActivePanel()->getRootFolder()->getCurSelectedItem(); +	if (!current_item) +	{ +		return NULL; +	} +	const LLUUID &item_id = current_item->getListener()->getUUID(); +	LLInventoryItem *item = gInventory.getItem(item_id); +	return item; +} diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index 784f5e43b7..62eeecc5e2 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -1,85 +1,80 @@ -/** 
 - * @file LLSidepanelInventory.h
 - * @brief Side Bar "Inventory" 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_LLSIDEPANELINVENTORY_H
 -#define LL_LLSIDEPANELINVENTORY_H
 -
 -#include "llpanel.h"
 -
 -class LLInventoryItem;
 -class LLSidepanelObjectInfo;
 -class LLTabContainer;
 -class LLPanelMainInventory;
 -class LLFolderViewItem;
 -
 -class LLSidepanelInventory : public LLPanel
 -{
 -public:
 -	LLSidepanelInventory();
 -	virtual ~LLSidepanelInventory();
 -
 -	/*virtual*/ BOOL postBuild();
 -	/*virtual*/ void onOpen(const LLSD& key);
 -
 -	void setItem(LLInventoryItem* item);
 -
 -protected:
 -	LLInventoryItem *getSelectedItem();
 -	void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
 -	void onTabSelected();
 -	void toggleObjectInfoPanel(BOOL visible);
 -	void updateVerbs();
 -	void performActionOnSelection(const std::string &action);
 -
 -	LLTabContainer*				mTabContainer;
 -	LLSidepanelObjectInfo*		mSidepanelObjectInfo;
 -	LLPanelMainInventory*		mPanelMainInventory;
 -
 -	void 						onInfoButtonClicked();
 -	void 						onShareButtonClicked();
 -	void 						onWearButtonClicked();
 -	void 						onPlayButtonClicked();
 -	void 						onTeleportButtonClicked();
 -	void 						onOverflowButtonClicked();
 -	void 						onBackButtonClicked();
 -	
 -	LLButton*					mInfoBtn;
 -	LLButton*					mShareBtn;
 -	LLButton*					mWearBtn;
 -	LLButton*					mPlayBtn;
 -	LLButton*					mTeleportBtn;
 -	LLButton*					mOverflowBtn;
 -
 -	// Pointer to a item
 -	LLPointer<LLInventoryItem>	mItem;
 -};
 -
 -#endif //LL_LLSIDEPANELINVENTORY_H
 +/**  + * @file LLSidepanelInventory.h + * @brief Side Bar "Inventory" 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_LLSIDEPANELINVENTORY_H +#define LL_LLSIDEPANELINVENTORY_H + +#include "llpanel.h" + +class LLInventoryItem; +class LLSidepanelObjectInfo; +class LLTabContainer; +class LLPanelMainInventory; +class LLFolderViewItem; + +class LLSidepanelInventory : public LLPanel +{ +public: +	LLSidepanelInventory(); +	virtual ~LLSidepanelInventory(); + +	/*virtual*/ BOOL postBuild(); +	/*virtual*/ void onOpen(const LLSD& key); + +protected: +	LLInventoryItem *getSelectedItem(); +	void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action); +	void onTabSelected(); +	void toggleObjectInfoPanel(BOOL visible); +	void updateVerbs(); +	void performActionOnSelection(const std::string &action); + +	LLTabContainer*				mTabContainer; +	LLSidepanelObjectInfo*		mSidepanelObjectInfo; +	LLPanelMainInventory*		mPanelMainInventory; + +	void 						onInfoButtonClicked(); +	void 						onShareButtonClicked(); +	void 						onWearButtonClicked(); +	void 						onPlayButtonClicked(); +	void 						onTeleportButtonClicked(); +	void 						onOverflowButtonClicked(); +	void 						onBackButtonClicked(); +	 +	LLButton*					mInfoBtn; +	LLButton*					mShareBtn; +	LLButton*					mWearBtn; +	LLButton*					mPlayBtn; +	LLButton*					mTeleportBtn; +	LLButton*					mOverflowBtn; +}; + +#endif //LL_LLSIDEPANELINVENTORY_H diff --git a/indra/newview/skins/default/html/da/loading/loading.html b/indra/newview/skins/default/html/da/loading/loading.html index cdad5702b9..5f3426eb60 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/>   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/>   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 3eddbc24f5..44a621b216 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/>   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/>   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 34e5c84c4d..1c62d2f73e 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/>   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/>   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 f03284ba8c..c4260b34c0 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/>   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/>   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 23c0ef03bc..b3953448e9 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/>   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/>   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 ade91f76c2..ab15a073ba 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/>   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/>   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 0f9af31f6e..ab37e41f04 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/>   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/>   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 069dc5d12f..35cf74a35f 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/>   ロード中...
 -		</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/>   ロード中... +		</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 39a8691f3f..0215bd7e47 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/>   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/>   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 515890c2d5..50f3dfb0c5 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/>   Ł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/>   Ł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 635ea62406..a83e1123d0 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/>   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/>   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 dcc0d73c1a..892c0b9f7f 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/>   Загрузка...
 -		</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/>   Загрузка... +		</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 e7812e7c8e..1ac07bff34 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/>   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/>   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 0f67994635..3b5b8679b4 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/>   Завантаж...
 -		</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/>   Завантаж... +		</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 462ea291d9..d1d5d25c92 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/>   请等待...
 -		</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/>   请等待... +		</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 74b7c7dd72..b4d0fa20ef 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/de/panel_edit_profile.xml b/indra/newview/skins/default/xui/de/panel_edit_profile.xml index 1f67e0231d..3203eacdb5 100644 --- a/indra/newview/skins/default/xui/de/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/de/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="Einwohner" />
 -   <string name="AcctTypeTrial"
 -    value="Test" />
 -   <string name="AcctTypeCharterMember"
 -    value="Charta-Mitglied" />
 -   <string name="AcctTypeEmployee"
 -    value="Linden Lab-Mitarbeiter" />
 -   <string name="PaymentInfoUsed"
 -    value="Zahlungsinfo verwendet" />
 -   <string name="PaymentInfoOnFile"
 -    value="Zahlungsinfo archiviert" />
 -   <string name="NoPaymentInfoOnFile"
 -    value="Keine Zahlungsinfo archiviert" />
 -   <string name="AgeVerified"
 -    value="Altersgeprüft" />
 -   <string name="NotAgeVerified"
 -    value="Nicht altersgeprüft" />
 -   <string name="partner_edit_link_url">
 -       http://www.secondlife.com/account/partners.php?lang=de
 -   </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">
 -	Antwort für Beschäftigt-Modus:
 -      </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="Einwohner" /> +   <string name="AcctTypeTrial" +    value="Test" /> +   <string name="AcctTypeCharterMember" +    value="Charta-Mitglied" /> +   <string name="AcctTypeEmployee" +    value="Linden Lab-Mitarbeiter" /> +   <string name="PaymentInfoUsed" +    value="Zahlungsinfo verwendet" /> +   <string name="PaymentInfoOnFile" +    value="Zahlungsinfo archiviert" /> +   <string name="NoPaymentInfoOnFile" +    value="Keine Zahlungsinfo archiviert" /> +   <string name="AgeVerified" +    value="Altersgeprüft" /> +   <string name="NotAgeVerified" +    value="Nicht altersgeprüft" /> +   <string name="partner_edit_link_url"> +       http://www.secondlife.com/account/partners.php?lang=de +   </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"> +	Antwort für Beschäftigt-Modus: +      </text> +    </panel> +    </panel> +</panel> diff --git a/indra/newview/skins/default/xui/en/floater_inventory.xml b/indra/newview/skins/default/xui/en/floater_inventory.xml index 6da4f9e6f3..3e19bdee0f 100644 --- a/indra/newview/skins/default/xui/en/floater_inventory.xml +++ b/indra/newview/skins/default/xui/en/floater_inventory.xml @@ -1,45 +1,45 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 -<floater
 - legacy_header_height="18"
 - auto_tile="true"
 - can_resize="true"
 - height="563"
 - layout="topleft"
 - min_height="150"
 - min_width="240"
 - name="Inventory"
 - help_topic="inventory"
 - save_rect="true"
 - save_visibility="true"
 - single_instance="true"
 - title="Inventory"
 - width="467">
 -    <floater.string
 -     name="Title">
 -        Inventory
 -    </floater.string>
 -    <floater.string
 -     name="TitleFetching">
 -        Inventory (Fetching [ITEM_COUNT] Items...) [FILTER]
 -    </floater.string>
 -    <floater.string
 -     name="TitleCompleted">
 -        Inventory ([ITEM_COUNT] Items) [FILTER]
 -    </floater.string>
 -    <floater.string
 -     name="Fetched">
 -        Fetched
 -    </floater.string>
 -<panel
 -     bottom="560"
 -	 class="panel_main_inventory"
 -	 filename="panel_main_inventory.xml"
 -	 follows="all"
 -	 layout="topleft"
 -	 left="0"
 -	 label="Inventory Panel"
 -	 name="Inventory Panel"
 -	 top="15"
 -	 width="467">
 -</panel>
 -</floater>
 +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + auto_tile="true" + can_resize="true" + height="563" + layout="topleft" + min_height="150" + min_width="240" + name="Inventory" + help_topic="inventory" + save_rect="true" + save_visibility="true" + single_instance="true" + title="Inventory" + width="467"> +    <floater.string +     name="Title"> +        Inventory +    </floater.string> +    <floater.string +     name="TitleFetching"> +        Inventory (Fetching [ITEM_COUNT] Items...) [FILTER] +    </floater.string> +    <floater.string +     name="TitleCompleted"> +        Inventory ([ITEM_COUNT] Items) [FILTER] +    </floater.string> +    <floater.string +     name="Fetched"> +        Fetched +    </floater.string> +<panel +     bottom="560" +	 class="panel_main_inventory" +	 filename="panel_main_inventory.xml" +	 follows="all" +	 layout="topleft" +	 left="0" +	 label="Inventory Panel" +	 name="Inventory Panel" +	 top="15" +	 width="467"> +</panel> +</floater> diff --git a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml index edff1a093a..7eaf4fa3ab 100644 --- a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml @@ -1,112 +1,112 @@ -<?xml version="1.0" encoding="utf-8"?>
 -<menu
 -         create_jump_keys="true"
 -         layout="topleft"
 -         mouse_opaque="false"
 -         visible="false"
 -         name="Gear Menu">
 -  <menu_item_call
 -   label="View Profile"
 -   layout="topleft"
 -   enabled="true" 
 -   name="view_profile">
 -    <menu_item_call.on_click
 -     function="InspectAvatar.ViewProfile"/>
 -  </menu_item_call>
 -  <menu_item_call
 -   label="Add Friend"
 -   layout="topleft"
 -   name="add_friend">
 -    <menu_item_call.on_click
 -     function="InspectAvatar.AddFriend"/>
 -  </menu_item_call>
 -  <menu_item_call
 -   label="IM"
 -   layout="topleft"
 -   name="im">
 -    <menu_item_call.on_click
 -     function="InspectAvatar.IM"/>
 -  </menu_item_call>
 -  <menu_item_call
 -   label="Call"
 -   layout="topleft"
 -   enabled="true"
 -   name="call">
 -  </menu_item_call>
 -  <menu_item_call
 -   label="Teleport"
 -   layout="topleft"
 -   name="teleport">
 -    <menu_item_call.on_click
 -     function="InspectAvatar.Teleport"/>
 -  </menu_item_call>
 -  <menu_item_call
 -   label="Invite to Group"
 -   layout="topleft"
 -   name="invite_to_group">
 -    <menu_item_call.on_click
 -     function="InspectAvatar.InviteToGroup"/>
 -  </menu_item_call>
 -  <menu_item_separator layout="topleft" />
 -  <menu_item_call
 -   label="Block"
 -   layout="topleft"
 -   name="block">
 -    <menu_item_call.on_click
 -     function="InspectAvatar.Block"/>
 -  </menu_item_call>
 -  <menu_item_call
 -   label="Report"
 -   layout="topleft"
 -   name="report">
 -    <menu_item_call.on_click
 -     function="InspectAvatar.Report"/>
 -  </menu_item_call>  
 -  <menu_item_call
 -   label="Freeze"
 -   name="freeze">
 -    <menu_item_call.on_click
 -     function="InspectAvatar.Freeze"/>
 -    <menu_item_call.on_visible
 -     function="IsGodCustomerService"/>
 -  </menu_item_call>
 -  <menu_item_call
 -   label="Eject"
 -   name="eject">
 -    <menu_item_call.on_click
 -     function="InspectAvatar.Eject"/>
 -    <menu_item_call.on_visible
 -     function="IsGodCustomerService"/>
 -  </menu_item_call>
 -  <menu_item_call
 -   label="Debug"
 -   name="debug">
 -    <menu_item_call.on_click
 -     function="InspectAvatar.Debug"/>
 -    <menu_item_call.on_visible
 -     function="IsGodCustomerService"/>
 -  </menu_item_call>
 -  <menu_item_call
 -   label="Find On Map"
 -   layout="topleft"
 -   name="find_on_map">
 -    <menu_item_call.on_click
 -     function="InspectAvatar.FindOnMap"/>
 -    <menu_item_call.on_visible
 -     function="InspectAvatar.VisibleFindOnMap"/>
 -  </menu_item_call>
 -  <menu_item_call
 -   label="Zoom In"
 -   layout="topleft"
 -   name="zoom_in">
 -    <menu_item_call.on_click
 -     function="InspectAvatar.ZoomIn"/>
 -  </menu_item_call>  
 -  <menu_item_call
 -   label="Pay"
 -   layout="topleft"
 -   name="pay">
 -    <menu_item_call.on_click
 -     function="InspectAvatar.Pay"/>
 -  </menu_item_call>
 +<?xml version="1.0" encoding="utf-8"?> +<menu +         create_jump_keys="true" +         layout="topleft" +         mouse_opaque="false" +         visible="false" +         name="Gear Menu"> +  <menu_item_call +   label="View Profile" +   layout="topleft" +   enabled="true"  +   name="view_profile"> +    <menu_item_call.on_click +     function="InspectAvatar.ViewProfile"/> +  </menu_item_call> +  <menu_item_call +   label="Add Friend" +   layout="topleft" +   name="add_friend"> +    <menu_item_call.on_click +     function="InspectAvatar.AddFriend"/> +  </menu_item_call> +  <menu_item_call +   label="IM" +   layout="topleft" +   name="im"> +    <menu_item_call.on_click +     function="InspectAvatar.IM"/> +  </menu_item_call> +  <menu_item_call +   label="Call" +   layout="topleft" +   enabled="true" +   name="call"> +  </menu_item_call> +  <menu_item_call +   label="Teleport" +   layout="topleft" +   name="teleport"> +    <menu_item_call.on_click +     function="InspectAvatar.Teleport"/> +  </menu_item_call> +  <menu_item_call +   label="Invite to Group" +   layout="topleft" +   name="invite_to_group"> +    <menu_item_call.on_click +     function="InspectAvatar.InviteToGroup"/> +  </menu_item_call> +  <menu_item_separator layout="topleft" /> +  <menu_item_call +   label="Block" +   layout="topleft" +   name="block"> +    <menu_item_call.on_click +     function="InspectAvatar.Block"/> +  </menu_item_call> +  <menu_item_call +   label="Report" +   layout="topleft" +   name="report"> +    <menu_item_call.on_click +     function="InspectAvatar.Report"/> +  </menu_item_call>   +  <menu_item_call +   label="Freeze" +   name="freeze"> +    <menu_item_call.on_click +     function="InspectAvatar.Freeze"/> +    <menu_item_call.on_visible +     function="IsGodCustomerService"/> +  </menu_item_call> +  <menu_item_call +   label="Eject" +   name="eject"> +    <menu_item_call.on_click +     function="InspectAvatar.Eject"/> +    <menu_item_call.on_visible +     function="IsGodCustomerService"/> +  </menu_item_call> +  <menu_item_call +   label="Debug" +   name="debug"> +    <menu_item_call.on_click +     function="InspectAvatar.Debug"/> +    <menu_item_call.on_visible +     function="IsGodCustomerService"/> +  </menu_item_call> +  <menu_item_call +   label="Find On Map" +   layout="topleft" +   name="find_on_map"> +    <menu_item_call.on_click +     function="InspectAvatar.FindOnMap"/> +    <menu_item_call.on_visible +     function="InspectAvatar.VisibleFindOnMap"/> +  </menu_item_call> +  <menu_item_call +   label="Zoom In" +   layout="topleft" +   name="zoom_in"> +    <menu_item_call.on_click +     function="InspectAvatar.ZoomIn"/> +  </menu_item_call>   +  <menu_item_call +   label="Pay" +   layout="topleft" +   name="pay"> +    <menu_item_call.on_click +     function="InspectAvatar.Pay"/> +  </menu_item_call>  </menu>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml index 240822e5ca..19c2bf3496 100644 --- a/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml @@ -1,53 +1,53 @@ -<?xml version="1.0" encoding="utf-8"?>
 -<menu
 -         create_jump_keys="true"
 -         layout="topleft"
 -         mouse_opaque="false"
 -         visible="false"
 -         name="Gear Menu">
 -  <menu_item_call
 -   label="Stand Up"
 -   layout="topleft"
 -   enabled="true"
 -   name="stand_up">
 -    <menu_item_call.on_click
 -     function="Self.StandUp"
 -     parameter="" />
 -    <menu_item_call.on_visible
 -     function="Self.VisibleStandUp" />
 -  </menu_item_call>
 -  <menu_item_call
 -   label="My Appearance"
 -   layout="topleft"
 -   name="my_appearance">
 -    <menu_item_call.on_click
 -     function="ShowFloater"
 -     parameter="appearance" />
 -    <menu_item_call.on_enable
 -     function="Edit.EnableCustomizeAvatar" />
 -  </menu_item_call>
 -  <menu_item_call
 -   label="My Profile"
 -   layout="topleft"
 -   enabled="true" 
 -   name="my_profile">
 -    <menu_item_call.on_click
 -     function="ShowAgentProfile"
 -     parameter="agent" />
 -  </menu_item_call>
 -  <menu_item_call
 -   label="My Friends"
 -   layout="topleft"
 -   name="my_friends">
 -    <menu_item_call.on_click
 -     function="Self.Friends"
 -     parameter="" />
 -  </menu_item_call>
 -  <menu_item_call
 -   label="My Groups"
 -   layout="topleft"
 -   name="my_groups">
 -    <menu_item_call.on_click
 -     function="Self.Groups" />
 -  </menu_item_call>
 +<?xml version="1.0" encoding="utf-8"?> +<menu +         create_jump_keys="true" +         layout="topleft" +         mouse_opaque="false" +         visible="false" +         name="Gear Menu"> +  <menu_item_call +   label="Stand Up" +   layout="topleft" +   enabled="true" +   name="stand_up"> +    <menu_item_call.on_click +     function="Self.StandUp" +     parameter="" /> +    <menu_item_call.on_visible +     function="Self.VisibleStandUp" /> +  </menu_item_call> +  <menu_item_call +   label="My Appearance" +   layout="topleft" +   name="my_appearance"> +    <menu_item_call.on_click +     function="ShowFloater" +     parameter="appearance" /> +    <menu_item_call.on_enable +     function="Edit.EnableCustomizeAvatar" /> +  </menu_item_call> +  <menu_item_call +   label="My Profile" +   layout="topleft" +   enabled="true"  +   name="my_profile"> +    <menu_item_call.on_click +     function="ShowAgentProfile" +     parameter="agent" /> +  </menu_item_call> +  <menu_item_call +   label="My Friends" +   layout="topleft" +   name="my_friends"> +    <menu_item_call.on_click +     function="Self.Friends" +     parameter="" /> +  </menu_item_call> +  <menu_item_call +   label="My Groups" +   layout="topleft" +   name="my_groups"> +    <menu_item_call.on_click +     function="Self.Groups" /> +  </menu_item_call>  </menu>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml index c50278ff8c..9a3fdcc327 100644 --- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml @@ -1,415 +1,415 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 -<panel
 - background_visible="true"
 - follows="all"
 - height="400"
 - label="Things"
 - layout="topleft"
 - min_height="350"
 - min_width="240"
 - name="inventory panel"
 - width="330">
 -    <panel.string
 -     name="Title">
 -        Things
 -    </panel.string>
 -    <filter_editor
 -     text_pad_left="12"
 -     follows="left|top|right"
 -	 font="SanSerif"
 -     height="20"
 -     label="Filter"
 -     layout="topleft"
 -     left="15"
 -     name="inventory search editor"
 -     top="34"
 -     width="300" />
 -    <tab_container
 -     follows="left|top|right|bottom"
 -     height="300"
 -     layout="topleft"
 -     left_delta="-4"
 -     name="inventory filter tabs"
 -     tab_position="top"
 -     top_pad="4"
 -     width="305">
 -        <inventory_panel
 -         follows="left|top|right|bottom"
 -         height="295"
 -         label="All Items"
 -         layout="topleft"
 -         left="1"
 -         name="All Items"
 -         top="16"
 -         width="290" />
 -        <inventory_panel
 -         follows="left|top|right|bottom"
 -         height="295"
 -         label="Recent Items"
 -         layout="topleft"
 -         left_delta="0"
 -         name="Recent Items"
 -         top_delta="0"
 -         width="290" />
 -    </tab_container>
 -    <menu_bar
 -     bg_visible="false"
 -     follows="left|top|right"
 -     height="18"
 -     layout="topleft"
 -     left_delta="0"
 -     mouse_opaque="false"
 -     name="Inventory Menu"
 -     top_delta="-45"
 -     width="290">
 -        <menu
 -         height="101"
 -         label="File"
 -         layout="topleft"
 -         left="0"
 -         mouse_opaque="false"
 -         name="File"
 -         tear_off="true"
 -         top="-117"
 -         width="128">
 -            <menu_item_call
 -             label="Open"
 -             layout="topleft"
 -             name="Open">
 -                <menu_item_call.on_click
 -                 function="Inventory.DoToSelected"
 -                 parameter="open" />
 -            </menu_item_call>
 -            <menu
 -             create_jump_keys="true"
 -             label="Upload"
 -             layout="topleft"
 -             name="upload"
 -             tear_off="true">
 -                <menu_item_call
 -                 label="Image (L$[COST])..."
 -                 layout="topleft"
 -                 name="Upload Image"
 -                 shortcut="control|U">
 -                    <menu_item_call.on_click
 -                     function="File.UploadImage"
 -                     parameter="" />
 -                    <menu_item_call.on_enable
 -                     function="File.EnableUpload" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="Sound (L$[COST])..."
 -                 layout="topleft"
 -                 name="Upload Sound">
 -                    <menu_item_call.on_click
 -                     function="File.UploadSound"
 -                     parameter="" />
 -                    <menu_item_call.on_enable
 -                     function="File.EnableUpload" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="Animation (L$[COST])..."
 -                 layout="topleft"
 -                 name="Upload Animation">
 -                    <menu_item_call.on_click
 -                     function="File.UploadAnim"
 -                     parameter="" />
 -                    <menu_item_call.on_enable
 -                     function="File.EnableUpload" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="Bulk (L$[COST] per file)..."
 -                 layout="topleft"
 -                 name="Bulk Upload">
 -                    <menu_item_call.on_click
 -                     function="File.UploadBulk"
 -                     parameter="" />
 -                </menu_item_call>
 -                <menu_item_separator
 -                 layout="topleft" />
 -            </menu>
 -            <menu_item_separator
 -             layout="topleft" />
 -            <menu_item_call
 -             label="New Window"
 -             layout="topleft"
 -             name="New Window">
 -                <menu_item_call.on_click
 -                 function="Inventory.NewWindow" />
 -            </menu_item_call>
 -            <menu_item_separator
 -             layout="topleft"
 -             name="separator2" />
 -            <menu_item_call
 -             label="Show Filters"
 -             layout="topleft"
 -             name="Show Filters">
 -                <menu_item_call.on_click
 -                 function="Inventory.ShowFilters" />
 -            </menu_item_call>
 -            <menu_item_call
 -             label="Reset Filters"
 -             layout="topleft"
 -             name="Reset Current">
 -                <menu_item_call.on_click
 -                 function="Inventory.ResetFilter" />
 -            </menu_item_call>
 -            <menu_item_call
 -             label="Close All Folders"
 -             layout="topleft"
 -             name="Close All Folders">
 -                <menu_item_call.on_click
 -                 function="Inventory.CloseAllFolders" />
 -            </menu_item_call>
 -            <menu_item_separator
 -             layout="topleft"
 -             name="separator3" />
 -            <menu_item_call
 -             label="Empty Trash"
 -             layout="topleft"
 -             name="Empty Trash">
 -                <menu_item_call.on_click
 -                 function="Inventory.EmptyTrash" />
 -            </menu_item_call>
 -            <menu_item_call
 -             label="Empty Lost And Found"
 -             layout="topleft"
 -             name="Empty Lost And Found">
 -                <menu_item_call.on_click
 -                 function="Inventory.EmptyLostAndFound" />
 -            </menu_item_call>
 -        </menu>
 -        <menu
 -         height="121"
 -         label="Create"
 -         layout="topleft"
 -         left="0"
 -         mouse_opaque="false"
 -         name="Create"
 -         tear_off="true"
 -         top="-201"
 -         width="121">
 -            <menu_item_call
 -             label="New Folder"
 -             layout="topleft"
 -             name="New Folder">
 -                <menu_item_call.on_click
 -                 function="Inventory.DoCreate"
 -                 parameter="category" />
 -            </menu_item_call>
 -            <menu_item_call
 -             label="New Script"
 -             layout="topleft"
 -             name="New Script">
 -                <menu_item_call.on_click
 -                 function="Inventory.DoCreate"
 -                 parameter="lsl" />
 -            </menu_item_call>
 -            <menu_item_call
 -             label="New Note"
 -             layout="topleft"
 -             name="New Note">
 -                <menu_item_call.on_click
 -                 function="Inventory.DoCreate"
 -                 parameter="notecard" />
 -            </menu_item_call>
 -            <menu_item_call
 -             label="New Gesture"
 -             layout="topleft"
 -             name="New Gesture">
 -                <menu_item_call.on_click
 -                 function="Inventory.DoCreate"
 -                 parameter="gesture" />
 -            </menu_item_call>
 -            <menu
 -             height="175"
 -             label="New Clothes"
 -             layout="topleft"
 -             left_delta="0"
 -             mouse_opaque="false"
 -             name="New Clothes"
 -             top_pad="514"
 -             width="125">
 -                <menu_item_call
 -                 label="New Shirt"
 -                 layout="topleft"
 -                 name="New Shirt">
 -                    <menu_item_call.on_click
 -                     function="Inventory.DoCreate"
 -                     parameter="shirt" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="New Pants"
 -                 layout="topleft"
 -                 name="New Pants">
 -                    <menu_item_call.on_click
 -                     function="Inventory.DoCreate"
 -                     parameter="pants" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="New Shoes"
 -                 layout="topleft"
 -                 name="New Shoes">
 -                    <menu_item_call.on_click
 -                     function="Inventory.DoCreate"
 -                     parameter="shoes" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="New Socks"
 -                 layout="topleft"
 -                 name="New Socks">
 -                    <menu_item_call.on_click
 -                     function="Inventory.DoCreate"
 -                     parameter="socks" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="New Jacket"
 -                 layout="topleft"
 -                 name="New Jacket">
 -                    <menu_item_call.on_click
 -                     function="Inventory.DoCreate"
 -                     parameter="jacket" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="New Skirt"
 -                 layout="topleft"
 -                 name="New Skirt">
 -                    <menu_item_call.on_click
 -                     function="Inventory.DoCreate"
 -                     parameter="skirt" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="New Gloves"
 -                 layout="topleft"
 -                 name="New Gloves">
 -                    <menu_item_call.on_click
 -                     function="Inventory.DoCreate"
 -                     parameter="gloves" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="New Undershirt"
 -                 layout="topleft"
 -                 name="New Undershirt">
 -                    <menu_item_call.on_click
 -                     function="Inventory.DoCreate"
 -                     parameter="undershirt" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="New Underpants"
 -                 layout="topleft"
 -                 name="New Underpants">
 -                    <menu_item_call.on_click
 -                     function="Inventory.DoCreate"
 -                     parameter="underpants" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="New Alpha"
 -                 layout="topleft"
 -                 name="New Alpha">
 -                    <menu_item_call.on_click
 -                     function="Inventory.DoCreate"
 -                     parameter="alpha" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="New Tattoo"
 -                 layout="topleft"
 -                 name="New Tattoo">
 -                    <menu_item_call.on_click
 -                     function="Inventory.DoCreate"
 -                     parameter="tattoo" />
 -                </menu_item_call>
 -            </menu>
 -            <menu
 -             height="85"
 -             label="New Body Parts"
 -             layout="topleft"
 -             left_delta="0"
 -             mouse_opaque="false"
 -             name="New Body Parts"
 -             top_pad="514"
 -             width="118">
 -                <menu_item_call
 -                 label="New Shape"
 -                 layout="topleft"
 -                 name="New Shape">
 -                    <menu_item_call.on_click
 -                     function="Inventory.DoCreate"
 -                     parameter="shape" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="New Skin"
 -                 layout="topleft"
 -                 name="New Skin">
 -                    <menu_item_call.on_click
 -                     function="Inventory.DoCreate"
 -                     parameter="skin" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="New Hair"
 -                 layout="topleft"
 -                 name="New Hair">
 -                    <menu_item_call.on_click
 -                     function="Inventory.DoCreate"
 -                     parameter="hair" />
 -                </menu_item_call>
 -                <menu_item_call
 -                 label="New Eyes"
 -                 layout="topleft"
 -                 name="New Eyes">
 -                    <menu_item_call.on_click
 -                     function="Inventory.DoCreate"
 -                     parameter="eyes" />
 -                </menu_item_call>
 -            </menu>
 -        </menu>
 -        <menu
 -         height="49"
 -         label="Sort"
 -         layout="topleft"
 -         left="0"
 -         mouse_opaque="false"
 -         name="Sort"
 -         tear_off="true"
 -         top="-113"
 -         width="118">
 -            <menu_item_check
 -             control_name="Inventory.SortByName"
 -             label="By Name"
 -             layout="topleft"
 -             name="By Name">
 -                <menu_item_check.on_click
 -                 function="Inventory.SetSortBy"
 -                 parameter="name" />
 -            </menu_item_check>
 -            <menu_item_check
 -             control_name="Inventory.SortByDate"
 -             label="By Date"
 -             layout="topleft"
 -             name="By Date">
 -                <menu_item_check.on_click
 -                 function="Inventory.SetSortBy"
 -                 parameter="date" />
 -            </menu_item_check>
 -            <menu_item_separator
 -             layout="topleft" />
 -            <menu_item_check
 -             control_name="Inventory.FoldersAlwaysByName"
 -             label="Folders Always By Name"
 -             layout="topleft"
 -             name="Folders Always By Name">
 -                <menu_item_check.on_click
 -                 function="Inventory.SetSortBy"
 -                 parameter="foldersalwaysbyname" />
 -            </menu_item_check>
 -            <menu_item_check
 -             control_name="Inventory.SystemFoldersToTop"
 -             label="System Folders To Top"
 -             layout="topleft"
 -             name="System Folders To Top">
 -                <menu_item_check.on_click
 -                 function="Inventory.SetSortBy"
 -                 parameter="systemfolderstotop" />
 -            </menu_item_check>
 -        </menu>
 -    </menu_bar>
 -</panel>
 +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + background_visible="true" + follows="all" + height="400" + label="Things" + layout="topleft" + min_height="350" + min_width="240" + name="inventory panel" + width="330"> +    <panel.string +     name="Title"> +        Things +    </panel.string> +    <filter_editor +     text_pad_left="12" +     follows="left|top|right" +	 font="SanSerif" +     height="20" +     label="Filter" +     layout="topleft" +     left="15" +     name="inventory search editor" +     top="34" +     width="300" /> +    <tab_container +     follows="left|top|right|bottom" +     height="300" +     layout="topleft" +     left_delta="-4" +     name="inventory filter tabs" +     tab_position="top" +     top_pad="4" +     width="305"> +        <inventory_panel +         follows="left|top|right|bottom" +         height="295" +         label="All Items" +         layout="topleft" +         left="1" +         name="All Items" +         top="16" +         width="290" /> +        <inventory_panel +         follows="left|top|right|bottom" +         height="295" +         label="Recent Items" +         layout="topleft" +         left_delta="0" +         name="Recent Items" +         top_delta="0" +         width="290" /> +    </tab_container> +    <menu_bar +     bg_visible="false" +     follows="left|top|right" +     height="18" +     layout="topleft" +     left_delta="0" +     mouse_opaque="false" +     name="Inventory Menu" +     top_delta="-45" +     width="290"> +        <menu +         height="101" +         label="File" +         layout="topleft" +         left="0" +         mouse_opaque="false" +         name="File" +         tear_off="true" +         top="-117" +         width="128"> +            <menu_item_call +             label="Open" +             layout="topleft" +             name="Open"> +                <menu_item_call.on_click +                 function="Inventory.DoToSelected" +                 parameter="open" /> +            </menu_item_call> +            <menu +             create_jump_keys="true" +             label="Upload" +             layout="topleft" +             name="upload" +             tear_off="true"> +                <menu_item_call +                 label="Image (L$[COST])..." +                 layout="topleft" +                 name="Upload Image" +                 shortcut="control|U"> +                    <menu_item_call.on_click +                     function="File.UploadImage" +                     parameter="" /> +                    <menu_item_call.on_enable +                     function="File.EnableUpload" /> +                </menu_item_call> +                <menu_item_call +                 label="Sound (L$[COST])..." +                 layout="topleft" +                 name="Upload Sound"> +                    <menu_item_call.on_click +                     function="File.UploadSound" +                     parameter="" /> +                    <menu_item_call.on_enable +                     function="File.EnableUpload" /> +                </menu_item_call> +                <menu_item_call +                 label="Animation (L$[COST])..." +                 layout="topleft" +                 name="Upload Animation"> +                    <menu_item_call.on_click +                     function="File.UploadAnim" +                     parameter="" /> +                    <menu_item_call.on_enable +                     function="File.EnableUpload" /> +                </menu_item_call> +                <menu_item_call +                 label="Bulk (L$[COST] per file)..." +                 layout="topleft" +                 name="Bulk Upload"> +                    <menu_item_call.on_click +                     function="File.UploadBulk" +                     parameter="" /> +                </menu_item_call> +                <menu_item_separator +                 layout="topleft" /> +            </menu> +            <menu_item_separator +             layout="topleft" /> +            <menu_item_call +             label="New Window" +             layout="topleft" +             name="New Window"> +                <menu_item_call.on_click +                 function="Inventory.NewWindow" /> +            </menu_item_call> +            <menu_item_separator +             layout="topleft" +             name="separator2" /> +            <menu_item_call +             label="Show Filters" +             layout="topleft" +             name="Show Filters"> +                <menu_item_call.on_click +                 function="Inventory.ShowFilters" /> +            </menu_item_call> +            <menu_item_call +             label="Reset Filters" +             layout="topleft" +             name="Reset Current"> +                <menu_item_call.on_click +                 function="Inventory.ResetFilter" /> +            </menu_item_call> +            <menu_item_call +             label="Close All Folders" +             layout="topleft" +             name="Close All Folders"> +                <menu_item_call.on_click +                 function="Inventory.CloseAllFolders" /> +            </menu_item_call> +            <menu_item_separator +             layout="topleft" +             name="separator3" /> +            <menu_item_call +             label="Empty Trash" +             layout="topleft" +             name="Empty Trash"> +                <menu_item_call.on_click +                 function="Inventory.EmptyTrash" /> +            </menu_item_call> +            <menu_item_call +             label="Empty Lost And Found" +             layout="topleft" +             name="Empty Lost And Found"> +                <menu_item_call.on_click +                 function="Inventory.EmptyLostAndFound" /> +            </menu_item_call> +        </menu> +        <menu +         height="121" +         label="Create" +         layout="topleft" +         left="0" +         mouse_opaque="false" +         name="Create" +         tear_off="true" +         top="-201" +         width="121"> +            <menu_item_call +             label="New Folder" +             layout="topleft" +             name="New Folder"> +                <menu_item_call.on_click +                 function="Inventory.DoCreate" +                 parameter="category" /> +            </menu_item_call> +            <menu_item_call +             label="New Script" +             layout="topleft" +             name="New Script"> +                <menu_item_call.on_click +                 function="Inventory.DoCreate" +                 parameter="lsl" /> +            </menu_item_call> +            <menu_item_call +             label="New Note" +             layout="topleft" +             name="New Note"> +                <menu_item_call.on_click +                 function="Inventory.DoCreate" +                 parameter="notecard" /> +            </menu_item_call> +            <menu_item_call +             label="New Gesture" +             layout="topleft" +             name="New Gesture"> +                <menu_item_call.on_click +                 function="Inventory.DoCreate" +                 parameter="gesture" /> +            </menu_item_call> +            <menu +             height="175" +             label="New Clothes" +             layout="topleft" +             left_delta="0" +             mouse_opaque="false" +             name="New Clothes" +             top_pad="514" +             width="125"> +                <menu_item_call +                 label="New Shirt" +                 layout="topleft" +                 name="New Shirt"> +                    <menu_item_call.on_click +                     function="Inventory.DoCreate" +                     parameter="shirt" /> +                </menu_item_call> +                <menu_item_call +                 label="New Pants" +                 layout="topleft" +                 name="New Pants"> +                    <menu_item_call.on_click +                     function="Inventory.DoCreate" +                     parameter="pants" /> +                </menu_item_call> +                <menu_item_call +                 label="New Shoes" +                 layout="topleft" +                 name="New Shoes"> +                    <menu_item_call.on_click +                     function="Inventory.DoCreate" +                     parameter="shoes" /> +                </menu_item_call> +                <menu_item_call +                 label="New Socks" +                 layout="topleft" +                 name="New Socks"> +                    <menu_item_call.on_click +                     function="Inventory.DoCreate" +                     parameter="socks" /> +                </menu_item_call> +                <menu_item_call +                 label="New Jacket" +                 layout="topleft" +                 name="New Jacket"> +                    <menu_item_call.on_click +                     function="Inventory.DoCreate" +                     parameter="jacket" /> +                </menu_item_call> +                <menu_item_call +                 label="New Skirt" +                 layout="topleft" +                 name="New Skirt"> +                    <menu_item_call.on_click +                     function="Inventory.DoCreate" +                     parameter="skirt" /> +                </menu_item_call> +                <menu_item_call +                 label="New Gloves" +                 layout="topleft" +                 name="New Gloves"> +                    <menu_item_call.on_click +                     function="Inventory.DoCreate" +                     parameter="gloves" /> +                </menu_item_call> +                <menu_item_call +                 label="New Undershirt" +                 layout="topleft" +                 name="New Undershirt"> +                    <menu_item_call.on_click +                     function="Inventory.DoCreate" +                     parameter="undershirt" /> +                </menu_item_call> +                <menu_item_call +                 label="New Underpants" +                 layout="topleft" +                 name="New Underpants"> +                    <menu_item_call.on_click +                     function="Inventory.DoCreate" +                     parameter="underpants" /> +                </menu_item_call> +                <menu_item_call +                 label="New Alpha" +                 layout="topleft" +                 name="New Alpha"> +                    <menu_item_call.on_click +                     function="Inventory.DoCreate" +                     parameter="alpha" /> +                </menu_item_call> +                <menu_item_call +                 label="New Tattoo" +                 layout="topleft" +                 name="New Tattoo"> +                    <menu_item_call.on_click +                     function="Inventory.DoCreate" +                     parameter="tattoo" /> +                </menu_item_call> +            </menu> +            <menu +             height="85" +             label="New Body Parts" +             layout="topleft" +             left_delta="0" +             mouse_opaque="false" +             name="New Body Parts" +             top_pad="514" +             width="118"> +                <menu_item_call +                 label="New Shape" +                 layout="topleft" +                 name="New Shape"> +                    <menu_item_call.on_click +                     function="Inventory.DoCreate" +                     parameter="shape" /> +                </menu_item_call> +                <menu_item_call +                 label="New Skin" +                 layout="topleft" +                 name="New Skin"> +                    <menu_item_call.on_click +                     function="Inventory.DoCreate" +                     parameter="skin" /> +                </menu_item_call> +                <menu_item_call +                 label="New Hair" +                 layout="topleft" +                 name="New Hair"> +                    <menu_item_call.on_click +                     function="Inventory.DoCreate" +                     parameter="hair" /> +                </menu_item_call> +                <menu_item_call +                 label="New Eyes" +                 layout="topleft" +                 name="New Eyes"> +                    <menu_item_call.on_click +                     function="Inventory.DoCreate" +                     parameter="eyes" /> +                </menu_item_call> +            </menu> +        </menu> +        <menu +         height="49" +         label="Sort" +         layout="topleft" +         left="0" +         mouse_opaque="false" +         name="Sort" +         tear_off="true" +         top="-113" +         width="118"> +            <menu_item_check +             control_name="Inventory.SortByName" +             label="By Name" +             layout="topleft" +             name="By Name"> +                <menu_item_check.on_click +                 function="Inventory.SetSortBy" +                 parameter="name" /> +            </menu_item_check> +            <menu_item_check +             control_name="Inventory.SortByDate" +             label="By Date" +             layout="topleft" +             name="By Date"> +                <menu_item_check.on_click +                 function="Inventory.SetSortBy" +                 parameter="date" /> +            </menu_item_check> +            <menu_item_separator +             layout="topleft" /> +            <menu_item_check +             control_name="Inventory.FoldersAlwaysByName" +             label="Folders Always By Name" +             layout="topleft" +             name="Folders Always By Name"> +                <menu_item_check.on_click +                 function="Inventory.SetSortBy" +                 parameter="foldersalwaysbyname" /> +            </menu_item_check> +            <menu_item_check +             control_name="Inventory.SystemFoldersToTop" +             label="System Folders To Top" +             layout="topleft" +             name="System Folders To Top"> +                <menu_item_check.on_click +                 function="Inventory.SetSortBy" +                 parameter="systemfolderstotop" /> +            </menu_item_check> +        </menu> +    </menu_bar> +</panel> 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 777d5b48fe..3582de1c71 100644 --- a/indra/newview/skins/default/xui/en/panel_side_tray.xml +++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml @@ -1,150 +1,150 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 -<!-- Side tray cannot show background because it is always 
 -	partially on screen to hold tab buttons. -->
 -<side_tray
 -  name="sidebar"
 -  background_visible="false"
 -  mouse_opaque="true"
 -  width="333"
 -  collapsed="true"
 ->
 -  <!-- Individual tabs must show background to have seemless
 -	appearance up to tray panel header word like "Home".
 -	Embedded panels are inset by a pixel and so their 
 -	backgrounds will not block the world fully. -->
 -  <sidetray_tab
 -    name="sidebar_home"
 -    help_topic="sidebar_home"
 -    tab_title="Home"
 -    description="Home."
 -    image="TabIcon_Open_Off"
 -	image_selected="TabIcon_Close_Off"
 -    mouse_opaque="false"
 -    background_visible="true"
 -  >
 -      <panel
 -        name="panel_home"
 -        filename="panel_sidetray_home_tab.xml"
 -        label="home"
 -      />
 -  </sidetray_tab>
 -
 -  <sidetray_tab
 -    name="sidebar_people"
 -    help_topic="sidebar_people"
 -    tab_title="People"
 -    description="Find your friends, contacts and people nearby."
 -    image="TabIcon_People_Off"
 -    image_selected="TabIcon_People_Selected"
 -    mouse_opaque="false"
 -    background_visible="true"
 -  >
 -    <panel_container
 -      name="panel_container"
 -      width="333"
 -    >
 -      <panel
 -        class="panel_people"
 -        name="panel_people"
 -        filename="panel_people.xml"
 -      />
 -      <panel
 -        class="panel_profile_view"
 -        name="panel_profile_view"
 -        filename="panel_profile_view.xml"
 -      />
 -      <panel
 -        class="panel_group_info_sidetray"
 -        name="panel_group_info_sidetray"
 -        filename="panel_group_info_sidetray.xml"
 -        label="Group Info"
 -        font="SansSerifBold"
 -      />
 -      <panel
 -        class="panel_block_list_sidetray"
 -        name="panel_block_list_sidetray"
 -        filename="panel_block_list_sidetray.xml"
 -        label="Blocked Residents & Objects"
 -        font="SansSerifBold"
 -      />
 -
 -    </panel_container>
 -  </sidetray_tab>
 -  
 -  <sidetray_tab
 -    name="sidebar_places"
 -    help_topic="sidebar_places"
 -    tab_title="Places"
 -    label="Places"
 -    description="Find places to go and places you've visited before."
 -    image="TabIcon_Places_Off"
 -	image_selected="TabIcon_Places_Selected"
 -    mouse_opaque="false"
 -    background_visible="true"
 -  >
 -      <panel
 -        class="panel_places"
 -        name="panel_places"
 -        filename="panel_places.xml"
 -        label="Places"
 -        font="SansSerifBold"
 -      />
 -  </sidetray_tab>
 -
 -  <sidetray_tab
 -    name="sidebar_me"
 -    help_topic="sidebar_me"
 -    tab_title="Me"
 -    description="Edit your public profile and Picks."
 -    image="TabIcon_Me_Off"
 -    image_selected="TabIcon_Me_Selected"
 -    mouse_opaque="false"
 -    background_visible="true"
 -  >
 -      <panel
 -        class="panel_me_profile_view"
 -        name="panel_me_profile"
 -        filename="panel_me_profile.xml"
 -        label="Me"
 -      />
 -  </sidetray_tab>
 -
 -  <sidetray_tab
 -    name="sidebar_appearance"
 -    help_topic="sidebar_appearance"
 -    tab_title="Appearance"
 -    description="Change your appearance and current look."
 -    image="TabIcon_Appearance_Off"
 -    image_selected="TabIcon_Appearance_Selected"
 -    mouse_opaque="false"
 -    background_visible="true"
 -  >
 -      <panel
 -        class="panel_appearance"
 -        name="panel_appearance"
 -        filename="panel_appearance.xml"
 -        label="Edit Appearance"
 -        font="SansSerifBold"
 -      />
 -  </sidetray_tab>
 -
 -  <sidetray_tab
 -    name="sidebar_inventory"
 -    help_topic="sidebar_inventory"
 -    tab_title="Inventory"
 -    description="Browse your inventory."
 -    image="TabIcon_Inventory_Off"
 -    image_selected="TabIcon_Inventory_Selected"
 -    mouse_opaque="false"
 -    background_visible="true"
 -  >
 -      <panel
 -        class="sidepanel_inventory"
 -        name="sidepanel_inventory"
 -        filename="sidepanel_inventory.xml"
 -        label="Edit Inventory"
 -        font="SansSerifBold"
 -      />
 -  </sidetray_tab>
 -
 -</side_tray>
 +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<!-- Side tray cannot show background because it is always  +	partially on screen to hold tab buttons. --> +<side_tray +  name="sidebar" +  background_visible="false" +  mouse_opaque="true" +  width="333" +  collapsed="true" +> +  <!-- Individual tabs must show background to have seemless +	appearance up to tray panel header word like "Home". +	Embedded panels are inset by a pixel and so their  +	backgrounds will not block the world fully. --> +  <sidetray_tab +    name="sidebar_home" +    help_topic="sidebar_home" +    tab_title="Home" +    description="Home." +    image="TabIcon_Open_Off" +	image_selected="TabIcon_Close_Off" +    mouse_opaque="false" +    background_visible="true" +  > +      <panel +        name="panel_home" +        filename="panel_sidetray_home_tab.xml" +        label="home" +      /> +  </sidetray_tab> + +  <sidetray_tab +    name="sidebar_people" +    help_topic="sidebar_people" +    tab_title="People" +    description="Find your friends, contacts and people nearby." +    image="TabIcon_People_Off" +    image_selected="TabIcon_People_Selected" +    mouse_opaque="false" +    background_visible="true" +  > +    <panel_container +      name="panel_container" +      width="333" +    > +      <panel +        class="panel_people" +        name="panel_people" +        filename="panel_people.xml" +      /> +      <panel +        class="panel_profile_view" +        name="panel_profile_view" +        filename="panel_profile_view.xml" +      /> +      <panel +        class="panel_group_info_sidetray" +        name="panel_group_info_sidetray" +        filename="panel_group_info_sidetray.xml" +        label="Group Info" +        font="SansSerifBold" +      /> +      <panel +        class="panel_block_list_sidetray" +        name="panel_block_list_sidetray" +        filename="panel_block_list_sidetray.xml" +        label="Blocked Residents & Objects" +        font="SansSerifBold" +      /> + +    </panel_container> +  </sidetray_tab> +   +  <sidetray_tab +    name="sidebar_places" +    help_topic="sidebar_places" +    tab_title="Places" +    label="Places" +    description="Find places to go and places you've visited before." +    image="TabIcon_Places_Off" +	image_selected="TabIcon_Places_Selected" +    mouse_opaque="false" +    background_visible="true" +  > +      <panel +        class="panel_places" +        name="panel_places" +        filename="panel_places.xml" +        label="Places" +        font="SansSerifBold" +      /> +  </sidetray_tab> + +  <sidetray_tab +    name="sidebar_me" +    help_topic="sidebar_me" +    tab_title="Me" +    description="Edit your public profile and Picks." +    image="TabIcon_Me_Off" +    image_selected="TabIcon_Me_Selected" +    mouse_opaque="false" +    background_visible="true" +  > +      <panel +        class="panel_me_profile_view" +        name="panel_me_profile" +        filename="panel_me_profile.xml" +        label="Me" +      /> +  </sidetray_tab> + +  <sidetray_tab +    name="sidebar_appearance" +    help_topic="sidebar_appearance" +    tab_title="Appearance" +    description="Change your appearance and current look." +    image="TabIcon_Appearance_Off" +    image_selected="TabIcon_Appearance_Selected" +    mouse_opaque="false" +    background_visible="true" +  > +      <panel +        class="panel_appearance" +        name="panel_appearance" +        filename="panel_appearance.xml" +        label="Edit Appearance" +        font="SansSerifBold" +      /> +  </sidetray_tab> + +  <sidetray_tab +    name="sidebar_inventory" +    help_topic="sidebar_inventory" +    tab_title="Inventory" +    description="Browse your inventory." +    image="TabIcon_Inventory_Off" +    image_selected="TabIcon_Inventory_Selected" +    mouse_opaque="false" +    background_visible="true" +  > +      <panel +        class="sidepanel_inventory" +        name="sidepanel_inventory" +        filename="sidepanel_inventory.xml" +        label="Edit Inventory" +        font="SansSerifBold" +      /> +  </sidetray_tab> + +</side_tray> diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml index 79a1cc945d..d0c3cdfafc 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml @@ -1,122 +1,122 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 -<panel
 - background_visible="true"
 - follows="all"
 - height="400"
 - label="Things"
 - layout="topleft"
 - min_height="350"
 - min_width="240"
 - name="objects panel"
 - width="333">
 -    <tab_container
 -     follows="all"
 -     height="390"
 -     layout="topleft"
 -     left="9"
 -     name="Inventory Tabs"
 -     tab_position="top"
 -     top="0"
 -     width="313"
 -	 tab_height="0"
 -	 visible="true">
 -	 <panel
 -	      class="panel_main_inventory"
 -		  filename="panel_main_inventory.xml"
 -		  follows="all"
 -		  layout="topleft"
 -		  left="0"
 -		  name="panel_main_inventory"
 -		  top="15"
 -		  label=""
 -		  height="330"
 -		  width="467">
 -    <panel
 -     height="25"
 -     layout="bottomright"
 -     left="0"
 -     help_topic="objects_button_tab"
 -     name="button_panel"
 -	 bottom="0"
 -     width="313">
 -        <button
 -         enabled="true"
 -         follows="bottom|left"
 -         font="SansSerifSmallBold"
 -         height="25"
 -         label="Info"
 -         layout="topleft"
 -         left="0"
 -         name="info_btn"
 -         top="0"
 -         width="60" />
 -        <button
 -         enabled="true"
 -         follows="bottom|left"
 -         font="SansSerifSmallBold"
 -         height="25"
 -         label="Share"
 -         layout="topleft"
 -         left_pad="5"
 -         name="share_btn"
 -         top="0"
 -         width="60" />
 -        <button
 -         enabled="false"
 -         follows="bottom|left"
 -         font="SansSerifSmallBold"
 -         height="25"
 -         label="Wear"
 -         layout="topleft"
 -         left="130"
 -         name="wear_btn"
 -         top="0"
 -         width="60" />
 -        <button
 -         enabled="false"
 -         follows="bottom|left"
 -         font="SansSerifSmallBold"
 -         height="25"
 -         label="Play"
 -         layout="topleft"
 -         name="play_btn"
 -         left="130"
 -         top="0"
 -         width="50" />
 -        <button
 -         enabled="false"
 -         follows="bottom|left"
 -         font="SansSerifSmallBold"
 -         height="25"
 -         label="Teleport"
 -         layout="topleft"
 -         left="130"
 -         name="teleport_btn"
 -         top="0"
 -         width="77" />
 -        <button
 -         follows="bottom|right"
 -         font="SansSerifSmallBold"
 -         height="25"
 -         label="v"
 -         layout="topleft"
 -         name="overflow_btn"
 -         right="-10"
 -         top="0"
 -         width="30" />
 -    </panel>
 -    </panel>
 -   </tab_container>
 -
 -    <panel
 -     class="sidepanel_object_info"
 -     filename="sidepanel_object_info.xml"
 -     follows="all"
 -     height="360"
 -     layout="topleft"
 -     left="0"
 -     help_topic="objects_info_tab"
 -     name="sidepanel_object_info"
 -     top="30"
 -     visible="false" />
 -</panel>
 +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + background_visible="true" + follows="all" + height="400" + label="Things" + layout="topleft" + min_height="350" + min_width="240" + name="objects panel" + width="333"> +    <tab_container +     follows="all" +     height="390" +     layout="topleft" +     left="9" +     name="Inventory Tabs" +     tab_position="top" +     top="0" +     width="313" +	 tab_height="0" +	 visible="true"> +	 <panel +	      class="panel_main_inventory" +		  filename="panel_main_inventory.xml" +		  follows="all" +		  layout="topleft" +		  left="0" +		  name="panel_main_inventory" +		  top="15" +		  label="" +		  height="330" +		  width="467"> +    <panel +     height="25" +     layout="bottomright" +     left="0" +     help_topic="objects_button_tab" +     name="button_panel" +	 bottom="0" +     width="313"> +        <button +         enabled="true" +         follows="bottom|left" +         font="SansSerifSmallBold" +         height="25" +         label="Info" +         layout="topleft" +         left="0" +         name="info_btn" +         top="0" +         width="60" /> +        <button +         enabled="true" +         follows="bottom|left" +         font="SansSerifSmallBold" +         height="25" +         label="Share" +         layout="topleft" +         left_pad="5" +         name="share_btn" +         top="0" +         width="60" /> +        <button +         enabled="false" +         follows="bottom|left" +         font="SansSerifSmallBold" +         height="25" +         label="Wear" +         layout="topleft" +         left="130" +         name="wear_btn" +         top="0" +         width="60" /> +        <button +         enabled="false" +         follows="bottom|left" +         font="SansSerifSmallBold" +         height="25" +         label="Play" +         layout="topleft" +         name="play_btn" +         left="130" +         top="0" +         width="50" /> +        <button +         enabled="false" +         follows="bottom|left" +         font="SansSerifSmallBold" +         height="25" +         label="Teleport" +         layout="topleft" +         left="130" +         name="teleport_btn" +         top="0" +         width="77" /> +        <button +         follows="bottom|right" +         font="SansSerifSmallBold" +         height="25" +         label="v" +         layout="topleft" +         name="overflow_btn" +         right="-10" +         top="0" +         width="30" /> +    </panel> +    </panel> +   </tab_container> + +    <panel +     class="sidepanel_object_info" +     filename="sidepanel_object_info.xml" +     follows="all" +     height="360" +     layout="topleft" +     left="0" +     help_topic="objects_info_tab" +     name="sidepanel_object_info" +     top="30" +     visible="false" /> +</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 bcf4128e01..c12dd8d58c 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/fr/panel_edit_profile.xml b/indra/newview/skins/default/xui/fr/panel_edit_profile.xml index f62ea7c80f..3a1585bce2 100644 --- a/indra/newview/skins/default/xui/fr/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/fr/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="Résident" />
 -   <string name="AcctTypeTrial"
 -    value="Essai" />
 -   <string name="AcctTypeCharterMember"
 -    value="Membre originaire" />
 -   <string name="AcctTypeEmployee"
 -    value="Employé(e) de Linden Lab" />
 -   <string name="PaymentInfoUsed"
 -    value="Infos de paiement utilisées" />
 -   <string name="PaymentInfoOnFile"
 -    value="Infos de paiement enregistrées" />
 -   <string name="NoPaymentInfoOnFile"
 -    value="Aucune info de paiement" />
 -   <string name="AgeVerified"
 -    value="Âge vérifié" />
 -   <string name="NotAgeVerified"
 -    value="Âge non vérifié" />
 -   <string name="partner_edit_link_url">
 -       http://www.secondlife.com/account/partners.php?lang=fr
 -   </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="Partenaire :"/>
 -        <panel name="partner_data_panel">
 -            <text name="partner_text" value="[FIRST] [LAST]"/>
 -         </panel>
 -      <text name="text_box3">
 -	Réponse si occupé(e) :
 -      </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="Résident" /> +   <string name="AcctTypeTrial" +    value="Essai" /> +   <string name="AcctTypeCharterMember" +    value="Membre originaire" /> +   <string name="AcctTypeEmployee" +    value="Employé(e) de Linden Lab" /> +   <string name="PaymentInfoUsed" +    value="Infos de paiement utilisées" /> +   <string name="PaymentInfoOnFile" +    value="Infos de paiement enregistrées" /> +   <string name="NoPaymentInfoOnFile" +    value="Aucune info de paiement" /> +   <string name="AgeVerified" +    value="Âge vérifié" /> +   <string name="NotAgeVerified" +    value="Âge non vérifié" /> +   <string name="partner_edit_link_url"> +       http://www.secondlife.com/account/partners.php?lang=fr +   </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="Partenaire :"/> +        <panel name="partner_data_panel"> +            <text name="partner_text" value="[FIRST] [LAST]"/> +         </panel> +      <text name="text_box3"> +	Réponse si occupé(e) : +      </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 0eba7bf3b6..33f3c367c2 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 'Occupato':
 -      </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 'Occupato': +      </text> +    </panel> +    </panel> +</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_edit_profile.xml b/indra/newview/skins/default/xui/ja/panel_edit_profile.xml index ca4ab3e773..2cf8456187 100644 --- a/indra/newview/skins/default/xui/ja/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/ja/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="住人" />
 -   <string name="AcctTypeTrial"
 -    value="トライアル" />
 -   <string name="AcctTypeCharterMember"
 -    value="特権メンバー" />
 -   <string name="AcctTypeEmployee"
 -    value="Linden Lab従業員" />
 -   <string name="PaymentInfoUsed"
 -    value="支払い情報登録済" />
 -   <string name="PaymentInfoOnFile"
 -    value="支払い情報登録済み" />
 -   <string name="NoPaymentInfoOnFile"
 -    value="支払い情報未登録" />
 -   <string name="AgeVerified"
 -    value="年齢確認済み" />
 -   <string name="NotAgeVerified"
 -    value="年齢未確認" />
 -   <string name="partner_edit_link_url">
 -       http://www.secondlife.com/account/partners.php?lang=ja
 -   </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="パートナー:"/>
 -        <panel name="partner_data_panel">
 -            <text name="partner_text" value="[FIRST] [LAST]"/>
 -         </panel>
 -      <text name="text_box3">
 -	取り込み中応答メッセージ:
 -      </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="住人" /> +   <string name="AcctTypeTrial" +    value="トライアル" /> +   <string name="AcctTypeCharterMember" +    value="特権メンバー" /> +   <string name="AcctTypeEmployee" +    value="Linden Lab従業員" /> +   <string name="PaymentInfoUsed" +    value="支払い情報登録済" /> +   <string name="PaymentInfoOnFile" +    value="支払い情報登録済み" /> +   <string name="NoPaymentInfoOnFile" +    value="支払い情報未登録" /> +   <string name="AgeVerified" +    value="年齢確認済み" /> +   <string name="NotAgeVerified" +    value="年齢未確認" /> +   <string name="partner_edit_link_url"> +       http://www.secondlife.com/account/partners.php?lang=ja +   </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="パートナー:"/> +        <panel name="partner_data_panel"> +            <text name="partner_text" value="[FIRST] [LAST]"/> +         </panel> +      <text name="text_box3"> +	取り込み中応答メッセージ: +      </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 00f8c087de..172395e20a 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 e449a92d7e..97fa3118f8 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 e97e77cfe6..a989cab167 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/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index 009be35f64..d31a81e128 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -1,423 +1,423 @@ -/**
 - * @file   lllogininstance_test.cpp
 - * @brief  Test for lllogininstance.cpp.
 - * 
 - * $LicenseInfo:firstyear=2008&license=internal$
 - * Copyright (c) 2008, Linden Research, Inc.
 - * $/LicenseInfo$
 - */
 -
 -// Precompiled header
 -#include "../llviewerprecompiledheaders.h"
 -// Own header
 -#include "../lllogininstance.h"
 -// STL headers
 -// std headers
 -// external library headers
 -// other Linden headers
 -#include "../test/lltut.h"
 -#include "llevents.h"
 -
 -#if defined(LL_WINDOWS)
 -#pragma warning(disable: 4355)      // using 'this' in base-class ctor initializer expr
 -#endif
 -
 -// Constants
 -const std::string VIEWERLOGIN_URI("viewerlogin_uri");
 -const std::string VIEWERLOGIN_GRIDLABEL("viewerlogin_grid");
 -
 -const std::string APPVIEWER_SERIALNUMBER("appviewer_serialno");
 -
 -// Link seams.
 -
 -//-----------------------------------------------------------------------------
 -static LLEventStream gTestPump("test_pump");
 -
 -#include "lllogin.h"
 -static std::string gLoginURI;
 -static LLSD gLoginCreds;
 -static bool gDisconnectCalled = false;
 -class LLLogin::Impl
 -{
 -};
 -LLLogin::LLLogin() {}
 -LLLogin::~LLLogin() {}
 -LLEventPump& LLLogin::getEventPump() { return gTestPump; }
 -void LLLogin::connect(const std::string& uri, const LLSD& credentials) 
 -{
 -	gLoginURI = uri;
 -	gLoginCreds = credentials;
 -}
 -
 -void LLLogin::disconnect() 
 -{
 -	gDisconnectCalled = true;
 -}
 -
 -//-----------------------------------------------------------------------------
 -#include "../llviewernetwork.h"
 -unsigned char gMACAddress[MAC_ADDRESS_BYTES] = {'1','2','3','4','5','6'};		/* Flawfinder: ignore */
 -
 -LLViewerLogin::LLViewerLogin() {}
 -LLViewerLogin::~LLViewerLogin() {}
 -void LLViewerLogin::getLoginURIs(std::vector<std::string>& uris) const 
 -{
 -	uris.push_back(VIEWERLOGIN_URI);
 -}
 -std::string LLViewerLogin::getGridLabel() const { return VIEWERLOGIN_GRIDLABEL; }
 -
 -//-----------------------------------------------------------------------------
 -#include "../llviewercontrol.h"
 -LLControlGroup gSavedSettings("Global");
 -std::string gCurrentVersion = "invalid_version";
 -
 -LLControlGroup::LLControlGroup(const std::string& name) :
 -	LLInstanceTracker<LLControlGroup, std::string>(name){}
 -LLControlGroup::~LLControlGroup() {}
 -void LLControlGroup::setBOOL(const std::string& name, BOOL val) {}
 -BOOL LLControlGroup::getBOOL(const std::string& name) { return FALSE; }
 -U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only) { return 1; }
 -void LLControlGroup::setString(const std::string& name, const std::string& val) {}
 -std::string LLControlGroup::getString(const std::string& name) { return "test_string"; }
 -BOOL LLControlGroup::declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist) { return TRUE; }
 -BOOL LLControlGroup::declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist) { return TRUE; }
 -
 -#include "lluicolortable.h"
 -void LLUIColorTable::saveUserSettings(void)const {}
 -
 -//-----------------------------------------------------------------------------
 -#include "../llurlsimstring.h"
 -LLURLSimString LLURLSimString::sInstance;
 -bool LLURLSimString::parse() { return true; }
 -
 -//-----------------------------------------------------------------------------
 -#include "llnotifications.h"
 -#include "llfloaterreg.h"
 -static std::string gTOSType;
 -static LLEventPump * gTOSReplyPump = NULL;
 -
 -//static
 -LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key, BOOL focus)
 -{
 -	gTOSType = name;
 -	gTOSReplyPump = &LLEventPumps::instance().obtain(key["reply_pump"]);
 -	return NULL;
 -}
 -
 -//-----------------------------------------------------------------------------
 -// LLNotifications
 -class MockNotifications : public LLNotificationsInterface
 -{
 -	boost::function<void (const LLSD&, const LLSD&)> mResponder;
 -	int mAddedCount;
 -
 -public: 
 -	MockNotifications() :
 -		mResponder(0),
 -		mAddedCount(0)
 -	{
 -	}
 -
 -	virtual ~MockNotifications() {}
 -
 -	/* virtual */ LLNotificationPtr add(
 -					const std::string& name,
 -					const LLSD& substitutions,
 -					const LLSD& payload, 
 -					LLNotificationFunctorRegistry::ResponseFunctor functor)
 -	{
 -		mResponder = functor;
 -		mAddedCount++;
 -		return LLNotificationPtr((LLNotification*)NULL);
 -	}
 -
 -	void sendYesResponse()
 -	{
 -		LLSD notification;
 -		LLSD response;
 -		response = 1;
 -		mResponder(notification, response);
 -	}
 -
 -	void sendNoResponse()
 -	{
 -		LLSD notification;
 -		LLSD response;
 -		response = 2;
 -		mResponder(notification, response);
 -	}
 -
 -	void sendBogusResponse()
 -	{
 -		LLSD notification;
 -		LLSD response;
 -		response = 666;
 -		mResponder(notification, response);
 -	}
 -
 -	int addedCount() { return mAddedCount; }
 -};
 -
 -S32 LLNotification::getSelectedOption(const LLSD& notification, const LLSD& response)
 -{
 -	return response.asInteger();
 -}
 -
 -// misc
 -std::string xml_escape_string(const std::string& in)
 -{
 -	return in;
 -}
 -
 -/*****************************************************************************
 -*   TUT
 -*****************************************************************************/
 -namespace tut
 -{
 -    struct lllogininstance_data
 -    {
 -		lllogininstance_data() : logininstance(LLLoginInstance::getInstance())
 -		{
 -			// Global initialization
 -			gLoginURI.clear();
 -			gLoginCreds.clear();
 -			gDisconnectCalled = false;
 -
 -			gTOSType = ""; // Set to invalid value.
 -			gTOSReplyPump = 0; // clear the callback.
 -
 -
 -			gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", FALSE);
 -			gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", FALSE);
 -			gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", FALSE);
 -			gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", FALSE);
 -			gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", FALSE);
 -			gSavedSettings.declareString("VersionChannelName", "test_version_string", "", FALSE);
 -			gSavedSettings.declareString("NextLoginLocation", "", "", FALSE);
 -			gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", FALSE);
 -
 -			credentials["first"] = "testfirst";
 -			credentials["last"] = "testlast";
 -			credentials["passwd"] = "testpass";
 -
 -			logininstance->setNotificationsInterface(¬ifications);
 -		}
 -
 -		LLLoginInstance* logininstance;
 -		LLSD credentials;
 -		MockNotifications notifications;
 -    };
 -
 -    typedef test_group<lllogininstance_data> lllogininstance_group;
 -    typedef lllogininstance_group::object lllogininstance_object;
 -    lllogininstance_group llsdmgr("lllogininstance");
 -
 -    template<> template<>
 -    void lllogininstance_object::test<1>()
 -    {
 -		set_test_name("Test Simple Success And Disconnect");
 -
 -		// Test default connect.
 -		logininstance->connect(credentials);
 -
 -		ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI); 
 -
 -		// Dummy success response.
 -		LLSD response;
 -		response["state"] = "online";
 -		response["change"] = "connect";
 -		response["progress"] = 1.0;
 -		response["transfer_rate"] = 7;
 -		response["data"] = "test_data";
 -
 -		gTestPump.post(response);
 -
 -		ensure("Success response", logininstance->authSuccess());
 -		ensure_equals("Test Response Data", logininstance->getResponse().asString(), "test_data");
 -
 -		logininstance->disconnect();
 -
 -		ensure_equals("Called Login Module Disconnect", gDisconnectCalled, true);
 -
 -		response.clear();
 -		response["state"] = "offline";
 -		response["change"] = "disconnect";
 -		response["progress"] = 0.0;
 -		response["transfer_rate"] = 0;
 -		response["data"] = "test_data";
 -
 -		gTestPump.post(response);
 -
 -		ensure("Disconnected", !(logininstance->authSuccess()));
 -    }
 -
 -    template<> template<>
 -    void lllogininstance_object::test<2>()
 -    {
 -		set_test_name("Test User TOS/Critical message Interaction");
 -
 -		const std::string test_uri = "testing-uri";
 -
 -		// Test default connect.
 -		logininstance->connect(test_uri, credentials);
 -
 -		// connect should call LLLogin::connect to init gLoginURI and gLoginCreds.
 -		ensure_equals("Default connect uri", gLoginURI, "testing-uri"); 
 -		ensure_equals("Default for agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), false);
 -		ensure_equals("Default for read critical", gLoginCreds["params"]["read_critical"].asBoolean(), false);
 -
 -		// TOS failure response.
 -		LLSD response;
 -		response["state"] = "offline";
 -		response["change"] = "fail.login";
 -		response["progress"] = 0.0;
 -		response["transfer_rate"] = 7;
 -		response["data"]["reason"] = "tos";
 -		gTestPump.post(response);
 -
 -		ensure_equals("TOS Dialog type", gTOSType, "message_tos");
 -		ensure("TOS callback given", gTOSReplyPump != 0);
 -		gTOSReplyPump->post(false); // Call callback denying TOS.
 -		ensure("No TOS, failed auth", logininstance->authFailure());
 -
 -		// Start again.
 -		logininstance->connect(test_uri, credentials);
 -		gTestPump.post(response); // Fail for tos again.
 -		gTOSReplyPump->post(true); // Accept tos, should reconnect w/ agree_to_tos.
 -		ensure_equals("Accepted agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), true);
 -		ensure("Incomplete login status", !logininstance->authFailure() && !logininstance->authSuccess());
 -	
 -		// Fail connection, attempt connect again.
 -		// The new request should have reset agree to tos to default.
 -		response["data"]["reason"] = "key"; // bad creds.
 -		gTestPump.post(response);
 -		ensure("TOS auth failure", logininstance->authFailure());
 -
 -		logininstance->connect(test_uri, credentials);
 -		ensure_equals("Reset to default for agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), false);
 -
 -		// Critical Message failure response.
 -		logininstance->connect(test_uri, credentials);
 -		response["data"]["reason"] = "critical"; // Change response to "critical message"
 -		gTestPump.post(response);
 -
 -		ensure_equals("TOS Dialog type", gTOSType, "message_critical");
 -		ensure("TOS callback given", gTOSReplyPump != 0);
 -		gTOSReplyPump->post(true); 
 -		ensure_equals("Accepted read critical message", gLoginCreds["params"]["read_critical"].asBoolean(), true);
 -		ensure("Incomplete login status", !logininstance->authFailure() && !logininstance->authSuccess());
 -
 -		// Fail then attempt new connection
 -		response["data"]["reason"] = "key"; // bad creds.
 -		gTestPump.post(response);
 -		ensure("TOS auth failure", logininstance->authFailure());
 -		logininstance->connect(test_uri, credentials);
 -		ensure_equals("Default for agree to tos", gLoginCreds["params"]["read_critical"].asBoolean(), false);
 -	}
 -
 -    template<> template<>
 -    void lllogininstance_object::test<3>()
 -    {
 -		set_test_name("Test Mandatory Update User Accepts");
 -
 -		// Part 1 - Mandatory Update, with User accepts response.
 -		// Test connect with update needed.
 -		logininstance->connect(credentials);
 -
 -		ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI); 
 -
 -		// Update needed failure response.
 -		LLSD response;
 -		response["state"] = "offline";
 -		response["change"] = "fail.login";
 -		response["progress"] = 0.0;
 -		response["transfer_rate"] = 7;
 -		response["data"]["reason"] = "update";
 -		gTestPump.post(response);
 -
 -		ensure_equals("Notification added", notifications.addedCount(), 1);
 -
 -		notifications.sendYesResponse();
 -
 -		ensure("Disconnected", !(logininstance->authSuccess()));
 -	}
 -
 -	template<> template<>
 -    void lllogininstance_object::test<4>()
 -    {
 -		set_test_name("Test Mandatory Update User Decline");
 -
 -		// Test connect with update needed.
 -		logininstance->connect(credentials);
 -
 -		ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI); 
 -
 -		// Update needed failure response.
 -		LLSD response;
 -		response["state"] = "offline";
 -		response["change"] = "fail.login";
 -		response["progress"] = 0.0;
 -		response["transfer_rate"] = 7;
 -		response["data"]["reason"] = "update";
 -		gTestPump.post(response);
 -
 -		ensure_equals("Notification added", notifications.addedCount(), 1);
 -		notifications.sendNoResponse();
 -
 -		ensure("Disconnected", !(logininstance->authSuccess()));
 -	}
 -
 -	template<> template<>
 -    void lllogininstance_object::test<6>()
 -    {
 -		set_test_name("Test Optional Update User Accept");
 -
 -		// Part 3 - Mandatory Update, with bogus response.
 -		// Test connect with update needed.
 -		logininstance->connect(credentials);
 -
 -		ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI); 
 -
 -		// Update needed failure response.
 -		LLSD response;
 -		response["state"] = "offline";
 -		response["change"] = "fail.login";
 -		response["progress"] = 0.0;
 -		response["transfer_rate"] = 7;
 -		response["data"]["reason"] = "optional";
 -		gTestPump.post(response);
 -
 -		ensure_equals("Notification added", notifications.addedCount(), 1);
 -		notifications.sendYesResponse();
 -
 -		ensure("Disconnected", !(logininstance->authSuccess()));
 -	}
 -
 -	template<> template<>
 -    void lllogininstance_object::test<7>()
 -    {
 -		set_test_name("Test Optional Update User Denies");
 -
 -		// Part 3 - Mandatory Update, with bogus response.
 -		// Test connect with update needed.
 -		logininstance->connect(credentials);
 -
 -		ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI); 
 -
 -		// Update needed failure response.
 -		LLSD response;
 -		response["state"] = "offline";
 -		response["change"] = "fail.login";
 -		response["progress"] = 0.0;
 -		response["transfer_rate"] = 7;
 -		response["data"]["reason"] = "optional";
 -		gTestPump.post(response);
 -
 -		ensure_equals("Notification added", notifications.addedCount(), 1);
 -		notifications.sendNoResponse();
 -
 -		// User skips, should be reconnecting.
 -		ensure_equals("reconnect uri", gLoginURI, VIEWERLOGIN_URI); 
 -		ensure_equals("skipping optional update", gLoginCreds["params"]["skipoptional"].asBoolean(), true); 
 -	}
 -}
 +/** + * @file   lllogininstance_test.cpp + * @brief  Test for lllogininstance.cpp. + *  + * $LicenseInfo:firstyear=2008&license=internal$ + * Copyright (c) 2008, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "../llviewerprecompiledheaders.h" +// Own header +#include "../lllogininstance.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "../test/lltut.h" +#include "llevents.h" + +#if defined(LL_WINDOWS) +#pragma warning(disable: 4355)      // using 'this' in base-class ctor initializer expr +#endif + +// Constants +const std::string VIEWERLOGIN_URI("viewerlogin_uri"); +const std::string VIEWERLOGIN_GRIDLABEL("viewerlogin_grid"); + +const std::string APPVIEWER_SERIALNUMBER("appviewer_serialno"); + +// Link seams. + +//----------------------------------------------------------------------------- +static LLEventStream gTestPump("test_pump"); + +#include "lllogin.h" +static std::string gLoginURI; +static LLSD gLoginCreds; +static bool gDisconnectCalled = false; +class LLLogin::Impl +{ +}; +LLLogin::LLLogin() {} +LLLogin::~LLLogin() {} +LLEventPump& LLLogin::getEventPump() { return gTestPump; } +void LLLogin::connect(const std::string& uri, const LLSD& credentials)  +{ +	gLoginURI = uri; +	gLoginCreds = credentials; +} + +void LLLogin::disconnect()  +{ +	gDisconnectCalled = true; +} + +//----------------------------------------------------------------------------- +#include "../llviewernetwork.h" +unsigned char gMACAddress[MAC_ADDRESS_BYTES] = {'1','2','3','4','5','6'};		/* Flawfinder: ignore */ + +LLViewerLogin::LLViewerLogin() {} +LLViewerLogin::~LLViewerLogin() {} +void LLViewerLogin::getLoginURIs(std::vector<std::string>& uris) const  +{ +	uris.push_back(VIEWERLOGIN_URI); +} +std::string LLViewerLogin::getGridLabel() const { return VIEWERLOGIN_GRIDLABEL; } + +//----------------------------------------------------------------------------- +#include "../llviewercontrol.h" +LLControlGroup gSavedSettings("Global"); +std::string gCurrentVersion = "invalid_version"; + +LLControlGroup::LLControlGroup(const std::string& name) : +	LLInstanceTracker<LLControlGroup, std::string>(name){} +LLControlGroup::~LLControlGroup() {} +void LLControlGroup::setBOOL(const std::string& name, BOOL val) {} +BOOL LLControlGroup::getBOOL(const std::string& name) { return FALSE; } +U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only) { return 1; } +void LLControlGroup::setString(const std::string& name, const std::string& val) {} +std::string LLControlGroup::getString(const std::string& name) { return "test_string"; } +BOOL LLControlGroup::declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist) { return TRUE; } +BOOL LLControlGroup::declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist) { return TRUE; } + +#include "lluicolortable.h" +void LLUIColorTable::saveUserSettings(void)const {} + +//----------------------------------------------------------------------------- +#include "../llurlsimstring.h" +LLURLSimString LLURLSimString::sInstance; +bool LLURLSimString::parse() { return true; } + +//----------------------------------------------------------------------------- +#include "llnotifications.h" +#include "llfloaterreg.h" +static std::string gTOSType; +static LLEventPump * gTOSReplyPump = NULL; + +//static +LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key, BOOL focus) +{ +	gTOSType = name; +	gTOSReplyPump = &LLEventPumps::instance().obtain(key["reply_pump"]); +	return NULL; +} + +//----------------------------------------------------------------------------- +// LLNotifications +class MockNotifications : public LLNotificationsInterface +{ +	boost::function<void (const LLSD&, const LLSD&)> mResponder; +	int mAddedCount; + +public:  +	MockNotifications() : +		mResponder(0), +		mAddedCount(0) +	{ +	} + +	virtual ~MockNotifications() {} + +	/* virtual */ LLNotificationPtr add( +					const std::string& name, +					const LLSD& substitutions, +					const LLSD& payload,  +					LLNotificationFunctorRegistry::ResponseFunctor functor) +	{ +		mResponder = functor; +		mAddedCount++; +		return LLNotificationPtr((LLNotification*)NULL); +	} + +	void sendYesResponse() +	{ +		LLSD notification; +		LLSD response; +		response = 1; +		mResponder(notification, response); +	} + +	void sendNoResponse() +	{ +		LLSD notification; +		LLSD response; +		response = 2; +		mResponder(notification, response); +	} + +	void sendBogusResponse() +	{ +		LLSD notification; +		LLSD response; +		response = 666; +		mResponder(notification, response); +	} + +	int addedCount() { return mAddedCount; } +}; + +S32 LLNotification::getSelectedOption(const LLSD& notification, const LLSD& response) +{ +	return response.asInteger(); +} + +// misc +std::string xml_escape_string(const std::string& in) +{ +	return in; +} + +/***************************************************************************** +*   TUT +*****************************************************************************/ +namespace tut +{ +    struct lllogininstance_data +    { +		lllogininstance_data() : logininstance(LLLoginInstance::getInstance()) +		{ +			// Global initialization +			gLoginURI.clear(); +			gLoginCreds.clear(); +			gDisconnectCalled = false; + +			gTOSType = ""; // Set to invalid value. +			gTOSReplyPump = 0; // clear the callback. + + +			gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", FALSE); +			gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", FALSE); +			gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", FALSE); +			gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", FALSE); +			gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", FALSE); +			gSavedSettings.declareString("VersionChannelName", "test_version_string", "", FALSE); +			gSavedSettings.declareString("NextLoginLocation", "", "", FALSE); +			gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", FALSE); + +			credentials["first"] = "testfirst"; +			credentials["last"] = "testlast"; +			credentials["passwd"] = "testpass"; + +			logininstance->setNotificationsInterface(¬ifications); +		} + +		LLLoginInstance* logininstance; +		LLSD credentials; +		MockNotifications notifications; +    }; + +    typedef test_group<lllogininstance_data> lllogininstance_group; +    typedef lllogininstance_group::object lllogininstance_object; +    lllogininstance_group llsdmgr("lllogininstance"); + +    template<> template<> +    void lllogininstance_object::test<1>() +    { +		set_test_name("Test Simple Success And Disconnect"); + +		// Test default connect. +		logininstance->connect(credentials); + +		ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);  + +		// Dummy success response. +		LLSD response; +		response["state"] = "online"; +		response["change"] = "connect"; +		response["progress"] = 1.0; +		response["transfer_rate"] = 7; +		response["data"] = "test_data"; + +		gTestPump.post(response); + +		ensure("Success response", logininstance->authSuccess()); +		ensure_equals("Test Response Data", logininstance->getResponse().asString(), "test_data"); + +		logininstance->disconnect(); + +		ensure_equals("Called Login Module Disconnect", gDisconnectCalled, true); + +		response.clear(); +		response["state"] = "offline"; +		response["change"] = "disconnect"; +		response["progress"] = 0.0; +		response["transfer_rate"] = 0; +		response["data"] = "test_data"; + +		gTestPump.post(response); + +		ensure("Disconnected", !(logininstance->authSuccess())); +    } + +    template<> template<> +    void lllogininstance_object::test<2>() +    { +		set_test_name("Test User TOS/Critical message Interaction"); + +		const std::string test_uri = "testing-uri"; + +		// Test default connect. +		logininstance->connect(test_uri, credentials); + +		// connect should call LLLogin::connect to init gLoginURI and gLoginCreds. +		ensure_equals("Default connect uri", gLoginURI, "testing-uri");  +		ensure_equals("Default for agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), false); +		ensure_equals("Default for read critical", gLoginCreds["params"]["read_critical"].asBoolean(), false); + +		// TOS failure response. +		LLSD response; +		response["state"] = "offline"; +		response["change"] = "fail.login"; +		response["progress"] = 0.0; +		response["transfer_rate"] = 7; +		response["data"]["reason"] = "tos"; +		gTestPump.post(response); + +		ensure_equals("TOS Dialog type", gTOSType, "message_tos"); +		ensure("TOS callback given", gTOSReplyPump != 0); +		gTOSReplyPump->post(false); // Call callback denying TOS. +		ensure("No TOS, failed auth", logininstance->authFailure()); + +		// Start again. +		logininstance->connect(test_uri, credentials); +		gTestPump.post(response); // Fail for tos again. +		gTOSReplyPump->post(true); // Accept tos, should reconnect w/ agree_to_tos. +		ensure_equals("Accepted agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), true); +		ensure("Incomplete login status", !logininstance->authFailure() && !logininstance->authSuccess()); +	 +		// Fail connection, attempt connect again. +		// The new request should have reset agree to tos to default. +		response["data"]["reason"] = "key"; // bad creds. +		gTestPump.post(response); +		ensure("TOS auth failure", logininstance->authFailure()); + +		logininstance->connect(test_uri, credentials); +		ensure_equals("Reset to default for agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), false); + +		// Critical Message failure response. +		logininstance->connect(test_uri, credentials); +		response["data"]["reason"] = "critical"; // Change response to "critical message" +		gTestPump.post(response); + +		ensure_equals("TOS Dialog type", gTOSType, "message_critical"); +		ensure("TOS callback given", gTOSReplyPump != 0); +		gTOSReplyPump->post(true);  +		ensure_equals("Accepted read critical message", gLoginCreds["params"]["read_critical"].asBoolean(), true); +		ensure("Incomplete login status", !logininstance->authFailure() && !logininstance->authSuccess()); + +		// Fail then attempt new connection +		response["data"]["reason"] = "key"; // bad creds. +		gTestPump.post(response); +		ensure("TOS auth failure", logininstance->authFailure()); +		logininstance->connect(test_uri, credentials); +		ensure_equals("Default for agree to tos", gLoginCreds["params"]["read_critical"].asBoolean(), false); +	} + +    template<> template<> +    void lllogininstance_object::test<3>() +    { +		set_test_name("Test Mandatory Update User Accepts"); + +		// Part 1 - Mandatory Update, with User accepts response. +		// Test connect with update needed. +		logininstance->connect(credentials); + +		ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);  + +		// Update needed failure response. +		LLSD response; +		response["state"] = "offline"; +		response["change"] = "fail.login"; +		response["progress"] = 0.0; +		response["transfer_rate"] = 7; +		response["data"]["reason"] = "update"; +		gTestPump.post(response); + +		ensure_equals("Notification added", notifications.addedCount(), 1); + +		notifications.sendYesResponse(); + +		ensure("Disconnected", !(logininstance->authSuccess())); +	} + +	template<> template<> +    void lllogininstance_object::test<4>() +    { +		set_test_name("Test Mandatory Update User Decline"); + +		// Test connect with update needed. +		logininstance->connect(credentials); + +		ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);  + +		// Update needed failure response. +		LLSD response; +		response["state"] = "offline"; +		response["change"] = "fail.login"; +		response["progress"] = 0.0; +		response["transfer_rate"] = 7; +		response["data"]["reason"] = "update"; +		gTestPump.post(response); + +		ensure_equals("Notification added", notifications.addedCount(), 1); +		notifications.sendNoResponse(); + +		ensure("Disconnected", !(logininstance->authSuccess())); +	} + +	template<> template<> +    void lllogininstance_object::test<6>() +    { +		set_test_name("Test Optional Update User Accept"); + +		// Part 3 - Mandatory Update, with bogus response. +		// Test connect with update needed. +		logininstance->connect(credentials); + +		ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);  + +		// Update needed failure response. +		LLSD response; +		response["state"] = "offline"; +		response["change"] = "fail.login"; +		response["progress"] = 0.0; +		response["transfer_rate"] = 7; +		response["data"]["reason"] = "optional"; +		gTestPump.post(response); + +		ensure_equals("Notification added", notifications.addedCount(), 1); +		notifications.sendYesResponse(); + +		ensure("Disconnected", !(logininstance->authSuccess())); +	} + +	template<> template<> +    void lllogininstance_object::test<7>() +    { +		set_test_name("Test Optional Update User Denies"); + +		// Part 3 - Mandatory Update, with bogus response. +		// Test connect with update needed. +		logininstance->connect(credentials); + +		ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);  + +		// Update needed failure response. +		LLSD response; +		response["state"] = "offline"; +		response["change"] = "fail.login"; +		response["progress"] = 0.0; +		response["transfer_rate"] = 7; +		response["data"]["reason"] = "optional"; +		gTestPump.post(response); + +		ensure_equals("Notification added", notifications.addedCount(), 1); +		notifications.sendNoResponse(); + +		// User skips, should be reconnecting. +		ensure_equals("reconnect uri", gLoginURI, VIEWERLOGIN_URI);  +		ensure_equals("skipping optional update", gLoginCreds["params"]["skipoptional"].asBoolean(), true);  +	} +} diff --git a/indra/tools/vstool/README.txt b/indra/tools/vstool/README.txt index e419180031..6f64aa41df 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 24f1031f81..5d8764b6bf 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 8859671802..543a0a2efc 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 cc268d59d9..5c41c916e2 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; +        } +    } +}  | 
