Merge. Refresh from viewer-release after 3.6.10 release

Tue, 12 Nov 2013 14:06:38 -0500

author
Monty Brandenberg <monty@lindenlab.com>
date
Tue, 12 Nov 2013 14:06:38 -0500
changeset 40735
c7ea0015ea29
parent 40734
12872e1718f4
parent 39940
f83f2230ead2
child 40736
a78f44e8b7a1
child 40737
c55d1d91d904

Merge. Refresh from viewer-release after 3.6.10 release

autobuild.xml file | annotate | diff | revisions
indra/llcommon/llversionviewer.h file | annotate | diff | revisions
indra/newview/app_settings/settings.xml file | annotate | diff | revisions
indra/newview/lltexturefetch.cpp file | annotate | diff | revisions
indra/newview/llviewerregion.cpp file | annotate | diff | revisions
     1.1 --- a/.hgtags	Thu Oct 17 18:26:04 2013 -0400
     1.2 +++ b/.hgtags	Tue Nov 12 14:06:38 2013 -0500
     1.3 @@ -467,3 +467,5 @@
     1.4  bf6d453046011a11de2643fac610cc5258650f82 3.6.5-release
     1.5  ae457ece77001767ae9613148c495e7b98cc0f4a 3.6.7-release
     1.6  d40c66e410741de7e90b1ed6dac28dd8a2d7e1f6 3.6.8-release
     1.7 +70eda3721d36df3e00730629c42a1304e5bc65b8 3.6.9-release
     1.8 +5b54b36862ff8bc3b6935673c9d1c1f22ee8d521 3.6.10-release
     2.1 --- a/BuildParams	Thu Oct 17 18:26:04 2013 -0400
     2.2 +++ b/BuildParams	Tue Nov 12 14:06:38 2013 -0500
     2.3 @@ -27,9 +27,6 @@
     2.4  Linux.gcc_version = /usr/bin/gcc-4.6
     2.5  Linux.cxx_version = /usr/bin/g++-4.6
     2.6  
     2.7 -# Setup default sourceid so Windows can pick up the TeamCity override
     2.8 -sourceid = ""
     2.9 -
    2.10  ################################################################
    2.11  ####      Examples of how to set the viewer_channel         ####
    2.12  #
    2.13 @@ -50,6 +47,18 @@
    2.14  ################################################################
    2.15  viewer_channel = "Second Life Test"
    2.16  
    2.17 +# Setup default packaging parameters.
    2.18 +sourceid = ""
    2.19 +additional_packages = "Amazon Desura B C"
    2.20 +Amazon_sourceid = "1207v_Amazon"
    2.21 +Amazon_viewer_channel_suffix = " Amazon"
    2.22 +Desura_sourceid = "1208_desura"
    2.23 +Desura_viewer_channel_suffix = " Desura"
    2.24 +B_sourceid = "1301_B"
    2.25 +B_viewer_channel_suffix = " B"
    2.26 +C_sourceid = "1302_C"
    2.27 +C_viewer_channel_suffix = " C"
    2.28 +
    2.29  # Report changes since...
    2.30  viewer-development.show_changes_since = last_sprint
    2.31  
     3.1 --- a/autobuild.xml	Thu Oct 17 18:26:04 2013 -0400
     3.2 +++ b/autobuild.xml	Tue Nov 12 14:06:38 2013 -0500
     3.3 @@ -1965,11 +1965,11 @@
     3.4      <key>package_description</key>
     3.5      <map>
     3.6        <key>description</key>
     3.7 -      <string>Spell checking dictionaries</string>
     3.8 +      <string>Second Life Viewer</string>
     3.9        <key>license</key>
    3.10 -      <string>various open</string>
    3.11 +      <string>LGPL</string>
    3.12        <key>name</key>
    3.13 -      <string>dictionaries</string>
    3.14 +      <string>Second Life Viewer</string>
    3.15        <key>platforms</key>
    3.16        <map>
    3.17          <key>common</key>
     4.1 --- a/build.sh	Thu Oct 17 18:26:04 2013 -0400
     4.2 +++ b/build.sh	Tue Nov 12 14:06:38 2013 -0500
     4.3 @@ -38,22 +38,22 @@
     4.4  
     4.5  installer_Darwin()
     4.6  {
     4.7 -  ls -1td "$(build_dir_Darwin ${last_built_variant:-Release})/newview/"*.dmg 2>/dev/null | sed 1q
     4.8 +  ls -1tr "$(build_dir_Darwin ${last_built_variant:-Release})/newview/"*"$additional_package_name"*.dmg 2>/dev/null | sed 1q
     4.9  }
    4.10  
    4.11  installer_Linux()
    4.12  {
    4.13 -  ls -1td "$(build_dir_Linux ${last_built_variant:-Release})/newview/"*.tar.bz2 2>/dev/null | sed 1q
    4.14 +  ls -1tr "$(build_dir_Linux ${last_built_variant:-Release})/newview/"*"$additional_package_name"*.tar.bz2 2>/dev/null | grep -v symbols | sed 1q
    4.15  }
    4.16  
    4.17  installer_CYGWIN()
    4.18  {
    4.19    v=${last_built_variant:-Release}
    4.20    d=$(build_dir_CYGWIN $v)
    4.21 -  if [ -r "$d/newview/$v/touched.bat" ]
    4.22 +  if [ -r "$d/newview/$additional_package_name$v/touched.bat" ]
    4.23    then
    4.24 -    p=$(sed 's:.*=::' "$d/newview/$v/touched.bat")
    4.25 -    echo "$d/newview/$v/$p"
    4.26 +    p=$(sed 's:.*=::' "$d/newview/$additional_package_name$v/touched.bat")
    4.27 +    echo "$d/newview/$additional_package_name$v/$p"
    4.28    fi
    4.29  }
    4.30  
    4.31 @@ -355,10 +355,28 @@
    4.32        # Coverity doesn't package, so it's ok, anything else is fail
    4.33        succeeded=$build_coverity
    4.34      else
    4.35 +      # Upload base package.
    4.36        upload_item installer "$package" binary/octet-stream
    4.37        upload_item quicklink "$package" binary/octet-stream
    4.38        [ -f $build_dir/summary.json ] && upload_item installer $build_dir/summary.json text/plain
    4.39  
    4.40 +      # Upload additional packages.
    4.41 +      for package_id in $additional_packages
    4.42 +      do
    4.43 +        case $arch in
    4.44 +        CYGWIN) export additional_package_name="$package_id/" ;;
    4.45 +        *) export additional_package_name=$package_id ;;
    4.46 +        esac
    4.47 +        package=$(installer_$arch)
    4.48 +        if [ x"$package" != x ]
    4.49 +        then
    4.50 +          upload_item installer "$package" binary/octet-stream
    4.51 +        else
    4.52 +          record_failure "Failed to upload $package_id package."
    4.53 +        fi
    4.54 +      done
    4.55 +      export additional_package_name=""
    4.56 +
    4.57        case "$last_built_variant" in
    4.58        Release)
    4.59          # Upload crash reporter files
     5.1 --- a/doc/contributions.txt	Thu Oct 17 18:26:04 2013 -0400
     5.2 +++ b/doc/contributions.txt	Tue Nov 12 14:06:38 2013 -0500
     5.3 @@ -175,8 +175,11 @@
     5.4  	STORM-1685
     5.5  	STORM-1713
     5.6  	STORM-1899
     5.7 +	STORM-1932
     5.8 +	STORM-1933
     5.9  	MAINT-2368
    5.10  	STORM-1931
    5.11 +	MAINT-2773
    5.12  Aralara Rajal
    5.13  Arare Chantilly
    5.14  	CHUIBUG-191
    5.15 @@ -304,9 +307,13 @@
    5.16  Ciaran Laval
    5.17  Cinder Roxley
    5.18      BUG-2326
    5.19 +    OPEN-185
    5.20      STORM-1703
    5.21  	STORM-1948
    5.22 +    STORM-1888
    5.23 +    STORM-1958
    5.24      STORM-1952
    5.25 +    STORM-1951
    5.26  Clara Young
    5.27  Coaldust Numbers
    5.28      VWR-1095
    5.29 @@ -652,7 +659,7 @@
    5.30  	STORM-1809
    5.31  	STORM-1793
    5.32  	STORM-1810
    5.33 -	STORM-1877
    5.34 +	STORM-1838
    5.35  	STORM-1892
    5.36  	STORM-1894
    5.37  	STORM-1860
    5.38 @@ -662,8 +669,11 @@
    5.39  	STORM-1858
    5.40  	STORM-1862
    5.41  	STORM-1918
    5.42 +	STORM-1929
    5.43  	STORM-1953
    5.44  	OPEN-161
    5.45 +	STORM-1953
    5.46 +	STORM-1957
    5.47  Kadah Coba
    5.48  	STORM-1060
    5.49      STORM-1843
    5.50 @@ -679,7 +689,9 @@
    5.51  Kaimen Takahe
    5.52  Katharine Berry
    5.53  	STORM-1900
    5.54 +    OPEN-149
    5.55  	STORM-1940
    5.56 +    OPEN-149
    5.57  	STORM-1941
    5.58  Keklily Longfall
    5.59  Ken Lavender
    5.60 @@ -928,7 +940,9 @@
    5.61  	STORM-1936
    5.62  	BUG-3605
    5.63  	CHUIBUG-197
    5.64 +	OPEN-187
    5.65  	STORM-1937
    5.66 +	OPEN-187
    5.67  Nicky Perian
    5.68  	OPEN-1
    5.69  	STORM-1087
    5.70 @@ -1125,6 +1139,7 @@
    5.71  snowy Sidran
    5.72  Sovereign Engineer
    5.73      MAINT-2334
    5.74 +    OPEN-189
    5.75  SpacedOut Frye
    5.76  	VWR-34
    5.77  	VWR-45
    5.78 @@ -1293,6 +1308,7 @@
    5.79  Whimsy Winx
    5.80  Whirly Fizzle
    5.81  	STORM-1895
    5.82 +	VWR-29543
    5.83  	MAINT-873
    5.84  	STORM-1930
    5.85  Whoops Babii
    5.86 @@ -1356,6 +1372,7 @@
    5.87  Zak Westminster
    5.88  Zai Lynch
    5.89  	VWR-19505
    5.90 +    STORM-1902
    5.91  Zana Kohime
    5.92  Zaren Alexander
    5.93  Zarkonnen Decosta
     6.1 --- a/indra/CMakeLists.txt	Thu Oct 17 18:26:04 2013 -0400
     6.2 +++ b/indra/CMakeLists.txt	Tue Nov 12 14:06:38 2013 -0500
     6.3 @@ -63,10 +63,11 @@
     6.4  # viewer media plugins
     6.5  add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
     6.6  
     6.7 -# llplugin testbed code (is this the right way to include it?)
     6.8 -if (LL_TESTS AND NOT LINUX)
     6.9 -  add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest)
    6.10 -endif (LL_TESTS AND NOT LINUX)
    6.11 +  # llplugin testbed code (is this the right way to include it?)
    6.12 +  if (LL_TESTS AND NOT LINUX)
    6.13 +    add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest)
    6.14 +    add_subdirectory(${VIEWER_PREFIX}test_apps/llfbconnecttest)
    6.15 +  endif (LL_TESTS AND NOT LINUX)
    6.16  
    6.17  if (LINUX)
    6.18    add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
     7.1 --- a/indra/cmake/BuildVersion.cmake	Thu Oct 17 18:26:04 2013 -0400
     7.2 +++ b/indra/cmake/BuildVersion.cmake	Tue Nov 12 14:06:38 2013 -0500
     7.3 @@ -16,22 +16,26 @@
     7.4  
     7.5          else (DEFINED ENV{revision})
     7.6             find_program(MERCURIAL hg)
     7.7 -           if (DEFINED MERCURIAL)
     7.8 +           find_program(WORDCOUNT wc)
     7.9 +           find_program(SED sed)
    7.10 +           if (DEFINED MERCURIAL AND DEFINED WORDCOUNT AND DEFINED SED)
    7.11                execute_process(
    7.12 -                 COMMAND ${MERCURIAL} log -r tip --template "{rev}"
    7.13 +                 COMMAND ${MERCURIAL} log -r tip:0 --template '\\n'
    7.14 +                 COMMAND ${WORDCOUNT} -l
    7.15 +                 COMMAND ${SED} "s/ //g"
    7.16                   OUTPUT_VARIABLE VIEWER_VERSION_REVISION
    7.17                   OUTPUT_STRIP_TRAILING_WHITESPACE
    7.18                   )
    7.19                if ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
    7.20                   message("Revision (from hg) ${VIEWER_VERSION_REVISION}")
    7.21                else ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
    7.22 +                 message("Revision not set (repository not found?); using 0")
    7.23                   set(VIEWER_VERSION_REVISION 0 )
    7.24 -                 message("Revision not set, repository not found, using ${VIEWER_VERSION_REVISION}")
    7.25                endif ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
    7.26 -           else (DEFINED MERCURIAL)
    7.27 +           else (DEFINED MERCURIAL AND DEFINED WORDCOUNT AND DEFINED SED)
    7.28 +              message("Revision not set: 'hg', 'wc' or 'sed' not found; using 0")
    7.29                set(VIEWER_VERSION_REVISION 0)
    7.30 -              message("Revision not set, 'hg' not found (${MERCURIAL}), using ${VIEWER_VERSION_REVISION}")
    7.31 -           endif (DEFINED MERCURIAL)
    7.32 +           endif (DEFINED MERCURIAL AND DEFINED WORDCOUNT AND DEFINED SED)
    7.33          endif (DEFINED ENV{revision})
    7.34          message("Building '${VIEWER_CHANNEL}' Version ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
    7.35      else ( EXISTS ${VIEWER_VERSION_BASE_FILE} )
     8.1 --- a/indra/lib/python/indra/util/llmanifest.py	Thu Oct 17 18:26:04 2013 -0400
     8.2 +++ b/indra/lib/python/indra/util/llmanifest.py	Tue Nov 12 14:06:38 2013 -0500
     8.3 @@ -224,15 +224,98 @@
     8.4      for opt in args:
     8.5          print "Option:", opt, "=", args[opt]
     8.6  
     8.7 +    # pass in sourceid as an argument now instead of an environment variable
     8.8 +    try:
     8.9 +        args['sourceid'] = os.environ["sourceid"]
    8.10 +    except KeyError:
    8.11 +        args['sourceid'] = ""
    8.12 +
    8.13 +    # Build base package.
    8.14 +    touch = args.get('touch')
    8.15 +    if touch:
    8.16 +        print 'Creating base package'
    8.17 +    args['package_id'] = "" # base package has no package ID
    8.18      wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
    8.19      wm.do(*args['actions'])
    8.20 +    # Store package file for later if making touched file.
    8.21 +    base_package_file = ""
    8.22 +    if touch:
    8.23 +        print 'Created base package ', wm.package_file
    8.24 +        base_package_file = "" + wm.package_file
    8.25  
    8.26 +    # handle multiple packages if set
    8.27 +    try:
    8.28 +        additional_packages = os.environ["additional_packages"]
    8.29 +    except KeyError:
    8.30 +        additional_packages = ""
    8.31 +    if additional_packages:
    8.32 +        # Determine destination prefix / suffix for additional packages.
    8.33 +        base_dest_postfix = args['dest']
    8.34 +        base_dest_prefix = ""
    8.35 +        base_dest_parts = args['dest'].split(os.sep)
    8.36 +        if len(base_dest_parts) > 1:
    8.37 +            base_dest_postfix = base_dest_parts[len(base_dest_parts) - 1]
    8.38 +            base_dest_prefix = base_dest_parts[0]
    8.39 +            i = 1
    8.40 +            while i < len(base_dest_parts) - 1:
    8.41 +                base_dest_prefix = base_dest_prefix + os.sep + base_dest_parts[i]
    8.42 +                i = i + 1
    8.43 +        # Determine touched prefix / suffix for additional packages.
    8.44 +        base_touch_postfix = ""
    8.45 +        base_touch_prefix = ""
    8.46 +        if touch:
    8.47 +            base_touch_postfix = touch
    8.48 +            base_touch_parts = touch.split('/')
    8.49 +            if "arwin" in args['platform']:
    8.50 +                if len(base_touch_parts) > 1:
    8.51 +                    base_touch_postfix = base_touch_parts[len(base_touch_parts) - 1]
    8.52 +                    base_touch_prefix = base_touch_parts[0]
    8.53 +                    i = 1
    8.54 +                    while i < len(base_touch_parts) - 1:
    8.55 +                        base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i]
    8.56 +                        i = i + 1
    8.57 +            else:
    8.58 +                if len(base_touch_parts) > 2:
    8.59 +                    base_touch_postfix = base_touch_parts[len(base_touch_parts) - 2] + '/' + base_touch_parts[len(base_touch_parts) - 1]
    8.60 +                    base_touch_prefix = base_touch_parts[0]
    8.61 +                    i = 1
    8.62 +                    while i < len(base_touch_parts) - 2:
    8.63 +                        base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i]
    8.64 +                        i = i + 1
    8.65 +        # Store base channel name.
    8.66 +        base_channel_name = args['channel']
    8.67 +        # Build each additional package.
    8.68 +        package_id_list = additional_packages.split(" ")
    8.69 +        for package_id in package_id_list:
    8.70 +            try:
    8.71 +                args['package_id'] = package_id
    8.72 +                args['channel'] = base_channel_name + os.environ[package_id + "_viewer_channel_suffix"]
    8.73 +                if package_id + "_sourceid" in os.environ:
    8.74 +                    args['sourceid'] = os.environ[package_id + "_sourceid"]
    8.75 +                else:
    8.76 +                    args['sourceid'] = ""
    8.77 +                args['dest'] = base_dest_prefix + os.sep + package_id + os.sep + base_dest_postfix
    8.78 +            except KeyError:
    8.79 +                sys.stderr.write("Failed to create package for package_id: %s" % package_id)
    8.80 +                sys.stderr.flush()
    8.81 +                continue
    8.82 +            if touch:
    8.83 +                print 'Creating additional package for ', package_id, ' in ', args['dest']
    8.84 +            wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
    8.85 +            wm.do(*args['actions'])
    8.86 +            if touch:
    8.87 +                print 'Created additional package ', wm.package_file, ' for ', package_id
    8.88 +                faketouch = base_touch_prefix + '/' + package_id + '/' + base_touch_postfix
    8.89 +                fp = open(faketouch, 'w')
    8.90 +                fp.write('set package_file=%s\n' % wm.package_file)
    8.91 +                fp.close()
    8.92 +    
    8.93      # Write out the package file in this format, so that it can easily be called
    8.94      # and used in a .bat file - yeah, it sucks, but this is the simplest...
    8.95      touch = args.get('touch')
    8.96      if touch:
    8.97          fp = open(touch, 'w')
    8.98 -        fp.write('set package_file=%s\n' % wm.package_file)
    8.99 +        fp.write('set package_file=%s\n' % base_package_file)
   8.100          fp.close()
   8.101          print 'touched', touch
   8.102      return 0
     9.1 --- a/indra/llcommon/llsd.cpp	Thu Oct 17 18:26:04 2013 -0400
     9.2 +++ b/indra/llcommon/llsd.cpp	Tue Nov 12 14:06:38 2013 -0500
     9.3 @@ -506,6 +506,8 @@
     9.4  
     9.5  		LLSD::array_iterator beginArray() { return mData.begin(); }
     9.6  		LLSD::array_iterator endArray() { return mData.end(); }
     9.7 +		LLSD::reverse_array_iterator rbeginArray() { return mData.rbegin(); }
     9.8 +		LLSD::reverse_array_iterator rendArray() { return mData.rend(); }
     9.9  		virtual LLSD::array_const_iterator beginArray() const { return mData.begin(); }
    9.10  		virtual LLSD::array_const_iterator endArray() const { return mData.end(); }
    9.11  
    9.12 @@ -947,6 +949,9 @@
    9.13  LLSD::array_const_iterator	LLSD::beginArray() const{ return safe(impl).beginArray(); }
    9.14  LLSD::array_const_iterator	LLSD::endArray() const	{ return safe(impl).endArray(); }
    9.15  
    9.16 +LLSD::reverse_array_iterator	LLSD::rbeginArray()		{ return makeArray(impl).rbeginArray(); }
    9.17 +LLSD::reverse_array_iterator	LLSD::rendArray()		{ return makeArray(impl).rendArray(); }
    9.18 +
    9.19  namespace llsd
    9.20  {
    9.21  
    10.1 --- a/indra/llcommon/llsd.h	Thu Oct 17 18:26:04 2013 -0400
    10.2 +++ b/indra/llcommon/llsd.h	Tue Nov 12 14:06:38 2013 -0500
    10.3 @@ -320,11 +320,15 @@
    10.4  		
    10.5  		typedef std::vector<LLSD>::iterator			array_iterator;
    10.6  		typedef std::vector<LLSD>::const_iterator	array_const_iterator;
    10.7 -		
    10.8 +		typedef std::vector<LLSD>::reverse_iterator reverse_array_iterator;
    10.9 +
   10.10  		array_iterator			beginArray();
   10.11  		array_iterator			endArray();
   10.12  		array_const_iterator	beginArray() const;
   10.13  		array_const_iterator	endArray() const;
   10.14 +
   10.15 +		reverse_array_iterator	rbeginArray();
   10.16 +		reverse_array_iterator	rendArray();
   10.17  	//@}
   10.18  	
   10.19  	/** @name Type Testing */
    11.1 --- a/indra/llcommon/llsys.cpp	Thu Oct 17 18:26:04 2013 -0400
    11.2 +++ b/indra/llcommon/llsys.cpp	Tue Nov 12 14:06:38 2013 -0500
    11.3 @@ -114,6 +114,9 @@
    11.4  static const F32 MEM_INFO_WINDOW = 10*60;
    11.5  
    11.6  #if LL_WINDOWS
    11.7 +// We cannot trust GetVersionEx function on Win8.1 , we should check this value when creating OS string
    11.8 +static const U32 WINNT_WINBLUE = 0x0603;
    11.9 +
   11.10  #ifndef DLLVERSIONINFO
   11.11  typedef struct _DllVersionInfo
   11.12  {
   11.13 @@ -214,6 +217,26 @@
   11.14      }
   11.15  }
   11.16  
   11.17 +#if LL_WINDOWS
   11.18 +// GetVersionEx should not works correct with Windows 8.1 and the later version. We need to check this case 
   11.19 +static bool	check_for_version(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
   11.20 +{
   11.21 +    OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 };
   11.22 +    DWORDLONG        const dwlConditionMask = VerSetConditionMask(
   11.23 +        VerSetConditionMask(
   11.24 +        VerSetConditionMask(
   11.25 +            0, VER_MAJORVERSION, VER_GREATER_EQUAL),
   11.26 +               VER_MINORVERSION, VER_GREATER_EQUAL),
   11.27 +               VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
   11.28 +
   11.29 +    osvi.dwMajorVersion = wMajorVersion;
   11.30 +    osvi.dwMinorVersion = wMinorVersion;
   11.31 +    osvi.wServicePackMajor = wServicePackMajor;
   11.32 +
   11.33 +    return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
   11.34 +}
   11.35 +#endif
   11.36 +
   11.37  
   11.38  LLOSInfo::LLOSInfo() :
   11.39  	mMajorVer(0), mMinorVer(0), mBuild(0), mOSVersionString("")	 
   11.40 @@ -222,6 +245,7 @@
   11.41  #if LL_WINDOWS
   11.42  	OSVERSIONINFOEX osvi;
   11.43  	BOOL bOsVersionInfoEx;
   11.44 +	BOOL bShouldUseShellVersion = false;
   11.45  
   11.46  	// Try calling GetVersionEx using the OSVERSIONINFOEX structure.
   11.47  	ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
   11.48 @@ -284,10 +308,18 @@
   11.49  				}
   11.50  				else if(osvi.dwMinorVersion == 2)
   11.51  				{
   11.52 -					if(osvi.wProductType == VER_NT_WORKSTATION)
   11.53 -						mOSStringSimple = "Microsoft Windows 8 ";
   11.54 +					if (check_for_version(HIBYTE(WINNT_WINBLUE), LOBYTE(WINNT_WINBLUE), 0))
   11.55 +					{
   11.56 +						mOSStringSimple = "Microsoft Windows 8.1 ";
   11.57 +						bShouldUseShellVersion = true; // GetVersionEx failed, going to use shell version
   11.58 +					}
   11.59  					else
   11.60 -						mOSStringSimple = "Windows Server 2012 ";
   11.61 +					{
   11.62 +						if(osvi.wProductType == VER_NT_WORKSTATION)
   11.63 +							mOSStringSimple = "Microsoft Windows 8 ";
   11.64 +						else
   11.65 +							mOSStringSimple = "Windows Server 2012 ";
   11.66 +					}
   11.67  				}
   11.68  
   11.69  				///get native system info if available..
   11.70 @@ -354,9 +386,8 @@
   11.71  			}
   11.72  			else
   11.73  			{
   11.74 -				tmpstr = llformat("%s (Build %d)",
   11.75 -								  csdversion.c_str(),
   11.76 -								  (osvi.dwBuildNumber & 0xffff));
   11.77 +				tmpstr = !bShouldUseShellVersion ?  llformat("%s (Build %d)", csdversion.c_str(), (osvi.dwBuildNumber & 0xffff)):
   11.78 +					llformat("%s (Build %d)", csdversion.c_str(), shell32_build);
   11.79  			}
   11.80  
   11.81  			mOSString = mOSStringSimple + tmpstr;
   11.82 @@ -392,7 +423,7 @@
   11.83  	std::string compatibility_mode;
   11.84  	if(got_shell32_version)
   11.85  	{
   11.86 -		if(osvi.dwMajorVersion != shell32_major || osvi.dwMinorVersion != shell32_minor)
   11.87 +		if((osvi.dwMajorVersion != shell32_major || osvi.dwMinorVersion != shell32_minor) && !bShouldUseShellVersion)
   11.88  		{
   11.89  			compatibility_mode = llformat(" compatibility mode. real ver: %d.%d (Build %d)", 
   11.90  											shell32_major,
    12.1 --- a/indra/llcommon/llversionviewer.h	Thu Oct 17 18:26:04 2013 -0400
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,41 +0,0 @@
    12.4 -/** 
    12.5 - * @file llversionviewer.h
    12.6 - * @brief
    12.7 - *
    12.8 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
    12.9 - * Second Life Viewer Source Code
   12.10 - * Copyright (C) 2010, Linden Research, Inc.
   12.11 - * 
   12.12 - * This library is free software; you can redistribute it and/or
   12.13 - * modify it under the terms of the GNU Lesser General Public
   12.14 - * License as published by the Free Software Foundation;
   12.15 - * version 2.1 of the License only.
   12.16 - * 
   12.17 - * This library is distributed in the hope that it will be useful,
   12.18 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.19 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12.20 - * Lesser General Public License for more details.
   12.21 - * 
   12.22 - * You should have received a copy of the GNU Lesser General Public
   12.23 - * License along with this library; if not, write to the Free Software
   12.24 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   12.25 - * 
   12.26 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   12.27 - * $/LicenseInfo$
   12.28 - */
   12.29 -
   12.30 -#ifndef LL_LLVERSIONVIEWER_H
   12.31 -#define LL_LLVERSIONVIEWER_H
   12.32 -
   12.33 -const S32 LL_VERSION_MAJOR = 3;
   12.34 -const S32 LL_VERSION_MINOR = 4;
   12.35 -const S32 LL_VERSION_PATCH = 6;
   12.36 -const S32 LL_VERSION_BUILD = 0;
   12.37 -
   12.38 -const char * const LL_CHANNEL = "Second Life Developer";
   12.39 -
   12.40 -#if LL_DARWIN
   12.41 -const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer";
   12.42 -#endif
   12.43 -
   12.44 -#endif
    13.1 --- a/indra/llinventory/llparcel.cpp	Thu Oct 17 18:26:04 2013 -0400
    13.2 +++ b/indra/llinventory/llparcel.cpp	Tue Nov 12 14:06:38 2013 -0500
    13.3 @@ -414,117 +414,6 @@
    13.4  }
    13.5  
    13.6  
    13.7 -bool LLParcel::isAgentBlockedFromParcel(LLParcel* parcelp,
    13.8 -                                        const LLUUID& agent_id,
    13.9 -                                        const uuid_vec_t& group_ids,
   13.10 -                                        const BOOL is_agent_identified,
   13.11 -                                        const BOOL is_agent_transacted,
   13.12 -                                        const BOOL is_agent_ageverified)
   13.13 -{
   13.14 -    S32 current_group_access = parcelp->blockAccess(agent_id, LLUUID::null, is_agent_identified, is_agent_transacted, is_agent_ageverified);
   13.15 -    S32 count;
   13.16 -    bool is_allowed = (current_group_access == BA_ALLOWED) ? true: false;
   13.17 -    LLUUID group_id;
   13.18 -    
   13.19 -    count = group_ids.size();
   13.20 -    for (int i = 0; i < count && !is_allowed; i++)
   13.21 -    {
   13.22 -        group_id = group_ids[i];
   13.23 -        current_group_access = parcelp->blockAccess(agent_id, group_id, is_agent_identified, is_agent_transacted, is_agent_ageverified);
   13.24 -        
   13.25 -        if (current_group_access == BA_ALLOWED) is_allowed = true;
   13.26 -    }
   13.27 -    
   13.28 -    return !is_allowed;
   13.29 -}
   13.30 -
   13.31 -BOOL LLParcel::isAgentBanned(const LLUUID& agent_id) const
   13.32 -{
   13.33 -	// Test ban list
   13.34 -	if (mBanList.find(agent_id) != mBanList.end())
   13.35 -	{
   13.36 -		return TRUE;
   13.37 -	}
   13.38 -    
   13.39 -    return FALSE;
   13.40 -}
   13.41 -
   13.42 -S32 LLParcel::blockAccess(const LLUUID& agent_id, const LLUUID& group_id,
   13.43 -                          const BOOL is_agent_identified,
   13.44 -                          const BOOL is_agent_transacted,
   13.45 -                          const BOOL is_agent_ageverified) const
   13.46 -{
   13.47 -    // Test ban list
   13.48 -    if (isAgentBanned(agent_id))
   13.49 -    {
   13.50 -        return BA_BANNED;
   13.51 -    }
   13.52 -    
   13.53 -    // Always allow owner on (unless he banned himself, useful for
   13.54 -    // testing). We will also allow estate owners/managers in if they 
   13.55 -    // are not explicitly banned.
   13.56 -    if (agent_id == mOwnerID)
   13.57 -    {
   13.58 -        return BA_ALLOWED;
   13.59 -    }
   13.60 -    
   13.61 -    // Special case when using pass list where group access is being restricted but not 
   13.62 -    // using access list.	 In this case group members are allowed only if they buy a pass.
   13.63 -    // We return BA_NOT_IN_LIST if not in list
   13.64 -    BOOL passWithGroup = getParcelFlag(PF_USE_PASS_LIST) && !getParcelFlag(PF_USE_ACCESS_LIST) 
   13.65 -    && getParcelFlag(PF_USE_ACCESS_GROUP) && !mGroupID.isNull() && group_id == mGroupID;
   13.66 -    
   13.67 -    
   13.68 -    // Test group list
   13.69 -    if (getParcelFlag(PF_USE_ACCESS_GROUP)
   13.70 -        && !mGroupID.isNull()
   13.71 -        && group_id == mGroupID
   13.72 -        && !passWithGroup)
   13.73 -    {
   13.74 -        return BA_ALLOWED;
   13.75 -    }
   13.76 -    
   13.77 -    // Test access list
   13.78 -    if (getParcelFlag(PF_USE_ACCESS_LIST) || passWithGroup )
   13.79 -    {
   13.80 -        if (mAccessList.find(agent_id) != mAccessList.end())
   13.81 -        {
   13.82 -            return BA_ALLOWED;
   13.83 -        }
   13.84 -        
   13.85 -        return BA_NOT_ON_LIST; 
   13.86 -    }
   13.87 -    
   13.88 -    // If we're not doing any other limitations, all users
   13.89 -    // can enter, unless
   13.90 -    if (		 !getParcelFlag(PF_USE_ACCESS_GROUP)
   13.91 -                 && !getParcelFlag(PF_USE_ACCESS_LIST))
   13.92 -    { 
   13.93 -        //If the land is group owned, and you are in the group, bypass these checks
   13.94 -        if(getIsGroupOwned() && group_id == mGroupID)
   13.95 -        {
   13.96 -            return BA_ALLOWED;
   13.97 -        }
   13.98 -        
   13.99 -        // Test for "payment" access levels
  13.100 -        // Anonymous - No Payment Info on File
  13.101 -        if(getParcelFlag(PF_DENY_ANONYMOUS) && !is_agent_identified && !is_agent_transacted)
  13.102 -        {
  13.103 -            return BA_NO_ACCESS_LEVEL;
  13.104 -        }
  13.105 -        // AgeUnverified - Not Age Verified
  13.106 -        if(getParcelFlag(PF_DENY_AGEUNVERIFIED) && !is_agent_ageverified)
  13.107 -        {
  13.108 -			return BA_NOT_AGE_VERIFIED;
  13.109 -        }
  13.110 -    
  13.111 -        return BA_ALLOWED;
  13.112 -    }
  13.113 -    
  13.114 -    return BA_NOT_IN_GROUP;
  13.115 -    
  13.116 -}
  13.117 -
  13.118  
  13.119  void LLParcel::setArea(S32 area, S32 sim_object_limit)
  13.120  {
    14.1 --- a/indra/llinventory/llparcel.h	Thu Oct 17 18:26:04 2013 -0400
    14.2 +++ b/indra/llinventory/llparcel.h	Tue Nov 12 14:06:38 2013 -0500
    14.3 @@ -527,23 +527,6 @@
    14.4  	// Can this agent change the shape of the land?
    14.5  	BOOL	allowTerraformBy(const LLUUID &agent_id) const;
    14.6  
    14.7 -	// Returns 0 if access is OK, otherwise a BA_ return code above.
    14.8 -	S32	 blockAccess(const LLUUID& agent_id, 
    14.9 -			const LLUUID& group_id, 
   14.10 -			const BOOL is_agent_identified, 
   14.11 -			const BOOL is_agent_transacted,
   14.12 -			const BOOL is_agent_ageverified) const;
   14.13 -
   14.14 -	// Only checks if the agent is explicitly banned from this parcel
   14.15 -	BOOL isAgentBanned(const LLUUID& agent_id) const;
   14.16 -
   14.17 -	static bool isAgentBlockedFromParcel(LLParcel* parcelp, 
   14.18 -									const LLUUID& agent_id,
   14.19 -									const uuid_vec_t& group_ids,
   14.20 -									const BOOL is_agent_identified,
   14.21 -									const BOOL is_agent_transacted,
   14.22 -									const BOOL is_agent_ageverified);
   14.23 -
   14.24  	bool	operator==(const LLParcel &rhs) const;
   14.25  
   14.26  	// Calculate rent - area * rent * discount rate
    15.1 --- a/indra/llmath/llvolume.cpp	Thu Oct 17 18:26:04 2013 -0400
    15.2 +++ b/indra/llmath/llvolume.cpp	Tue Nov 12 14:06:38 2013 -0500
    15.3 @@ -166,7 +166,8 @@
    15.4  
    15.5  	F32 rd = s1*t2-s2*t1;
    15.6  
    15.7 -	float r = ((rd*rd) > FLT_EPSILON) ? 1.0F / rd : 1024.f; //some made up large ratio for division by zero
    15.8 +	float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd)
    15.9 +											    : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero
   15.10  
   15.11  	llassert(llfinite(r));
   15.12  	llassert(!llisnan(r));
   15.13 @@ -6789,7 +6790,8 @@
   15.14          
   15.15  		F32 rd = s1*t2-s2*t1;
   15.16  
   15.17 -		float r = ((rd*rd) > FLT_EPSILON) ? 1.0F / rd : 1024.f; //some made up large ratio for division by zero
   15.18 +		float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd)
   15.19 +													 : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero
   15.20  
   15.21  		llassert(llfinite(r));
   15.22  		llassert(!llisnan(r));
    16.1 --- a/indra/llmath/v4color.h	Thu Oct 17 18:26:04 2013 -0400
    16.2 +++ b/indra/llmath/v4color.h	Tue Nov 12 14:06:38 2013 -0500
    16.3 @@ -50,7 +50,7 @@
    16.4  		LLColor4(F32 r, F32 g, F32 b);		// Initializes LLColor4 to (r, g, b, 1)
    16.5  		LLColor4(F32 r, F32 g, F32 b, F32 a);		// Initializes LLColor4 to (r. g, b, a)
    16.6  		LLColor4(U32 clr);							// Initializes LLColor4 to (r=clr>>24, etc))
    16.7 -		LLColor4(const F32 *vec);			// Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1)
    16.8 +		LLColor4(const F32 *vec);			// Initializes LLColor4 to (vec[0]. vec[1], vec[2], vec[3])
    16.9  		LLColor4(const LLColor3 &vec, F32 a = 1.f);	// Initializes LLColor4 to (vec, a)
   16.10  		explicit LLColor4(const LLSD& sd);
   16.11  		explicit LLColor4(const LLColor4U& color4u);  // "explicit" to avoid automatic conversion
    17.1 --- a/indra/llmessage/llhttpclient.cpp	Thu Oct 17 18:26:04 2013 -0400
    17.2 +++ b/indra/llmessage/llhttpclient.cpp	Tue Nov 12 14:06:38 2013 -0500
    17.3 @@ -217,7 +217,8 @@
    17.4  	Injector* body_injector,
    17.5  	LLCurl::ResponderPtr responder,
    17.6  	const F32 timeout = HTTP_REQUEST_EXPIRY_SECS,
    17.7 -	const LLSD& headers = LLSD()
    17.8 +	const LLSD& headers = LLSD(),
    17.9 +	bool follow_redirects = true
   17.10      )
   17.11  {
   17.12  	if (!LLHTTPClient::hasPump())
   17.13 @@ -231,7 +232,7 @@
   17.14  	}
   17.15  	LLPumpIO::chain_t chain;
   17.16  
   17.17 -	LLURLRequest* req = new LLURLRequest(method, url);
   17.18 +	LLURLRequest* req = new LLURLRequest(method, url, follow_redirects);
   17.19  	if(!req->isValid())//failed
   17.20  	{
   17.21  		if (responder)
   17.22 @@ -334,7 +335,8 @@
   17.23  	S32 bytes,
   17.24  	ResponderPtr responder,
   17.25  	const LLSD& hdrs,
   17.26 -	const F32 timeout)
   17.27 +	const F32 timeout,
   17.28 +	bool follow_redirects /* = true */)
   17.29  {
   17.30  	LLSD headers = hdrs;
   17.31  	if(offset > 0 || bytes > 0)
   17.32 @@ -342,37 +344,42 @@
   17.33  		std::string range = llformat("bytes=%d-%d", offset, offset+bytes-1);
   17.34  		headers["Range"] = range;
   17.35  	}
   17.36 -    request(url,LLURLRequest::HTTP_GET, NULL, responder, timeout, headers);
   17.37 +    request(url,LLURLRequest::HTTP_GET, NULL, responder, timeout, headers, follow_redirects);
   17.38  }
   17.39  
   17.40  void LLHTTPClient::head(
   17.41  	const std::string& url,
   17.42  	ResponderPtr responder,
   17.43  	const LLSD& headers,
   17.44 -	const F32 timeout)
   17.45 +	const F32 timeout,
   17.46 +	bool follow_redirects /* = true */)
   17.47  {
   17.48 -	request(url, LLURLRequest::HTTP_HEAD, NULL, responder, timeout, headers);
   17.49 +	request(url, LLURLRequest::HTTP_HEAD, NULL, responder, timeout, headers, follow_redirects);
   17.50  }
   17.51  
   17.52 -void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout)
   17.53 +void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout,
   17.54 +					   bool follow_redirects /* = true */)
   17.55  {
   17.56 -	request(url, LLURLRequest::HTTP_GET, NULL, responder, timeout, headers);
   17.57 +	request(url, LLURLRequest::HTTP_GET, NULL, responder, timeout, headers, follow_redirects);
   17.58  }
   17.59 -void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout)
   17.60 +void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const LLSD& headers,
   17.61 +								 const F32 timeout, bool follow_redirects /* = true */)
   17.62  {
   17.63 -	request(url, LLURLRequest::HTTP_HEAD, NULL, responder, timeout, headers);
   17.64 +	request(url, LLURLRequest::HTTP_HEAD, NULL, responder, timeout, headers, follow_redirects);
   17.65  }
   17.66 -void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const F32 timeout)
   17.67 +void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const F32 timeout,
   17.68 +								 bool follow_redirects /* = true */)
   17.69  {
   17.70 -	getHeaderOnly(url, responder, LLSD(), timeout);
   17.71 +	getHeaderOnly(url, responder, LLSD(), timeout, follow_redirects);
   17.72  }
   17.73  
   17.74 -void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const LLSD& headers, const F32 timeout)
   17.75 +void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const LLSD& headers,
   17.76 +					   const F32 timeout, bool follow_redirects /* = true */)
   17.77  {
   17.78  	LLURI uri;
   17.79  	
   17.80  	uri = LLURI::buildHTTP(url, LLSD::emptyArray(), query);
   17.81 -	get(uri.asString(), responder, headers, timeout);
   17.82 +	get(uri.asString(), responder, headers, timeout, follow_redirects);
   17.83  }
   17.84  
   17.85  // A simple class for managing data returned from a curl http request.
    18.1 --- a/indra/llmessage/llhttpclient.h	Thu Oct 17 18:26:04 2013 -0400
    18.2 +++ b/indra/llmessage/llhttpclient.h	Tue Nov 12 14:06:38 2013 -0500
    18.3 @@ -63,10 +63,15 @@
    18.4  		const std::string& url,
    18.5  		ResponderPtr,
    18.6  		const LLSD& headers = LLSD(),
    18.7 -		const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
    18.8 -	static void getByteRange(const std::string& url, S32 offset, S32 bytes, ResponderPtr, const LLSD& headers=LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
    18.9 -	static void get(const std::string& url, ResponderPtr, const LLSD& headers = LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
   18.10 -	static void get(const std::string& url, const LLSD& query, ResponderPtr, const LLSD& headers = LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
   18.11 +		const F32 timeout=HTTP_REQUEST_EXPIRY_SECS,
   18.12 +		bool follow_redirects = true);
   18.13 +	static void getByteRange(const std::string& url, S32 offset, S32 bytes, ResponderPtr,
   18.14 +							 const LLSD& headers=LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS,
   18.15 +							 bool follow_redirects = true);
   18.16 +	static void get(const std::string& url, ResponderPtr, const LLSD& headers = LLSD(),
   18.17 +					const F32 timeout=HTTP_REQUEST_EXPIRY_SECS, bool follow_redirects = true);
   18.18 +	static void get(const std::string& url, const LLSD& query, ResponderPtr, const LLSD& headers = LLSD(),
   18.19 +					const F32 timeout=HTTP_REQUEST_EXPIRY_SECS, bool follow_redirects = true);
   18.20  
   18.21  	static void put(
   18.22  		const std::string& url,
   18.23 @@ -74,8 +79,10 @@
   18.24  		ResponderPtr,
   18.25  		const LLSD& headers = LLSD(),
   18.26  		const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
   18.27 -	static void getHeaderOnly(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
   18.28 -	static void getHeaderOnly(const std::string& url, ResponderPtr, const LLSD& headers, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
   18.29 +	static void getHeaderOnly(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS,
   18.30 +							  bool follow_redirects = true);
   18.31 +	static void getHeaderOnly(const std::string& url, ResponderPtr, const LLSD& headers,
   18.32 +							  const F32 timeout=HTTP_REQUEST_EXPIRY_SECS, bool follow_redirects = true);
   18.33  
   18.34  	static void post(
   18.35  		const std::string& url,
    19.1 --- a/indra/llmessage/llinstantmessage.h	Thu Oct 17 18:26:04 2013 -0400
    19.2 +++ b/indra/llmessage/llinstantmessage.h	Tue Nov 12 14:06:38 2013 -0500
    19.3 @@ -126,7 +126,7 @@
    19.4  	IM_LURE_ACCEPTED = 23,
    19.5  	IM_LURE_DECLINED = 24,
    19.6  	IM_GODLIKE_LURE_USER = 25,
    19.7 -	IM_YET_TO_BE_USED = 26,
    19.8 +	IM_TELEPORT_REQUEST = 26,
    19.9  
   19.10  	// IM that notifie of a new group election.
   19.11  	// Name is name of person who called vote.
    20.1 --- a/indra/llmessage/llurlrequest.cpp	Thu Oct 17 18:26:04 2013 -0400
    20.2 +++ b/indra/llmessage/llurlrequest.cpp	Tue Nov 12 14:06:38 2013 -0500
    20.3 @@ -150,16 +150,19 @@
    20.4  	return VERBS[action];
    20.5  }
    20.6  
    20.7 -LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action) :
    20.8 -	mAction(action)
    20.9 +LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action, bool follow_redirects /* = true */) :
   20.10 +	mAction(action),
   20.11 +	mFollowRedirects(follow_redirects)
   20.12  {
   20.13  	initialize();
   20.14  }
   20.15  
   20.16  LLURLRequest::LLURLRequest(
   20.17  	LLURLRequest::ERequestAction action,
   20.18 -	const std::string& url) :
   20.19 -	mAction(action)
   20.20 +	const std::string& url,
   20.21 +	bool follow_redirects /* = true */) :
   20.22 +	mAction(action),
   20.23 +	mFollowRedirects(follow_redirects)
   20.24  {
   20.25  	initialize();
   20.26  	setURL(url);
   20.27 @@ -479,12 +482,18 @@
   20.28  	case HTTP_HEAD:
   20.29  		mDetail->mCurlRequest->setopt(CURLOPT_HEADER, 1);
   20.30  		mDetail->mCurlRequest->setopt(CURLOPT_NOBODY, 1);
   20.31 -		mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1);
   20.32 +		if (mFollowRedirects)
   20.33 +		{
   20.34 +			mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1);
   20.35 +		}
   20.36  		rv = true;
   20.37  		break;
   20.38  	case HTTP_GET:
   20.39  		mDetail->mCurlRequest->setopt(CURLOPT_HTTPGET, 1);
   20.40 -		mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1);
   20.41 +		if (mFollowRedirects)
   20.42 +		{
   20.43 +			mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1);
   20.44 +		}
   20.45  
   20.46  		// Set Accept-Encoding to allow response compression
   20.47  		mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, "");
    21.1 --- a/indra/llmessage/llurlrequest.h	Thu Oct 17 18:26:04 2013 -0400
    21.2 +++ b/indra/llmessage/llurlrequest.h	Tue Nov 12 14:06:38 2013 -0500
    21.3 @@ -95,7 +95,7 @@
    21.4  	 *
    21.5  	 * @param action One of the ERequestAction enumerations.
    21.6  	 */
    21.7 -	LLURLRequest(ERequestAction action);
    21.8 +	LLURLRequest(ERequestAction action, bool follow_redirects = true);
    21.9  
   21.10  	/** 
   21.11  	 * @brief Constructor.
   21.12 @@ -103,7 +103,7 @@
   21.13  	 * @param action One of the ERequestAction enumerations.
   21.14  	 * @param url The url of the request. It should already be encoded.
   21.15  	 */
   21.16 -	LLURLRequest(ERequestAction action, const std::string& url);
   21.17 +	LLURLRequest(ERequestAction action, const std::string& url, bool follow_redirects = true);
   21.18  
   21.19  	/** 
   21.20  	 * @brief Destructor.
   21.21 @@ -219,10 +219,11 @@
   21.22  	};
   21.23  	EState mState;
   21.24  	ERequestAction mAction;
   21.25 +	bool mFollowRedirects;
   21.26  	LLURLRequestDetail* mDetail;
   21.27  	LLIOPipe::ptr_t mCompletionCallback;
   21.28 -	 S32 mRequestTransferedBytes;
   21.29 -	 S32 mResponseTransferedBytes;
   21.30 +	S32 mRequestTransferedBytes;
   21.31 +	S32 mResponseTransferedBytes;
   21.32  
   21.33  	static CURLcode _sslCtxCallback(CURL * curl, void *sslctx, void *param);
   21.34  	
    22.1 --- a/indra/llplugin/llplugincookiestore.cpp	Thu Oct 17 18:26:04 2013 -0400
    22.2 +++ b/indra/llplugin/llplugincookiestore.cpp	Tue Nov 12 14:06:38 2013 -0500
    22.3 @@ -87,6 +87,16 @@
    22.4  	return result;
    22.5  }
    22.6  
    22.7 +std::string LLPluginCookieStore::Cookie::getDomain() const
    22.8 +{
    22.9 +	std::string result;
   22.10 +	if(mDomainEnd > mDomainStart)
   22.11 +	{
   22.12 +		result += mCookie.substr(mDomainStart, mDomainEnd - mDomainStart);
   22.13 +	}
   22.14 +	return result;
   22.15 +}
   22.16 +
   22.17  bool LLPluginCookieStore::Cookie::parse(const std::string &host)
   22.18  {
   22.19  	bool first_field = true;
   22.20 @@ -662,3 +672,21 @@
   22.21  	}
   22.22  }
   22.23  
   22.24 +void LLPluginCookieStore::removeCookiesByDomain(const std::string &domain)
   22.25 +{
   22.26 +	cookie_map_t::iterator iter = mCookies.begin();
   22.27 +	while(iter != mCookies.end())
   22.28 +	{ 
   22.29 +		if(iter->second->getDomain() == domain)
   22.30 +		{
   22.31 +            cookie_map_t::iterator doErase = iter;
   22.32 +            iter++;
   22.33 +			delete doErase->second;
   22.34 +			mCookies.erase(doErase);
   22.35 +		}
   22.36 +        else
   22.37 +        {
   22.38 +            iter++;
   22.39 +        }
   22.40 +	}
   22.41 +}
    23.1 --- a/indra/llplugin/llplugincookiestore.h	Thu Oct 17 18:26:04 2013 -0400
    23.2 +++ b/indra/llplugin/llplugincookiestore.h	Tue Nov 12 14:06:38 2013 -0500
    23.3 @@ -67,6 +67,8 @@
    23.4  	// quote or unquote a string as per the definition of 'quoted-string' in rfc2616
    23.5  	static std::string quoteString(const std::string &s);
    23.6  	static std::string unquoteString(const std::string &s);
    23.7 +
    23.8 +	void removeCookiesByDomain(const std::string &domain);
    23.9  	
   23.10  private:
   23.11  
   23.12 @@ -79,6 +81,7 @@
   23.13  		
   23.14  		// Construct a string from the cookie that uniquely represents it, to be used as a key in a std::map.
   23.15  		std::string getKey() const;
   23.16 +		std::string getDomain() const;
   23.17  		
   23.18  		const std::string &getCookie() const { return mCookie; };
   23.19  		bool isSessionCookie() const { return mDate.isNull(); };
    24.1 --- a/indra/llrender/llrendertarget.cpp	Thu Oct 17 18:26:04 2013 -0400
    24.2 +++ b/indra/llrender/llrendertarget.cpp	Tue Nov 12 14:06:38 2013 -0500
    24.3 @@ -364,35 +364,55 @@
    24.4  
    24.5  		sBytesAllocated -= mResX*mResY*4;
    24.6  	}
    24.7 -	else if (mUseDepth && mFBO)
    24.8 -	{ //detach shared depth buffer
    24.9 +	else if (mFBO)
   24.10 +	{
   24.11  		glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
   24.12 -		if (mStencil)
   24.13 -		{ //attached as a renderbuffer
   24.14 -			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
   24.15 -			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
   24.16 -			mStencil = false;
   24.17 +
   24.18 +		if (mUseDepth)
   24.19 +		{ //detach shared depth buffer
   24.20 +			if (mStencil)
   24.21 +			{ //attached as a renderbuffer
   24.22 +				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
   24.23 +				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
   24.24 +				mStencil = false;
   24.25 +			}
   24.26 +			else
   24.27 +			{ //attached as a texture
   24.28 +				glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
   24.29 +			}
   24.30 +			mUseDepth = false;
   24.31  		}
   24.32 -		else
   24.33 -		{ //attached as a texture
   24.34 -			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
   24.35 +	}
   24.36 +
   24.37 +	// Detach any extra color buffers (e.g. SRGB spec buffers)
   24.38 +	//
   24.39 +	if (mFBO && (mTex.size() > 1))
   24.40 +	{		
   24.41 +		S32 z;
   24.42 +		for (z = mTex.size() - 1; z >= 1; z--)
   24.43 +		{
   24.44 +			sBytesAllocated -= mResX*mResY*4;
   24.45 +			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+z, LLTexUnit::getInternalType(mUsage), 0, 0);
   24.46 +			stop_glerror();
   24.47 +			LLImageGL::deleteTextures(1, &mTex[z]);
   24.48  		}
   24.49 -		mUseDepth = false;
   24.50  	}
   24.51  
   24.52  	if (mFBO)
   24.53  	{
   24.54  		glDeleteFramebuffers(1, (GLuint *) &mFBO);
   24.55 +		stop_glerror();
   24.56  		mFBO = 0;
   24.57  	}
   24.58  
   24.59  	if (mTex.size() > 0)
   24.60  	{
   24.61 -		sBytesAllocated -= mResX*mResY*4*mTex.size();
   24.62 -		LLImageGL::deleteTextures(mTex.size(), &mTex[0]);
   24.63 +		sBytesAllocated -= mResX*mResY*4;
   24.64 +		LLImageGL::deleteTextures(1, &mTex[0]);
   24.65 +	}
   24.66 +
   24.67  		mTex.clear();
   24.68  		mInternalFormat.clear();
   24.69 -	}
   24.70  	
   24.71  	mResX = mResY = 0;
   24.72  
    25.1 --- a/indra/llui/CMakeLists.txt	Thu Oct 17 18:26:04 2013 -0400
    25.2 +++ b/indra/llui/CMakeLists.txt	Tue Nov 12 14:06:38 2013 -0500
    25.3 @@ -75,6 +75,7 @@
    25.4      llmultislider.cpp
    25.5      llmultisliderctrl.cpp
    25.6      llnotifications.cpp
    25.7 +    llnotificationslistener.cpp
    25.8      llnotificationsutil.cpp
    25.9      llpanel.cpp
   25.10      llprogressbar.cpp
   25.11 @@ -128,6 +129,7 @@
   25.12      llviewmodel.cpp
   25.13      llview.cpp
   25.14      llviewquery.cpp
   25.15 +    llviewereventrecorder.cpp
   25.16      llwindowshade.cpp
   25.17      llxuiparser.cpp
   25.18      )
   25.19 @@ -183,6 +185,7 @@
   25.20      llmultislider.h
   25.21      llnotificationptr.h
   25.22      llnotifications.h
   25.23 +    llnotificationslistener.h
   25.24      llnotificationsutil.h
   25.25      llnotificationtemplate.h
   25.26      llnotificationvisibilityrule.h
   25.27 @@ -240,6 +243,7 @@
   25.28      llviewinject.h
   25.29      llviewmodel.h
   25.30      llview.h
   25.31 +    llviewereventrecorder.h
   25.32      llviewquery.h
   25.33      llwindowshade.h
   25.34      llxuiparser.h
    26.1 --- a/indra/llui/llbutton.cpp	Thu Oct 17 18:26:04 2013 -0400
    26.2 +++ b/indra/llui/llbutton.cpp	Tue Nov 12 14:06:38 2013 -0500
    26.3 @@ -49,6 +49,7 @@
    26.4  #include "lluictrlfactory.h"
    26.5  #include "llhelp.h"
    26.6  #include "lldockablefloater.h"
    26.7 +#include "llviewereventrecorder.h"
    26.8  
    26.9  static LLDefaultChildRegistry::Register<LLButton> r("button");
   26.10  
   26.11 @@ -443,6 +444,8 @@
   26.12  		 */
   26.13  		LLUICtrl::handleMouseDown(x, y, mask);
   26.14  
   26.15 +		LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
   26.16 +
   26.17  		if(mMouseDownSignal) (*mMouseDownSignal)(this, LLSD());
   26.18  
   26.19  		mMouseDownTimer.start();
   26.20 @@ -473,6 +476,7 @@
   26.21  		 * by calling LLUICtrl::mMouseUpSignal(x, y, mask);
   26.22  		 */
   26.23  		LLUICtrl::handleMouseUp(x, y, mask);
   26.24 +		LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); 
   26.25  
   26.26  		// Regardless of where mouseup occurs, handle callback
   26.27  		if(mMouseUpSignal) (*mMouseUpSignal)(this, LLSD());
    27.1 --- a/indra/llui/llchatentry.h	Thu Oct 17 18:26:04 2013 -0400
    27.2 +++ b/indra/llui/llchatentry.h	Tue Nov 12 14:06:38 2013 -0500
    27.3 @@ -62,8 +62,8 @@
    27.4  
    27.5  	virtual void	draw();
    27.6  	virtual	void	onCommit();
    27.7 -	/*virtual*/ void	onFocusReceived();
    27.8 -	/*virtual*/ void	onFocusLost();
    27.9 +    /*virtual*/ void	onFocusReceived();
   27.10 +    /*virtual*/ void	onFocusLost();
   27.11  
   27.12  	void enableSingleLineMode(bool single_line_mode);
   27.13  	boost::signals2::connection setTextExpandedCallback(const commit_signal_t::slot_type& cb);
    28.1 --- a/indra/llui/llcombobox.cpp	Thu Oct 17 18:26:04 2013 -0400
    28.2 +++ b/indra/llui/llcombobox.cpp	Tue Nov 12 14:06:38 2013 -0500
    28.3 @@ -534,6 +534,13 @@
    28.4  	}
    28.5  }
    28.6  
    28.7 +void LLComboBox::setLeftTextPadding(S32 pad)
    28.8 +{
    28.9 +	S32 left_pad, right_pad;
   28.10 +	mTextEntry->getTextPadding(&left_pad, &right_pad);
   28.11 +	mTextEntry->setTextPadding(pad, right_pad);
   28.12 +}
   28.13 +
   28.14  void* LLComboBox::getCurrentUserdata()
   28.15  {
   28.16  	LLScrollListItem* item = mList->getFirstSelected();
    29.1 --- a/indra/llui/llcombobox.h	Thu Oct 17 18:26:04 2013 -0400
    29.2 +++ b/indra/llui/llcombobox.h	Tue Nov 12 14:06:38 2013 -0500
    29.3 @@ -190,6 +190,8 @@
    29.4  	virtual BOOL	operateOnAll(EOperation op);
    29.5  
    29.6  	//========================================================================
    29.7 +
    29.8 +	void			setLeftTextPadding(S32 pad);
    29.9  	
   29.10  	void*			getCurrentUserdata();
   29.11  
    30.1 --- a/indra/llui/llcommandmanager.cpp	Thu Oct 17 18:26:04 2013 -0400
    30.2 +++ b/indra/llui/llcommandmanager.cpp	Tue Nov 12 14:06:38 2013 -0500
    30.3 @@ -50,6 +50,8 @@
    30.4  LLCommand::Params::Params()
    30.5  	: available_in_toybox("available_in_toybox", false)
    30.6  	, icon("icon")
    30.7 +	, hover_icon_unselected("hover_icon_unselected")
    30.8 +	, hover_icon_selected("hover_icon_selected")
    30.9  	, label_ref("label_ref")
   30.10  	, name("name")
   30.11  	, tooltip_ref("tooltip_ref")
   30.12 @@ -71,6 +73,8 @@
   30.13  	: mIdentifier(p.name)
   30.14  	, mAvailableInToybox(p.available_in_toybox)
   30.15  	, mIcon(p.icon)
   30.16 +	, mHoverIconUnselected(p.hover_icon_unselected)
   30.17 +	, mHoverIconSelected(p.hover_icon_selected)
   30.18  	, mLabelRef(p.label_ref)
   30.19  	, mName(p.name)
   30.20  	, mTooltipRef(p.tooltip_ref)
    31.1 --- a/indra/llui/llcommandmanager.h	Thu Oct 17 18:26:04 2013 -0400
    31.2 +++ b/indra/llui/llcommandmanager.h	Tue Nov 12 14:06:38 2013 -0500
    31.3 @@ -96,6 +96,9 @@
    31.4  		Mandatory<std::string>	name;
    31.5  		Mandatory<std::string>	tooltip_ref;
    31.6  
    31.7 +		Optional<std::string>   hover_icon_selected;
    31.8 +		Optional<std::string>   hover_icon_unselected;
    31.9 +
   31.10  		Mandatory<std::string>	execute_function;
   31.11  		Optional<LLSD>			execute_parameters;
   31.12  
   31.13 @@ -124,6 +127,8 @@
   31.14  	const std::string& labelRef() const { return mLabelRef; }
   31.15  	const std::string& name() const { return mName; }
   31.16  	const std::string& tooltipRef() const { return mTooltipRef; }
   31.17 +	const std::string& hoverIconUnselected() const {return mHoverIconUnselected; }
   31.18 +	const std::string& hoverIconSelected() const {return mHoverIconSelected; }
   31.19  
   31.20  	const std::string& executeFunctionName() const { return mExecuteFunction; }
   31.21  	const LLSD& executeParameters() const { return mExecuteParameters; }
   31.22 @@ -150,6 +155,8 @@
   31.23  	std::string mLabelRef;
   31.24  	std::string mName;
   31.25  	std::string mTooltipRef;
   31.26 +	std::string mHoverIconUnselected;
   31.27 +	std::string mHoverIconSelected;
   31.28  
   31.29  	std::string mExecuteFunction;
   31.30  	LLSD        mExecuteParameters;
    32.1 --- a/indra/llui/llfloater.cpp	Thu Oct 17 18:26:04 2013 -0400
    32.2 +++ b/indra/llui/llfloater.cpp	Tue Nov 12 14:06:38 2013 -0500
    32.3 @@ -29,7 +29,7 @@
    32.4  // mini-map floater, etc.
    32.5  
    32.6  #include "linden_common.h"
    32.7 -
    32.8 +#include "llviewereventrecorder.h"
    32.9  #include "llfloater.h"
   32.10  
   32.11  #include "llfocusmgr.h"
   32.12 @@ -509,8 +509,8 @@
   32.13  	
   32.14  	if( gFocusMgr.childHasKeyboardFocus(this))
   32.15  	{
   32.16 -		// Just in case we might still have focus here, release it.
   32.17 -		releaseFocus();
   32.18 +	// Just in case we might still have focus here, release it.
   32.19 +	releaseFocus();
   32.20  	}
   32.21  
   32.22  	// This is important so that floaters with persistent rects (i.e., those
   32.23 @@ -642,7 +642,10 @@
   32.24  
   32.25  void LLFloater::openFloater(const LLSD& key)
   32.26  {
   32.27 -	llinfos << "Opening floater " << getName() << llendl;
   32.28 +    llinfos << "Opening floater " << getName() << " full path: " << getPathname() << llendl;
   32.29 +
   32.30 +	LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), true,"floater"); // Last param is event subtype or empty string
   32.31 +
   32.32  	mKey = key; // in case we need to open ourselves again
   32.33  
   32.34  	if (getSoundFlags() != SILENT 
   32.35 @@ -696,6 +699,7 @@
   32.36  void LLFloater::closeFloater(bool app_quitting)
   32.37  {
   32.38  	llinfos << "Closing floater " << getName() << llendl;
   32.39 +	LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), false,"floater"); // Last param is event subtype or empty string
   32.40  	if (app_quitting)
   32.41  	{
   32.42  		LLFloater::sQuitting = true;
   32.43 @@ -1335,7 +1339,7 @@
   32.44  	{
   32.45  		return;
   32.46  	}
   32.47 -	LLUICtrl* last_focus = gFocusMgr.getLastFocusForGroup(this);
   32.48 +	LLView* last_focus = gFocusMgr.getLastFocusForGroup(this);
   32.49  	// a descendent already has focus
   32.50  	BOOL child_had_focus = hasFocus();
   32.51  
   32.52 @@ -1543,6 +1547,17 @@
   32.53  }
   32.54  
   32.55  // virtual
   32.56 +BOOL LLFloater::handleMouseUp(S32 x, S32 y, MASK mask)
   32.57 +{
   32.58 +	lldebugs << "LLFloater::handleMouseUp calling LLPanel (really LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << llendl;
   32.59 +	BOOL handled = LLPanel::handleMouseUp(x,y,mask); // Not implemented in LLPanel so this actually calls LLView
   32.60 +	if (handled) {
   32.61 +		LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
   32.62 +	}
   32.63 +	return handled;
   32.64 +}
   32.65 +
   32.66 +// virtual
   32.67  BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask)
   32.68  {
   32.69  	if( mMinimized )
   32.70 @@ -1562,7 +1577,11 @@
   32.71  	else
   32.72  	{
   32.73  		bringToFront( x, y );
   32.74 -		return LLPanel::handleMouseDown( x, y, mask );
   32.75 +		BOOL handled = LLPanel::handleMouseDown( x, y, mask ); 
   32.76 +		if (handled) {
   32.77 +			LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); 
   32.78 +		}
   32.79 +		return handled;
   32.80  	}
   32.81  }
   32.82  
   32.83 @@ -1802,7 +1821,7 @@
   32.84  	self->onClickCloseBtn();
   32.85  }
   32.86  
   32.87 -void	LLFloater::onClickCloseBtn()
   32.88 +void LLFloater::onClickCloseBtn(bool app_quitting)
   32.89  {
   32.90  	closeFloater(false);
   32.91  }
    33.1 --- a/indra/llui/llfloater.h	Thu Oct 17 18:26:04 2013 -0400
    33.2 +++ b/indra/llui/llfloater.h	Tue Nov 12 14:06:38 2013 -0500
    33.3 @@ -289,6 +289,7 @@
    33.4  	S32				getHeaderHeight() const { return mHeaderHeight; }
    33.5  
    33.6  	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
    33.7 +	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask);
    33.8  	virtual BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask);
    33.9  	virtual BOOL	handleDoubleClick(S32 x, S32 y, MASK mask);
   33.10  	virtual BOOL	handleMiddleMouseDown(S32 x, S32 y, MASK mask);
   33.11 @@ -389,7 +390,7 @@
   33.12  
   33.13  	void			destroy(); // Don't call this directly.  You probably want to call closeFloater()
   33.14  
   33.15 -	virtual	void	onClickCloseBtn();
   33.16 +	virtual	void	onClickCloseBtn(bool app_quitting = false);
   33.17  
   33.18  	virtual void	updateTitleButtons();
   33.19  
    34.1 --- a/indra/llui/llfocusmgr.cpp	Thu Oct 17 18:26:04 2013 -0400
    34.2 +++ b/indra/llui/llfocusmgr.cpp	Tue Nov 12 14:06:38 2013 -0500
    34.3 @@ -469,7 +469,7 @@
    34.4  	mAppHasFocus = focus; 
    34.5  }
    34.6  
    34.7 -LLUICtrl* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) const
    34.8 +LLView* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) const
    34.9  {
   34.10  	if (subtree_root)
   34.11  	{
   34.12 @@ -477,7 +477,7 @@
   34.13  		if (found_it != mImpl->mFocusHistory.end())
   34.14  		{
   34.15  			// found last focus for this subtree
   34.16 -			return static_cast<LLUICtrl*>(found_it->second.get());
   34.17 +			return found_it->second.get();
   34.18  		}
   34.19  	}
   34.20  	return NULL;
    35.1 --- a/indra/llui/llfocusmgr.h	Thu Oct 17 18:26:04 2013 -0400
    35.2 +++ b/indra/llui/llfocusmgr.h	Tue Nov 12 14:06:38 2013 -0500
    35.3 @@ -97,7 +97,7 @@
    35.4  	void			triggerFocusFlash();
    35.5  	BOOL			getAppHasFocus() const { return mAppHasFocus; }
    35.6  	void			setAppHasFocus(BOOL focus);
    35.7 -	LLUICtrl*		getLastFocusForGroup(LLView* subtree_root) const;
    35.8 +	LLView*		getLastFocusForGroup(LLView* subtree_root) const;
    35.9  	void			clearLastFocusForGroup(LLView* subtree_root);
   35.10  
   35.11  	// If setKeyboardFocus(NULL) is called, and there is a non-NULL default
    36.1 --- a/indra/llui/llfolderview.cpp	Thu Oct 17 18:26:04 2013 -0400
    36.2 +++ b/indra/llui/llfolderview.cpp	Tue Nov 12 14:06:38 2013 -0500
    36.3 @@ -185,7 +185,7 @@
    36.4  	mAutoOpenCandidate = NULL;
    36.5  	mAutoOpenTimer.stop();
    36.6  	mKeyboardSelection = FALSE;
    36.7 -	mIndentation = p.folder_indentation;
    36.8 +	mIndentation = 	getParentFolder() ? getParentFolder()->getIndentation() + mLocalIndentation : 0;  
    36.9  
   36.10  	//clear label
   36.11  	// go ahead and render root folder as usual
   36.12 @@ -1613,7 +1613,7 @@
   36.13  	{
   36.14  		getFolderViewModel()->getFilter().clearModified();
   36.15  	}
   36.16 -    
   36.17 +
   36.18  	// automatically show matching items, and select first one if we had a selection
   36.19  	if (mNeedsAutoSelect)
   36.20  	{
   36.21 @@ -1653,13 +1653,13 @@
   36.22  
   36.23    BOOL is_visible = isInVisibleChain();
   36.24  
   36.25 -  // Puts folders/items in proper positions
   36.26 +  //Puts folders/items in proper positions
   36.27    // arrange() takes the model filter flag into account and call sort() if necessary (CHUI-849)
   36.28    // It also handles the open/close folder animation
   36.29 -  if (is_visible)
   36.30 +  if ( is_visible )
   36.31    {
   36.32      sanitizeSelection();
   36.33 -    if (needsArrange())
   36.34 +    if( needsArrange() )
   36.35      {
   36.36        S32 height = 0;
   36.37        S32 width = 0;
    37.1 --- a/indra/llui/llfolderviewitem.cpp	Thu Oct 17 18:26:04 2013 -0400
    37.2 +++ b/indra/llui/llfolderviewitem.cpp	Tue Nov 12 14:06:38 2013 -0500
    37.3 @@ -307,7 +307,12 @@
    37.4  // addToFolder() returns TRUE if it succeeds. FALSE otherwise
    37.5  void LLFolderViewItem::addToFolder(LLFolderViewFolder* folder)
    37.6  {
    37.7 -	folder->addItem(this);
    37.8 +	folder->addItem(this); 
    37.9 +
   37.10 +	// Compute indentation since parent folder changed
   37.11 +	mIndentation = (getParentFolder())
   37.12 +		? getParentFolder()->getIndentation() + mLocalIndentation
   37.13 +		: 0; 
   37.14  }
   37.15  
   37.16  
   37.17 @@ -521,7 +526,7 @@
   37.18  
   37.19  BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
   37.20  {
   37.21 -	static LLCachedControl<S32> drag_and_drop_threshold(*LLUI::sSettingGroups["config"],"DragAndDropDistanceThreshold");
   37.22 +	static LLCachedControl<S32> drag_and_drop_threshold(*LLUI::sSettingGroups["config"],"DragAndDropDistanceThreshold", 3);
   37.23  
   37.24  	mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
   37.25  
   37.26 @@ -940,6 +945,11 @@
   37.27  void LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder)
   37.28  {
   37.29  	folder->addFolder(this);
   37.30 +
   37.31 +	// Compute indentation since parent folder changed
   37.32 +	mIndentation = (getParentFolder())
   37.33 +		? getParentFolder()->getIndentation() + mLocalIndentation
   37.34 +		: 0; 
   37.35  }
   37.36  
   37.37  static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
   37.38 @@ -1109,7 +1119,7 @@
   37.39  
   37.40  BOOL LLFolderViewFolder::needsArrange()
   37.41  {
   37.42 -	return mLastArrangeGeneration < getRoot()->getArrangeGeneration(); 
   37.43 +	return mLastArrangeGeneration < getRoot()->getArrangeGeneration();
   37.44  }
   37.45  
   37.46  // Passes selection information on to children and record selection
    38.1 --- a/indra/llui/llmodaldialog.cpp	Thu Oct 17 18:26:04 2013 -0400
    38.2 +++ b/indra/llui/llmodaldialog.cpp	Tue Nov 12 14:06:38 2013 -0500
    38.3 @@ -34,7 +34,7 @@
    38.4  #include "llui.h"
    38.5  #include "llwindow.h"
    38.6  #include "llkeyboard.h"
    38.7 -
    38.8 +#include "llmenugl.h"
    38.9  // static
   38.10  std::list<LLModalDialog*> LLModalDialog::sModalStack;
   38.11  
   38.12 @@ -161,6 +161,18 @@
   38.13  
   38.14  BOOL LLModalDialog::handleMouseDown(S32 x, S32 y, MASK mask)
   38.15  {
   38.16 +	LLView* popup_menu = LLMenuGL::sMenuContainer->getVisibleMenu();
   38.17 +	if (popup_menu != NULL)
   38.18 +	{
   38.19 +		S32 mx, my;
   38.20 +		LLUI::getMousePositionScreen(&mx, &my);
   38.21 +		LLRect menu_screen_rc = popup_menu->calcScreenRect();
   38.22 +		if(!menu_screen_rc.pointInRect(mx, my))
   38.23 +		{
   38.24 +			LLMenuGL::sMenuContainer->hideMenus();
   38.25 +		}
   38.26 +	}
   38.27 +
   38.28  	if (mModal)
   38.29  	{
   38.30  		if (!LLFloater::handleMouseDown(x, y, mask))
   38.31 @@ -173,16 +185,34 @@
   38.32  	{
   38.33  		LLFloater::handleMouseDown(x, y, mask);
   38.34  	}
   38.35 +
   38.36 +
   38.37  	return TRUE;
   38.38  }
   38.39  
   38.40  BOOL LLModalDialog::handleHover(S32 x, S32 y, MASK mask)		
   38.41 -{ 
   38.42 +{
   38.43  	if( childrenHandleHover(x, y, mask) == NULL )
   38.44  	{
   38.45  		getWindow()->setCursor(UI_CURSOR_ARROW);
   38.46 -		lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;		
   38.47 +		lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
   38.48  	}
   38.49 +
   38.50 +	LLView* popup_menu = LLMenuGL::sMenuContainer->getVisibleMenu();
   38.51 +	if (popup_menu != NULL)
   38.52 +	{
   38.53 +		S32 mx, my;
   38.54 +		LLUI::getMousePositionScreen(&mx, &my);
   38.55 +		LLRect menu_screen_rc = popup_menu->calcScreenRect();
   38.56 +		if(menu_screen_rc.pointInRect(mx, my))
   38.57 +		{
   38.58 +			S32 local_x = mx - popup_menu->getRect().mLeft;
   38.59 +			S32 local_y = my - popup_menu->getRect().mBottom;
   38.60 +			popup_menu->handleHover(local_x, local_y, mask);
   38.61 +			gFocusMgr.setMouseCapture(NULL);
   38.62 +		}
   38.63 +	}
   38.64 +
   38.65  	return TRUE;
   38.66  }
   38.67  
   38.68 @@ -210,6 +240,7 @@
   38.69  
   38.70  BOOL LLModalDialog::handleRightMouseDown(S32 x, S32 y, MASK mask)
   38.71  {
   38.72 +	LLMenuGL::sMenuContainer->hideMenus();
   38.73  	childrenHandleRightMouseDown(x, y, mask);
   38.74  	return TRUE;
   38.75  }
    39.1 --- a/indra/llui/llnotifications.cpp	Thu Oct 17 18:26:04 2013 -0400
    39.2 +++ b/indra/llui/llnotifications.cpp	Tue Nov 12 14:06:38 2013 -0500
    39.3 @@ -1206,6 +1206,7 @@
    39.4  :	LLNotificationChannelBase(LLNotificationFilters::includeEverything),
    39.5  	mIgnoreAllNotifications(false)
    39.6  {
    39.7 +        mListener.reset(new LLNotificationsListener(*this));
    39.8  	LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
    39.9  }
   39.10  
    40.1 --- a/indra/llui/llnotifications.h	Thu Oct 17 18:26:04 2013 -0400
    40.2 +++ b/indra/llui/llnotifications.h	Tue Nov 12 14:06:38 2013 -0500
    40.3 @@ -98,6 +98,8 @@
    40.4  #include "llrefcount.h"
    40.5  #include "llsdparam.h"
    40.6  
    40.7 +#include "llnotificationslistener.h"
    40.8 +
    40.9  class LLAvatarName;
   40.10  typedef enum e_notification_priority
   40.11  {
   40.12 @@ -978,6 +980,8 @@
   40.13  
   40.14  	bool mIgnoreAllNotifications;
   40.15  
   40.16 +	boost::scoped_ptr<LLNotificationsListener> mListener;
   40.17 +
   40.18  	std::vector<LLNotificationChannelPtr> mDefaultChannels;
   40.19  };
   40.20  
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/indra/llui/llnotificationslistener.cpp	Tue Nov 12 14:06:38 2013 -0500
    41.3 @@ -0,0 +1,359 @@
    41.4 +/**
    41.5 + * @file   llnotificationslistener.cpp
    41.6 + * @author Brad Kittenbrink
    41.7 + * @date   2009-07-08
    41.8 + * @brief  Implementation for llnotificationslistener.
    41.9 + * 
   41.10 + * $LicenseInfo:firstyear=2009&license=viewerlgpl$
   41.11 + * Second Life Viewer Source Code
   41.12 + * Copyright (C) 2010, Linden Research, Inc.
   41.13 + * 
   41.14 + * This library is free software; you can redistribute it and/or
   41.15 + * modify it under the terms of the GNU Lesser General Public
   41.16 + * License as published by the Free Software Foundation;
   41.17 + * version 2.1 of the License only.
   41.18 + * 
   41.19 + * This library is distributed in the hope that it will be useful,
   41.20 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   41.21 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   41.22 + * Lesser General Public License for more details.
   41.23 + * 
   41.24 + * You should have received a copy of the GNU Lesser General Public
   41.25 + * License along with this library; if not, write to the Free Software
   41.26 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   41.27 + * 
   41.28 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   41.29 + * $/LicenseInfo$
   41.30 + */
   41.31 +
   41.32 +#include "linden_common.h"
   41.33 +#include "llnotificationslistener.h"
   41.34 +#include "llnotifications.h"
   41.35 +#include "llnotificationtemplate.h"
   41.36 +#include "llsd.h"
   41.37 +#include "llui.h"
   41.38 +
   41.39 +LLNotificationsListener::LLNotificationsListener(LLNotifications & notifications) :
   41.40 +    LLEventAPI("LLNotifications",
   41.41 +               "LLNotifications listener to (e.g.) pop up a notification"),
   41.42 +    mNotifications(notifications)
   41.43 +{
   41.44 +    add("requestAdd",
   41.45 +        "Add a notification with specified [\"name\"], [\"substitutions\"] and [\"payload\"].\n"
   41.46 +        "If optional [\"reply\"] specified, arrange to send user response on that LLEventPump.",
   41.47 +        &LLNotificationsListener::requestAdd);
   41.48 +    /*    add("listChannels",
   41.49 +        "Post to [\"reply\"] a map of info on existing channels",
   41.50 +        &LLNotificationsListener::listChannels,
   41.51 +        LLSD().with("reply", LLSD()));
   41.52 +    */
   41.53 +    add("listChannelNotifications",
   41.54 +        "Post to [\"reply\"] an array of info on notifications in channel [\"channel\"]",
   41.55 +        &LLNotificationsListener::listChannelNotifications,
   41.56 +        LLSD().with("reply", LLSD()).with("channel", LLSD()));
   41.57 +    add("respond",
   41.58 +        "Respond to notification [\"uuid\"] with data in [\"response\"]",
   41.59 +        &LLNotificationsListener::respond,
   41.60 +        LLSD().with("uuid", LLSD()));
   41.61 +    add("cancel",
   41.62 +        "Cancel notification [\"uuid\"]",
   41.63 +        &LLNotificationsListener::cancel,
   41.64 +        LLSD().with("uuid", LLSD()));
   41.65 +    add("ignore",
   41.66 +        "Ignore future notification [\"name\"]\n"
   41.67 +        "(from <notification name= > in notifications.xml)\n"
   41.68 +        "according to boolean [\"ignore\"].\n"
   41.69 +        "If [\"name\"] is omitted or undefined, [un]ignore all future notifications.\n"
   41.70 +        "Note that ignored notifications are not forwarded unless intercepted before\n"
   41.71 +        "the \"Ignore\" channel.",
   41.72 +        &LLNotificationsListener::ignore);
   41.73 +    add("forward",
   41.74 +        "Forward to [\"pump\"] future notifications on channel [\"channel\"]\n"
   41.75 +        "according to boolean [\"forward\"]. When enabled, only types matching\n"
   41.76 +        "[\"types\"] are forwarded, as follows:\n"
   41.77 +        "omitted or undefined: forward all notifications\n"
   41.78 +        "string: forward only the specific named [sig]type\n"
   41.79 +        "array of string: forward any notification matching any named [sig]type.\n"
   41.80 +        "When boolean [\"respond\"] is true, we auto-respond to each forwarded\n"
   41.81 +        "notification.",
   41.82 +        &LLNotificationsListener::forward,
   41.83 +        LLSD().with("channel", LLSD()));
   41.84 +}
   41.85 +
   41.86 +// This is here in the .cpp file so we don't need the definition of class
   41.87 +// Forwarder in the header file.
   41.88 +LLNotificationsListener::~LLNotificationsListener()
   41.89 +{
   41.90 +}
   41.91 +
   41.92 +void LLNotificationsListener::requestAdd(const LLSD& event_data) const
   41.93 +{
   41.94 +	if(event_data.has("reply"))
   41.95 +	{
   41.96 +		mNotifications.add(event_data["name"], 
   41.97 +						   event_data["substitutions"], 
   41.98 +						   event_data["payload"],
   41.99 +						   boost::bind(&LLNotificationsListener::NotificationResponder, 
  41.100 +									   this, 
  41.101 +									   event_data["reply"].asString(), 
  41.102 +									   _1, _2
  41.103 +									   )
  41.104 +						   );
  41.105 +	}
  41.106 +	else
  41.107 +	{
  41.108 +		mNotifications.add(event_data["name"], 
  41.109 +						   event_data["substitutions"], 
  41.110 +						   event_data["payload"]);
  41.111 +	}
  41.112 +}
  41.113 +
  41.114 +void LLNotificationsListener::NotificationResponder(const std::string& reply_pump, 
  41.115 +										const LLSD& notification, 
  41.116 +										const LLSD& response) const
  41.117 +{
  41.118 +	LLSD reponse_event;
  41.119 +	reponse_event["notification"] = notification;
  41.120 +	reponse_event["response"] = response;
  41.121 +	LLEventPumps::getInstance()->obtain(reply_pump).post(reponse_event);
  41.122 +}
  41.123 +/*
  41.124 +void LLNotificationsListener::listChannels(const LLSD& params) const
  41.125 +{
  41.126 +    LLReqID reqID(params);
  41.127 +    LLSD response(reqID.makeResponse());
  41.128 +    for (LLNotifications::
  41.129 +
  41.130 +
  41.131 +
  41.132 +    for (LLNotifications::ChannelMap::const_iterator cmi(mNotifications.mChannels.begin()),
  41.133 +                                                     cmend(mNotifications.mChannels.end());
  41.134 +         cmi != cmend; ++cmi)
  41.135 +    {
  41.136 +        LLSD channelInfo;
  41.137 +        channelInfo["parent"] = cmi->second->getParentChannelName();
  41.138 +        response[cmi->first] = channelInfo;
  41.139 +    }
  41.140 +    LLEventPumps::instance().obtain(params["reply"]).post(response);
  41.141 +}
  41.142 +*/
  41.143 +void LLNotificationsListener::listChannelNotifications(const LLSD& params) const
  41.144 +{
  41.145 +    LLReqID reqID(params);
  41.146 +    LLSD response(reqID.makeResponse());
  41.147 +    LLNotificationChannelPtr channel(mNotifications.getChannel(params["channel"]));
  41.148 +    if (channel)
  41.149 +    {
  41.150 +        LLSD notifications(LLSD::emptyArray());
  41.151 +        for (LLNotificationChannel::Iterator ni(channel->begin()), nend(channel->end());
  41.152 +             ni != nend; ++ni)
  41.153 +        {
  41.154 +            notifications.append(asLLSD(*ni));
  41.155 +        }
  41.156 +        response["notifications"] = notifications;
  41.157 +    }
  41.158 +    LLEventPumps::instance().obtain(params["reply"]).post(response);
  41.159 +}
  41.160 +
  41.161 +void LLNotificationsListener::respond(const LLSD& params) const
  41.162 +{
  41.163 +    LLNotificationPtr notification(mNotifications.find(params["uuid"]));
  41.164 +    if (notification)
  41.165 +    {
  41.166 +        notification->respond(params["response"]);
  41.167 +    }
  41.168 +}
  41.169 +
  41.170 +void LLNotificationsListener::cancel(const LLSD& params) const
  41.171 +{
  41.172 +    LLNotificationPtr notification(mNotifications.find(params["uuid"]));
  41.173 +    if (notification)
  41.174 +    {
  41.175 +        mNotifications.cancel(notification);
  41.176 +    }
  41.177 +}
  41.178 +
  41.179 +void LLNotificationsListener::ignore(const LLSD& params) const
  41.180 +{
  41.181 +    // Calling a method named "ignore", but omitting its "ignore" Boolean
  41.182 +    // argument, should by default cause something to be ignored. Explicitly
  41.183 +    // pass ["ignore"] = false to cancel ignore.
  41.184 +    bool ignore = true;
  41.185 +    if (params.has("ignore"))
  41.186 +    {
  41.187 +        ignore = params["ignore"].asBoolean();
  41.188 +    }
  41.189 +    // This method can be used to affect either a single notification name or
  41.190 +    // all future notifications. The two use substantially different mechanisms.
  41.191 +    if (params["name"].isDefined())
  41.192 +    {
  41.193 +        // ["name"] was passed: ignore just that notification
  41.194 +		LLNotificationTemplatePtr templatep = mNotifications.getTemplate(params["name"]);
  41.195 +		if (templatep)
  41.196 +		{
  41.197 +			templatep->mForm->setIgnored(ignore);
  41.198 +		}
  41.199 +    }
  41.200 +    else
  41.201 +    {
  41.202 +        // no ["name"]: ignore all future notifications
  41.203 +        mNotifications.setIgnoreAllNotifications(ignore);
  41.204 +    }
  41.205 +}
  41.206 +
  41.207 +class LLNotificationsListener::Forwarder: public LLEventTrackable
  41.208 +{
  41.209 +    LOG_CLASS(LLNotificationsListener::Forwarder);
  41.210 +public:
  41.211 +    Forwarder(LLNotifications& llnotifications, const std::string& channel):
  41.212 +        mNotifications(llnotifications),
  41.213 +        mRespond(false)
  41.214 +    {
  41.215 +        // Connect to the specified channel on construction. Because
  41.216 +        // LLEventTrackable is a base, we should automatically disconnect when
  41.217 +        // destroyed.
  41.218 +        LLNotificationChannelPtr channelptr(llnotifications.getChannel(channel));
  41.219 +        if (channelptr)
  41.220 +        {
  41.221 +            // Insert our processing as a "passed filter" listener. This way
  41.222 +            // we get to run before all the "changed" listeners, and we get to
  41.223 +            // swipe it (hide it from the other listeners) if desired.
  41.224 +            channelptr->connectPassedFilter(boost::bind(&Forwarder::handle, this, _1));
  41.225 +        }
  41.226 +    }
  41.227 +
  41.228 +    void setPumpName(const std::string& name) { mPumpName = name; }
  41.229 +    void setTypes(const LLSD& types) { mTypes = types; }
  41.230 +    void setRespond(bool respond) { mRespond = respond; }
  41.231 +
  41.232 +private:
  41.233 +    bool handle(const LLSD& notification) const;
  41.234 +    bool matchType(const LLSD& filter, const std::string& type) const;
  41.235 +
  41.236 +    LLNotifications& mNotifications;
  41.237 +    std::string mPumpName;
  41.238 +    LLSD mTypes;
  41.239 +    bool mRespond;
  41.240 +};
  41.241 +
  41.242 +void LLNotificationsListener::forward(const LLSD& params)
  41.243 +{
  41.244 +    std::string channel(params["channel"]);
  41.245 +    // First decide whether we're supposed to start forwarding or stop it.
  41.246 +    // Default to true.
  41.247 +    bool forward = true;
  41.248 +    if (params.has("forward"))
  41.249 +    {
  41.250 +        forward = params["forward"].asBoolean();
  41.251 +    }
  41.252 +    if (! forward)
  41.253 +    {
  41.254 +        // This is a request to stop forwarding notifications on the specified
  41.255 +        // channel. The rest of the params don't matter.
  41.256 +        // Because mForwarders contains scoped_ptrs, erasing the map entry
  41.257 +        // DOES delete the heap Forwarder object. Because Forwarder derives
  41.258 +        // from LLEventTrackable, destroying it disconnects it from the
  41.259 +        // channel.
  41.260 +        mForwarders.erase(channel);
  41.261 +        return;
  41.262 +    }
  41.263 +    // From here on, we know we're being asked to start (or modify) forwarding
  41.264 +    // on the specified channel. Find or create an appropriate Forwarder.
  41.265 +    ForwarderMap::iterator
  41.266 +        entry(mForwarders.insert(ForwarderMap::value_type(channel, ForwarderMap::mapped_type())).first);
  41.267 +    if (! entry->second)
  41.268 +    {
  41.269 +        entry->second.reset(new Forwarder(mNotifications, channel));
  41.270 +    }
  41.271 +    // Now, whether this Forwarder is brand-new or not, update it with the new
  41.272 +    // request info.
  41.273 +    Forwarder& fwd(*entry->second);
  41.274 +    fwd.setPumpName(params["pump"]);
  41.275 +    fwd.setTypes(params["types"]);
  41.276 +    fwd.setRespond(params["respond"]);
  41.277 +}
  41.278 +
  41.279 +bool LLNotificationsListener::Forwarder::handle(const LLSD& notification) const
  41.280 +{
  41.281 +    LL_INFOS("LLNotificationsListener") << "handle(" << notification << ")" << LL_ENDL;
  41.282 +    if (notification["sigtype"].asString() == "delete")
  41.283 +    {
  41.284 +        LL_INFOS("LLNotificationsListener") << "ignoring delete" << LL_ENDL;
  41.285 +        // let other listeners see the "delete" operation
  41.286 +        return false;
  41.287 +    }
  41.288 +    LLNotificationPtr note(mNotifications.find(notification["id"]));
  41.289 +    if (! note)
  41.290 +    {
  41.291 +        LL_INFOS("LLNotificationsListener") << notification["id"] << " not found" << LL_ENDL;
  41.292 +        return false;
  41.293 +    }
  41.294 +    if (! matchType(mTypes, note->getType()))
  41.295 +    {
  41.296 +        LL_INFOS("LLNotificationsListener") << "didn't match types " << mTypes << LL_ENDL;
  41.297 +        // We're not supposed to intercept this particular notification. Let
  41.298 +        // other listeners process it.
  41.299 +        return false;
  41.300 +    }
  41.301 +    LL_INFOS("LLNotificationsListener") << "sending via '" << mPumpName << "'" << LL_ENDL;
  41.302 +    // This is a notification we care about. Forward it through specified
  41.303 +    // LLEventPump.
  41.304 +    LLEventPumps::instance().obtain(mPumpName).post(asLLSD(note));
  41.305 +    // Are we also being asked to auto-respond?
  41.306 +    if (mRespond)
  41.307 +    {
  41.308 +        LL_INFOS("LLNotificationsListener") << "should respond" << LL_ENDL;
  41.309 +        note->respond(LLSD::emptyMap());
  41.310 +        // Did that succeed in removing the notification? Only cancel() if
  41.311 +        // it's still around -- otherwise we get an LL_ERRS crash!
  41.312 +        note = mNotifications.find(notification["id"]);
  41.313 +        if (note)
  41.314 +        {
  41.315 +            LL_INFOS("LLNotificationsListener") << "respond() didn't clear, canceling" << LL_ENDL;
  41.316 +            mNotifications.cancel(note);
  41.317 +        }
  41.318 +    }
  41.319 +    // If we've auto-responded to this notification, then it's going to be
  41.320 +    // deleted. Other listeners would get the change operation, try to look it
  41.321 +    // up and be baffled by lookup failure. So when we auto-respond, suppress
  41.322 +    // this notification: don't pass it to other listeners.
  41.323 +    return mRespond;
  41.324 +}
  41.325 +
  41.326 +bool LLNotificationsListener::Forwarder::matchType(const LLSD& filter, const std::string& type) const
  41.327 +{
  41.328 +    // Decide whether this notification matches filter:
  41.329 +    // undefined: forward all notifications
  41.330 +    if (filter.isUndefined())
  41.331 +    {
  41.332 +        return true;
  41.333 +    }
  41.334 +    // array of string: forward any notification matching any named type
  41.335 +    if (filter.isArray())
  41.336 +    {
  41.337 +        for (LLSD::array_const_iterator ti(filter.beginArray()), tend(filter.endArray());
  41.338 +             ti != tend; ++ti)
  41.339 +        {
  41.340 +            if (ti->asString() == type)
  41.341 +            {
  41.342 +                return true;
  41.343 +            }
  41.344 +        }
  41.345 +        // Didn't match any entry in the array
  41.346 +        return false;
  41.347 +    }
  41.348 +    // string: forward only the specific named type
  41.349 +    return (filter.asString() == type);
  41.350 +}
  41.351 +
  41.352 +LLSD LLNotificationsListener::asLLSD(LLNotificationPtr note)
  41.353 +{
  41.354 +    LLSD notificationInfo(note->asLLSD());
  41.355 +    // For some reason the following aren't included in LLNotification::asLLSD().
  41.356 +    notificationInfo["summary"] = note->summarize();
  41.357 +    notificationInfo["id"]      = note->id();
  41.358 +    notificationInfo["type"]    = note->getType();
  41.359 +    notificationInfo["message"] = note->getMessage();
  41.360 +    notificationInfo["label"]   = note->getLabel();
  41.361 +    return notificationInfo;
  41.362 +}
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/indra/llui/llnotificationslistener.h	Tue Nov 12 14:06:38 2013 -0500
    42.3 @@ -0,0 +1,69 @@
    42.4 +/**
    42.5 + * @file   llnotificationslistener.h
    42.6 + * @author Brad Kittenbrink
    42.7 + * @date   2009-07-08
    42.8 + * @brief  Wrap subset of LLNotifications API in event API for test scripts.
    42.9 + * 
   42.10 + * $LicenseInfo:firstyear=2009&license=viewerlgpl$
   42.11 + * Second Life Viewer Source Code
   42.12 + * Copyright (C) 2010, Linden Research, Inc.
   42.13 + * 
   42.14 + * This library is free software; you can redistribute it and/or
   42.15 + * modify it under the terms of the GNU Lesser General Public
   42.16 + * License as published by the Free Software Foundation;
   42.17 + * version 2.1 of the License only.
   42.18 + * 
   42.19 + * This library is distributed in the hope that it will be useful,
   42.20 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   42.21 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   42.22 + * Lesser General Public License for more details.
   42.23 + * 
   42.24 + * You should have received a copy of the GNU Lesser General Public
   42.25 + * License along with this library; if not, write to the Free Software
   42.26 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   42.27 + * 
   42.28 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   42.29 + * $/LicenseInfo$
   42.30 + */
   42.31 +
   42.32 +#ifndef LL_LLNOTIFICATIONSLISTENER_H
   42.33 +#define LL_LLNOTIFICATIONSLISTENER_H
   42.34 +
   42.35 +#include "lleventapi.h"
   42.36 +#include "llnotificationptr.h"
   42.37 +#include <boost/shared_ptr.hpp>
   42.38 +#include <map>
   42.39 +#include <string>
   42.40 +
   42.41 +class LLNotifications;
   42.42 +class LLSD;
   42.43 +
   42.44 +class LLNotificationsListener : public LLEventAPI
   42.45 +{
   42.46 +public:
   42.47 +    LLNotificationsListener(LLNotifications & notifications);
   42.48 +    ~LLNotificationsListener();
   42.49 +
   42.50 +private:
   42.51 +    void requestAdd(LLSD const & event_data) const;
   42.52 +
   42.53 +	void NotificationResponder(const std::string& replypump, 
   42.54 +							   const LLSD& notification, 
   42.55 +							   const LLSD& response) const;
   42.56 +
   42.57 +    void listChannels(const LLSD& params) const;
   42.58 +    void listChannelNotifications(const LLSD& params) const;
   42.59 +    void respond(const LLSD& params) const;
   42.60 +    void cancel(const LLSD& params) const;
   42.61 +    void ignore(const LLSD& params) const;
   42.62 +    void forward(const LLSD& params);
   42.63 +
   42.64 +    static LLSD asLLSD(LLNotificationPtr);
   42.65 +
   42.66 +    class Forwarder;
   42.67 +    typedef std::map<std::string, boost::shared_ptr<Forwarder> > ForwarderMap;
   42.68 +    ForwarderMap mForwarders;
   42.69 +	LLNotifications & mNotifications;
   42.70 +};
   42.71 +
   42.72 +#endif // LL_LLNOTIFICATIONSLISTENER_H
    43.1 --- a/indra/llui/llscrollcontainer.cpp	Thu Oct 17 18:26:04 2013 -0400
    43.2 +++ b/indra/llui/llscrollcontainer.cpp	Tue Nov 12 14:06:38 2013 -0500
    43.3 @@ -519,7 +519,7 @@
    43.4  
    43.5  void LLScrollContainer::updateScroll()
    43.6  {
    43.7 -	if (!mScrolledView)
    43.8 +	if (!getVisible() || !mScrolledView)
    43.9  	{
   43.10  		return;
   43.11  	}
    44.1 --- a/indra/llui/lltabcontainer.cpp	Thu Oct 17 18:26:04 2013 -0400
    44.2 +++ b/indra/llui/lltabcontainer.cpp	Tue Nov 12 14:06:38 2013 -0500
    44.3 @@ -27,7 +27,7 @@
    44.4  #include "linden_common.h"
    44.5  
    44.6  #include "lltabcontainer.h"
    44.7 -
    44.8 +#include "llviewereventrecorder.h"
    44.9  #include "llfocusmgr.h"
   44.10  #include "lllocalcliprect.h"
   44.11  #include "llrect.h"
   44.12 @@ -193,12 +193,15 @@
   44.13  :	tab_top_image_unselected("tab_top_image_unselected"),
   44.14  	tab_top_image_selected("tab_top_image_selected"),
   44.15  	tab_top_image_flash("tab_top_image_flash"),
   44.16 +	tab_top_image_hovered("tab_top_image_hovered"),
   44.17  	tab_bottom_image_unselected("tab_bottom_image_unselected"),
   44.18  	tab_bottom_image_selected("tab_bottom_image_selected"),
   44.19  	tab_bottom_image_flash("tab_bottom_image_flash"),
   44.20 +	tab_bottom_image_hovered("tab_bottom_image_hovered"),
   44.21  	tab_left_image_unselected("tab_left_image_unselected"),
   44.22  	tab_left_image_selected("tab_left_image_selected"),
   44.23 -	tab_left_image_flash("tab_left_image_flash")
   44.24 +	tab_left_image_flash("tab_left_image_flash"),
   44.25 +	tab_left_image_hovered("tab_left_image_hovered")
   44.26  {}
   44.27  
   44.28  LLTabContainer::Params::Params()
   44.29 @@ -218,7 +221,8 @@
   44.30  	open_tabs_on_drag_and_drop("open_tabs_on_drag_and_drop", false),
   44.31  	tab_icon_ctrl_pad("tab_icon_ctrl_pad", 0),
   44.32  	use_ellipses("use_ellipses"),
   44.33 -	font_halign("halign")
   44.34 +	font_halign("halign"),
   44.35 +	use_highlighting_on_hover("use_highlighting_on_hover",false)
   44.36  {}
   44.37  
   44.38  LLTabContainer::LLTabContainer(const LLTabContainer::Params& p)
   44.39 @@ -254,7 +258,8 @@
   44.40  	mCustomIconCtrlUsed(p.use_custom_icon_ctrl),
   44.41  	mOpenTabsOnDragAndDrop(p.open_tabs_on_drag_and_drop),
   44.42  	mTabIconCtrlPad(p.tab_icon_ctrl_pad),
   44.43 -	mUseTabEllipses(p.use_ellipses)
   44.44 +	mUseTabEllipses(p.use_ellipses),
   44.45 +	mUseHighlightingOnHover(p.use_highlighting_on_hover)
   44.46  {
   44.47  	static LLUICachedControl<S32> tabcntr_vert_tab_min_width ("UITabCntrVertTabMinWidth", 0);
   44.48  
   44.49 @@ -578,6 +583,11 @@
   44.50  			tab_button->setFocus(TRUE);
   44.51  		}
   44.52  	}
   44.53 +	if (handled) {
   44.54 +		// Note: May need to also capture local coords right here ?
   44.55 +		LLViewerEventRecorder::instance().update_xui(getPathname( ));
   44.56 +	}
   44.57 +
   44.58  	return handled;
   44.59  }
   44.60  
   44.61 @@ -629,30 +639,33 @@
   44.62  	BOOL handled = FALSE;
   44.63  	BOOL has_scroll_arrows = (getMaxScrollPos() > 0)  && !getTabsHidden();
   44.64  
   44.65 +	S32 local_x = x - getRect().mLeft;
   44.66 +	S32 local_y = y - getRect().mBottom;
   44.67 +
   44.68  	if (has_scroll_arrows)
   44.69  	{
   44.70  		if (mJumpPrevArrowBtn && mJumpPrevArrowBtn->getRect().pointInRect(x, y))
   44.71  		{
   44.72 -			S32 local_x = x - mJumpPrevArrowBtn->getRect().mLeft;
   44.73 -			S32 local_y = y - mJumpPrevArrowBtn->getRect().mBottom;
   44.74 +			local_x = x - mJumpPrevArrowBtn->getRect().mLeft;
   44.75 +			local_y = y - mJumpPrevArrowBtn->getRect().mBottom;
   44.76  			handled = mJumpPrevArrowBtn->handleMouseUp(local_x, local_y, mask);
   44.77  		}
   44.78  		else if (mJumpNextArrowBtn && mJumpNextArrowBtn->getRect().pointInRect(x,	y))
   44.79  		{
   44.80 -			S32	local_x	= x	- mJumpNextArrowBtn->getRect().mLeft;
   44.81 -			S32	local_y	= y	- mJumpNextArrowBtn->getRect().mBottom;
   44.82 +			local_x	= x	- mJumpNextArrowBtn->getRect().mLeft;
   44.83 +			local_y	= y	- mJumpNextArrowBtn->getRect().mBottom;
   44.84  			handled = mJumpNextArrowBtn->handleMouseUp(local_x,	local_y, mask);
   44.85  		}
   44.86  		else if (mPrevArrowBtn && mPrevArrowBtn->getRect().pointInRect(x, y))
   44.87  		{
   44.88 -			S32 local_x = x - mPrevArrowBtn->getRect().mLeft;
   44.89 -			S32 local_y = y - mPrevArrowBtn->getRect().mBottom;
   44.90 +			local_x = x - mPrevArrowBtn->getRect().mLeft;
   44.91 +			local_y = y - mPrevArrowBtn->getRect().mBottom;
   44.92  			handled = mPrevArrowBtn->handleMouseUp(local_x, local_y, mask);
   44.93  		}
   44.94  		else if (mNextArrowBtn && mNextArrowBtn->getRect().pointInRect(x, y))
   44.95  		{
   44.96 -			S32 local_x = x - mNextArrowBtn->getRect().mLeft;
   44.97 -			S32 local_y = y - mNextArrowBtn->getRect().mBottom;
   44.98 +			local_x = x - mNextArrowBtn->getRect().mLeft;
   44.99 +			local_y = y - mNextArrowBtn->getRect().mBottom;
  44.100  			handled = mNextArrowBtn->handleMouseUp(local_x, local_y, mask);
  44.101  		}
  44.102  	}
  44.103 @@ -676,6 +689,10 @@
  44.104  		}
  44.105  		gFocusMgr.setMouseCapture(NULL);
  44.106  	}
  44.107 +	if (handled) {
  44.108 +		// Note: may need to capture local coords here
  44.109 +		LLViewerEventRecorder::instance().update_xui(getPathname( ));
  44.110 +	}
  44.111  	return handled;
  44.112  }
  44.113  
  44.114 @@ -891,18 +908,30 @@
  44.115  			tuple->mButton->setImageUnselected(static_cast<LLUIImage*>(params.tab_top_image_unselected));
  44.116  			tuple->mButton->setImageSelected(static_cast<LLUIImage*>(params.tab_top_image_selected));
  44.117  			tuple->mButton->setImageFlash(static_cast<LLUIImage*>(params.tab_top_image_flash));
  44.118 +			if(mUseHighlightingOnHover)
  44.119 +			{
  44.120 +				tuple->mButton->setImageHoverUnselected(static_cast<LLUIImage*>(params.tab_top_image_hovered));
  44.121 +			}
  44.122  		}
  44.123  		else if (pos == LLTabContainer::BOTTOM)
  44.124  		{
  44.125  			tuple->mButton->setImageUnselected(static_cast<LLUIImage*>(params.tab_bottom_image_unselected));
  44.126  			tuple->mButton->setImageSelected(static_cast<LLUIImage*>(params.tab_bottom_image_selected));
  44.127  			tuple->mButton->setImageFlash(static_cast<LLUIImage*>(params.tab_bottom_image_flash));
  44.128 +			if(mUseHighlightingOnHover)
  44.129 +			{
  44.130 +				tuple->mButton->setImageHoverUnselected(static_cast<LLUIImage*>(params.tab_bottom_image_hovered));
  44.131 +			}
  44.132  		}
  44.133  		else if (pos == LLTabContainer::LEFT)
  44.134  		{
  44.135  			tuple->mButton->setImageUnselected(static_cast<LLUIImage*>(params.tab_left_image_unselected));
  44.136  			tuple->mButton->setImageSelected(static_cast<LLUIImage*>(params.tab_left_image_selected));
  44.137  			tuple->mButton->setImageFlash(static_cast<LLUIImage*>(params.tab_left_image_flash));
  44.138 +			if(mUseHighlightingOnHover)
  44.139 +			{
  44.140 +				tuple->mButton->setImageHoverUnselected(static_cast<LLUIImage*>(params.tab_left_image_hovered));
  44.141 +			}
  44.142  		}
  44.143  	}
  44.144  }
  44.145 @@ -1059,21 +1088,21 @@
  44.146  		
  44.147  		if (mIsVertical)
  44.148  		{
  44.149 -			p.name(std::string("vert tab button"));
  44.150 -			p.image_unselected(mMiddleTabParams.tab_left_image_unselected);
  44.151 -			p.image_selected(mMiddleTabParams.tab_left_image_selected);
  44.152 -			p.follows.flags = p.follows.flags() | FOLLOWS_TOP;
  44.153 +		  p.name("vtab_"+std::string(child->getName()));
  44.154 +		  p.image_unselected(mMiddleTabParams.tab_left_image_unselected);
  44.155 +		  p.image_selected(mMiddleTabParams.tab_left_image_selected);
  44.156 +		  p.follows.flags = p.follows.flags() | FOLLOWS_TOP;
  44.157  		}
  44.158  		else
  44.159 -		{
  44.160 -			p.name(std::string(child->getName()) + " tab");
  44.161 -			p.visible(false);
  44.162 -			p.image_unselected(tab_img);
  44.163 -			p.image_selected(tab_selected_img);
  44.164 -			p.follows.flags = p.follows.flags() | (getTabPosition() == TOP ? FOLLOWS_TOP : FOLLOWS_BOTTOM);
  44.165 -			// Try to squeeze in a bit more text
  44.166 -			p.pad_left( mLabelPadLeft );
  44.167 -			p.pad_right(2);
  44.168 +		  { 
  44.169 +		    p.name("htab_"+std::string(child->getName()));
  44.170 +		    p.visible(false);
  44.171 +		    p.image_unselected(tab_img);
  44.172 +		    p.image_selected(tab_selected_img);
  44.173 +		    p.follows.flags = p.follows.flags() | (getTabPosition() == TOP ? FOLLOWS_TOP : FOLLOWS_BOTTOM);
  44.174 +		    // Try to squeeze in a bit more text
  44.175 +		    p.pad_left( mLabelPadLeft );
  44.176 +		    p.pad_right(2);
  44.177  		}
  44.178  		
  44.179  		// *TODO : It seems wrong not to use p in both cases considering the way p is initialized
    45.1 --- a/indra/llui/lltabcontainer.h	Thu Oct 17 18:26:04 2013 -0400
    45.2 +++ b/indra/llui/lltabcontainer.h	Tue Nov 12 14:06:38 2013 -0500
    45.3 @@ -62,12 +62,15 @@
    45.4  		Optional<LLUIImage*>				tab_top_image_unselected,
    45.5  											tab_top_image_selected,
    45.6  											tab_top_image_flash,
    45.7 +											tab_top_image_hovered,
    45.8  											tab_bottom_image_unselected,
    45.9  											tab_bottom_image_selected,
   45.10  											tab_bottom_image_flash,
   45.11 +											tab_bottom_image_hovered,
   45.12  											tab_left_image_unselected,
   45.13  											tab_left_image_selected,
   45.14 -											tab_left_image_flash;		
   45.15 +											tab_left_image_flash,
   45.16 +											tab_left_image_hovered;
   45.17  		TabParams();
   45.18  	};
   45.19  
   45.20 @@ -114,6 +117,11 @@
   45.21  		 */
   45.22  		Optional<S32>						tab_icon_ctrl_pad;
   45.23  
   45.24 +		/**
   45.25 +		 *  This variable is used to found out should we highlight tab button on hover
   45.26 +		*/
   45.27 +		Optional<bool>						use_highlighting_on_hover;
   45.28 +
   45.29  		Params();
   45.30  	};
   45.31  
   45.32 @@ -307,6 +315,7 @@
   45.33  	bool							mOpenTabsOnDragAndDrop;
   45.34  	S32								mTabIconCtrlPad;
   45.35  	bool							mUseTabEllipses;
   45.36 +	bool                            mUseHighlightingOnHover;
   45.37  };
   45.38  
   45.39  #endif  // LL_TABCONTAINER_H
    46.1 --- a/indra/llui/lltextbase.cpp	Thu Oct 17 18:26:04 2013 -0400
    46.2 +++ b/indra/llui/lltextbase.cpp	Tue Nov 12 14:06:38 2013 -0500
    46.3 @@ -1029,7 +1029,7 @@
    46.4  BOOL LLTextBase::handleMouseUp(S32 x, S32 y, MASK mask)
    46.5  {
    46.6  	LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y);
    46.7 -	if (cur_segment && cur_segment->handleMouseUp(x, y, mask))
    46.8 +	if (hasMouseCapture() && cur_segment && cur_segment->handleMouseUp(x, y, mask))
    46.9  	{
   46.10  		// Did we just click on a link?
   46.11  		if (mURLClickSignal
    47.1 --- a/indra/llui/lltextbox.cpp	Thu Oct 17 18:26:04 2013 -0400
    47.2 +++ b/indra/llui/lltextbox.cpp	Tue Nov 12 14:06:38 2013 -0500
    47.3 @@ -60,10 +60,13 @@
    47.4  
    47.5  	if (!handled && mClickedCallback)
    47.6  	{
    47.7 +		handled = TRUE;
    47.8 +	}
    47.9 +
   47.10 +	if (handled)
   47.11 +	{
   47.12  		// Route future Mouse messages here preemptively.  (Release on mouse up.)
   47.13  		gFocusMgr.setMouseCapture( this );
   47.14 -
   47.15 -		handled = TRUE;
   47.16  	}
   47.17  
   47.18  	return handled;
   47.19 @@ -71,7 +74,7 @@
   47.20  
   47.21  BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask)
   47.22  {
   47.23 -	BOOL	handled = FALSE;
   47.24 +	BOOL	handled = LLTextBase::handleMouseUp(x, y, mask);
   47.25  
   47.26  	if (getSoundFlags() & MOUSE_UP)
   47.27  	{
   47.28 @@ -93,10 +96,6 @@
   47.29  			handled = TRUE;
   47.30  		}
   47.31  	}
   47.32 -	else
   47.33 -	{
   47.34 -		handled = LLTextBase::handleMouseUp(x, y, mask);
   47.35 -	}
   47.36  
   47.37  	return handled;
   47.38  }
    48.1 --- a/indra/llui/lltexteditor.cpp	Thu Oct 17 18:26:04 2013 -0400
    48.2 +++ b/indra/llui/lltexteditor.cpp	Tue Nov 12 14:06:38 2013 -0500
    48.3 @@ -666,6 +666,14 @@
    48.4  	updatePrimary();
    48.5  }
    48.6  
    48.7 +void LLTextEditor::selectByCursorPosition(S32 prev_cursor_pos, S32 next_cursor_pos)
    48.8 +{
    48.9 +	setCursorPos(prev_cursor_pos);
   48.10 +	startSelection();
   48.11 +	setCursorPos(next_cursor_pos);
   48.12 +	endSelection();
   48.13 +}
   48.14 +
   48.15  BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
   48.16  {
   48.17  	BOOL	handled = FALSE;
   48.18 @@ -713,7 +721,6 @@
   48.19  				setCursorAtLocalPos( x, y, true );
   48.20  				startSelection();
   48.21  			}
   48.22 -			gFocusMgr.setMouseCapture( this );
   48.23  		}
   48.24  
   48.25  		handled = TRUE;
   48.26 @@ -722,6 +729,10 @@
   48.27  	// Delay cursor flashing
   48.28  	resetCursorBlink();
   48.29  
   48.30 +	if (handled && !gFocusMgr.getMouseCapture())
   48.31 +	{
   48.32 +		gFocusMgr.setMouseCapture( this );
   48.33 +	}
   48.34  	return handled;
   48.35  }
   48.36  
    49.1 --- a/indra/llui/lltexteditor.h	Thu Oct 17 18:26:04 2013 -0400
    49.2 +++ b/indra/llui/lltexteditor.h	Tue Nov 12 14:06:38 2013 -0500
    49.3 @@ -144,6 +144,8 @@
    49.4  	virtual void	selectAll();
    49.5  	virtual BOOL	canSelectAll()	const;
    49.6  
    49.7 +	void 			selectByCursorPosition(S32 prev_cursor_pos, S32 next_cursor_pos);
    49.8 +
    49.9  	virtual bool	canLoadOrSaveToFile();
   49.10  
   49.11  	void			selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE);
    50.1 --- a/indra/llui/lltoolbar.cpp	Thu Oct 17 18:26:04 2013 -0400
    50.2 +++ b/indra/llui/lltoolbar.cpp	Tue Nov 12 14:06:38 2013 -0500
    50.3 @@ -928,6 +928,8 @@
    50.4  	button_p.label = LLTrans::getString(commandp->labelRef());
    50.5  	button_p.tool_tip = LLTrans::getString(commandp->tooltipRef());
    50.6  	button_p.image_overlay = LLUI::getUIImage(commandp->icon());
    50.7 +	button_p.image_hover_unselected = LLUI::getUIImage(commandp->hoverIconUnselected());
    50.8 +	button_p.image_hover_selected = LLUI::getUIImage(commandp->hoverIconSelected());
    50.9  	button_p.button_flash_enable = commandp->isFlashingAllowed();
   50.10  	button_p.overwriteFrom(mButtonParams[mButtonType]);
   50.11  	LLToolBarButton* button = LLUICtrlFactory::create<LLToolBarButton>(button_p);
    51.1 --- a/indra/llui/llui.h	Thu Oct 17 18:26:04 2013 -0400
    51.2 +++ b/indra/llui/llui.h	Tue Nov 12 14:06:38 2013 -0500
    51.3 @@ -405,11 +405,6 @@
    51.4  					  const std::string& comment = "Declared In Code")
    51.5  	:	LLCachedControl<T>(LLUI::getControlControlGroup(name), name, default_value, comment)
    51.6  	{}
    51.7 -
    51.8 -	// This constructor will signal an error if the control doesn't exist in the control group
    51.9 -	LLUICachedControl(const std::string& name)
   51.10 -	:	LLCachedControl<T>(LLUI::getControlControlGroup(name), name)
   51.11 -	{}
   51.12  };
   51.13  
   51.14  namespace LLInitParam
    52.1 --- a/indra/llui/lluictrl.cpp	Thu Oct 17 18:26:04 2013 -0400
    52.2 +++ b/indra/llui/lluictrl.cpp	Tue Nov 12 14:06:38 2013 -0500
    52.3 @@ -29,7 +29,7 @@
    52.4  
    52.5  #define LLUICTRL_CPP
    52.6  #include "lluictrl.h"
    52.7 -
    52.8 +#include "llviewereventrecorder.h"
    52.9  #include "llfocusmgr.h"
   52.10  #include "llpanel.h"
   52.11  #include "lluictrlfactory.h"
   52.12 @@ -308,22 +308,40 @@
   52.13  //virtual 
   52.14  BOOL LLUICtrl::handleMouseDown(S32 x, S32 y, MASK mask)
   52.15  {
   52.16 +
   52.17 +	lldebugs << "LLUICtrl::handleMouseDown calling	LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << llendl;
   52.18 +  
   52.19  	BOOL handled  = LLView::handleMouseDown(x,y,mask);
   52.20 +	
   52.21  	if (mMouseDownSignal)
   52.22  	{
   52.23  		(*mMouseDownSignal)(this,x,y,mask);
   52.24  	}
   52.25 +	lldebugs << "LLUICtrl::handleMousedown - handled is returning as: " << handled << "	  " << llendl;
   52.26 +	
   52.27 +	if (handled) {
   52.28 +		LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-56,-56,getPathname());
   52.29 +	}
   52.30  	return handled;
   52.31  }
   52.32  
   52.33  //virtual
   52.34  BOOL LLUICtrl::handleMouseUp(S32 x, S32 y, MASK mask)
   52.35  {
   52.36 +
   52.37 +	lldebugs << "LLUICtrl::handleMouseUp calling LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << llendl;
   52.38 +
   52.39  	BOOL handled  = LLView::handleMouseUp(x,y,mask);
   52.40 +	if (handled) {
   52.41 +		LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-56,-56,getPathname()); 
   52.42 +	}
   52.43  	if (mMouseUpSignal)
   52.44  	{
   52.45  		(*mMouseUpSignal)(this,x,y,mask);
   52.46  	}
   52.47 +
   52.48 +	lldebugs << "LLUICtrl::handleMouseUp - handled for xui " << getPathname() << "  -  is returning as: " << handled << "   " << llendl;
   52.49 +
   52.50  	return handled;
   52.51  }
   52.52  
    53.1 --- a/indra/llui/llview.cpp	Thu Oct 17 18:26:04 2013 -0400
    53.2 +++ b/indra/llui/llview.cpp	Tue Nov 12 14:06:38 2013 -0500
    53.3 @@ -48,7 +48,9 @@
    53.4  #include "lluictrlfactory.h"
    53.5  #include "lltooltip.h"
    53.6  #include "llsdutil.h"
    53.7 -
    53.8 +#include "llsdserialize.h"
    53.9 +#include "llviewereventrecorder.h"
   53.10 +#include "llkeyboard.h"
   53.11  // for ui edit hack
   53.12  #include "llbutton.h"
   53.13  #include "lllineeditor.h"
   53.14 @@ -642,13 +644,27 @@
   53.15  // virtual
   53.16  void LLView::handleVisibilityChange ( BOOL new_visibility )
   53.17  {
   53.18 +	BOOL old_visibility;
   53.19  	BOOST_FOREACH(LLView* viewp, mChildList)
   53.20  	{
   53.21  		// only views that are themselves visible will have their overall visibility affected by their ancestors
   53.22 -		if (viewp->getVisible())
   53.23 +		old_visibility=viewp->getVisible();
   53.24 +
   53.25 +		if (old_visibility!=new_visibility)
   53.26 +		{
   53.27 +			LLViewerEventRecorder::instance().logVisibilityChange( viewp->getPathname(), viewp->getName(), new_visibility,"widget");
   53.28 +		}
   53.29 +
   53.30 +		if (old_visibility)
   53.31  		{
   53.32  			viewp->handleVisibilityChange ( new_visibility );
   53.33  		}
   53.34 +
   53.35 +		// Consider changing returns to confirm success and know which widget grabbed it
   53.36 +		// For now assume success and log at highest xui possible 
   53.37 +		// NOTE we log actual state - which may differ if it somehow failed to set visibility
   53.38 +		lldebugs << "LLView::handleVisibilityChange	 - now: " << getVisible()  << " xui: " << viewp->getPathname() << " name: " << viewp->getName() << llendl;
   53.39 +		
   53.40  	}
   53.41  }
   53.42  
   53.43 @@ -697,6 +713,7 @@
   53.44  		&& getEnabled();
   53.45  }
   53.46  
   53.47 +// This is NOT event recording related
   53.48  void LLView::logMouseEvent()
   53.49  {
   53.50  	if (sDebugMouseHandling)
   53.51 @@ -743,7 +760,14 @@
   53.52  		if ((viewp->*method)( local_x, local_y, extra )
   53.53  			|| (allow_mouse_block && viewp->blockMouseEvent( local_x, local_y )))
   53.54  		{
   53.55 +			lldebugs << "LLView::childrenHandleMouseEvent calling updatemouseeventinfo - local_x|global x  "<< local_x << " " << x	<< "local/global y " << local_y << " " << y << llendl;
   53.56 +			lldebugs << "LLView::childrenHandleMouseEvent  getPathname for viewp result: " << viewp->getPathname() << "for this view: " << getPathname() << llendl;
   53.57 +
   53.58 +			LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); 
   53.59 +
   53.60 +			// This is NOT event recording related
   53.61  			viewp->logMouseEvent();
   53.62 +
   53.63  			return viewp;
   53.64  		}
   53.65  	}
   53.66 @@ -766,6 +790,7 @@
   53.67  		if (viewp->handleToolTip(local_x, local_y, mask) 
   53.68  			|| viewp->blockMouseEvent(local_x, local_y))
   53.69  		{
   53.70 +			// This is NOT event recording related
   53.71  			viewp->logMouseEvent();
   53.72  			return viewp;
   53.73  		}
   53.74 @@ -824,6 +849,7 @@
   53.75  		if (viewp->handleHover(local_x, local_y, mask)
   53.76  			|| viewp->blockMouseEvent(local_x, local_y))
   53.77  		{
   53.78 +			// This is NOT event recording related
   53.79  			viewp->logMouseEvent();
   53.80  			return viewp;
   53.81  		}
   53.82 @@ -907,10 +933,12 @@
   53.83  
   53.84  		if (!handled)
   53.85  		{
   53.86 +			// For event logging we don't care which widget handles it
   53.87 +			// So we capture the key at the end of this function once we know if it was handled
   53.88  			handled = handleKeyHere( key, mask );
   53.89 -			if (handled && LLView::sDebugKeys)
   53.90 +			if (handled)
   53.91  			{
   53.92 -				llinfos << "Key handled by " << getName() << llendl;
   53.93 +				llwarns << "Key handled by " << getName() << llendl;
   53.94  			}
   53.95  		}
   53.96  	}
   53.97 @@ -958,6 +986,11 @@
   53.98  		handled = mParentView->handleUnicodeChar(uni_char, FALSE);
   53.99  	}
  53.100  
  53.101 +	if (handled)
  53.102 +	{
  53.103 +		LLViewerEventRecorder::instance().logKeyUnicodeEvent(uni_char);
  53.104 +	}
  53.105 +	
  53.106  	return handled;
  53.107  }
  53.108  
  53.109 @@ -987,12 +1020,16 @@
  53.110  
  53.111  BOOL LLView::handleMouseUp(S32 x, S32 y, MASK mask)
  53.112  {
  53.113 -	return childrenHandleMouseUp( x, y, mask ) != NULL;
  53.114 +	LLView* r = childrenHandleMouseUp( x, y, mask );
  53.115 +
  53.116 +	return (r!=NULL);
  53.117  }
  53.118  
  53.119  BOOL LLView::handleMouseDown(S32 x, S32 y, MASK mask)
  53.120  {
  53.121 -	return childrenHandleMouseDown( x, y, mask ) != NULL;
  53.122 +	LLView* r= childrenHandleMouseDown(x, y, mask );
  53.123 +
  53.124 +	return (r!=NULL);
  53.125  }
  53.126  
  53.127  BOOL LLView::handleDoubleClick(S32 x, S32 y, MASK mask)
  53.128 @@ -1065,7 +1102,7 @@
  53.129  
  53.130  LLView* LLView::childrenHandleMouseUp(S32 x, S32 y, MASK mask)
  53.131  {
  53.132 -	return childrenHandleMouseEvent(&LLView::handleMouseUp, x, y, mask);
  53.133 +	return	childrenHandleMouseEvent(&LLView::handleMouseUp, x, y, mask);
  53.134  }
  53.135  
  53.136  LLView* LLView::childrenHandleRightMouseUp(S32 x, S32 y, MASK mask)
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/indra/llui/llviewereventrecorder.cpp	Tue Nov 12 14:06:38 2013 -0500
    54.3 @@ -0,0 +1,296 @@
    54.4 +/**
    54.5 + * @file llviewereventrecorder.cpp
    54.6 + * @brief Viewer event recording and playback support for mouse and keyboard events
    54.7 + *
    54.8 + * $LicenseInfo:firstyear=2013&license=viewerlgpl$
    54.9 + * 
   54.10 + * Copyright (c) 2013, Linden Research, Inc.
   54.11 + * This library is free software; you can redistribute it and/or
   54.12 + * modify it under the terms of the GNU Lesser General Public
   54.13 + * License as published by the Free Software Foundation;
   54.14 + * version 2.1 of the License only.
   54.15 + * 
   54.16 + * This library is distributed in the hope that it will be useful,
   54.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   54.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   54.19 + * Lesser General Public License for more details.
   54.20 + * 
   54.21 + * You should have received a copy of the GNU Lesser General Public
   54.22 + * License along with this library; if not, write to the Free Software
   54.23 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   54.24 + * 
   54.25 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   54.26 + * $/LicenseInfo$
   54.27 + */
   54.28 +
   54.29 +
   54.30 +#include "llviewereventrecorder.h"
   54.31 +#include "llui.h"
   54.32 +#include "llleap.h"
   54.33 +
   54.34 +LLViewerEventRecorder::LLViewerEventRecorder() {
   54.35 +
   54.36 +  clear(UNDEFINED);
   54.37 +
   54.38 +  // Remove any previous event log file
   54.39 +  std::string old_log_ui_events_to_llsd_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.old");
   54.40 +  LLFile::remove(old_log_ui_events_to_llsd_file);
   54.41 +  
   54.42 +
   54.43 +  mLogFilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.llsd");
   54.44 +  LLFile::rename(mLogFilename, old_log_ui_events_to_llsd_file);
   54.45 +
   54.46 +}
   54.47 +
   54.48 +
   54.49 +bool LLViewerEventRecorder::displayViewerEventRecorderMenuItems() {
   54.50 +  return LLUI::sSettingGroups["config"]->getBOOL("ShowEventRecorderMenuItems");
   54.51 +}
   54.52 +
   54.53 +
   54.54 +void LLViewerEventRecorder::setEventLoggingOn() {
   54.55 +  if (! mLog.is_open()) {
   54.56 +    mLog.open(mLogFilename, llofstream::out);
   54.57 +  }
   54.58 +  logEvents=true; 
   54.59 +  lldebugs << "LLViewerEventRecorder::setEventLoggingOn event logging turned on" << llendl;
   54.60 +}
   54.61 +
   54.62 +void LLViewerEventRecorder::setEventLoggingOff() {
   54.63 +  logEvents=false;
   54.64 +  mLog.flush();
   54.65 +  mLog.close();
   54.66 +  lldebugs << "LLViewerEventRecorder::setEventLoggingOff event logging turned off" << llendl;
   54.67 +}
   54.68 +
   54.69 +
   54.70 + LLViewerEventRecorder::~LLViewerEventRecorder() {
   54.71 +  if (mLog.is_open()) {
   54.72 +      mLog.close();
   54.73 +    }
   54.74 +}
   54.75 +
   54.76 +void LLViewerEventRecorder::clear_xui() {
   54.77 +  xui.clear();
   54.78 +}
   54.79 +
   54.80 +void LLViewerEventRecorder::clear(S32 r) {
   54.81 +
   54.82 +  xui.clear();
   54.83 +
   54.84 +  local_x=r;
   54.85 +  local_y=r;
   54.86 +
   54.87 +  global_x=r;
   54.88 +  global_y=r;
   54.89 +    
   54.90 +
   54.91 +}
   54.92 +
   54.93 +void LLViewerEventRecorder::setMouseLocalCoords(S32 x, S32 y) {
   54.94 +  local_x=x;
   54.95 +  local_y=y;
   54.96 +}
   54.97 +
   54.98 +void LLViewerEventRecorder::setMouseGlobalCoords(S32 x, S32 y) {
   54.99 +  global_x=x;
  54.100 +  global_y=y;
  54.101 +}
  54.102 +
  54.103 +void LLViewerEventRecorder::updateMouseEventInfo(S32 local_x, S32 local_y, S32 global_x, S32 global_y, std::string mName) {
  54.104 +
  54.105 +  LLView * target_view = LLUI::resolvePath(LLUI::getRootView(), xui);
  54.106 +  if (! target_view) {
  54.107 +    lldebugs << "LLViewerEventRecorder::updateMouseEventInfo - xui path on file at moment is NOT valid - so DO NOT record these local coords" << llendl;
  54.108 +    return;
  54.109 +  }
  54.110 +  lldebugs << "LLViewerEventRecorder::updateMouseEventInfo b4 updatemouseeventinfo - local_x|global x   "<< this->local_x << " " << this->global_x  << "local/global y " << this->local_y << " " << this->global_y << " mname: " << mName << " xui: " << xui << llendl;
  54.111 +
  54.112 +
  54.113 +  if (this->local_x < 1 && this->local_y<1 && local_x && local_y) {
  54.114 +    this->local_x=local_x;
  54.115 +    this->local_y=local_y;
  54.116 +  }
  54.117 +  this->global_x=global_x;
  54.118 +  this->global_y=global_y;
  54.119 +
  54.120 +  // ONLY record deepest xui path for hierarchy searches - or first/only xui for floaters/panels reached via mouse captor - and llmousehandler
  54.121 +  if (mName!="" &&  mName!="/" && xui=="") { 
  54.122 +    //	xui=std::string("/")+mName+xui; 
  54.123 +    //xui=mName+xui; 
  54.124 +    xui = mName; // TODO review confirm we never call with partial path - also cAN REMOVE CHECK FOR "" - ON OTHER HAND IT'S PRETTY HARMLESS
  54.125 +  }
  54.126 +
  54.127 +  lldebugs << "LLViewerEventRecorder::updateMouseEventInfo after updatemouseeventinfo - local_x|global x   "<< this->local_x << " " << this->global_x  << "local/global y " << this->local_y << " " << this->global_y << " mname: " << mName << " xui: " << xui << llendl;
  54.128 +}
  54.129 +
  54.130 +void LLViewerEventRecorder::logVisibilityChange(std::string xui, std::string name, BOOL visibility, std::string event_subtype) {
  54.131 +
  54.132 +  LLSD  event=LLSD::emptyMap();
  54.133 +
  54.134 +  event.insert("event",LLSD(std::string("visibility")));
  54.135 +
  54.136 +  if (visibility) {
  54.137 +    event.insert("visibility",LLSD(true));
  54.138 +  } else {
  54.139 +    event.insert("visibility",LLSD(false));
  54.140 +  }
  54.141 +
  54.142 +  if (event_subtype!="") {
  54.143 +    event.insert("event_subtype", LLSD(event_subtype));
  54.144 +  }
  54.145 +
  54.146 +  if(name!="") {
  54.147 +    event.insert("name",LLSD(name));
  54.148 +  }
  54.149 +
  54.150 +  if (xui!="") {
  54.151 +    event.insert("path",LLSD(xui));
  54.152 +  }
  54.153 +
  54.154 +  event.insert("timestamp",LLSD(LLDate::now().asString())); 
  54.155 +  recordEvent(event);
  54.156 +}
  54.157 +
  54.158 +
  54.159 +std::string LLViewerEventRecorder::get_xui() {
  54.160 +  return xui;
  54.161 +}
  54.162 +void LLViewerEventRecorder::update_xui(std::string xui) {
  54.163 +  if (xui!="" && this->xui=="" ) {
  54.164 +    lldebugs << "LLViewerEventRecorder::update_xui to " << xui << llendl;
  54.165 +    this->xui=xui;
  54.166 +  } else {
  54.167 +    lldebugs << "LLViewerEventRecorder::update_xui called with empty string" << llendl;
  54.168 +  }
  54.169 +}
  54.170 +
  54.171 +void LLViewerEventRecorder::logKeyEvent(KEY key, MASK mask) {
  54.172 +
  54.173 +  // NOTE: Event recording only logs keydown events - the viewer itself hides keyup events at a fairly low level in the code and does not appear to care about them anywhere
  54.174 +
  54.175 +  LLSD event = LLSD::emptyMap();
  54.176 +
  54.177 +  event.insert("event",LLSD("type"));
  54.178 +
  54.179 +  // keysym ...or
  54.180 +  // keycode...or
  54.181 +  // char
  54.182 +  event.insert("keysym",LLSD(LLKeyboard::stringFromKey(key)));
  54.183 +
  54.184 +  // path (optional) - for now we are not recording path for key events during record - should not be needed for full record and playback of recorded steps
  54.185 +  // as a vita script - it does become useful if you edit the resulting vita script and wish to remove some steps leading to a key event - that sort of edit might
  54.186 +  // break the test script and it would be useful to have more context to make these sorts of edits safer
  54.187 + 
  54.188 +  // TODO  replace this with a call which extracts to an array of names of masks (just like vita expects during playback)
  54.189 +  // This is looking more and more like an object is a good idea, for this part a handy method call to setMask(mask) would be nice :-)
  54.190 +  // call the func - llkeyboard::llsdStringarrayFromMask
  54.191 +
  54.192 +  LLSD key_mask=LLSD::emptyArray();
  54.193 +
  54.194 +  if (mask & MASK_CONTROL)     { key_mask.append(LLSD("CTL")); }  // Mac command key - has code of 0x1  in llcommon/indra_contstants
  54.195 +  if (mask & MASK_ALT)         { key_mask.append(LLSD("ALT")); }
  54.196 +  if (mask & MASK_SHIFT)       { key_mask.append(LLSD("SHIFT")); }
  54.197 +  if (mask & MASK_MAC_CONTROL) { key_mask.append(LLSD("MAC_CONTROL")); }
  54.198 +
  54.199 +  event.insert("mask",key_mask); 
  54.200 +  event.insert("timestamp",LLSD(LLDate::now().asString())); 
  54.201 +
  54.202 +  // Although vita has keyDown and keyUp requests it does not have type as a high-level concept 
  54.203 +  // (maybe it should) - instead it has a convenience method that generates the keydown and keyup events 
  54.204 +  // Here  we will use  "type" as  our event type
  54.205 +
  54.206 +  lldebugs << "LLVIewerEventRecorder::logKeyEvent Serialized LLSD for event " << event.asString() << "\n" << llendl;
  54.207 +
  54.208 +
  54.209 +  //lldebugs  << "[VITA] key_name: "  << LLKeyboard::stringFromKey(key) << "mask: "<< mask  << "handled by " << getName() << llendl;
  54.210 +  lldebugs  << "LLVIewerEventRecorder::logKeyEvent  key_name: "  << LLKeyboard::stringFromKey(key) << "mask: "<< mask  << llendl;
  54.211 +
  54.212 +
  54.213 +  recordEvent(event);
  54.214 +
  54.215 +}
  54.216 +
  54.217 +void LLViewerEventRecorder::playbackRecording() {
  54.218 +
  54.219 +  LLSD LeapCommand;
  54.220 +
  54.221 +  // ivita sets this on startup, it also sends commands to the viewer to make start, stop, and playback menu items visible in viewer
  54.222 +  LeapCommand =LLUI::sSettingGroups["config"]->getLLSD("LeapPlaybackEventsCommand");
  54.223 +  
  54.224 +  lldebugs << "[VITA] launching playback - leap command is: " << LLSDXMLStreamer(LeapCommand) << llendl;
  54.225 +  LLLeap::create("", LeapCommand, false); // exception=false
  54.226 +  
  54.227 +}
  54.228 +
  54.229 +
  54.230 +void LLViewerEventRecorder::recordEvent(LLSD event) {
  54.231 +  lldebugs << "LLViewerEventRecorder::recordEvent event written to log: " << LLSDXMLStreamer(event) << llendl;
  54.232 +  mLog << event << std::endl;
  54.233 +  
  54.234 +}
  54.235 +void LLViewerEventRecorder::logKeyUnicodeEvent(llwchar uni_char) {
  54.236 +  if (! logEvents) return;
  54.237 +
  54.238 +  // Note: keyUp is not captured since the viewer seems to not care about keyUp events
  54.239 +
  54.240 +  LLSD event=LLSD::emptyMap();
  54.241 +
  54.242 +  event.insert("timestamp",LLSD(LLDate::now().asString()));
  54.243 +
  54.244 +  
  54.245 +  // keysym ...or
  54.246 +  // keycode...or
  54.247 +  // char
  54.248 +
  54.249 +  lldebugs << "Wrapped in conversion to wstring " <<  wstring_to_utf8str(LLWString( 1, uni_char)) << "\n" << llendl;
  54.250 +  
  54.251 +  event.insert("char",
  54.252 +	       LLSD(  wstring_to_utf8str(LLWString( 1,uni_char))  )
  54.253 +	       ); 
  54.254 +
  54.255 +  // path (optional) - for now we are not recording path for key events during record - should not be needed for full record and playback of recorded steps
  54.256 +  // as a vita script - it does become useful if you edit the resulting vita script and wish to remove some steps leading to a key event - that sort of edit might
  54.257 +  // break the test script and it would be useful to have more context to make these sorts of edits safer
  54.258 +
  54.259 +  // TODO need to consider mask keys too? Doesn't seem possible - at least not easily at this point
  54.260 +
  54.261 +  event.insert("event",LLSD("keyDown")); 
  54.262 +
  54.263 +  lldebugs  << "[VITA] unicode key: " << uni_char   << llendl;
  54.264 +  lldebugs  << "[VITA] dumpxml " << LLSDXMLStreamer(event) << "\n" << llendl;
  54.265 +
  54.266 +
  54.267 +  recordEvent(event);
  54.268 +
  54.269 +}
  54.270 +
  54.271 +void LLViewerEventRecorder::logMouseEvent(std::string button_state,std::string button_name)
  54.272 +{
  54.273 +  if (! logEvents) return; 
  54.274 +
  54.275 +  LLSD  event=LLSD::emptyMap();
  54.276 +
  54.277 +  event.insert("event",LLSD(std::string("mouse"+ button_state)));
  54.278 +  event.insert("button",LLSD(button_name));
  54.279 +  if (xui!="") {
  54.280 +    event.insert("path",LLSD(xui));
  54.281 +  }
  54.282 +
  54.283 +  if (local_x>0 && local_y>0) {
  54.284 +    event.insert("local_x",LLSD(local_x));
  54.285 +    event.insert("local_y",LLSD(local_y));
  54.286 +  }
  54.287 +
  54.288 +  if (global_x>0 && global_y>0) {
  54.289 +    event.insert("global_x",LLSD(global_x));
  54.290 +    event.insert("global_y",LLSD(global_y));
  54.291 +  }
  54.292 +  event.insert("timestamp",LLSD(LLDate::now().asString())); 
  54.293 +  recordEvent(event);
  54.294 +
  54.295 +
  54.296 +  clear(UNDEFINED);
  54.297 +   
  54.298 +
  54.299 +}
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/indra/llui/llviewereventrecorder.h	Tue Nov 12 14:06:38 2013 -0500
    55.3 @@ -0,0 +1,103 @@
    55.4 +/**
    55.5 + * @file llviewereventrecorder.h
    55.6 + * @brief Viewer event recording and playback support for mouse and keyboard events
    55.7 + *
    55.8 + * $LicenseInfo:firstyear=2013&license=viewerlgpl$
    55.9 + * 
   55.10 + * Copyright (c) 2013, Linden Research, Inc.
   55.11 + * This library is free software; you can redistribute it and/or
   55.12 + * modify it under the terms of the GNU Lesser General Public
   55.13 + * License as published by the Free Software Foundation;
   55.14 + * version 2.1 of the License only.
   55.15 + * 
   55.16 + * This library is distributed in the hope that it will be useful,
   55.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   55.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   55.19 + * Lesser General Public License for more details.
   55.20 + * 
   55.21 + * You should have received a copy of the GNU Lesser General Public
   55.22 + * License along with this library; if not, write to the Free Software
   55.23 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   55.24 + * 
   55.25 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   55.26 + * $/LicenseInfo$
   55.27 + */
   55.28 +
   55.29 +#ifndef LL_VIEWER_EVENT_RECORDER
   55.30 +#define LL_VIEWER_EVENT_RECORDER
   55.31 +
   55.32 +
   55.33 +#include "linden_common.h" 
   55.34 +
   55.35 +#include "lldir.h" 
   55.36 +#include "llsd.h"  
   55.37 +#include "llfile.h"
   55.38 +#include "llvfile.h"
   55.39 +#include "lldate.h"
   55.40 +#include "llsdserialize.h"
   55.41 +#include "llkeyboard.h"
   55.42 +#include "llstring.h"
   55.43 +
   55.44 +#include <sstream>
   55.45 +
   55.46 +#include "llsingleton.h" // includes llerror which we need here so we can skip the include here
   55.47 +
   55.48 +class LLViewerEventRecorder : public LLSingleton<LLViewerEventRecorder>
   55.49 +{
   55.50 +
   55.51 + public:
   55.52 +
   55.53 +  LLViewerEventRecorder(); // TODO Protect constructor better if we can (not happy in private section) - could add a factory... - we are singleton
   55.54 +  ~LLViewerEventRecorder();
   55.55 +
   55.56 +
   55.57 +  void updateMouseEventInfo(S32 local_x,S32 local_y, S32 global_x, S32 global_y,  std::string mName);
   55.58 +  void setMouseLocalCoords(S32 x,S32 y);
   55.59 +  void setMouseGlobalCoords(S32 x,S32 y);
   55.60 +
   55.61 +  void logMouseEvent(std::string button_state, std::string button_name );
   55.62 +  void logKeyEvent(KEY key, MASK mask);
   55.63 +  void logKeyUnicodeEvent(llwchar uni_char);
   55.64 +
   55.65 +  void logVisibilityChange(std::string xui, std::string name, BOOL visibility, std::string event_subtype);
   55.66 +
   55.67 +  void clear_xui();
   55.68 +  std::string get_xui();
   55.69 +  void update_xui(std::string xui);
   55.70 +
   55.71 +  bool getLoggingStatus();
   55.72 +  void setEventLoggingOn();
   55.73 +  void setEventLoggingOff();
   55.74 +
   55.75 +  void playbackRecording();
   55.76 +
   55.77 +  bool displayViewerEventRecorderMenuItems();
   55.78 +
   55.79 +
   55.80 + protected:
   55.81 +  // On if we wish to log events at the moment - toggle via Develop/Recorder submenu
   55.82 +  bool logEvents;
   55.83 +
   55.84 +  std::string mLogFilename;
   55.85 +  llofstream  mLog; 
   55.86 +
   55.87 +
   55.88 + private:
   55.89 +
   55.90 +  // Mouse event info 
   55.91 +  S32 global_x;
   55.92 +  S32 global_y;
   55.93 +  S32 local_x;
   55.94 +  S32 local_y;
   55.95 +
   55.96 +  // XUI path of UI element
   55.97 +  std::string xui;
   55.98 +
   55.99 +  // Actually write the event out to llsd log file
  55.100 +  void recordEvent(LLSD event);
  55.101 +
  55.102 +  void clear(S32 r); 
  55.103 +
  55.104 +  static const S32 UNDEFINED=-1;
  55.105 +};
  55.106 +#endif
    56.1 --- a/indra/llwindow/llwindowcallbacks.cpp	Thu Oct 17 18:26:04 2013 -0400
    56.2 +++ b/indra/llwindow/llwindowcallbacks.cpp	Tue Nov 12 14:06:38 2013 -0500
    56.3 @@ -122,6 +122,7 @@
    56.4  
    56.5  void LLWindowCallbacks::handleFocus(LLWindow *window)
    56.6  {
    56.7 +	 LL_WARNS("COCOA") << "Called handleFocus proto" << LL_ENDL;
    56.8  }
    56.9  
   56.10  void LLWindowCallbacks::handleFocusLost(LLWindow *window)
    57.1 --- a/indra/llwindow/llwindowmacosx-objc.h	Thu Oct 17 18:26:04 2013 -0400
    57.2 +++ b/indra/llwindow/llwindowmacosx-objc.h	Tue Nov 12 14:06:38 2013 -0500
    57.3 @@ -25,6 +25,9 @@
    57.4   * $/LicenseInfo$
    57.5   */
    57.6  
    57.7 +#ifndef LL_LLWINDOWMACOSX_OBJC_H
    57.8 +#define LL_LLWINDOWMACOSX_OBJC_H
    57.9 +
   57.10  #include <map>
   57.11  #include <vector>
   57.12  
   57.13 @@ -144,3 +147,5 @@
   57.14  GLViewRef getGLView();
   57.15  
   57.16  unsigned int getModifiers();
   57.17 +
   57.18 +#endif // LL_LLWINDOWMACOSX_OBJC_H
    58.1 --- a/indra/llwindow/llwindowmacosx.cpp	Thu Oct 17 18:26:04 2013 -0400
    58.2 +++ b/indra/llwindow/llwindowmacosx.cpp	Tue Nov 12 14:06:38 2013 -0500
    58.3 @@ -331,7 +331,16 @@
    58.4  
    58.5  void callWindowFocus()
    58.6  {
    58.7 -	gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation);
    58.8 +   if ( gWindowImplementation && gWindowImplementation->getCallbacks() )
    58.9 +	{
   58.10 +		gWindowImplementation->getCallbacks()->handleFocus (gWindowImplementation);
   58.11 +	}
   58.12 +	else
   58.13 +	{
   58.14 +		LL_WARNS("COCOA") << "Window Implementation or callbacks not yet initialized." << LL_ENDL;
   58.15 +	}
   58.16 +
   58.17 +
   58.18  }
   58.19  
   58.20  void callWindowUnfocus()
   58.21 @@ -1300,6 +1309,8 @@
   58.22  	OSMessageBox(text, caption, type);
   58.23  }
   58.24  
   58.25 +			// Note on event recording - QUIT is a known special case and we are choosing NOT to record it for the record and playback feature 
   58.26 +			// it is handled at a very low-level
   58.27  const char* cursorIDToName(int id)
   58.28  {
   58.29  	switch (id)
    59.1 --- a/indra/llxml/llcontrol.cpp	Thu Oct 17 18:26:04 2013 -0400
    59.2 +++ b/indra/llxml/llcontrol.cpp	Tue Nov 12 14:06:38 2013 -0500
    59.3 @@ -391,7 +391,7 @@
    59.4  		}
    59.5  		else
    59.6  		{
    59.7 -			llwarns << "Control named " << name << " already exists, ignoring new declaration." << llendl;
    59.8 +			LL_WARNS("Settings") << "Control named " << name << " already exists, ignoring new declaration." << LL_ENDL;
    59.9  		}
   59.10   		return existing_control;
   59.11  	}
   59.12 @@ -630,14 +630,14 @@
   59.13  
   59.14  	if (!xml_controls.parseFile(filename))
   59.15  	{
   59.16 -		llwarns << "Unable to open control file " << filename << llendl;
   59.17 +		LL_WARNS("Settings") << "Unable to open control file " << filename << LL_ENDL;
   59.18  		return 0;
   59.19  	}
   59.20  
   59.21  	LLXmlTreeNode* rootp = xml_controls.getRoot();
   59.22  	if (!rootp || !rootp->hasAttribute("version"))
   59.23  	{
   59.24 -		llwarns << "No valid settings header found in control file " << filename << llendl;
   59.25 +		LL_WARNS("Settings") << "No valid settings header found in control file " << filename << LL_ENDL;
   59.26  		return 0;
   59.27  	}
   59.28  
   59.29 @@ -650,7 +650,7 @@
   59.30  	// Check file version
   59.31  	if (version != CURRENT_VERSION)
   59.32  	{
   59.33 -		llinfos << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << llendl;
   59.34 +		LL_INFOS("Settings") << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << LL_ENDL;
   59.35  		return 0;
   59.36  	}
   59.37  
   59.38 @@ -668,7 +668,7 @@
   59.39  			if (!name.empty())
   59.40  			{
   59.41  				//read in to end of line
   59.42 -				llwarns << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << llendl;
   59.43 +				LL_WARNS("Settings") << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << LL_ENDL;
   59.44  			}
   59.45  			child_nodep = rootp->getNextChild();
   59.46  			continue;
   59.47 @@ -822,7 +822,7 @@
   59.48  		LLControlVariable* control = iter->second;
   59.49  		if (!control)
   59.50  		{
   59.51 -			llwarns << "Tried to save invalid control: " << iter->first << llendl;
   59.52 +			LL_WARNS("Settings") << "Tried to save invalid control: " << iter->first << LL_ENDL;
   59.53  		}
   59.54  		else if( control->shouldSave(nondefault_only) )
   59.55  		{
   59.56 @@ -838,12 +838,12 @@
   59.57  	{
   59.58  		LLSDSerialize::toPrettyXML(settings, file);
   59.59  		file.close();
   59.60 -		llinfos << "Saved to " << filename << llendl;
   59.61 +		LL_INFOS("Settings") << "Saved to " << filename << LL_ENDL;
   59.62  	}
   59.63  	else
   59.64  	{
   59.65          // This is a warning because sometime we want to use settings files which can't be written...
   59.66 -		llwarns << "Unable to open settings file: " << filename << llendl;
   59.67 +		LL_WARNS("Settings") << "Unable to open settings file: " << filename << LL_ENDL;
   59.68  		return 0;
   59.69  	}
   59.70  	return num_saved;
   59.71 @@ -856,14 +856,14 @@
   59.72  	infile.open(filename);
   59.73  	if(!infile.is_open())
   59.74  	{
   59.75 -		llwarns << "Cannot find file " << filename << " to load." << llendl;
   59.76 +		LL_WARNS("Settings") << "Cannot find file " << filename << " to load." << LL_ENDL;
   59.77  		return 0;
   59.78  	}
   59.79  
   59.80  	if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(settings, infile))
   59.81  	{
   59.82  		infile.close();
   59.83 -		llwarns << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << llendl;
   59.84 +		LL_WARNS("Settings") << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << LL_ENDL;
   59.85  		return loadFromFileLegacy(filename, TRUE, TYPE_STRING);
   59.86  	}
   59.87  
   59.88 @@ -976,6 +976,7 @@
   59.89  		++validitems;
   59.90  	}
   59.91  
   59.92 +	LL_DEBUGS("Settings") << "Loaded " << validitems << " settings from " << filename << LL_ENDL;
   59.93  	return validitems;
   59.94  }
   59.95  
   59.96 @@ -1012,7 +1013,7 @@
   59.97  	BOOL_CONTROL baz;
   59.98  
   59.99  	U32 count = gGlobals.loadFromFile("controls.ini");
  59.100 -	llinfos << "Loaded " << count << " controls" << llendl;
  59.101 +	LL_INFOS("Settings") << "Loaded " << count << " controls" << LL_ENDL;
  59.102  
  59.103  	// test insertion
  59.104  	foo = new LLControlVariable<F32>("gFoo", 5.f, 1.f, 20.f);
  59.105 @@ -1273,19 +1274,19 @@
  59.106  		LLColor4 color(sd);
  59.107  		if (color.mV[VRED] < 0.f || color.mV[VRED] > 1.f)
  59.108  		{
  59.109 -			llwarns << "Color " << control_name << " red value out of range: " << color << llendl;
  59.110 +			LL_WARNS("Settings") << "Color " << control_name << " red value out of range: " << color << LL_ENDL;
  59.111  		}
  59.112  		else if (color.mV[VGREEN] < 0.f || color.mV[VGREEN] > 1.f)
  59.113  		{
  59.114 -			llwarns << "Color " << control_name << " green value out of range: " << color << llendl;
  59.115 +			LL_WARNS("Settings") << "Color " << control_name << " green value out of range: " << color << LL_ENDL;
  59.116  		}
  59.117  		else if (color.mV[VBLUE] < 0.f || color.mV[VBLUE] > 1.f)
  59.118  		{
  59.119 -			llwarns << "Color " << control_name << " blue value out of range: " << color << llendl;
  59.120 +			LL_WARNS("Settings") << "Color " << control_name << " blue value out of range: " << color << LL_ENDL;
  59.121  		}
  59.122  		else if (color.mV[VALPHA] < 0.f || color.mV[VALPHA] > 1.f)
  59.123  		{
  59.124 -			llwarns << "Color " << control_name << " alpha value out of range: " << color << llendl;
  59.125 +			LL_WARNS("Settings") << "Color " << control_name << " alpha value out of range: " << color << LL_ENDL;
  59.126  		}
  59.127  
  59.128  		return LLColor4(sd);
    60.1 --- a/indra/llxml/llcontrol.h	Thu Oct 17 18:26:04 2013 -0400
    60.2 +++ b/indra/llxml/llcontrol.h	Tue Nov 12 14:06:38 2013 -0500
    60.3 @@ -408,16 +408,6 @@
    60.4  		}
    60.5  	}
    60.6  
    60.7 -	LLCachedControl(LLControlGroup& group,
    60.8 -					const std::string& name)
    60.9 -	{
   60.10 -		mCachedControlPtr = LLControlCache<T>::getInstance(name);
   60.11 -		if (mCachedControlPtr.isNull())
   60.12 -		{
   60.13 -			mCachedControlPtr = new LLControlCache<T>(group, name);
   60.14 -		}
   60.15 -	}
   60.16 -
   60.17  	operator const T&() const { return mCachedControlPtr->getValue(); }
   60.18  	operator boost::function<const T&()> () const { return boost::function<const T&()>(*this); }
   60.19  	const T& operator()() { return mCachedControlPtr->getValue(); }
    61.1 --- a/indra/newview/CMakeLists.txt	Thu Oct 17 18:26:04 2013 -0400
    61.2 +++ b/indra/newview/CMakeLists.txt	Tue Nov 12 14:06:38 2013 -0500
    61.3 @@ -191,6 +191,7 @@
    61.4      llexpandabletextbox.cpp
    61.5      llexternaleditor.cpp
    61.6      llface.cpp
    61.7 +    llfacebookconnect.cpp
    61.8      llfasttimerview.cpp
    61.9      llfavoritesbar.cpp
   61.10      llfeaturemanager.cpp
   61.11 @@ -273,6 +274,7 @@
   61.12      llfloatersettingsdebug.cpp
   61.13      llfloatersidepanelcontainer.cpp
   61.14      llfloatersnapshot.cpp
   61.15 +    llfloatersocial.cpp
   61.16      llfloatersounddevices.cpp
   61.17      llfloaterspellchecksettings.cpp
   61.18      llfloatertelehub.cpp
   61.19 @@ -508,6 +510,7 @@
   61.20      llsidetraypanelcontainer.cpp
   61.21      llsky.cpp
   61.22      llslurl.cpp
   61.23 +    llsnapshotlivepreview.cpp
   61.24      llspatialpartition.cpp
   61.25      llspeakers.cpp
   61.26      llspeakingindicatormanager.cpp
   61.27 @@ -776,6 +779,7 @@
   61.28      llexpandabletextbox.h
   61.29      llexternaleditor.h
   61.30      llface.h
   61.31 +    llfacebookconnect.h
   61.32      llfasttimerview.h
   61.33      llfavoritesbar.h
   61.34      llfeaturemanager.h
   61.35 @@ -858,6 +862,7 @@
   61.36      llfloatersettingsdebug.h
   61.37      llfloatersidepanelcontainer.h
   61.38      llfloatersnapshot.h
   61.39 +    llfloatersocial.h
   61.40      llfloatersounddevices.h
   61.41      llfloaterspellchecksettings.h
   61.42      llfloatertelehub.h
   61.43 @@ -1082,6 +1087,7 @@
   61.44      llsidetraypanelcontainer.h
   61.45      llsky.h
   61.46      llslurl.h
   61.47 +    llsnapshotlivepreview.h
   61.48      llspatialpartition.h
   61.49      llspeakers.h
   61.50      llspeakingindicatormanager.h
    62.1 --- a/indra/newview/VIEWER_VERSION.txt	Thu Oct 17 18:26:04 2013 -0400
    62.2 +++ b/indra/newview/VIEWER_VERSION.txt	Tue Nov 12 14:06:38 2013 -0500
    62.3 @@ -1,1 +1,1 @@
    62.4 -3.6.9
    62.5 +3.6.11
    63.1 --- a/indra/newview/app_settings/commands.xml	Thu Oct 17 18:26:04 2013 -0400
    63.2 +++ b/indra/newview/app_settings/commands.xml	Tue Nov 12 14:06:38 2013 -0500
    63.3 @@ -3,6 +3,8 @@
    63.4    <command name="aboutland"
    63.5             available_in_toybox="true"
    63.6             icon="Command_AboutLand_Icon"
    63.7 +           hover_icon_unselected="Command_Highlighting_Icon"
    63.8 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
    63.9             label_ref="Command_AboutLand_Label"
   63.10             tooltip_ref="Command_AboutLand_Tooltip"
   63.11             execute_function="Floater.ToggleOrBringToFront"
   63.12 @@ -13,6 +15,8 @@
   63.13    <command name="appearance"  
   63.14             available_in_toybox="true"
   63.15             icon="Command_Appearance_Icon"
   63.16 +           hover_icon_unselected="Command_Highlighting_Icon"
   63.17 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
   63.18             label_ref="Command_Appearance_Label"
   63.19             tooltip_ref="Command_Appearance_Tooltip"
   63.20             execute_function="Floater.ToggleOrBringToFront"
   63.21 @@ -23,6 +27,8 @@
   63.22    <command name="avatar"
   63.23             available_in_toybox="true"
   63.24             icon="Command_Avatar_Icon"
   63.25 +           hover_icon_unselected="Command_Highlighting_Icon"
   63.26 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
   63.27             label_ref="Command_Avatar_Label"
   63.28             tooltip_ref="Command_Avatar_Tooltip"
   63.29             execute_function="Floater.ToggleOrBringToFront"
   63.30 @@ -33,6 +39,8 @@
   63.31    <command name="build"
   63.32             available_in_toybox="true"
   63.33             icon="Command_Build_Icon"
   63.34 +           hover_icon_unselected="Command_Highlighting_Icon"
   63.35 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
   63.36             label_ref="Command_Build_Label"
   63.37             tooltip_ref="Command_Build_Tooltip"
   63.38             execute_function="Build.Toggle"
   63.39 @@ -46,6 +54,8 @@
   63.40             available_in_toybox="true"
   63.41  		   is_flashing_allowed="true"
   63.42             icon="Command_Chat_Icon"
   63.43 +           hover_icon_unselected="Command_Highlighting_Icon"
   63.44 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
   63.45             label_ref="Command_Chat_Label"
   63.46             tooltip_ref="Command_Conversations_Tooltip"
   63.47             execute_function="Floater.ToggleOrBringToFront"
   63.48 @@ -56,6 +66,8 @@
   63.49    <command name="compass"
   63.50             available_in_toybox="false"
   63.51             icon="Command_Compass_Icon"
   63.52 +           hover_icon_unselected="Command_Highlighting_Icon"
   63.53 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
   63.54             label_ref="Command_Compass_Label"
   63.55             tooltip_ref="Command_Compass_Tooltip"
   63.56             execute_function="Floater.ToggleOrBringToFront"
   63.57 @@ -66,6 +78,8 @@
   63.58    <command name="destinations"
   63.59             available_in_toybox="true"
   63.60             icon="Command_Destinations_Icon"
   63.61 +           hover_icon_unselected="Command_Highlighting_Icon"
   63.62 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
   63.63             label_ref="Command_Destinations_Label"
   63.64             tooltip_ref="Command_Destinations_Tooltip"
   63.65             execute_function="Floater.ToggleOrBringToFront"
   63.66 @@ -76,6 +90,8 @@
   63.67    <command name="gestures"
   63.68             available_in_toybox="true"
   63.69             icon="Command_Gestures_Icon"
   63.70 +           hover_icon_unselected="Command_Highlighting_Icon"
   63.71 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
   63.72             label_ref="Command_Gestures_Label"
   63.73             tooltip_ref="Command_Gestures_Tooltip"
   63.74             execute_function="Floater.ToggleOrBringToFront"
   63.75 @@ -86,6 +102,8 @@
   63.76    <command name="howto"
   63.77             available_in_toybox="true"
   63.78             icon="Command_HowTo_Icon"
   63.79 +           hover_icon_unselected="Command_Highlighting_Icon"
   63.80 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
   63.81             label_ref="Command_HowTo_Label"
   63.82             tooltip_ref="Command_HowTo_Tooltip"
   63.83             execute_function="Help.ToggleHowTo"
   63.84 @@ -94,6 +112,8 @@
   63.85    <command name="inventory"
   63.86             available_in_toybox="true"
   63.87             icon="Command_Inventory_Icon"
   63.88 +           hover_icon_unselected="Command_Highlighting_Icon"
   63.89 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
   63.90             label_ref="Command_Inventory_Label"
   63.91             tooltip_ref="Command_Inventory_Tooltip"
   63.92             execute_function="Floater.ToggleOrBringToFront"
   63.93 @@ -104,6 +124,8 @@
   63.94    <command name="map"
   63.95             available_in_toybox="true"
   63.96             icon="Command_Map_Icon"
   63.97 +           hover_icon_unselected="Command_Highlighting_Icon"
   63.98 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
   63.99             label_ref="Command_Map_Label"
  63.100             tooltip_ref="Command_Map_Tooltip"
  63.101             execute_function="Floater.ToggleOrBringToFront"
  63.102 @@ -114,6 +136,8 @@
  63.103    <command name="marketplace"
  63.104             available_in_toybox="false"
  63.105             icon="Command_Marketplace_Icon"
  63.106 +           hover_icon_unselected="Command_Highlighting_Icon"
  63.107 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
  63.108             label_ref="Command_Marketplace_Label"
  63.109             tooltip_ref="Command_Marketplace_Tooltip"
  63.110             execute_function="Avatar.OpenMarketplace"
  63.111 @@ -121,6 +145,8 @@
  63.112    <command name="minimap"
  63.113             available_in_toybox="true"
  63.114             icon="Command_MiniMap_Icon"
  63.115 +           hover_icon_unselected="Command_Highlighting_Icon"
  63.116 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
  63.117             label_ref="Command_MiniMap_Label"
  63.118             tooltip_ref="Command_MiniMap_Tooltip"
  63.119             execute_function="Floater.ToggleOrBringToFront"
  63.120 @@ -131,6 +157,8 @@
  63.121    <command name="move"
  63.122             available_in_toybox="true"
  63.123             icon="Command_Move_Icon"
  63.124 +           hover_icon_unselected="Command_Highlighting_Icon"
  63.125 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
  63.126             label_ref="Command_Move_Label"
  63.127             tooltip_ref="Command_Move_Tooltip"
  63.128             execute_function="Floater.ToggleOrBringToFront"
  63.129 @@ -141,6 +169,8 @@
  63.130    <command name="outbox"
  63.131             available_in_toybox="false"
  63.132             icon="Command_Outbox_Icon"
  63.133 +           hover_icon_unselected="Command_Highlighting_Icon"
  63.134 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
  63.135             label_ref="Command_Outbox_Label"
  63.136             tooltip_ref="Command_Outbox_Tooltip"
  63.137             execute_function="Floater.ToggleOrBringToFront"
  63.138 @@ -151,6 +181,8 @@
  63.139    <command name="people"
  63.140             available_in_toybox="true"
  63.141             icon="Command_People_Icon"
  63.142 +           hover_icon_unselected="Command_Highlighting_Icon"
  63.143 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
  63.144             label_ref="Command_People_Label"
  63.145             tooltip_ref="Command_People_Tooltip"
  63.146             execute_function="Floater.ToggleOrBringToFront"
  63.147 @@ -161,6 +193,8 @@
  63.148    <command name="picks"
  63.149             available_in_toybox="true"
  63.150             icon="Command_Picks_Icon"
  63.151 +           hover_icon_unselected="Command_Highlighting_Icon"
  63.152 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
  63.153             label_ref="Command_Picks_Label"
  63.154             tooltip_ref="Command_Picks_Tooltip"
  63.155             execute_function="Floater.ToggleOrBringToFront"
  63.156 @@ -171,6 +205,8 @@
  63.157    <command name="places"
  63.158             available_in_toybox="true"
  63.159             icon="Command_Places_Icon"
  63.160 +           hover_icon_unselected="Command_Highlighting_Icon"
  63.161 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
  63.162             label_ref="Command_Places_Label"
  63.163             tooltip_ref="Command_Places_Tooltip"
  63.164             execute_function="Floater.ToggleOrBringToFront"
  63.165 @@ -181,6 +217,8 @@
  63.166    <command name="preferences"
  63.167             available_in_toybox="true"
  63.168             icon="Command_Preferences_Icon"
  63.169 +           hover_icon_unselected="Command_Highlighting_Icon"
  63.170 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
  63.171             label_ref="Command_Preferences_Label"
  63.172             tooltip_ref="Command_Preferences_Tooltip"
  63.173             execute_function="Floater.ToggleOrBringToFront"
  63.174 @@ -191,6 +229,8 @@
  63.175    <command name="profile"
  63.176             available_in_toybox="true"
  63.177             icon="Command_Profile_Icon"
  63.178 +           hover_icon_unselected="Command_Highlighting_Icon"
  63.179 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
  63.180             label_ref="Command_Profile_Label"
  63.181             tooltip_ref="Command_Profile_Tooltip"
  63.182             execute_function="Avatar.ToggleMyProfile"
  63.183 @@ -199,6 +239,8 @@
  63.184    <command name="search"
  63.185             available_in_toybox="true"
  63.186             icon="Command_Search_Icon"
  63.187 +           hover_icon_unselected="Command_Highlighting_Icon"
  63.188 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
  63.189             label_ref="Command_Search_Label"
  63.190             tooltip_ref="Command_Search_Tooltip"
  63.191             execute_function="Floater.ToggleOrBringToFront"
  63.192 @@ -209,6 +251,8 @@
  63.193    <command name="snapshot"
  63.194             available_in_toybox="true"
  63.195             icon="Command_Snapshot_Icon"
  63.196 +           hover_icon_unselected="Command_Highlighting_Icon"
  63.197 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
  63.198             label_ref="Command_Snapshot_Label"
  63.199             tooltip_ref="Command_Snapshot_Tooltip"
  63.200             execute_function="Floater.ToggleOrBringToFront"
  63.201 @@ -216,9 +260,21 @@
  63.202             is_running_function="Floater.IsOpen"
  63.203             is_running_parameters="snapshot"
  63.204             />
  63.205 +  <command name="social"
  63.206 +           available_in_toybox="true"
  63.207 +           icon="Command_Social_Icon"
  63.208 +           label_ref="Command_Social_Label"
  63.209 +           tooltip_ref="Command_Social_Tooltip"
  63.210 +           execute_function="Floater.ToggleOrBringToFront"
  63.211 +           execute_parameters="social"
  63.212 +           is_running_function="Floater.IsOpen"
  63.213 +           is_running_parameters="social"
  63.214 +           />
  63.215    <command name="speak"
  63.216             available_in_toybox="true"
  63.217             icon="Command_Speak_Icon"
  63.218 +           hover_icon_unselected="Command_Highlighting_Icon"
  63.219 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
  63.220             label_ref="Command_Speak_Label"
  63.221             tooltip_ref="Command_Speak_Tooltip"
  63.222             execute_function="Agent.PressMicrophone"
  63.223 @@ -233,6 +289,8 @@
  63.224    <command name="view"
  63.225             available_in_toybox="true"
  63.226             icon="Command_View_Icon"
  63.227 +           hover_icon_unselected="Command_Highlighting_Icon"
  63.228 +           hover_icon_selected="Command_Highlighting_Selected_Icon"
  63.229             label_ref="Command_View_Label"
  63.230             tooltip_ref="Command_View_Tooltip"
  63.231             execute_function="Floater.ToggleOrBringToFront"
    64.1 --- a/indra/newview/app_settings/settings.xml	Thu Oct 17 18:26:04 2013 -0400
    64.2 +++ b/indra/newview/app_settings/settings.xml	Tue Nov 12 14:06:38 2013 -0500
    64.3 @@ -4941,6 +4941,16 @@
    64.4        <key>Value</key>
    64.5        <array />
    64.6      </map>
    64.7 +    <key>LeapPlaybackEventsCommand</key>
    64.8 +    <map>
    64.9 +      <key>Comment</key>
   64.10 +      <string>Command line to use leap to launch playback of event recordings</string>
   64.11 +      <key>Persist</key>
   64.12 +      <integer>0</integer>
   64.13 +      <key>Type</key>
   64.14 +      <string>LLSD</string>
   64.15 +      <key>Value</key>
   64.16 +    </map>
   64.17      <key>LSLFindCaseInsensitivity</key>
   64.18          <map>
   64.19          <key>Comment</key>
   64.20 @@ -5932,6 +5942,17 @@
   64.21        <key>Value</key>
   64.22        <real>1.6</real>
   64.23      </map>
   64.24 +    <key>MaxPersistentNotifications</key>
   64.25 +    <map>
   64.26 +      <key>Comment</key>
   64.27 +      <string>Maximum amount of persistent notifications</string>
   64.28 +      <key>Persist</key>
   64.29 +      <integer>1</integer>
   64.30 +      <key>Type</key>
   64.31 +      <string>S32</string>
   64.32 +      <key>Value</key>
   64.33 +      <real>250</real>
   64.34 +    </map>
   64.35      <key>MaxSelectDistance</key>
   64.36      <map>
   64.37        <key>Comment</key>
   64.38 @@ -9840,7 +9861,7 @@
   64.39      <key>RenderUseVAO</key>
   64.40      <map>
   64.41        <key>Comment</key>
   64.42 -      <string>[EXPERIMENTAL] Use GL Vertex Array Objects</string>
   64.43 +      <string>[EXPERIMENTAL] Use GL Vertex Array Objects.</string>
   64.44        <key>Persist</key>
   64.45        <integer>1</integer>
   64.46        <key>Type</key>
   64.47 @@ -10476,6 +10497,17 @@
   64.48        <key>Value</key>
   64.49        <integer>0</integer>
   64.50      </map>
   64.51 +    <key>ShowEventRecorderMenuItems</key>
   64.52 +    <map>
   64.53 +      <key>Comment</key>
   64.54 +      <string>Whether or not Event Recorder menu choices - Start / Stop event recording should appear in the (currently) Develop menu</string>
   64.55 +      <key>Persist</key>
   64.56 +      <integer>0</integer>
   64.57 +      <key>Type</key>
   64.58 +      <string>Boolean</string>
   64.59 +      <key>Value</key>
   64.60 +      <integer>0</integer>
   64.61 +    </map>
   64.62      <key>ShowGestureButton</key>
   64.63      <map>
   64.64        <key>Comment</key>
   64.65 @@ -13116,6 +13148,17 @@
   64.66        <key>Value</key>
   64.67        <integer>0</integer>
   64.68      </map>
   64.69 +    <key>SocialPhotoResolution</key>
   64.70 +    <map>
   64.71 +      <key>Comment</key>
   64.72 +      <string>Default resolution when sharing photo using the social floater</string>
   64.73 +      <key>Persist</key>
   64.74 +      <integer>1</integer>
   64.75 +      <key>Type</key>
   64.76 +      <string>String</string>
   64.77 +      <key>Value</key>
   64.78 +      <string>[i800,i600]</string>
   64.79 +    </map>  
   64.80      <key>sourceid</key>
   64.81      <map>
   64.82        <key>Comment</key>
   64.83 @@ -13334,7 +13377,7 @@
   64.84        <key>Type</key>
   64.85        <string>String</string>
   64.86        <key>Value</key>
   64.87 -      <string>-1</string>
   64.88 +      <string>0</string>
   64.89      </map>
   64.90      <key>VivoxDebugSIPURIHostName</key>
   64.91      <map>
    65.1 --- a/indra/newview/app_settings/settings_per_account.xml	Thu Oct 17 18:26:04 2013 -0400
    65.2 +++ b/indra/newview/app_settings/settings_per_account.xml	Tue Nov 12 14:06:38 2013 -0500
    65.3 @@ -77,6 +77,17 @@
    65.4          <key>Value</key>
    65.5              <integer>412</integer>
    65.6      </map>
    65.7 +    <key>ConversationsParticipantListCollapsed</key>
    65.8 +    <map>
    65.9 +        <key>Comment</key>
   65.10 +            <string>Stores the expanded/collapsed state of Nearby chat participant list</string>
   65.11 +        <key>Persist</key>
   65.12 +            <integer>1</integer>
   65.13 +        <key>Type</key>
   65.14 +            <string>Boolean</string>
   65.15 +        <key>Value</key>
   65.16 +            <integer>true</integer>
   65.17 +    </map>   
   65.18      <key>InstantMessageLogPath</key>
   65.19          <map>
   65.20          <key>Comment</key>
    66.1 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl	Thu Oct 17 18:26:04 2013 -0400
    66.2 +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl	Tue Nov 12 14:06:38 2013 -0500
    66.3 @@ -33,8 +33,8 @@
    66.4  	mat4 ret;
    66.5  	int i = int(floor(weight.x));
    66.6  	float x = fract(weight.x);
    66.7 -		
    66.8 -	ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1], x);
    66.9 +	
   66.10 +	ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1],  x);
   66.11  	ret[1] = mix(matrixPalette[i+15],matrixPalette[i+16], x);
   66.12  	ret[2] = mix(matrixPalette[i+30],matrixPalette[i+31], x);
   66.13  	ret[3] = vec4(0,0,0,1);
    67.1 --- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl	Thu Oct 17 18:26:04 2013 -0400
    67.2 +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl	Tue Nov 12 14:06:38 2013 -0500
    67.3 @@ -34,14 +34,17 @@
    67.4  	
    67.5  	vec4 w = fract(weight4);
    67.6  	vec4 index = floor(weight4);
    67.7 -	
    67.8 +
    67.9 +		 index = min(index, vec4(31.0));
   67.10 +		 index = max(index, vec4( 0.0));
   67.11 +
   67.12  	float scale = 1.0/(w.x+w.y+w.z+w.w);
   67.13  	w *= scale;
   67.14 -	
   67.15 -	mat4 mat = matrixPalette[int(index.x)]*w.x;
   67.16 -	mat += matrixPalette[int(index.y)]*w.y;
   67.17 -	mat += matrixPalette[int(index.z)]*w.z;
   67.18 -	mat += matrixPalette[int(index.w)]*w.w;
   67.19 +
   67.20 +	mat4 mat  = matrixPalette[int(index.x)]*w.x;
   67.21 +		 mat += matrixPalette[int(index.y)]*w.y;
   67.22 +		 mat += matrixPalette[int(index.z)]*w.z;
   67.23 +		 mat += matrixPalette[int(index.w)]*w.w;
   67.24  		
   67.25  	return mat;
   67.26  }
    68.1 --- a/indra/newview/app_settings/toolbars.xml	Thu Oct 17 18:26:04 2013 -0400
    68.2 +++ b/indra/newview/app_settings/toolbars.xml	Tue Nov 12 14:06:38 2013 -0500
    68.3 @@ -6,6 +6,7 @@
    68.4      <command name="speak"/>
    68.5      <command name="destinations"/>
    68.6      <command name="people"/>
    68.7 +    <command name="social"/>
    68.8      <command name="profile"/>
    68.9      <command name="move"/>
   68.10      <command name="view"/>
    69.1 --- a/indra/newview/llagent.cpp	Thu Oct 17 18:26:04 2013 -0400
    69.2 +++ b/indra/newview/llagent.cpp	Tue Nov 12 14:06:38 2013 -0500
    69.3 @@ -1092,11 +1092,19 @@
    69.4  //-----------------------------------------------------------------------------
    69.5  const LLVector3 &LLAgent::getPositionAgent()
    69.6  {
    69.7 -	if (isAgentAvatarValid() && !gAgentAvatarp->mDrawable.isNull())
    69.8 +	if (isAgentAvatarValid())
    69.9  	{
   69.10 -		mFrameAgent.setOrigin(gAgentAvatarp->getRenderPosition());	
   69.11 +		if(gAgentAvatarp->mDrawable.isNull())
   69.12 +		{
   69.13 +			mFrameAgent.setOrigin(gAgentAvatarp->getPositionAgent());
   69.14 +		}
   69.15 +		else
   69.16 +		{
   69.17 +			mFrameAgent.setOrigin(gAgentAvatarp->getRenderPosition());
   69.18 +		}
   69.19  	}
   69.20  
   69.21 +
   69.22  	return mFrameAgent.getOrigin();
   69.23  }
   69.24  
    70.1 --- a/indra/newview/llagentui.cpp	Thu Oct 17 18:26:04 2013 -0400
    70.2 +++ b/indra/newview/llagentui.cpp	Tue Nov 12 14:06:38 2013 -0500
    70.3 @@ -112,6 +112,11 @@
    70.4  		case LOCATION_FORMAT_NORMAL:
    70.5  			buffer = llformat("%s", region_name.c_str());
    70.6  			break;
    70.7 +		case LOCATION_FORMAT_NORMAL_COORDS:
    70.8 +			buffer = llformat("%s (%d, %d, %d)",
    70.9 +				region_name.c_str(),
   70.10 +				pos_x, pos_y, pos_z);
   70.11 +			break;
   70.12  		case LOCATION_FORMAT_NO_COORDS:
   70.13  			buffer = llformat("%s%s%s",
   70.14  				region_name.c_str(),
   70.15 @@ -143,6 +148,11 @@
   70.16  		case LOCATION_FORMAT_NORMAL:
   70.17  			buffer = llformat("%s, %s", parcel_name.c_str(), region_name.c_str());
   70.18  			break;
   70.19 +		case LOCATION_FORMAT_NORMAL_COORDS:
   70.20 +			buffer = llformat("%s (%d, %d, %d)",
   70.21 +				parcel_name.c_str(),
   70.22 +				pos_x, pos_y, pos_z);
   70.23 +			break;
   70.24  		case LOCATION_FORMAT_NO_MATURITY:
   70.25  			buffer = llformat("%s, %s (%d, %d, %d)",
   70.26  				parcel_name.c_str(),
    71.1 --- a/indra/newview/llagentui.h	Thu Oct 17 18:26:04 2013 -0400
    71.2 +++ b/indra/newview/llagentui.h	Tue Nov 12 14:06:38 2013 -0500
    71.3 @@ -35,6 +35,7 @@
    71.4  	enum ELocationFormat
    71.5  	{
    71.6  		LOCATION_FORMAT_NORMAL,			// Parcel
    71.7 +		LOCATION_FORMAT_NORMAL_COORDS,	// Parcel (x, y, z)
    71.8  		LOCATION_FORMAT_LANDMARK,		// Parcel, Region
    71.9  		LOCATION_FORMAT_NO_MATURITY,	// Parcel, Region (x, y, z)
   71.10  		LOCATION_FORMAT_NO_COORDS,		// Parcel, Region - Maturity
    72.1 --- a/indra/newview/llagentwearables.cpp	Thu Oct 17 18:26:04 2013 -0400
    72.2 +++ b/indra/newview/llagentwearables.cpp	Tue Nov 12 14:06:38 2013 -0500
    72.3 @@ -1538,7 +1538,11 @@
    72.4  	std::set<LLUUID> requested_item_ids;
    72.5  	std::set<LLUUID> current_item_ids;
    72.6  	for (S32 i=0; i<obj_item_array.count(); i++)
    72.7 -		requested_item_ids.insert(obj_item_array[i].get()->getLinkedUUID());
    72.8 +	{
    72.9 +		const LLUUID & requested_id = obj_item_array[i].get()->getLinkedUUID();
   72.10 +		//llinfos << "Requested attachment id " << requested_id << llendl;
   72.11 +		requested_item_ids.insert(requested_id);
   72.12 +	}
   72.13  
   72.14  	// Build up list of objects to be removed and items currently attached.
   72.15  	llvo_vec_t objects_to_remove;
   72.16 @@ -1555,16 +1559,27 @@
   72.17  			if (objectp)
   72.18  			{
   72.19  				LLUUID object_item_id = objectp->getAttachmentItemID();
   72.20 +
   72.21 +				bool remove_attachment = true;
   72.22  				if (requested_item_ids.find(object_item_id) != requested_item_ids.end())
   72.23 +				{	// Object currently worn, was requested to keep it
   72.24 +					// Flag as currently worn so we won't have to add it again.
   72.25 +					remove_attachment = false;
   72.26 +				}
   72.27 +				else if (objectp->isTempAttachment())
   72.28 +				{	// Check if we should keep this temp attachment
   72.29 +					remove_attachment = LLAppearanceMgr::instance().shouldRemoveTempAttachment(objectp->getID());
   72.30 +				}
   72.31 +
   72.32 +				if (remove_attachment)
   72.33  				{
   72.34 -					// Object currently worn, was requested.
   72.35 -					// Flag as currently worn so we won't have to add it again.
   72.36 -					current_item_ids.insert(object_item_id);
   72.37 +					// llinfos << "found object to remove, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << llendl;
   72.38 +					objects_to_remove.push_back(objectp);
   72.39  				}
   72.40  				else
   72.41  				{
   72.42 -					// object currently worn, not requested.
   72.43 -					objects_to_remove.push_back(objectp);
   72.44 +					// llinfos << "found object to keep, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << llendl;
   72.45 +					current_item_ids.insert(object_item_id);
   72.46  				}
   72.47  			}
   72.48  		}
    73.1 --- a/indra/newview/llappearancemgr.cpp	Thu Oct 17 18:26:04 2013 -0400
    73.2 +++ b/indra/newview/llappearancemgr.cpp	Tue Nov 12 14:06:38 2013 -0500
    73.3 @@ -3415,21 +3415,50 @@
    73.4  		llwarns << "called with empty list, nothing to do" << llendl;
    73.5  	}
    73.6  	for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
    73.7 -			{
    73.8 +	{
    73.9  		const LLUUID& id_to_remove = *it;
   73.10  		const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove);
   73.11  		removeCOFItemLinks(linked_item_id);
   73.12 -			}
   73.13 +		addDoomedTempAttachment(linked_item_id);
   73.14 +	}
   73.15  	updateAppearanceFromCOF();
   73.16 -	}
   73.17 +}
   73.18  
   73.19  void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
   73.20  {
   73.21  	LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove);
   73.22  	removeCOFItemLinks(linked_item_id);
   73.23 +	addDoomedTempAttachment(linked_item_id);
   73.24  	updateAppearanceFromCOF();
   73.25  }
   73.26  
   73.27 +
   73.28 +// Adds the given item ID to mDoomedTempAttachmentIDs iff it's a temp attachment
   73.29 +void LLAppearanceMgr::addDoomedTempAttachment(const LLUUID& id_to_remove)
   73.30 +{
   73.31 +	LLViewerObject * attachmentp = gAgentAvatarp->findAttachmentByID(id_to_remove);
   73.32 +	if (attachmentp &&
   73.33 +		attachmentp->isTempAttachment())
   73.34 +	{	// If this is a temp attachment and we want to remove it, record the ID 
   73.35 +		// so it will be deleted when attachments are synced up with COF
   73.36 +		mDoomedTempAttachmentIDs.insert(id_to_remove);
   73.37 +		//llinfos << "Will remove temp attachment id " << id_to_remove << llendl;
   73.38 +	}
   73.39 +}
   73.40 +
   73.41 +// Find AND REMOVES the given UUID from mDoomedTempAttachmentIDs
   73.42 +bool LLAppearanceMgr::shouldRemoveTempAttachment(const LLUUID& item_id)
   73.43 +{
   73.44 +	doomed_temp_attachments_t::iterator iter = mDoomedTempAttachmentIDs.find(item_id);
   73.45 +	if (iter != mDoomedTempAttachmentIDs.end())
   73.46 +	{
   73.47 +		mDoomedTempAttachmentIDs.erase(iter);
   73.48 +		return true;
   73.49 +	}
   73.50 +	return false;
   73.51 +}
   73.52 +
   73.53 +
   73.54  bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body)
   73.55  {
   73.56  	if (!item || !item->isWearableType()) return false;
    74.1 --- a/indra/newview/llappearancemgr.h	Thu Oct 17 18:26:04 2013 -0400
    74.2 +++ b/indra/newview/llappearancemgr.h	Tue Nov 12 14:06:38 2013 -0500
    74.3 @@ -142,6 +142,9 @@
    74.4  	void removeAllClothesFromAvatar();
    74.5  	void removeAllAttachmentsFromAvatar();
    74.6  
    74.7 +	// Special handling of temp attachments, which are not in the COF
    74.8 +	bool shouldRemoveTempAttachment(const LLUUID& item_id);
    74.9 +
   74.10  	//has the current outfit changed since it was loaded?
   74.11  	bool isOutfitDirty() { return mOutfitIsDirty; }
   74.12  
   74.13 @@ -239,6 +242,12 @@
   74.14  
   74.15  	std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
   74.16  
   74.17 +	// Set of temp attachment UUIDs that should be removed
   74.18 +	typedef std::set<LLUUID> doomed_temp_attachments_t;
   74.19 +	doomed_temp_attachments_t	mDoomedTempAttachmentIDs;
   74.20 +
   74.21 +	void addDoomedTempAttachment(const LLUUID& id_to_remove);
   74.22 +
   74.23  	//////////////////////////////////////////////////////////////////////////////////
   74.24  	// Item-specific convenience functions 
   74.25  public:
    75.1 --- a/indra/newview/llappviewer.cpp	Thu Oct 17 18:26:04 2013 -0400
    75.2 +++ b/indra/newview/llappviewer.cpp	Tue Nov 12 14:06:38 2013 -0500
    75.3 @@ -223,6 +223,10 @@
    75.4  #include "llmachineid.h"
    75.5  #include "llmainlooprepeater.h"
    75.6  
    75.7 +
    75.8 +#include "llviewereventrecorder.h"
    75.9 +
   75.10 +
   75.11  // *FIX: These extern globals should be cleaned up.
   75.12  // The globals either represent state/config/resource-storage of either 
   75.13  // this app, or another 'component' of the viewer. App globals should be 
   75.14 @@ -696,6 +700,7 @@
   75.15  LLAppViewer::~LLAppViewer()
   75.16  {
   75.17  	delete mSettingsLocationList;
   75.18 +	LLViewerEventRecorder::instance().~LLViewerEventRecorder();
   75.19  
   75.20  	LLLoginInstance::instance().setUpdaterService(0);
   75.21  	
   75.22 @@ -2250,13 +2255,13 @@
   75.23  
   75.24  		BOOST_FOREACH(const SettingsFile& file, group.files)
   75.25  		{
   75.26 -			llinfos << "Attempting to load settings for the group " << file.name()
   75.27 -			    << " - from location " << location_key << llendl;
   75.28 +			LL_INFOS("Settings") << "Attempting to load settings for the group " << file.name()
   75.29 +			    << " - from location " << location_key << LL_ENDL;
   75.30  
   75.31  			LLControlGroup* settings_group = LLControlGroup::getInstance(file.name);
   75.32  			if(!settings_group)
   75.33  			{
   75.34 -				llwarns << "No matching settings group for name " << file.name() << llendl;
   75.35 +				LL_WARNS("Settings") << "No matching settings group for name " << file.name() << LL_ENDL;
   75.36  				continue;
   75.37  			}
   75.38  
   75.39 @@ -2285,7 +2290,7 @@
   75.40  
   75.41  			if(settings_group->loadFromFile(full_settings_path, set_defaults, file.persistent))
   75.42  			{	// success!
   75.43 -				llinfos << "Loaded settings file " << full_settings_path << llendl;
   75.44 +				LL_INFOS("Settings") << "Loaded settings file " << full_settings_path << LL_ENDL;
   75.45  			}
   75.46  			else
   75.47  			{	// failed to load
   75.48 @@ -2299,7 +2304,7 @@
   75.49  					// only complain if we actually have a filename at this point
   75.50  					if (!full_settings_path.empty())
   75.51  					{
   75.52 -						llinfos << "Cannot load " << full_settings_path << " - No settings found." << llendl;
   75.53 +						LL_INFOS("Settings") << "Cannot load " << full_settings_path << " - No settings found." << LL_ENDL;
   75.54  					}
   75.55  				}
   75.56  			}
   75.57 @@ -2395,8 +2400,6 @@
   75.58  	gSavedSettings.setString("ClientSettingsFile", 
   75.59          gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Global")));
   75.60  
   75.61 -	gSavedSettings.setString("VersionChannelName", LLVersionInfo::getChannel());
   75.62 -
   75.63  #ifndef	LL_RELEASE_FOR_DOWNLOAD
   75.64  	// provide developer build only overrides for these control variables that are not
   75.65  	// persisted to settings.xml
   75.66 @@ -2460,8 +2463,8 @@
   75.67  			gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, 
   75.68  										   clp.getOption("settings")[0]);		
   75.69  		gSavedSettings.setString("ClientSettingsFile", user_settings_filename);
   75.70 -		llinfos	<< "Using command line specified settings filename: " 
   75.71 -			<< user_settings_filename << llendl;
   75.72 +		LL_INFOS("Settings")	<< "Using command line specified settings filename: " 
   75.73 +			<< user_settings_filename << LL_ENDL;
   75.74  	}
   75.75  
   75.76  	// - load overrides from user_settings 
   75.77 @@ -2477,8 +2480,8 @@
   75.78  	{
   75.79  		std::string session_settings_filename = clp.getOption("sessionsettings")[0];		
   75.80  		gSavedSettings.setString("SessionSettingsFile", session_settings_filename);
   75.81 -		llinfos	<< "Using session settings filename: " 
   75.82 -			<< session_settings_filename << llendl;
   75.83 +		LL_INFOS("Settings")	<< "Using session settings filename: " 
   75.84 +			<< session_settings_filename << LL_ENDL;
   75.85  	}
   75.86  	loadSettingsFromDirectory("Session");
   75.87  
   75.88 @@ -2486,8 +2489,8 @@
   75.89  	{
   75.90  		std::string user_session_settings_filename = clp.getOption("usersessionsettings")[0];		
   75.91  		gSavedSettings.setString("UserSessionSettingsFile", user_session_settings_filename);
   75.92 -		llinfos	<< "Using user session settings filename: " 
   75.93 -			<< user_session_settings_filename << llendl;
   75.94 +		LL_INFOS("Settings") << "Using user session settings filename: " 
   75.95 +			<< user_session_settings_filename << LL_ENDL;
   75.96  
   75.97  	}
   75.98  	loadSettingsFromDirectory("UserSession");
   75.99 @@ -2575,9 +2578,13 @@
  75.100          }
  75.101      }
  75.102  
  75.103 +    if  (clp.hasOption("logevents")) {
  75.104 +	LLViewerEventRecorder::instance().setEventLoggingOn();
  75.105 +    }
  75.106 +
  75.107  	std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel"));
  75.108  	if(! CmdLineChannel.empty())
  75.109 -	{
  75.110 +    {
  75.111  		LLVersionInfo::resetChannel(CmdLineChannel);
  75.112  	}
  75.113  
  75.114 @@ -2589,16 +2596,16 @@
  75.115  		LLFastTimer::sLog = TRUE;
  75.116  		LLFastTimer::sLogName = std::string("performance");		
  75.117  	}
  75.118 -
  75.119 +	
  75.120  	std::string test_name(gSavedSettings.getString("LogMetrics"));
  75.121  	if (! test_name.empty())
  75.122 -	{
  75.123 -		LLFastTimer::sMetricLog = TRUE ;
  75.124 + 	{
  75.125 + 		LLFastTimer::sMetricLog = TRUE ;
  75.126  		// '--logmetrics' is specified with a named test metric argument so the data gathering is done only on that test
  75.127  		// In the absence of argument, every metric would be gathered (makes for a rather slow run and hard to decipher report...)
  75.128  		llinfos << "'--logmetrics' argument : " << test_name << llendl;
  75.129 -		LLFastTimer::sLogName = test_name;
  75.130 - 	}
  75.131 +			LLFastTimer::sLogName = test_name;
  75.132 +		}
  75.133  
  75.134  	if (clp.hasOption("graphicslevel"))
  75.135  	{
  75.136 @@ -2607,14 +2614,14 @@
  75.137  		// that value for validity.
  75.138  		U32 graphicslevel = gSavedSettings.getU32("RenderQualityPerformance");
  75.139  		if (LLFeatureManager::instance().isValidGraphicsLevel(graphicslevel))
  75.140 -		{
  75.141 +        {
  75.142  			// graphicslevel is valid: save it and engage it later. Capture
  75.143  			// the requested value separately from the settings variable
  75.144  			// because, if this is the first run, LLViewerWindow's constructor
  75.145  			// will call LLFeatureManager::applyRecommendedSettings(), which
  75.146  			// overwrites this settings variable!
  75.147  			mForceGraphicsLevel = graphicslevel;
  75.148 -		}
  75.149 +        }
  75.150  	}
  75.151  
  75.152  	LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance");
  75.153 @@ -2645,16 +2652,32 @@
  75.154      // What can happen is that someone can use IE (or potentially 
  75.155      // other browsers) and do the rough equivalent of command 
  75.156      // injection and steal passwords. Phoenix. SL-55321
  75.157 +	LLSLURL start_slurl;
  75.158  	std::string CmdLineLoginLocation(gSavedSettings.getString("CmdLineLoginLocation"));
  75.159  	if(! CmdLineLoginLocation.empty())
  75.160 -	{
  75.161 -		LLSLURL start_slurl(CmdLineLoginLocation);
  75.162 +    {
  75.163 +		start_slurl = CmdLineLoginLocation;
  75.164  		LLStartUp::setStartSLURL(start_slurl);
  75.165  		if(start_slurl.getType() == LLSLURL::LOCATION) 
  75.166  		{  
  75.167  			LLGridManager::getInstance()->setGridChoice(start_slurl.getGrid());
  75.168 +    }
  75.169 +    }
  75.170 +
  75.171 +	//RN: if we received a URL, hand it off to the existing instance.
  75.172 +	// don't call anotherInstanceRunning() when doing URL handoff, as
  75.173 +	// it relies on checking a marker file which will not work when running
  75.174 +	// out of different directories
  75.175 +
  75.176 +	if (start_slurl.isValid() &&
  75.177 +		(gSavedSettings.getBOOL("SLURLPassToOtherInstance")))
  75.178 +	{
  75.179 +		if (sendURLToOtherInstance(start_slurl.getSLURLString()))
  75.180 +		{
  75.181 +			// successfully handed off URL to existing instance, exit
  75.182 +			return false;
  75.183  		}
  75.184 -	}
  75.185 +    }
  75.186  
  75.187  	const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
  75.188  	if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
  75.189 @@ -2795,7 +2818,7 @@
  75.190  		LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL;
  75.191  		LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
  75.192  	}
  75.193 -	else if ((clp.hasOption("login") || clp.hasOption("autologin"))
  75.194 +	else if (   (   clp.hasOption("login") || clp.hasOption("autologin"))
  75.195  			 && gSavedSettings.getString("CmdLineLoginLocation").empty())
  75.196  	{
  75.197  		// If automatic login from command line with --login switch
  75.198 @@ -3179,7 +3202,7 @@
  75.199  		LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false);
  75.200  		gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel);
  75.201  	}
  75.202 -
  75.203 +			
  75.204  	// Set this flag in case we crash while initializing GL
  75.205  	gSavedSettings.setBOOL("RenderInitError", TRUE);
  75.206  	gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
    76.1 --- a/indra/newview/llappviewerwin32.cpp	Thu Oct 17 18:26:04 2013 -0400
    76.2 +++ b/indra/newview/llappviewerwin32.cpp	Tue Nov 12 14:06:38 2013 -0500
    76.3 @@ -172,21 +172,20 @@
    76.4  			nvapi_error(status);
    76.5  			return;
    76.6  		}
    76.7 +
    76.8 +        // (5) Now we apply (or save) our changes to the system
    76.9 +        status = NvAPI_DRS_SaveSettings(hSession);
   76.10 +        if (status != NVAPI_OK) 
   76.11 +        {
   76.12 +            nvapi_error(status);
   76.13 +            return;
   76.14 +        }
   76.15  	}
   76.16  	else if (status != NVAPI_OK)
   76.17  	{
   76.18  		nvapi_error(status);
   76.19  		return;
   76.20  	}
   76.21 -
   76.22 -	
   76.23 -
   76.24 -	// (5) Now we apply (or save) our changes to the system
   76.25 -	status = NvAPI_DRS_SaveSettings(hSession);
   76.26 -	if (status != NVAPI_OK) 
   76.27 -	{
   76.28 -		nvapi_error(status);
   76.29 -	}
   76.30  }
   76.31  
   76.32  //#define DEBUGGING_SEH_FILTER 1
    77.1 --- a/indra/newview/llautoreplace.cpp	Thu Oct 17 18:26:04 2013 -0400
    77.2 +++ b/indra/newview/llautoreplace.cpp	Tue Nov 12 14:06:38 2013 -0500
    77.3 @@ -39,7 +39,7 @@
    77.4  	replacement_length = 0;
    77.5  	replacement_string.clear();
    77.6  
    77.7 -	static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace");
    77.8 +	static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace", 0);
    77.9  	if (perform_autoreplace)
   77.10  	{
   77.11  		S32 word_end = cursor_pos - 1;
   77.12 @@ -679,7 +679,7 @@
   77.13  std::string LLAutoReplaceSettings::replaceWord(const std::string currentWord)
   77.14  {
   77.15  	std::string returnedWord = currentWord; // in case no replacement is found
   77.16 -	static LLCachedControl<bool> autoreplace_enabled(gSavedSettings, "AutoReplace");
   77.17 +	static LLCachedControl<bool> autoreplace_enabled(gSavedSettings, "AutoReplace", false);
   77.18  	if ( autoreplace_enabled )
   77.19  	{
   77.20  		LL_DEBUGS("AutoReplace")<<"checking '"<<currentWord<<"'"<< LL_ENDL;
    78.1 --- a/indra/newview/llavataractions.cpp	Thu Oct 17 18:26:04 2013 -0400
    78.2 +++ b/indra/newview/llavataractions.cpp	Tue Nov 12 14:06:38 2013 -0500
    78.3 @@ -73,6 +73,8 @@
    78.4  #include "llcallingcard.h"
    78.5  #include "llslurl.h"			// IDEVO
    78.6  #include "llsidepanelinventory.h"
    78.7 +#include "llavatarname.h"
    78.8 +#include "llagentui.h"
    78.9  
   78.10  // static
   78.11  void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
   78.12 @@ -391,6 +393,72 @@
   78.13  	}
   78.14  }
   78.15  
   78.16 +void LLAvatarActions::teleport_request_callback(const LLSD& notification, const LLSD& response)
   78.17 +{
   78.18 +	S32 option;
   78.19 +	if (response.isInteger()) 
   78.20 +	{
   78.21 +		option = response.asInteger();
   78.22 +	}
   78.23 +	else
   78.24 +	{
   78.25 +		option = LLNotificationsUtil::getSelectedOption(notification, response);
   78.26 +	}
   78.27 +
   78.28 +	if (0 == option)
   78.29 +	{
   78.30 +		LLMessageSystem* msg = gMessageSystem;
   78.31 +
   78.32 +		msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
   78.33 +		msg->nextBlockFast(_PREHASH_AgentData);
   78.34 +		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
   78.35 +		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
   78.36 +
   78.37 +		msg->nextBlockFast(_PREHASH_MessageBlock);
   78.38 +		msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
   78.39 +		msg->addUUIDFast(_PREHASH_ToAgentID, notification["substitutions"]["uuid"] );
   78.40 +		msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
   78.41 +		msg->addU8Fast(_PREHASH_Dialog, IM_TELEPORT_REQUEST);
   78.42 +		msg->addUUIDFast(_PREHASH_ID, LLUUID::null);
   78.43 +		msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
   78.44 +
   78.45 +		std::string name;
   78.46 +		LLAgentUI::buildFullname(name);
   78.47 +
   78.48 +		msg->addStringFast(_PREHASH_FromAgentName, name);
   78.49 +		msg->addStringFast(_PREHASH_Message, response["message"]);
   78.50 +		msg->addU32Fast(_PREHASH_ParentEstateID, 0);
   78.51 +		msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
   78.52 +		msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
   78.53 +
   78.54 +		gMessageSystem->addBinaryDataFast(
   78.55 +				_PREHASH_BinaryBucket,
   78.56 +				EMPTY_BINARY_BUCKET,
   78.57 +				EMPTY_BINARY_BUCKET_SIZE);
   78.58 +
   78.59 +		gAgent.sendReliableMessage();
   78.60 +	}
   78.61 +}
   78.62 +
   78.63 +// static
   78.64 +void LLAvatarActions::teleportRequest(const LLUUID& id)
   78.65 +{
   78.66 +	LLSD notification;
   78.67 +	notification["uuid"] = id;
   78.68 +	LLAvatarName av_name;
   78.69 +	if (!LLAvatarNameCache::get(id, &av_name))
   78.70 +	{
   78.71 +		// unlikely ... they just picked this name from somewhere...
   78.72 +		LLAvatarNameCache::get(id, boost::bind(&LLAvatarActions::teleportRequest, id));
   78.73 +		return; // reinvoke this when the name resolves
   78.74 +	}
   78.75 +	notification["NAME"] = av_name.getCompleteName();
   78.76 +
   78.77 +	LLSD payload;
   78.78 +
   78.79 +	LLNotificationsUtil::add("TeleportRequestPrompt", notification, payload, teleport_request_callback);
   78.80 +}
   78.81 +
   78.82  // static
   78.83  void LLAvatarActions::kick(const LLUUID& id)
   78.84  {
    79.1 --- a/indra/newview/llavataractions.h	Thu Oct 17 18:26:04 2013 -0400
    79.2 +++ b/indra/newview/llavataractions.h	Tue Nov 12 14:06:38 2013 -0500
    79.3 @@ -111,6 +111,12 @@
    79.4  	static void pay(const LLUUID& id);
    79.5  
    79.6  	/**
    79.7 +	 * Request teleport from other avatar
    79.8 +	 */
    79.9 +	static void teleportRequest(const LLUUID& id);
   79.10 +	static void teleport_request_callback(const LLSD& notification, const LLSD& response);
   79.11 +
   79.12 +	/**
   79.13  	 * Share items with the avatar.
   79.14  	 */
   79.15  	static void share(const LLUUID& id);
    80.1 --- a/indra/newview/llavatarrenderinfoaccountant.cpp	Thu Oct 17 18:26:04 2013 -0400
    80.2 +++ b/indra/newview/llavatarrenderinfoaccountant.cpp	Tue Nov 12 14:06:38 2013 -0500
    80.3 @@ -336,7 +336,7 @@
    80.4  		sRenderInfoReportTimer.resetWithExpiry(SECS_BETWEEN_REGION_SCANS);
    80.5  	}
    80.6  
    80.7 -	static LLCachedControl<U32> render_auto_mute_functions(gSavedSettings, "RenderAutoMuteFunctions");
    80.8 +	static LLCachedControl<U32> render_auto_mute_functions(gSavedSettings, "RenderAutoMuteFunctions", 0);
    80.9  	static U32 prev_render_auto_mute_functions = (U32) -1;
   80.10  	if (prev_render_auto_mute_functions != render_auto_mute_functions)
   80.11  	{
    81.1 --- a/indra/newview/llblocklist.cpp	Thu Oct 17 18:26:04 2013 -0400
    81.2 +++ b/indra/newview/llblocklist.cpp	Tue Nov 12 14:06:38 2013 -0500
    81.3 @@ -41,10 +41,14 @@
    81.4  LLBlockList::LLBlockList(const Params& p)
    81.5  :	LLFlatListViewEx(p),
    81.6   	mSelectedItem(NULL),
    81.7 - 	mDirty(true)
    81.8 + 	mDirty(true),
    81.9 +	mShouldAddAll(true),
   81.10 +	mActionType(NONE),
   81.11 +	mMuteListSize(0)
   81.12  {
   81.13  
   81.14  	LLMuteList::getInstance()->addObserver(this);
   81.15 +	mMuteListSize = LLMuteList::getInstance()->getMutes().size();
   81.16  
   81.17  	// Set up context menu.
   81.18  	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
   81.19 @@ -73,6 +77,41 @@
   81.20  	LLMuteList::getInstance()->removeObserver(this);
   81.21  }
   81.22  
   81.23 +void LLBlockList::createList()
   81.24 +{
   81.25 +	std::vector<LLMute> mutes = LLMuteList::instance().getMutes();
   81.26 +	std::vector<LLMute>::const_iterator mute_it = mutes.begin();
   81.27 +
   81.28 +	for (; mute_it != mutes.end(); ++mute_it)
   81.29 +	{
   81.30 +		addNewItem(&*mute_it);
   81.31 +	}
   81.32 +}
   81.33 +
   81.34 +BlockListActionType LLBlockList::getCurrentMuteListActionType()
   81.35 +{
   81.36 +	BlockListActionType type = NONE;
   81.37 +	U32 curSize = LLMuteList::getInstance()->getMutes().size();
   81.38 +	if( curSize > mMuteListSize)
   81.39 +		type = ADD;
   81.40 +	else if(curSize < mMuteListSize)
   81.41 +		type = REMOVE;
   81.42 +
   81.43 +	return type;
   81.44 +}
   81.45 +
   81.46 +void LLBlockList::onChangeDetailed(const LLMute &mute)
   81.47 +{
   81.48 +	mActionType = getCurrentMuteListActionType();
   81.49 +
   81.50 +	mCurItemId = mute.mID;
   81.51 +	mCurItemName = mute.mName;
   81.52 +	mCurItemType = mute.mType;
   81.53 +	mCurItemFlags = mute.mFlags;
   81.54 +
   81.55 +	refresh();
   81.56 +}
   81.57 +
   81.58  BOOL LLBlockList::handleRightMouseDown(S32 x, S32 y, MASK mask)
   81.59  {
   81.60  	BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
   81.61 @@ -88,6 +127,16 @@
   81.62  	return handled;
   81.63  }
   81.64  
   81.65 +void LLBlockList::removeListItem(const LLMute* mute)
   81.66 +{
   81.67 +	removeItemByUUID(mute->mID);
   81.68 +}
   81.69 +
   81.70 +void LLBlockList::hideListItem(LLBlockedListItem* item, bool show)
   81.71 +{
   81.72 +	item->setVisible(show);
   81.73 +}
   81.74 +
   81.75  void LLBlockList::setNameFilter(const std::string& filter)
   81.76  {
   81.77  	std::string filter_upper = filter;
   81.78 @@ -136,28 +185,56 @@
   81.79  	bool have_filter = !mNameFilter.empty();
   81.80  
   81.81  	// save selection to restore it after list rebuilt
   81.82 -	LLUUID selected = getSelectedUUID();
   81.83 +	LLUUID selected = getSelectedUUID(), next_selected;
   81.84  
   81.85 -	// calling refresh may be initiated by removing currently selected item
   81.86 -	// so select next item and save the selection to restore it after list rebuilt
   81.87 -	if (!selectNextItemPair(false, true))
   81.88 +	if(mShouldAddAll)	// creating list of blockers
   81.89  	{
   81.90 -		selectNextItemPair(true, true);
   81.91 +		clear();
   81.92 +		createList();
   81.93 +		mShouldAddAll = false;
   81.94  	}
   81.95 -	LLUUID next_selected = getSelectedUUID();
   81.96 +	else
   81.97 +	{
   81.98 +		// handle remove/add functionality
   81.99 +		LLMute mute(mCurItemId, mCurItemName, mCurItemType, mCurItemFlags);
  81.100 +		if(mActionType == ADD)
  81.101 +		{
  81.102 +			addNewItem(&mute);
  81.103 +		}
  81.104 +		else if(mActionType == REMOVE)
  81.105 +		{
  81.106 +			if(selected == mute.mID)
  81.107 +			{
  81.108 +				// we are going to remove currently selected item, so select next item and save the selection to restore it
  81.109 +				if (!selectNextItemPair(false, true))
  81.110 +				{
  81.111 +					selectNextItemPair(true, true);
  81.112 +				}
  81.113 +				next_selected = getSelectedUUID();
  81.114 +			}
  81.115 +			removeListItem(&mute);
  81.116 +		}
  81.117 +		mActionType = NONE;
  81.118 +	}
  81.119  
  81.120 -	clear();
  81.121 +	// handle filter functionality
  81.122 +	if(have_filter || (!have_filter && !mPrevNameFilter.empty()))
  81.123 +	{
  81.124 +		// we should update visibility of our items if previous filter was not empty
  81.125 +		std::vector < LLPanel* > allItems;
  81.126 +		getItems(allItems);
  81.127 +		std::vector < LLPanel* >::iterator it = allItems.begin();
  81.128  
  81.129 -	std::vector<LLMute> mutes = LLMuteList::instance().getMutes();
  81.130 -	std::vector<LLMute>::const_iterator mute_it = mutes.begin();
  81.131 -
  81.132 -	for (; mute_it != mutes.end(); ++mute_it)
  81.133 -	{
  81.134 -		if (have_filter && !findInsensitive(mute_it->mName, mNameFilter))
  81.135 -			continue;
  81.136 -
  81.137 -		addNewItem(&*mute_it);
  81.138 +		for(; it != allItems.end() ; ++it)
  81.139 +		{
  81.140 +			LLBlockedListItem * curItem = dynamic_cast<LLBlockedListItem *> (*it);
  81.141 +			if(curItem)
  81.142 +			{
  81.143 +				hideListItem(curItem, findInsensitive(curItem->getName(), mNameFilter));
  81.144 +			}
  81.145 +		}
  81.146  	}
  81.147 +	mPrevNameFilter = mNameFilter;
  81.148  
  81.149  	if (getItemPair(selected))
  81.150  	{
  81.151 @@ -169,6 +246,7 @@
  81.152  		// previously selected item was removed, so select next item
  81.153  		selectItemPair(getItemPair(next_selected), true);
  81.154  	}
  81.155 +	mMuteListSize = LLMuteList::getInstance()->getMutes().size();
  81.156  
  81.157  	// Sort the list.
  81.158  	sort();
    82.1 --- a/indra/newview/llblocklist.h	Thu Oct 17 18:26:04 2013 -0400
    82.2 +++ b/indra/newview/llblocklist.h	Tue Nov 12 14:06:38 2013 -0500
    82.3 @@ -34,6 +34,8 @@
    82.4  class LLBlockedListItem;
    82.5  class LLMute;
    82.6  
    82.7 +enum BlockListActionType {NONE, ADD, REMOVE};
    82.8 +
    82.9  /**
   82.10   * List of blocked avatars and objects.
   82.11   * This list represents contents of the LLMuteList.
   82.12 @@ -56,7 +58,8 @@
   82.13  	LLToggleableMenu*	getContextMenu() const { return mContextMenu.get(); }
   82.14  	LLBlockedListItem*	getBlockedItem() const;
   82.15  
   82.16 -	virtual void onChange() { refresh(); }
   82.17 +	virtual void onChange() { }
   82.18 +	virtual void onChangeDetailed(const LLMute& );
   82.19  	virtual void draw();
   82.20  
   82.21  	void setNameFilter(const std::string& filter);
   82.22 @@ -67,18 +70,32 @@
   82.23  private:
   82.24  
   82.25  	void addNewItem(const LLMute* mute);
   82.26 +	void removeListItem(const LLMute* mute);
   82.27 +	void hideListItem(LLBlockedListItem* item, bool show);
   82.28  	void setDirty(bool dirty = true) { mDirty = dirty; }
   82.29  	bool findInsensitive(std::string haystack, const std::string& needle_upper);
   82.30  
   82.31  	bool isActionEnabled(const LLSD& userdata);
   82.32  	void onCustomAction (const LLSD& userdata);
   82.33 +	void createList();
   82.34  
   82.35 -
   82.36 +	BlockListActionType getCurrentMuteListActionType();
   82.37 +	
   82.38  	LLHandle<LLToggleableMenu>	mContextMenu;
   82.39  
   82.40  	LLBlockedListItem*			mSelectedItem;
   82.41  	std::string 				mNameFilter;
   82.42  	bool 						mDirty;
   82.43 +	bool						mShouldAddAll;
   82.44 +	BlockListActionType			mActionType;
   82.45 +	U32							mMuteListSize;
   82.46 +
   82.47 +	// This data is used to save information about item that currently changed(added or removed) 
   82.48 +	LLUUID						mCurItemId;
   82.49 +	std::string					mCurItemName;
   82.50 +	LLMute::EType 				mCurItemType;
   82.51 +	U32							mCurItemFlags;
   82.52 +	std::string					mPrevNameFilter;
   82.53  
   82.54  };
   82.55  
    83.1 --- a/indra/newview/llchathistory.cpp	Thu Oct 17 18:26:04 2013 -0400
    83.2 +++ b/indra/newview/llchathistory.cpp	Tue Nov 12 14:06:38 2013 -0500
    83.3 @@ -60,6 +60,8 @@
    83.4  #include "llstring.h"
    83.5  #include "llurlaction.h"
    83.6  #include "llviewercontrol.h"
    83.7 +#include "llviewerobjectlist.h"
    83.8 +#include "llmutelist.h"
    83.9  
   83.10  static LLDefaultChildRegistry::Register<LLChatHistory> r("chat_history");
   83.11  
   83.12 @@ -181,6 +183,18 @@
   83.13  		{
   83.14  			LLAvatarActions::startIM(getAvatarId());
   83.15  		}
   83.16 +		else if (level == "teleport")
   83.17 +		{
   83.18 +			LLAvatarActions::offerTeleport(getAvatarId());
   83.19 +		}
   83.20 +		else if (level == "voice_call")
   83.21 +		{
   83.22 +			LLAvatarActions::startCall(getAvatarId());
   83.23 +		}
   83.24 +		else if (level == "chat_history")
   83.25 +		{
   83.26 +			LLAvatarActions::viewChatHistory(getAvatarId());
   83.27 +		}
   83.28  		else if (level == "add")
   83.29  		{
   83.30  			LLAvatarActions::requestFriendshipDialog(getAvatarId(), mFrom);
   83.31 @@ -189,13 +203,75 @@
   83.32  		{
   83.33  			LLAvatarActions::removeFriendDialog(getAvatarId());
   83.34  		}
   83.35 +		else if (level == "invite_to_group")
   83.36 +		{
   83.37 +			LLAvatarActions::inviteToGroup(getAvatarId());
   83.38 +		}
   83.39 +		else if (level == "zoom_in")
   83.40 +		{
   83.41 +			handle_zoom_to_object(getAvatarId());
   83.42 +		}
   83.43 +		else if (level == "map")
   83.44 +		{
   83.45 +			LLAvatarActions::showOnMap(getAvatarId());
   83.46 +		}
   83.47 +		else if (level == "share")
   83.48 +		{
   83.49 +			LLAvatarActions::share(getAvatarId());
   83.50 +		}
   83.51 +		else if (level == "pay")
   83.52 +		{
   83.53 +			LLAvatarActions::pay(getAvatarId());
   83.54 +		}
   83.55 +		else if(level == "block_unblock")
   83.56 +		{
   83.57 +			mute(getAvatarId(), LLMute::flagVoiceChat);
   83.58 +		}
   83.59 +		else if(level == "mute_unmute")
   83.60 +		{
   83.61 +			mute(getAvatarId(), LLMute::flagTextChat);
   83.62 +		}
   83.63 +	}
   83.64 +
   83.65 +	bool onAvatarIconContextMenuItemChecked(const LLSD& userdata)
   83.66 +	{
   83.67 +		std::string level = userdata.asString();
   83.68 +
   83.69 +		if (level == "is_blocked")
   83.70 +		{
   83.71 +			return LLMuteList::getInstance()->isMuted(getAvatarId(), LLMute::flagVoiceChat);
   83.72 +		}
   83.73 +		if (level == "is_muted")
   83.74 +		{
   83.75 +			return LLMuteList::getInstance()->isMuted(getAvatarId(), LLMute::flagTextChat);
   83.76 +		}
   83.77 +		return false;
   83.78 +	}
   83.79 +
   83.80 +	void mute(const LLUUID& participant_id, U32 flags)
   83.81 +	{
   83.82 +		BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags);
   83.83 +		std::string name;
   83.84 +		gCacheName->getFullName(participant_id, name);
   83.85 +		LLMute mute(participant_id, name, LLMute::AGENT);
   83.86 +
   83.87 +		if (!is_muted)
   83.88 +		{
   83.89 +			LLMuteList::getInstance()->add(mute, flags);
   83.90 +		}
   83.91 +		else
   83.92 +		{
   83.93 +			LLMuteList::getInstance()->remove(mute, flags);
   83.94 +		}
   83.95  	}
   83.96  
   83.97  	BOOL postBuild()
   83.98  	{
   83.99  		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
  83.100 +		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable;
  83.101  
  83.102  		registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2));
  83.103 +		registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2));
  83.104  		registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2));
  83.105  
  83.106  		LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
  83.107 @@ -460,7 +536,7 @@
  83.108  
  83.109  		if(menu)
  83.110  		{
  83.111 -			bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarID) != NULL;
  83.112 +			bool is_friend = LLAvatarActions::isFriend(mAvatarID);
  83.113  			
  83.114  			menu->setItemEnabled("Add Friend", !is_friend);
  83.115  			menu->setItemEnabled("Remove Friend", is_friend);
  83.116 @@ -470,13 +546,34 @@
  83.117  				menu->setItemEnabled("Add Friend", false);
  83.118  				menu->setItemEnabled("Send IM", false);
  83.119  				menu->setItemEnabled("Remove Friend", false);
  83.120 +				menu->setItemEnabled("Offer Teleport",false);
  83.121 +				menu->setItemEnabled("Voice Call", false);
  83.122 +				menu->setItemEnabled("Invite Group", false);
  83.123 +				menu->setItemEnabled("Zoom In", false);
  83.124 +				menu->setItemEnabled("Share", false);
  83.125 +				menu->setItemEnabled("Pay", false);
  83.126 +				menu->setItemEnabled("Block Unblock", false);
  83.127 +				menu->setItemEnabled("Mute Text", false);
  83.128 +			}
  83.129 +			else
  83.130 +			{
  83.131 +				LLUUID currentSessionID = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, mAvatarID);
  83.132 +				if (mSessionID == currentSessionID)
  83.133 +				{
  83.134 +					menu->setItemVisible("Send IM", false);
  83.135 +				}
  83.136 +				menu->setItemEnabled("Offer Teleport", LLAvatarActions::canOfferTeleport(mAvatarID));
  83.137 +				menu->setItemEnabled("Voice Call", LLAvatarActions::canCall());
  83.138 +
  83.139 +				// We should only show 'Zoom in' item in a nearby chat
  83.140 +				bool should_show_zoom = !LLIMModel::getInstance()->findIMSession(currentSessionID);
  83.141 +				menu->setItemVisible("Zoom In", should_show_zoom && gObjectList.findObject(mAvatarID));	
  83.142 +				menu->setItemEnabled("Block Unblock", LLAvatarActions::canBlock(mAvatarID));
  83.143 +				menu->setItemEnabled("Mute Text", LLAvatarActions::canBlock(mAvatarID));
  83.144  			}
  83.145  
  83.146 -			if (mSessionID == LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, mAvatarID))
  83.147 -			{
  83.148 -				menu->setItemVisible("Send IM", false);
  83.149 -			}
  83.150 -
  83.151 +			menu->setItemEnabled("Chat History", LLLogChat::isTranscriptExist(mAvatarID));
  83.152 +			menu->setItemEnabled("Map", (LLAvatarTracker::instance().isBuddyOnline(mAvatarID) && is_agent_mappable(mAvatarID)) || gAgent.isGodlike() );
  83.153  			menu->buildDrawLabels();
  83.154  			menu->updateParent(LLMenuGL::sMenuContainer);
  83.155  			LLMenuGL::showPopup(this, menu, x, y);
  83.156 @@ -968,25 +1065,42 @@
  83.157  	// notify processing
  83.158  	if (chat.mNotifId.notNull())
  83.159  	{
  83.160 -		LLNotificationPtr notification = LLNotificationsUtil::find(chat.mNotifId);
  83.161 -		if (notification != NULL)
  83.162 +		bool create_toast = true;
  83.163 +		for (LLToastNotifyPanel::instance_iter ti(LLToastNotifyPanel::beginInstances())
  83.164 +			, tend(LLToastNotifyPanel::endInstances()); ti != tend; ++ti)
  83.165  		{
  83.166 -			LLIMToastNotifyPanel* notify_box = new LLIMToastNotifyPanel(
  83.167 +			LLToastNotifyPanel& panel = *ti;
  83.168 +			LLIMToastNotifyPanel * imtoastp = dynamic_cast<LLIMToastNotifyPanel *>(&panel);
  83.169 +			const std::string& notification_name = panel.getNotificationName();
  83.170 +			if (notification_name == "OfferFriendship" && panel.isControlPanelEnabled() && imtoastp)
  83.171 +			{
  83.172 +				create_toast = false;
  83.173 +				break;
  83.174 +			}
  83.175 +		}
  83.176 +
  83.177 +		if (create_toast)
  83.178 +		{
  83.179 +			LLNotificationPtr notification = LLNotificationsUtil::find(chat.mNotifId);
  83.180 +			if (notification != NULL)
  83.181 +			{
  83.182 +				LLIMToastNotifyPanel* notify_box = new LLIMToastNotifyPanel(
  83.183  					notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history, mEditor);
  83.184  
  83.185 -			//Prepare the rect for the view
  83.186 -			LLRect target_rect = mEditor->getDocumentView()->getRect();
  83.187 -			// squeeze down the widget by subtracting padding off left and right
  83.188 -			target_rect.mLeft += mLeftWidgetPad + mEditor->getHPad();
  83.189 -			target_rect.mRight -= mRightWidgetPad;
  83.190 -			notify_box->reshape(target_rect.getWidth(),	notify_box->getRect().getHeight());
  83.191 -			notify_box->setOrigin(target_rect.mLeft, notify_box->getRect().mBottom);
  83.192 +				//Prepare the rect for the view
  83.193 +				LLRect target_rect = mEditor->getDocumentView()->getRect();
  83.194 +				// squeeze down the widget by subtracting padding off left and right
  83.195 +				target_rect.mLeft += mLeftWidgetPad + mEditor->getHPad();
  83.196 +				target_rect.mRight -= mRightWidgetPad;
  83.197 +				notify_box->reshape(target_rect.getWidth(),	notify_box->getRect().getHeight());
  83.198 +				notify_box->setOrigin(target_rect.mLeft, notify_box->getRect().mBottom);
  83.199  
  83.200 -			LLInlineViewSegment::Params params;
  83.201 -			params.view = notify_box;
  83.202 -			params.left_pad = mLeftWidgetPad;
  83.203 -			params.right_pad = mRightWidgetPad;
  83.204 -			mEditor->appendWidget(params, "\n", false);
  83.205 +				LLInlineViewSegment::Params params;
  83.206 +				params.view = notify_box;
  83.207 +				params.left_pad = mLeftWidgetPad;
  83.208 +				params.right_pad = mRightWidgetPad;
  83.209 +				mEditor->appendWidget(params, "\n", false);
  83.210 +			}
  83.211  		}
  83.212  	}
  83.213  
  83.214 @@ -1016,7 +1130,7 @@
  83.215  		if (square_brackets)
  83.216  		{
  83.217  			message += "]";
  83.218 -	}
  83.219 +		}
  83.220  
  83.221  		mEditor->appendText(message, prependNewLineState, body_message_params);
  83.222  		prependNewLineState = false;
    84.1 --- a/indra/newview/llchiclet.cpp	Thu Oct 17 18:26:04 2013 -0400
    84.2 +++ b/indra/newview/llchiclet.cpp	Tue Nov 12 14:06:38 2013 -0500
    84.3 @@ -220,18 +220,25 @@
    84.4  
    84.5  bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification )
    84.6  {
    84.7 -	if (notification->getName() == "ScriptDialog")
    84.8 +	bool displayNotification;
    84.9 +	if (   (notification->getName() == "ScriptDialog") // special case for scripts
   84.10 +		// if there is no toast window for the notification, filter it
   84.11 +		|| (!LLNotificationWellWindow::getInstance()->findItemByID(notification->getID()))
   84.12 +		)
   84.13  	{
   84.14 -		return false;
   84.15 +		displayNotification = false;
   84.16  	}
   84.17 -
   84.18 -	if( !(notification->canLogToIM() && notification->hasFormElements())
   84.19 -		&& (!notification->getPayload().has("give_inventory_notification")
   84.20 -			|| notification->getPayload()["give_inventory_notification"]))
   84.21 +	else if( !(notification->canLogToIM() && notification->hasFormElements())
   84.22 +			&& (!notification->getPayload().has("give_inventory_notification")
   84.23 +				|| notification->getPayload()["give_inventory_notification"]))
   84.24  	{
   84.25 -		return true;
   84.26 +		displayNotification = true;
   84.27  	}
   84.28 -	return false;
   84.29 +	else
   84.30 +	{
   84.31 +		displayNotification = false;
   84.32 +	}
   84.33 +	return displayNotification;
   84.34  }
   84.35  
   84.36  //////////////////////////////////////////////////////////////////////////
    85.1 --- a/indra/newview/llconversationloglist.cpp	Thu Oct 17 18:26:04 2013 -0400
    85.2 +++ b/indra/newview/llconversationloglist.cpp	Tue Nov 12 14:06:38 2013 -0500
    85.3 @@ -313,6 +313,10 @@
    85.4  	{
    85.5  		LLAvatarActions::offerTeleport(selected_conversation_participant_id);
    85.6  	}
    85.7 +	else if ("request_teleport" == command_name)
    85.8 +	{
    85.9 +		LLAvatarActions::teleportRequest(selected_conversation_participant_id);
   85.10 +	}
   85.11  	else if("add_friend" == command_name)
   85.12  	{
   85.13  		if (!LLAvatarActions::isFriend(selected_conversation_participant_id))
    86.1 --- a/indra/newview/llconversationmodel.cpp	Thu Oct 17 18:26:04 2013 -0400
    86.2 +++ b/indra/newview/llconversationmodel.cpp	Tue Nov 12 14:06:38 2013 -0500
    86.3 @@ -132,6 +132,7 @@
    86.4  		items.push_back(std::string("view_profile"));
    86.5  		items.push_back(std::string("im"));
    86.6  		items.push_back(std::string("offer_teleport"));
    86.7 +		items.push_back(std::string("request_teleport"));
    86.8  		items.push_back(std::string("voice_call"));
    86.9  		items.push_back(std::string("chat_history"));
   86.10  		items.push_back(std::string("separator_chat_history"));
    87.1 --- a/indra/newview/llconversationview.cpp	Thu Oct 17 18:26:04 2013 -0400
    87.2 +++ b/indra/newview/llconversationview.cpp	Tue Nov 12 14:06:38 2013 -0500
    87.3 @@ -267,6 +267,23 @@
    87.4      //This node (conversation) was selected and a child (participant) was not
    87.5      if(result && getRoot())
    87.6      {
    87.7 +
    87.8 +		if(getRoot()->getCurSelectedItem() == this)
    87.9 +		{
   87.10 +			LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem());
   87.11 +			LLUUID session_id = item? item->getUUID() : LLUUID();
   87.12 +
   87.13 +			LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
   87.14 +			if (im_container->isConversationsPaneCollapsed() && im_container->getSelectedSession() == session_id)
   87.15 +			{
   87.16 +				im_container->collapseMessagesPane(!im_container->isMessagesPaneCollapsed());
   87.17 +			}
   87.18 +			else
   87.19 +			{
   87.20 +				im_container->collapseMessagesPane(false);
   87.21 +			}
   87.22 +
   87.23 +		}
   87.24  		selectConversationItem();
   87.25      }
   87.26  
   87.27 @@ -318,7 +335,6 @@
   87.28  		LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
   87.29  		im_container->flashConversationItemWidget(session_id,false);
   87.30  		im_container->selectConversationPair(session_id, false);
   87.31 -		im_container->collapseMessagesPane(false);
   87.32  	}
   87.33  }
   87.34  
    88.1 --- a/indra/newview/lldrawpoolalpha.cpp	Thu Oct 17 18:26:04 2013 -0400
    88.2 +++ b/indra/newview/lldrawpoolalpha.cpp	Tue Nov 12 14:06:38 2013 -0500
    88.3 @@ -382,9 +382,7 @@
    88.4  			bool is_particle_or_hud_particle = group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
    88.5  													  || group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
    88.6  
    88.7 -			bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow.
    88.8 -				// All particle systems seem to come off the wire with texture entries which claim that they glow.  This is probably a bug in the data.  Suppress.
    88.9 -				!is_particle_or_hud_particle;
   88.10 +			bool draw_glow_for_this_partition = mVertexShaderLevel > 0; // no shaders = no glow.
   88.11  
   88.12  			static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group");
   88.13  			LLFastTimer t(FTM_RENDER_ALPHA_GROUP_LOOP);
    89.1 --- a/indra/newview/llface.cpp	Thu Oct 17 18:26:04 2013 -0400
    89.2 +++ b/indra/newview/llface.cpp	Tue Nov 12 14:06:38 2013 -0500
    89.3 @@ -1386,7 +1386,7 @@
    89.4  		}
    89.5  	}
    89.6  	
    89.7 -	static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback");
    89.8 +	static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
    89.9  
   89.10  #ifdef GL_TRANSFORM_FEEDBACK_BUFFER
   89.11  	if (use_transform_feedback &&
   89.12 @@ -1526,7 +1526,6 @@
   89.13  		}
   89.14  
   89.15  		glBindBufferARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
   89.16 -
   89.17  		gGL.popMatrix();
   89.18  
   89.19  		if (cur_shader)
    90.1 --- a/indra/newview/llface.h	Thu Oct 17 18:26:04 2013 -0400
    90.2 +++ b/indra/newview/llface.h	Tue Nov 12 14:06:38 2013 -0500
    90.3 @@ -194,7 +194,8 @@
    90.4  
    90.5  	void		setSize(S32 numVertices, S32 num_indices = 0, bool align = false);
    90.6  	
    90.7 -	BOOL		genVolumeBBoxes(const LLVolume &volume, S32 f,const LLMatrix4& mat, BOOL global_volume = FALSE);
    90.8 +	BOOL		genVolumeBBoxes(const LLVolume &volume, S32 f,
    90.9 +									const LLMatrix4& mat_vert_in, BOOL global_volume = FALSE);
   90.10  	
   90.11  	void		init(LLDrawable* drawablep, LLViewerObject* objp);
   90.12  	void		destroy();
    91.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    91.2 +++ b/indra/newview/llfacebookconnect.cpp	Tue Nov 12 14:06:38 2013 -0500
    91.3 @@ -0,0 +1,582 @@
    91.4 +/** 
    91.5 + * @file llfacebookconnect.h
    91.6 + * @author Merov, Cho, Gil
    91.7 + * @brief Connection to Facebook Service
    91.8 + *
    91.9 + * $LicenseInfo:firstyear=2013&license=viewerlgpl$
   91.10 + * Second Life Viewer Source Code
   91.11 + * Copyright (C) 2013, Linden Research, Inc.
   91.12 + * 
   91.13 + * This library is free software; you can redistribute it and/or
   91.14 + * modify it under the terms of the GNU Lesser General Public
   91.15 + * License as published by the Free Software Foundation;
   91.16 + * version 2.1 of the License only.
   91.17 + * 
   91.18 + * This library is distributed in the hope that it will be useful,
   91.19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   91.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   91.21 + * Lesser General Public License for more details.
   91.22 + * 
   91.23 + * You should have received a copy of the GNU Lesser General Public
   91.24 + * License along with this library; if not, write to the Free Software
   91.25 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   91.26 + * 
   91.27 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   91.28 + * $/LicenseInfo$
   91.29 + */
   91.30 +
   91.31 +#include "llviewerprecompiledheaders.h"
   91.32 +
   91.33 +#include "llfacebookconnect.h"
   91.34 +
   91.35 +#include "llagent.h"
   91.36 +#include "llcallingcard.h"			// for LLAvatarTracker
   91.37 +#include "llcommandhandler.h"
   91.38 +#include "llhttpclient.h"
   91.39 +#include "llnotificationsutil.h"
   91.40 +#include "llurlaction.h"
   91.41 +#include "llimagepng.h"
   91.42 +#include "llimagejpeg.h"
   91.43 +#include "lltrans.h"
   91.44 +#include "llevents.h"
   91.45 +#include "llviewerregion.h"
   91.46 +
   91.47 +#include "llfloaterwebcontent.h"
   91.48 +#include "llfloaterreg.h"
   91.49 +
   91.50 +boost::scoped_ptr<LLEventPump> LLFacebookConnect::sStateWatcher(new LLEventStream("FacebookConnectState"));
   91.51 +boost::scoped_ptr<LLEventPump> LLFacebookConnect::sInfoWatcher(new LLEventStream("FacebookConnectInfo"));
   91.52 +boost::scoped_ptr<LLEventPump> LLFacebookConnect::sContentWatcher(new LLEventStream("FacebookConnectContent"));
   91.53 +
   91.54 +// Local functions
   91.55 +void log_facebook_connect_error(const std::string& request, U32 status, const std::string& reason, const std::string& code, const std::string& description)
   91.56 +{
   91.57 +    // Note: 302 (redirect) is *not* an error that warrants logging
   91.58 +    if (status != 302)
   91.59 +    {
   91.60 +		LL_WARNS("FacebookConnect") << request << " request failed with a " << status << " " << reason << ". Reason: " << code << " (" << description << ")" << LL_ENDL;
   91.61 +    }
   91.62 +}
   91.63 +
   91.64 +void toast_user_for_success()
   91.65 +{
   91.66 +	LLSD args;
   91.67 +    args["MESSAGE"] = LLTrans::getString("facebook_post_success");
   91.68 +    LLNotificationsUtil::add("FacebookConnect", args);
   91.69 +}
   91.70 +
   91.71 +///////////////////////////////////////////////////////////////////////////////
   91.72 +//
   91.73 +class LLFacebookConnectHandler : public LLCommandHandler
   91.74 +{
   91.75 +public:
   91.76 +	LLFacebookConnectHandler() : LLCommandHandler("fbc", UNTRUSTED_THROTTLE) { }
   91.77 +    
   91.78 +	bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
   91.79 +	{
   91.80 +		if (tokens.size() > 0)
   91.81 +		{
   91.82 +			if (tokens[0].asString() == "connect")
   91.83 +			{
   91.84 +				// this command probably came from the fbc_web browser, so close it
   91.85 +				LLFloater* fbc_web = LLFloaterReg::getInstance("fbc_web");
   91.86 +				if (fbc_web)
   91.87 +				{
   91.88 +					fbc_web->closeFloater();
   91.89 +				}
   91.90 +
   91.91 +				// connect to facebook
   91.92 +				if (query_map.has("code"))
   91.93 +				{
   91.94 +                    LLFacebookConnect::instance().connectToFacebook(query_map["code"], query_map.get("state"));
   91.95 +				}
   91.96 +				return true;
   91.97 +			}
   91.98 +		}
   91.99 +		return false;
  91.100 +	}
  91.101 +};
  91.102 +LLFacebookConnectHandler gFacebookConnectHandler;
  91.103 +
  91.104 +///////////////////////////////////////////////////////////////////////////////
  91.105 +//
  91.106 +class LLFacebookConnectResponder : public LLHTTPClient::Responder
  91.107 +{
  91.108 +	LOG_CLASS(LLFacebookConnectResponder);
  91.109 +public:
  91.110 +	
  91.111 +    LLFacebookConnectResponder()
  91.112 +    {
  91.113 +        LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
  91.114 +    }
  91.115 +    
  91.116 +	virtual void completed(U32 status, const std::string& reason, const LLSD& content)
  91.117 +	{
  91.118 +		if (isGoodStatus(status))
  91.119 +		{
  91.120 +			LL_DEBUGS("FacebookConnect") << "Connect successful. content: " << content << LL_ENDL;
  91.121 +			
  91.122 +            LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTED);
  91.123 +		}
  91.124 +		else if (status != 302)
  91.125 +		{
  91.126 +            LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_FAILED);
  91.127 +            log_facebook_connect_error("Connect", status, reason, content.get("error_code"), content.get("error_description"));
  91.128 +		}
  91.129 +	}
  91.130 +    
  91.131 +    void completedHeader(U32 status, const std::string& reason, const LLSD& content)
  91.132 +    {
  91.133 +        if (status == 302)
  91.134 +        {
  91.135 +            LLFacebookConnect::instance().openFacebookWeb(content["location"]);
  91.136 +        }
  91.137 +    }
  91.138 +};
  91.139 +
  91.140 +///////////////////////////////////////////////////////////////////////////////
  91.141 +//
  91.142 +class LLFacebookShareResponder : public LLHTTPClient::Responder
  91.143 +{
  91.144 +	LOG_CLASS(LLFacebookShareResponder);
  91.145 +public:
  91.146 +    
  91.147 +	LLFacebookShareResponder()
  91.148 +	{
  91.149 +		LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_POSTING);
  91.150 +	}
  91.151 +	
  91.152 +	virtual void completed(U32 status, const std::string& reason, const LLSD& content)
  91.153 +	{
  91.154 +		if (isGoodStatus(status))
  91.155 +		{
  91.156 +            toast_user_for_success();
  91.157 +			LL_DEBUGS("FacebookConnect") << "Post successful. content: " << content << LL_ENDL;
  91.158 +			
  91.159 +			LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_POSTED);
  91.160 +		}
  91.161 +		else if (status == 404)
  91.162 +		{
  91.163 +			LLFacebookConnect::instance().connectToFacebook();
  91.164 +		}
  91.165 +		else
  91.166 +		{
  91.167 +            LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_POST_FAILED);
  91.168 +            log_facebook_connect_error("Share", status, reason, content.get("error_code"), content.get("error_description"));
  91.169 +		}
  91.170 +	}
  91.171 +    
  91.172 +    void completedHeader(U32 status, const std::string& reason, const LLSD& content)
  91.173 +    {
  91.174 +        if (status == 302)
  91.175 +        {
  91.176 +            LLFacebookConnect::instance().openFacebookWeb(content["location"]);
  91.177 +        }
  91.178 +    }
  91.179 +};
  91.180 +
  91.181 +///////////////////////////////////////////////////////////////////////////////
  91.182 +//
  91.183 +class LLFacebookDisconnectResponder : public LLHTTPClient::Responder
  91.184 +{
  91.185 +	LOG_CLASS(LLFacebookDisconnectResponder);
  91.186 +public:
  91.187 + 
  91.188 +	LLFacebookDisconnectResponder()
  91.189 +	{
  91.190 +		LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_DISCONNECTING);
  91.191 +	}
  91.192 +
  91.193 +	void setUserDisconnected()
  91.194 +	{
  91.195 +		// Clear data
  91.196 +		LLFacebookConnect::instance().clearInfo();
  91.197 +		LLFacebookConnect::instance().clearContent();
  91.198 +		//Notify state change
  91.199 +		LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
  91.200 +	}
  91.201 +
  91.202 +	virtual void completed(U32 status, const std::string& reason, const LLSD& content)
  91.203 +	{
  91.204 +		if (isGoodStatus(status)) 
  91.205 +		{
  91.206 +			LL_DEBUGS("FacebookConnect") << "Disconnect successful. content: " << content << LL_ENDL;
  91.207 +			setUserDisconnected();
  91.208 +
  91.209 +		}
  91.210 +		//User not found so already disconnected
  91.211 +		else if(status == 404)
  91.212 +		{
  91.213 +			LL_DEBUGS("FacebookConnect") << "Already disconnected. content: " << content << LL_ENDL;
  91.214 +			setUserDisconnected();
  91.215 +		}
  91.216 +		else
  91.217 +		{
  91.218 +			LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
  91.219 +            log_facebook_connect_error("Disconnect", status, reason, content.get("error_code"), content.get("error_description"));
  91.220 +		}
  91.221 +	}
  91.222 +};
  91.223 +
  91.224 +///////////////////////////////////////////////////////////////////////////////
  91.225 +//
  91.226 +class LLFacebookConnectedResponder : public LLHTTPClient::Responder
  91.227 +{
  91.228 +	LOG_CLASS(LLFacebookConnectedResponder);
  91.229 +public:
  91.230 +    
  91.231 +	LLFacebookConnectedResponder(bool auto_connect) : mAutoConnect(auto_connect)
  91.232 +    {
  91.233 +		LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
  91.234 +    }
  91.235 +    
  91.236 +	virtual void completed(U32 status, const std::string& reason, const LLSD& content)
  91.237 +	{
  91.238 +		if (isGoodStatus(status))
  91.239 +		{
  91.240 +			LL_DEBUGS("FacebookConnect") << "Connect successful. content: " << content << LL_ENDL;
  91.241 +            
  91.242 +            LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTED);
  91.243 +		}
  91.244 +		else
  91.245 +		{
  91.246 +			// show the facebook login page if not connected yet
  91.247 +			if (status == 404)
  91.248 +			{
  91.249 +				if (mAutoConnect)
  91.250 +				{
  91.251 +					LLFacebookConnect::instance().connectToFacebook();
  91.252 +				}
  91.253 +				else
  91.254 +				{
  91.255 +					LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
  91.256 +				}
  91.257 +			}
  91.258 +            else
  91.259 +            {
  91.260 +                LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_FAILED);
  91.261 +				log_facebook_connect_error("Connected", status, reason, content.get("error_code"), content.get("error_description"));
  91.262 +            }
  91.263 +		}
  91.264 +	}
  91.265 +    
  91.266 +private:
  91.267 +	bool mAutoConnect;
  91.268 +};
  91.269 +
  91.270 +///////////////////////////////////////////////////////////////////////////////
  91.271 +//
  91.272 +class LLFacebookInfoResponder : public LLHTTPClient::Responder
  91.273 +{
  91.274 +	LOG_CLASS(LLFacebookInfoResponder);
  91.275 +public:
  91.276 +
  91.277 +	virtual void completed(U32 status, const std::string& reason, const LLSD& info)
  91.278 +	{
  91.279 +		if (isGoodStatus(status))
  91.280 +		{
  91.281 +			llinfos << "Facebook: Info received" << llendl;
  91.282 +			LL_DEBUGS("FacebookConnect") << "Getting Facebook info successful. info: " << info << LL_ENDL;
  91.283 +			LLFacebookConnect::instance().storeInfo(info);
  91.284 +		}
  91.285 +		else
  91.286 +		{
  91.287 +			log_facebook_connect_error("Info", status, reason, info.get("error_code"), info.get("error_description"));
  91.288 +		}
  91.289 +	}
  91.290 +
  91.291 +	void completedHeader(U32 status, const std::string& reason, const LLSD& content)
  91.292 +	{
  91.293 +		if (status == 302)
  91.294 +		{
  91.295 +			LLFacebookConnect::instance().openFacebookWeb(content["location"]);
  91.296 +		}
  91.297 +	}
  91.298 +};
  91.299 +
  91.300 +///////////////////////////////////////////////////////////////////////////////
  91.301 +//
  91.302 +class LLFacebookFriendsResponder : public LLHTTPClient::Responder
  91.303 +{
  91.304 +	LOG_CLASS(LLFacebookFriendsResponder);
  91.305 +public:
  91.306 +
  91.307 +	virtual void completed(U32 status, const std::string& reason, const LLSD& content)
  91.308 +	{
  91.309 +		if (isGoodStatus(status))
  91.310 +		{
  91.311 +			LL_DEBUGS("FacebookConnect") << "Getting Facebook friends successful. content: " << content << LL_ENDL;
  91.312 +			LLFacebookConnect::instance().storeContent(content);
  91.313 +		}
  91.314 +		else
  91.315 +		{
  91.316 +            log_facebook_connect_error("Friends", status, reason, content.get("error_code"), content.get("error_description"));
  91.317 +		}
  91.318 +	}
  91.319 +
  91.320 +    void completedHeader(U32 status, const std::string& reason, const LLSD& content)
  91.321 +    {
  91.322 +        if (status == 302)
  91.323 +        {
  91.324 +            LLFacebookConnect::instance().openFacebookWeb(content["location"]);
  91.325 +        }
  91.326 +    }
  91.327 +};
  91.328 +
  91.329 +///////////////////////////////////////////////////////////////////////////////
  91.330 +//
  91.331 +LLFacebookConnect::LLFacebookConnect()
  91.332 +:	mConnectionState(FB_NOT_CONNECTED),
  91.333 +	mConnected(false),
  91.334 +	mInfo(),
  91.335 +    mContent(),
  91.336 +	mRefreshInfo(false),
  91.337 +	mRefreshContent(false),
  91.338 +	mReadFromMaster(false)
  91.339 +{
  91.340 +}
  91.341 +
  91.342 +void LLFacebookConnect::openFacebookWeb(std::string url)
  91.343 +{
  91.344 +	// Open the URL in an internal browser window without navigation UI
  91.345 +	LLFloaterWebContent::Params p;
  91.346 +    p.url(url).show_chrome(true);
  91.347 +    p.url(url).allow_address_entry(false);
  91.348 +    p.url(url).allow_back_forward_navigation(false);
  91.349 +    p.url(url).trusted_content(true);
  91.350 +	LLFloater *floater = LLFloaterReg::showInstance("fbc_web", p);
  91.351 +	//the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems).
  91.352 +	//So when showing the internal web browser, set focus to it's containing floater "fbc_web". When a mouse event 
  91.353 +	//occurs on the "webbrowser" panel part of the floater, a mouse cursor will properly show and the "webbrowser" will gain focus.
  91.354 +	//fbc_web floater contains the "webbrowser" panel.    JIRA: ACME-744
  91.355 +	gFocusMgr.setKeyboardFocus( floater );
  91.356 +
  91.357 +	//LLUrlAction::openURLExternal(url);
  91.358 +}
  91.359 +
  91.360 +std::string LLFacebookConnect::getFacebookConnectURL(const std::string& route, bool include_read_from_master)
  91.361 +{
  91.362 +    std::string url("");
  91.363 +    LLViewerRegion *regionp = gAgent.getRegion();
  91.364 +    if (regionp)
  91.365 +    {
  91.366 +        url = regionp->getCapability("FacebookConnect");
  91.367 +        url += route;
  91.368 +    
  91.369 +        if (include_read_from_master && mReadFromMaster)
  91.370 +        {
  91.371 +            url += "?read_from_master=true";
  91.372 +        }
  91.373 +    }
  91.374 +	return url;
  91.375 +}
  91.376 +
  91.377 +void LLFacebookConnect::connectToFacebook(const std::string& auth_code, const std::string& auth_state)
  91.378 +{
  91.379 +	LLSD body;
  91.380 +	if (!auth_code.empty())
  91.381 +		body["code"] = auth_code;
  91.382 +	if (!auth_state.empty())
  91.383 +		body["state"] = auth_state;
  91.384 +    
  91.385 +	LLHTTPClient::put(getFacebookConnectURL("/connection"), body, new LLFacebookConnectResponder());
  91.386 +}
  91.387 +
  91.388 +void LLFacebookConnect::disconnectFromFacebook()
  91.389 +{
  91.390 +	LLHTTPClient::del(getFacebookConnectURL("/connection"), new LLFacebookDisconnectResponder());
  91.391 +}
  91.392 +
  91.393 +void LLFacebookConnect::checkConnectionToFacebook(bool auto_connect)
  91.394 +{
  91.395 +	const bool follow_redirects = false;
  91.396 +	const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
  91.397 +	LLHTTPClient::get(getFacebookConnectURL("/connection", true), new LLFacebookConnectedResponder(auto_connect),
  91.398 +						LLSD(), timeout, follow_redirects);
  91.399 +}
  91.400 +
  91.401 +void LLFacebookConnect::loadFacebookInfo()
  91.402 +{
  91.403 +	if(mRefreshInfo)
  91.404 +	{
  91.405 +		const bool follow_redirects = false;
  91.406 +		const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
  91.407 +		LLHTTPClient::get(getFacebookConnectURL("/info", true), new LLFacebookInfoResponder(),
  91.408 +			LLSD(), timeout, follow_redirects);
  91.409 +	}
  91.410 +}
  91.411 +
  91.412 +void LLFacebookConnect::loadFacebookFriends()
  91.413 +{
  91.414 +	if(mRefreshContent)
  91.415 +	{
  91.416 +		const bool follow_redirects = false;
  91.417 +		const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
  91.418 +		LLHTTPClient::get(getFacebookConnectURL("/friends", true), new LLFacebookFriendsResponder(),
  91.419 +			LLSD(), timeout, follow_redirects);
  91.420 +	}
  91.421 +}
  91.422 +
  91.423 +void LLFacebookConnect::postCheckin(const std::string& location, const std::string& name, const std::string& description, const std::string& image, const std::string& message)
  91.424 +{
  91.425 +	LLSD body;
  91.426 +	if (!location.empty())
  91.427 +		body["location"] = location;
  91.428 +	if (!name.empty())
  91.429 +		body["name"] = name;
  91.430 +	if (!description.empty())
  91.431 +		body["description"] = description;
  91.432 +	if (!image.empty())
  91.433 +		body["image"] = image;
  91.434 +	if (!message.empty())
  91.435 +		body["message"] = message;
  91.436 +
  91.437 +	// Note: we can use that route for different publish action. We should be able to use the same responder.
  91.438 +	LLHTTPClient::post(getFacebookConnectURL("/share/checkin", true), body, new LLFacebookShareResponder());
  91.439 +}
  91.440 +
  91.441 +void LLFacebookConnect::sharePhoto(const std::string& image_url, const std::string& caption)
  91.442 +{
  91.443 +	LLSD body;
  91.444 +	body["image"] = image_url;
  91.445 +	body["caption"] = caption;
  91.446 +	
  91.447 +    // Note: we can use that route for different publish action. We should be able to use the same responder.
  91.448 +	LLHTTPClient::post(getFacebookConnectURL("/share/photo", true), body, new LLFacebookShareResponder());
  91.449 +}
  91.450 +
  91.451 +void LLFacebookConnect::sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption)
  91.452 +{
  91.453 +	std::string imageFormat;
  91.454 +	if (dynamic_cast<LLImagePNG*>(image.get()))
  91.455 +	{
  91.456 +		imageFormat = "png";
  91.457 +	}
  91.458 +	else if (dynamic_cast<LLImageJPEG*>(image.get()))
  91.459 +	{
  91.460 +		imageFormat = "jpg";
  91.461 +	}
  91.462 +	else
  91.463 +	{
  91.464 +		llwarns << "Image to upload is not a PNG or JPEG" << llendl;
  91.465 +		return;
  91.466 +	}
  91.467 +	
  91.468 +	// All this code is mostly copied from LLWebProfile::post()
  91.469 +	const std::string boundary = "----------------------------0123abcdefab";
  91.470 +
  91.471 +	LLSD headers;
  91.472 +	headers["Content-Type"] = "multipart/form-data; boundary=" + boundary;
  91.473 +
  91.474 +	std::ostringstream body;
  91.475 +
  91.476 +	// *NOTE: The order seems to matter.
  91.477 +	body	<< "--" << boundary << "\r\n"
  91.478 +			<< "Content-Disposition: form-data; name=\"caption\"\r\n\r\n"
  91.479 +			<< caption << "\r\n";
  91.480 +
  91.481 +	body	<< "--" << boundary << "\r\n"
  91.482 +			<< "Content-Disposition: form-data; name=\"image\"; filename=\"snapshot." << imageFormat << "\"\r\n"
  91.483 +			<< "Content-Type: image/" << imageFormat << "\r\n\r\n";
  91.484 +
  91.485 +	// Insert the image data.
  91.486 +	// *FIX: Treating this as a string will probably screw it up ...
  91.487 +	U8* image_data = image->getData();
  91.488 +	for (S32 i = 0; i < image->getDataSize(); ++i)
  91.489 +	{
  91.490 +		body << image_data[i];
  91.491 +	}
  91.492 +
  91.493 +	body <<	"\r\n--" << boundary << "--\r\n";
  91.494 +
  91.495 +	// postRaw() takes ownership of the buffer and releases it later.
  91.496 +	size_t size = body.str().size();
  91.497 +	U8 *data = new U8[size];
  91.498 +	memcpy(data, body.str().data(), size);
  91.499 +	
  91.500 +    // Note: we can use that route for different publish action. We should be able to use the same responder.
  91.501 +	LLHTTPClient::postRaw(getFacebookConnectURL("/share/photo", true), data, size, new LLFacebookShareResponder(), headers);
  91.502 +}
  91.503 +
  91.504 +void LLFacebookConnect::updateStatus(const std::string& message)
  91.505 +{
  91.506 +	LLSD body;
  91.507 +	body["message"] = message;
  91.508 +	
  91.509 +    // Note: we can use that route for different publish action. We should be able to use the same responder.
  91.510 +	LLHTTPClient::post(getFacebookConnectURL("/share/wall", true), body, new LLFacebookShareResponder());
  91.511 +}
  91.512 +
  91.513 +void LLFacebookConnect::storeInfo(const LLSD& info)
  91.514 +{
  91.515 +	mInfo = info;
  91.516 +	mRefreshInfo = false;
  91.517 +
  91.518 +	sInfoWatcher->post(info);
  91.519 +}
  91.520 +
  91.521 +const LLSD& LLFacebookConnect::getInfo() const
  91.522 +{
  91.523 +	return mInfo;
  91.524 +}
  91.525 +
  91.526 +void LLFacebookConnect::clearInfo()
  91.527 +{
  91.528 +	mInfo = LLSD();
  91.529 +}
  91.530 +
  91.531 +void LLFacebookConnect::storeContent(const LLSD& content)
  91.532 +{
  91.533 +    mContent = content;
  91.534 +	mRefreshContent = false;
  91.535 +
  91.536 +	sContentWatcher->post(content);
  91.537 +}
  91.538 +
  91.539 +const LLSD& LLFacebookConnect::getContent() const
  91.540 +{
  91.541 +    return mContent;
  91.542 +}
  91.543 +
  91.544 +void LLFacebookConnect::clearContent()
  91.545 +{
  91.546 +    mContent = LLSD();
  91.547 +}
  91.548 +
  91.549 +void LLFacebookConnect::setDataDirty()
  91.550 +{
  91.551 +	mRefreshInfo = true;
  91.552 +	mRefreshContent = true;
  91.553 +}
  91.554 +
  91.555 +void LLFacebookConnect::setConnectionState(LLFacebookConnect::EConnectionState connection_state)
  91.556 +{
  91.557 +	if(connection_state == FB_CONNECTED)
  91.558 +	{
  91.559 +		mReadFromMaster = true;
  91.560 +		setConnected(true);
  91.561 +		setDataDirty();
  91.562 +	}
  91.563 +	else if(connection_state == FB_NOT_CONNECTED)
  91.564 +	{
  91.565 +		setConnected(false);
  91.566 +	}
  91.567 +	else if(connection_state == FB_POSTED)
  91.568 +	{
  91.569 +		mReadFromMaster = false;
  91.570 +	}
  91.571 +
  91.572 +	if (mConnectionState != connection_state)
  91.573 +	{
  91.574 +		LLSD state_info;
  91.575 +		state_info["enum"] = connection_state;
  91.576 +		sStateWatcher->post(state_info);
  91.577 +	}
  91.578 +	
  91.579 +	mConnectionState = connection_state;
  91.580 +}
  91.581 +
  91.582 +void LLFacebookConnect::setConnected(bool connected)
  91.583 +{
  91.584 +	mConnected = connected;
  91.585 +}
    92.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.2 +++ b/indra/newview/llfacebookconnect.h	Tue Nov 12 14:06:38 2013 -0500
    92.3 @@ -0,0 +1,106 @@
    92.4 +/** 
    92.5 + * @file llfacebookconnect.h
    92.6 + * @author Merov, Cho, Gil
    92.7 + * @brief Connection to Facebook Service
    92.8 + *
    92.9 + * $LicenseInfo:firstyear=2013&license=viewerlgpl$
   92.10 + * Second Life Viewer Source Code
   92.11 + * Copyright (C) 2013, Linden Research, Inc.
   92.12 + * 
   92.13 + * This library is free software; you can redistribute it and/or
   92.14 + * modify it under the terms of the GNU Lesser General Public
   92.15 + * License as published by the Free Software Foundation;
   92.16 + * version 2.1 of the License only.
   92.17 + * 
   92.18 + * This library is distributed in the hope that it will be useful,
   92.19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   92.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   92.21 + * Lesser General Public License for more details.
   92.22 + * 
   92.23 + * You should have received a copy of the GNU Lesser General Public
   92.24 + * License along with this library; if not, write to the Free Software
   92.25 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   92.26 + * 
   92.27 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
   92.28 + * $/LicenseInfo$
   92.29 + */
   92.30 +
   92.31 +#ifndef LL_LLFACEBOOKCONNECT_H
   92.32 +#define LL_LLFACEBOOKCONNECT_H
   92.33 +
   92.34 +#include "llsingleton.h"
   92.35 +#include "llimage.h"
   92.36 +
   92.37 +class LLEventPump;
   92.38 +
   92.39 +/**
   92.40 + * @class LLFacebookConnect
   92.41 + *
   92.42 + * Manages authentication to, and interaction with, a web service allowing the
   92.43 + * the viewer to get Facebook OpenGraph data.
   92.44 + */
   92.45 +class LLFacebookConnect : public LLSingleton<LLFacebookConnect>
   92.46 +{
   92.47 +	LOG_CLASS(LLFacebookConnect);
   92.48 +public:
   92.49 +    enum EConnectionState
   92.50 +	{
   92.51 +		FB_NOT_CONNECTED = 0,
   92.52 +		FB_CONNECTION_IN_PROGRESS = 1,
   92.53 +		FB_CONNECTED = 2,
   92.54 +		FB_CONNECTION_FAILED = 3,
   92.55 +		FB_POSTING = 4,
   92.56 +		FB_POSTED = 5,
   92.57 +		FB_POST_FAILED = 6,
   92.58 +		FB_DISCONNECTING = 7,
   92.59 +		FB_DISCONNECT_FAILED = 8
   92.60 +	};
   92.61 +	
   92.62 +	void connectToFacebook(const std::string& auth_code = "", const std::string& auth_state = "");	// Initiate the complete FB connection. Please use checkConnectionToFacebook() in normal use.
   92.63 +	void disconnectFromFacebook();																	// Disconnect from the FBC service.
   92.64 +    void checkConnectionToFacebook(bool auto_connect = false);										// Check if an access token is available on the FBC service. If not, call connectToFacebook().
   92.65 +    
   92.66 +	void loadFacebookInfo();
   92.67 +    void loadFacebookFriends();
   92.68 +	void postCheckin(const std::string& location, const std::string& name, const std::string& description, const std::string& picture, const std::string& message);
   92.69 +    void sharePhoto(const std::string& image_url, const std::string& caption);
   92.70 +	void sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption);
   92.71 +	void updateStatus(const std::string& message);
   92.72 +	
   92.73 +	void storeInfo(const LLSD& info);
   92.74 +	const LLSD& getInfo() const;
   92.75 +	void clearInfo();
   92.76 +	void storeContent(const LLSD& content);
   92.77 +    const LLSD& getContent() const;
   92.78 +	void clearContent();
   92.79 +	void setDataDirty();
   92.80 +    
   92.81 +    void setConnectionState(EConnectionState connection_state);
   92.82 +	void setConnected(bool connected);
   92.83 +	bool isConnected() { return mConnected; }
   92.84 +	bool isTransactionOngoing() { return ((mConnectionState == FB_CONNECTION_IN_PROGRESS) || (mConnectionState == FB_POSTING) || (mConnectionState == FB_DISCONNECTING)); }
   92.85 +    EConnectionState getConnectionState() { return mConnectionState; }
   92.86 +    
   92.87 +    void openFacebookWeb(std::string url);
   92.88 +
   92.89 +private:
   92.90 +	friend class LLSingleton<LLFacebookConnect>;
   92.91 +
   92.92 +	LLFacebookConnect();
   92.93 +	~LLFacebookConnect() {};
   92.94 + 	std::string getFacebookConnectURL(const std::string& route = "", bool include_read_from_master = false);
   92.95 +   
   92.96 +    EConnectionState mConnectionState;
   92.97 +	BOOL mConnected;
   92.98 +	LLSD mInfo;
   92.99 +    LLSD mContent;
  92.100 +	bool mRefreshInfo;
  92.101 +	bool mRefreshContent;
  92.102 +	bool mReadFromMaster;
  92.103 +	
  92.104 +	static boost::scoped_ptr<LLEventPump> sStateWatcher;
  92.105 +	static boost::scoped_ptr<LLEventPump> sInfoWatcher;
  92.106 +	static boost::scoped_ptr<LLEventPump> sContentWatcher;
  92.107 +};
  92.108 +
  92.109 +#endif // LL_LLFACEBOOKCONNECT_H
    93.1 --- a/indra/newview/llfasttimerview.cpp	Thu Oct 17 18:26:04 2013 -0400
    93.2 +++ b/indra/newview/llfasttimerview.cpp	Tue Nov 12 14:06:38 2013 -0500
    93.3 @@ -1545,7 +1545,7 @@
    93.4  		return ;
    93.5  	}
    93.6  }
    93.7 -void	LLFastTimerView::onClickCloseBtn()
    93.8 +void	LLFastTimerView::onClickCloseBtn(bool)
    93.9  {
   93.10  	setVisible(false);
   93.11  }
    94.1 --- a/indra/newview/llfasttimerview.h	Thu Oct 17 18:26:04 2013 -0400
    94.2 +++ b/indra/newview/llfasttimerview.h	Tue Nov 12 14:06:38 2013 -0500
    94.3 @@ -63,7 +63,7 @@
    94.4  	F64 getTime(const std::string& name);
    94.5  
    94.6  protected:
    94.7 -	virtual	void	onClickCloseBtn();
    94.8 +	virtual	void	onClickCloseBtn(bool app_quitting = false);
    94.9  private:	
   94.10  	typedef std::vector<std::vector<S32> > bar_positions_t;
   94.11  	bar_positions_t mBarStart;
    95.1 --- a/indra/newview/llfilepicker.cpp	Thu Oct 17 18:26:04 2013 -0400
    95.2 +++ b/indra/newview/llfilepicker.cpp	Tue Nov 12 14:06:38 2013 -0500
    95.3 @@ -422,6 +422,19 @@
    95.4  			L"PNG Images (*.png)\0*.png\0" \
    95.5  			L"\0";
    95.6  		break;
    95.7 +	case FFSAVE_TGAPNG:
    95.8 +		if (filename.empty())
    95.9 +		{
   95.10 +			wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE);	/*Flawfinder: ignore*/
   95.11 +			//PNG by default
   95.12 +		}
   95.13 +		mOFN.lpstrDefExt = L"png";
   95.14 +		mOFN.lpstrFilter =
   95.15 +			L"PNG Images (*.png)\0*.png\0" \
   95.16 +			L"Targa Images (*.tga)\0*.tga\0" \
   95.17 +			L"\0";
   95.18 +		break;
   95.19 +		
   95.20  	case FFSAVE_JPEG:
   95.21  		if (filename.empty())
   95.22  		{
   95.23 @@ -640,13 +653,16 @@
   95.24  			creator = "TVOD";
   95.25  			extension = "wav";
   95.26  			break;
   95.27 -		
   95.28  		case FFSAVE_TGA:
   95.29  			type = "TPIC";
   95.30  			creator = "prvw";
   95.31  			extension = "tga";
   95.32  			break;
   95.33 -		
   95.34 +		case FFSAVE_TGAPNG:
   95.35 +			type = "PNG";
   95.36 +			creator = "prvw";
   95.37 +			extension = "png";
   95.38 +			break;
   95.39  		case FFSAVE_BMP:
   95.40  			type = "BMPf";
   95.41  			creator = "prvw";
   95.42 @@ -921,6 +937,22 @@
   95.43  		g_slist_free (file_list);
   95.44  	}
   95.45  
   95.46 +	// let's save the extension of the last added file(considering current filter)
   95.47 +	GtkFileFilter *gfilter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(widget));
   95.48 +	if(gfilter)
   95.49 +	{
   95.50 +		std::string filter = gtk_file_filter_get_name(gfilter);
   95.51 +
   95.52 +		if(filter == LLTrans::getString("png_image_files"))
   95.53 +		{
   95.54 +			picker->mCurrentExtension = ".png";
   95.55 +		}
   95.56 +		else if(filter == LLTrans::getString("targa_image_files"))
   95.57 +		{
   95.58 +			picker->mCurrentExtension = ".tga";
   95.59 +		}
   95.60 +	}
   95.61 +
   95.62  	// set the default path for this usage context.
   95.63  	const char* cur_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget));
   95.64  	if (cur_folder != NULL)
   95.65 @@ -1092,6 +1124,24 @@
   95.66  							LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)");
   95.67  }
   95.68  
   95.69 +static std::string add_save_texture_filter_to_gtkchooser(GtkWindow *picker)
   95.70 +{
   95.71 +	GtkFileFilter *gfilter_tga = gtk_file_filter_new();
   95.72 +	GtkFileFilter *gfilter_png = gtk_file_filter_new();
   95.73 +
   95.74 +	gtk_file_filter_add_pattern(gfilter_tga, "*.tga");
   95.75 +	gtk_file_filter_add_mime_type(gfilter_png, "image/png");
   95.76 +	std::string caption = LLTrans::getString("save_texture_image_files") + " (*.tga; *.png)";
   95.77 +	gtk_file_filter_set_name(gfilter_tga, LLTrans::getString("targa_image_files").c_str());
   95.78 +	gtk_file_filter_set_name(gfilter_png, LLTrans::getString("png_image_files").c_str());
   95.79 +
   95.80 +	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
   95.81 +					gfilter_png);
   95.82 +	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
   95.83 +					gfilter_tga);
   95.84 +	return caption;
   95.85 +}
   95.86 +
   95.87  BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
   95.88  {
   95.89  	BOOL rtn = FALSE;
   95.90 @@ -1129,6 +1179,15 @@
   95.91  				(picker, "image/bmp", LLTrans::getString("bitmap_image_files") + " (*.bmp)");
   95.92  			suggest_ext = ".bmp";
   95.93  			break;
   95.94 +		case FFSAVE_PNG:
   95.95 +			caption += add_simple_mime_filter_to_gtkchooser
   95.96 +				(picker, "image/png", LLTrans::getString("png_image_files") + " (*.png)");
   95.97 +			suggest_ext = ".png";
   95.98 +			break;
   95.99 +		case FFSAVE_TGAPNG:
  95.100 +			caption += add_save_texture_filter_to_gtkchooser(picker);
  95.101 +			suggest_ext = ".png";
  95.102 +			break;
  95.103  		case FFSAVE_AVI:
  95.104  			caption += add_simple_mime_filter_to_gtkchooser
  95.105  				(picker, "video/x-msvideo",
  95.106 @@ -1181,9 +1240,17 @@
  95.107  		}
  95.108  
  95.109  		gtk_widget_show_all(GTK_WIDGET(picker));
  95.110 +
  95.111  		gtk_main();
  95.112  
  95.113  		rtn = (getFileCount() == 1);
  95.114 +
  95.115 +		if(rtn && filter == FFSAVE_TGAPNG)
  95.116 +		{
  95.117 +			std::string selected_file = mFiles.back();
  95.118 +			mFiles.pop_back();
  95.119 +			mFiles.push_back(selected_file + mCurrentExtension);
  95.120 +		}
  95.121  	}
  95.122  
  95.123  	gViewerWindow->getWindow()->afterDialog();
    96.1 --- a/indra/newview/llfilepicker.h	Thu Oct 17 18:26:04 2013 -0400
    96.2 +++ b/indra/newview/llfilepicker.h	Tue Nov 12 14:06:38 2013 -0500
    96.3 @@ -107,6 +107,7 @@
    96.4  		FFSAVE_PNG = 13,
    96.5  		FFSAVE_JPEG = 14,
    96.6  		FFSAVE_SCRIPT = 15,
    96.7 +		FFSAVE_TGAPNG = 16
    96.8  	};
    96.9  
   96.10  	// open the dialog. This is a modal operation
   96.11 @@ -175,6 +176,8 @@
   96.12  	// we remember the last path that was accessed for a particular usage
   96.13  	std::map <std::string, std::string> mContextToPathMap;
   96.14  	std::string mCurContextName;
   96.15 +	// we also remember the extension of the last added file.
   96.16 +	std::string mCurrentExtension;
   96.17  #endif
   96.18  
   96.19  	std::vector<std::string> mFiles;
    97.1 --- a/indra/newview/llfloaterconversationpreview.cpp	Thu Oct 17 18:26:04 2013 -0400
    97.2 +++ b/indra/newview/llfloaterconversationpreview.cpp	Tue Nov 12 14:06:38 2013 -0500
    97.3 @@ -44,7 +44,8 @@
    97.4  	mPageSize(gSavedSettings.getS32("ConversationHistoryPageSize")),
    97.5  	mAccountName(session_id[LL_FCP_ACCOUNT_NAME]),
    97.6  	mCompleteName(session_id[LL_FCP_COMPLETE_NAME]),
    97.7 -	mMutex(NULL)
    97.8 +	mMutex(NULL),
    97.9 +	mShowHistory(false)
   97.10  {
   97.11  }
   97.12  
   97.13 @@ -91,12 +92,11 @@
   97.14  	mPageSpinner->setMinValue(1);
   97.15  	mPageSpinner->set(1);
   97.16  	mPageSpinner->setEnabled(false);
   97.17 -	mChatHistoryLoaded = false;
   97.18  	LLLogChat::startChatHistoryThread(file, load_params);
   97.19  	return LLFloater::postBuild();
   97.20  }
   97.21  
   97.22 -void LLFloaterConversationPreview::setPages(std::list<LLSD>& messages,const std::string& file_name)
   97.23 +void LLFloaterConversationPreview::setPages(std::list<LLSD>& messages, const std::string& file_name)
   97.24  {
   97.25  	if(file_name == mChatHistoryFileName)
   97.26  	{
   97.27 @@ -111,34 +111,30 @@
   97.28  
   97.29  		std::string total_page_num = llformat("/ %d", mCurrentPage+1);
   97.30  		getChild<LLTextBox>("page_num_label")->setValue(total_page_num);
   97.31 -		mChatHistoryLoaded = true;
   97.32 +		mShowHistory = true;
   97.33  	}
   97.34  }
   97.35  
   97.36  void LLFloaterConversationPreview::draw()
   97.37  {
   97.38 -	if(mChatHistoryLoaded)
   97.39 +	if(mShowHistory)
   97.40  	{
   97.41  		showHistory();
   97.42 -		mChatHistoryLoaded = false;
   97.43 +		mShowHistory = false;
   97.44  	}
   97.45  	LLFloater::draw();
   97.46  }
   97.47  
   97.48  void LLFloaterConversationPreview::onOpen(const LLSD& key)
   97.49  {
   97.50 -	if(mChatHistoryLoaded)
   97.51 -	{
   97.52 -		showHistory();
   97.53 -	}
   97.54 +	mShowHistory = true;
   97.55  }
   97.56  
   97.57  void LLFloaterConversationPreview::showHistory()
   97.58  {
   97.59 -	// additional protection to avoid changes of mMessages in setPages()
   97.60 +	// additional protection to avoid changes of mMessages in setPages
   97.61  	LLMutexLock lock(&mMutex);
   97.62 -
   97.63 -	if (!mMessages.size() || mCurrentPage * mPageSize >= mMessages.size())
   97.64 +	if(!mMessages.size() || mCurrentPage * mPageSize >= mMessages.size())
   97.65  	{
   97.66  		return;
   97.67  	}
   97.68 @@ -147,7 +143,7 @@
   97.69  	std::ostringstream message;
   97.70  	std::list<LLSD>::const_iterator iter = mMessages.begin();
   97.71  	std::advance(iter, mCurrentPage * mPageSize);
   97.72 -
   97.73 +	
   97.74  	for (int msg_num = 0; iter != mMessages.end() && msg_num < mPageSize; ++iter, ++msg_num)
   97.75  	{
   97.76  		LLSD msg = *iter;
   97.77 @@ -198,10 +194,11 @@
   97.78  void LLFloaterConversationPreview::onMoreHistoryBtnClick()
   97.79  {
   97.80  	mCurrentPage = (int)(mPageSpinner->getValueF32());
   97.81 -	if (--mCurrentPage < 0)
   97.82 +	if (!mCurrentPage)
   97.83  	{
   97.84  		return;
   97.85  	}
   97.86  
   97.87 -	showHistory();
   97.88 +	mCurrentPage--;
   97.89 +	mShowHistory = true;
   97.90  }
    98.1 --- a/indra/newview/llfloaterconversationpreview.h	Thu Oct 17 18:26:04 2013 -0400
    98.2 +++ b/indra/newview/llfloaterconversationpreview.h	Tue Nov 12 14:06:38 2013 -0500
    98.3 @@ -62,7 +62,7 @@
    98.4  	std::string		mAccountName;
    98.5  	std::string		mCompleteName;
    98.6  	std::string     mChatHistoryFileName;
    98.7 -	bool			mChatHistoryLoaded;
    98.8 +	bool			mShowHistory;
    98.9  };
   98.10  
   98.11  #endif /* LLFLOATERCONVERSATIONPREVIEW_H_ */
    99.1 --- a/indra/newview/llfloatergroupinvite.cpp	Thu Oct 17 18:26:04 2013 -0400
    99.2 +++ b/indra/newview/llfloatergroupinvite.cpp	Tue Nov 12 14:06:38 2013 -0500
    99.3 @@ -30,6 +30,8 @@
    99.4  #include "llpanelgroupinvite.h"
    99.5  #include "lltrans.h"
    99.6  #include "lldraghandle.h"
    99.7 +#include "llagent.h"
    99.8 +#include "llgroupmgr.h"
    99.9  
   99.10  class LLFloaterGroupInvite::impl
   99.11  {
   99.12 @@ -123,6 +125,12 @@
   99.13  	LLFloaterGroupInvite *fgi = get_if_there(impl::sInstances,
   99.14  											 group_id,
   99.15  											 (LLFloaterGroupInvite*)NULL);
   99.16 +
   99.17 +	// refresh group information
   99.18 +	gAgent.sendAgentDataUpdateRequest();
   99.19 +	LLGroupMgr::getInstance()->clearGroupData(group_id);
   99.20 +
   99.21 +
   99.22  	if (!fgi)
   99.23  	{
   99.24  		fgi = new LLFloaterGroupInvite(group_id);
   100.1 --- a/indra/newview/llfloaterimcontainer.cpp	Thu Oct 17 18:26:04 2013 -0400
   100.2 +++ b/indra/newview/llfloaterimcontainer.cpp	Tue Nov 12 14:06:38 2013 -0500
   100.3 @@ -101,6 +101,7 @@
   100.4  
   100.5  	gSavedPerAccountSettings.setBOOL("ConversationsListPaneCollapsed", mConversationsPane->isCollapsed());
   100.6  	gSavedPerAccountSettings.setBOOL("ConversationsMessagePaneCollapsed", mMessagesPane->isCollapsed());
   100.7 +	gSavedPerAccountSettings.setBOOL("ConversationsParticipantListCollapsed", !isParticipantListExpanded());
   100.8  
   100.9  	if (!LLSingleton<LLIMMgr>::destroyed())
  100.10  	{
  100.11 @@ -250,6 +251,11 @@
  100.12  	// Init the sort order now that the root had been created
  100.13  	setSortOrder(LLConversationSort(gSavedSettings.getU32("ConversationSortOrder")));
  100.14  	
  100.15 +	//We should expand nearby chat participants list for the new user
  100.16 +	if(gAgent.isFirstLogin() || !gSavedPerAccountSettings.getBOOL("ConversationsParticipantListCollapsed"))
  100.17 +	{
  100.18 +		expandConversation();
  100.19 +	}
  100.20  	// Keep the xml set title around for when we have to overwrite it
  100.21  	mGeneralTitle = getTitle();
  100.22  	
  100.23 @@ -662,10 +668,10 @@
  100.24  			LLFloater* session_floater = widget->getSessionFloater();
  100.25  			if (session_floater != nearby_chat)
  100.26  			{
  100.27 -				widget->setVisibleIfDetached(visible);
  100.28 -			}
  100.29 +		    widget->setVisibleIfDetached(visible);
  100.30  		}
  100.31  	}
  100.32 +	}
  100.33  	
  100.34  	// Now, do the normal multifloater show/hide
  100.35  	LLMultiFloater::setVisible(visible);
  100.36 @@ -700,13 +706,13 @@
  100.37  	// Only select other sessions
  100.38  	if (!getSelectedSession().isNull())
  100.39  	{
  100.40 -		selectConversationPair(getSelectedSession(), false, take_focus);
  100.41 +    selectConversationPair(getSelectedSession(), false, take_focus);
  100.42  	}
  100.43  	if (mInitialized && mIsFirstLaunch)
  100.44  	{
  100.45  		collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
  100.46  		mIsFirstLaunch = false;
  100.47 -	}
  100.48 +}
  100.49  }
  100.50  
  100.51  void LLFloaterIMContainer::updateResizeLimits()
  100.52 @@ -715,6 +721,16 @@
  100.53  	assignResizeLimits();
  100.54  }
  100.55  
  100.56 +bool LLFloaterIMContainer::isMessagesPaneCollapsed()
  100.57 +{
  100.58 +	return mMessagesPane->isCollapsed();
  100.59 +}
  100.60 +
  100.61 +bool LLFloaterIMContainer::isConversationsPaneCollapsed()
  100.62 +{
  100.63 +	return mConversationsPane->isCollapsed();
  100.64 +}
  100.65 +
  100.66  void LLFloaterIMContainer::collapseMessagesPane(bool collapse)
  100.67  {
  100.68  	if (mMessagesPane->isCollapsed() == collapse)
  100.69 @@ -784,8 +800,8 @@
  100.70  		mConversationsPane->setTargetDim(gSavedPerAccountSettings.getS32("ConversationsListPaneWidth"));
  100.71  	}
  100.72  
  100.73 -	S32 delta_width =
  100.74 -			gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") - mConversationsPane->getMinDim();
  100.75 +	S32 delta_width = gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") 
  100.76 +		- mConversationsPane->getMinDim() - mConversationsStack->getPanelSpacing() + 1;
  100.77  
  100.78  	reshapeFloaterAndSetResizeLimits(collapse, delta_width);
  100.79  
  100.80 @@ -834,7 +850,7 @@
  100.81  
  100.82  	S32 conv_pane_target_width = is_conv_pane_expanded
  100.83  		? ( is_msg_pane_expanded?mConversationsPane->getRect().getWidth():mConversationsPane->getExpandedMinDim() )
  100.84 -		: mConversationsPane->getMinDim();
  100.85 +			: mConversationsPane->getMinDim();
  100.86  
  100.87  	S32 msg_pane_min_width  = is_msg_pane_expanded ? mMessagesPane->getExpandedMinDim() : 0;
  100.88  	S32 new_min_width = conv_pane_target_width + msg_pane_min_width + summary_width_of_visible_borders;
  100.89 @@ -995,7 +1011,7 @@
  100.90  			conversation_floater->setSortOrder(order);
  100.91  		}
  100.92  	}
  100.93 -
  100.94 +	
  100.95  	gSavedSettings.setU32("ConversationSortOrder", (U32)order);
  100.96  }
  100.97  
  100.98 @@ -1080,6 +1096,10 @@
  100.99  		{
 100.100  			LLAvatarActions::offerTeleport(selectedIDS);
 100.101  		}
 100.102 +		else if ("request_teleport" == command)
 100.103 +		{
 100.104 +			LLAvatarActions::teleportRequest(selectedIDS.front());
 100.105 +		}
 100.106  		else if ("voice_call" == command)
 100.107  		{
 100.108  			LLAvatarActions::startCall(userID);
 100.109 @@ -1182,7 +1202,7 @@
 100.110          }
 100.111          else if("chat_history" == command)
 100.112          {
 100.113 -        	if (selectedIDS.size() > 0)
 100.114 +			if (selectedIDS.size() > 0)
 100.115  			{
 100.116  				LLAvatarActions::viewChatHistory(selectedIDS.front());
 100.117  			}
 100.118 @@ -1204,7 +1224,7 @@
 100.119      	    {
 100.120      	      	LLFloaterReg::showInstance("preview_conversation", LLSD(LLUUID::null), true);
 100.121      	    }
 100.122 -    	}
 100.123 +}
 100.124      }
 100.125  }
 100.126  
 100.127 @@ -1235,7 +1255,7 @@
 100.128  
 100.129      if (action == "group_profile")
 100.130      {
 100.131 -    	LLGroupActions::show(mSelectedSession);
 100.132 +        LLGroupActions::show(mSelectedSession);
 100.133      }
 100.134      else if (action == "activate_group")
 100.135      {
 100.136 @@ -2082,6 +2102,19 @@
 100.137  		}
 100.138  	}
 100.139  }
 100.140 +bool LLFloaterIMContainer::isParticipantListExpanded()
 100.141 +{
 100.142 +	bool is_expanded = false;
 100.143 +	if(!mConversationsPane->isCollapsed())
 100.144 +	{
 100.145 +		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,getSelectedSession()));
 100.146 +		if (widget)
 100.147 +		{
 100.148 +			is_expanded = widget->isOpen();
 100.149 +		}
 100.150 +	}
 100.151 +	return is_expanded;
 100.152 +}
 100.153  
 100.154  // By default, if torn off session is currently frontmost, LLFloater::isFrontmost() will return FALSE, which can lead to some bugs
 100.155  // So LLFloater::isFrontmost() is overriden here to check both selected session and the IM floater itself
 100.156 @@ -2098,7 +2131,7 @@
 100.157  
 100.158  // For conversations, closeFloater() (linked to Ctrl-W) does not actually close the floater but the active conversation.
 100.159  // This is intentional so it doesn't confuse the user. onClickCloseBtn() closes the whole floater.
 100.160 -void LLFloaterIMContainer::onClickCloseBtn()
 100.161 +void LLFloaterIMContainer::onClickCloseBtn(bool app_quitting/* = false*/)
 100.162  {
 100.163  	// Always unminimize before trying to close.
 100.164  	// Most of the time the user will never see this state.
 100.165 @@ -2107,7 +2140,7 @@
 100.166  		LLMultiFloater::setMinimized(FALSE);
 100.167  	}
 100.168  
 100.169 -	LLFloater::closeFloater();
 100.170 +	LLFloater::closeFloater(app_quitting);
 100.171  }
 100.172  
 100.173  void LLFloaterIMContainer::closeHostedFloater()
 100.174 @@ -2154,7 +2187,7 @@
 100.175  	if(app_quitting)
 100.176  	{
 100.177  		closeAllConversations();
 100.178 -		onClickCloseBtn();
 100.179 +		onClickCloseBtn(app_quitting);
 100.180  	}
 100.181  	else
 100.182  	{
   101.1 --- a/indra/newview/llfloaterimcontainer.h	Thu Oct 17 18:26:04 2013 -0400
   101.2 +++ b/indra/newview/llfloaterimcontainer.h	Tue Nov 12 14:06:38 2013 -0500
   101.3 @@ -90,6 +90,8 @@
   101.4  	static void onCurrentChannelChanged(const LLUUID& session_id);
   101.5  
   101.6  	void collapseMessagesPane(bool collapse);
   101.7 +	bool isMessagesPaneCollapsed();
   101.8 +	bool isConversationsPaneCollapsed();
   101.9  	
  101.10  	// Callbacks
  101.11  	static void idle(void* user_data);
  101.12 @@ -134,7 +136,7 @@
  101.13  	void onStubCollapseButtonClicked();
  101.14  	void processParticipantsStyleUpdate();
  101.15  	void onSpeakButtonClicked();
  101.16 -	/*virtual*/ void onClickCloseBtn();
  101.17 +	/*virtual*/ void onClickCloseBtn(bool app_quitting = false);
  101.18  	/*virtual*/ void closeHostedFloater();
  101.19  
  101.20  	void collapseConversationsPane(bool collapse, bool save_is_allowed=true);
  101.21 @@ -172,6 +174,7 @@
  101.22  	void toggleAllowTextChat(const LLUUID& participant_uuid);
  101.23  	void toggleMute(const LLUUID& participant_id, U32 flags);
  101.24  	void openNearbyChat();
  101.25 +	bool isParticipantListExpanded();
  101.26  
  101.27  	LLButton* mExpandCollapseBtn;
  101.28  	LLButton* mStubCollapseBtn;
   102.1 --- a/indra/newview/llfloaterimnearbychat.cpp	Thu Oct 17 18:26:04 2013 -0400
   102.2 +++ b/indra/newview/llfloaterimnearbychat.cpp	Tue Nov 12 14:06:38 2013 -0500
   102.3 @@ -308,7 +308,8 @@
   102.4  }
   102.5  
   102.6  // virtual
   102.7 -void LLFloaterIMNearbyChat::onClickCloseBtn()
   102.8 +void LLFloaterIMNearbyChat::onClickCloseBtn(bool)
   102.9 +
  102.10  {
  102.11  	if (!isTornOff())
  102.12  	{
  102.13 @@ -493,11 +494,11 @@
  102.14  			if (!rest_of_match.empty())
  102.15  			{
  102.16  				mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
  102.17 -
  102.18  				// Select to end of line, starting from the character
  102.19  				// after the last one the user typed.
  102.20 -				mInputEditor->selectNext(rest_of_match, false);
  102.21 +				mInputEditor->selectByCursorPosition(utf8_out_str.size()-rest_of_match.size(),utf8_out_str.size());
  102.22  			}
  102.23 +
  102.24  		}
  102.25  		else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
  102.26  		{
   103.1 --- a/indra/newview/llfloaterimnearbychat.h	Thu Oct 17 18:26:04 2013 -0400
   103.2 +++ b/indra/newview/llfloaterimnearbychat.h	Tue Nov 12 14:06:38 2013 -0500
   103.3 @@ -95,7 +95,7 @@
   103.4  	void onChatFontChange(LLFontGL* fontp);
   103.5  
   103.6  	/*virtual*/ void onTearOffClicked();
   103.7 -	/*virtual*/ void onClickCloseBtn();
   103.8 +	/*virtual*/ void onClickCloseBtn(bool app_qutting = false);
   103.9  
  103.10  	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
  103.11  	EChatType processChatTypeTriggers(EChatType type, std::string &str);
   104.1 --- a/indra/newview/llfloaterimsession.cpp	Thu Oct 17 18:26:04 2013 -0400
   104.2 +++ b/indra/newview/llfloaterimsession.cpp	Tue Nov 12 14:06:38 2013 -0500
   104.3 @@ -112,7 +112,7 @@
   104.4  }
   104.5  
   104.6  // virtual
   104.7 -void LLFloaterIMSession::onClickCloseBtn()
   104.8 +void LLFloaterIMSession::onClickCloseBtn(bool)
   104.9  {
  104.10  	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
  104.11  
   105.1 --- a/indra/newview/llfloaterimsession.h	Thu Oct 17 18:26:04 2013 -0400
   105.2 +++ b/indra/newview/llfloaterimsession.h	Tue Nov 12 14:06:38 2013 -0500
   105.3 @@ -141,7 +141,7 @@
   105.4  	/*virtual*/ void refresh();
   105.5  
   105.6      /*virtual*/ void onTearOffClicked();
   105.7 -	/*virtual*/ void onClickCloseBtn();
   105.8 +	/*virtual*/ void onClickCloseBtn(bool app_qutting);
   105.9  
  105.10  	// Update the window title and input field help text
  105.11  	/*virtual*/ void updateSessionName(const std::string& name);
   106.1 --- a/indra/newview/llfloaterland.cpp	Thu Oct 17 18:26:04 2013 -0400
   106.2 +++ b/indra/newview/llfloaterland.cpp	Tue Nov 12 14:06:38 2013 -0500
   106.3 @@ -2097,7 +2097,6 @@
   106.4  // virtual
   106.5  void LLPanelLandOptions::draw()
   106.6  {
   106.7 -	refreshSearch();	// Is this necessary?  JC
   106.8  	LLPanel::draw();
   106.9  }
  106.10  
  106.11 @@ -2111,9 +2110,8 @@
  106.12  		mCheckShowDirectory->set(FALSE);
  106.13  		mCheckShowDirectory->setEnabled(FALSE);
  106.14  
  106.15 -		// *TODO:Translate
  106.16 -		const std::string& none_string = LLParcel::getCategoryUIString(LLParcel::C_NONE);
  106.17 -		mCategoryCombo->setSimple(none_string);
  106.18 +		const std::string& none_string = LLParcel::getCategoryString(LLParcel::C_NONE);
  106.19 +		mCategoryCombo->setValue(none_string);
  106.20  		mCategoryCombo->setEnabled(FALSE);
  106.21  		return;
  106.22  	}
  106.23 @@ -2140,10 +2138,9 @@
  106.24  	mCheckShowDirectory	->set(show_directory);
  106.25  
  106.26  	// Set by string in case the order in UI doesn't match the order by index.
  106.27 -	// *TODO:Translate
  106.28  	LLParcel::ECategory cat = parcel->getCategory();
  106.29 -	const std::string& category_string = LLParcel::getCategoryUIString(cat);
  106.30 -	mCategoryCombo->setSimple(category_string);
  106.31 +	const std::string& category_string = LLParcel::getCategoryString(cat);
  106.32 +	mCategoryCombo->setValue(category_string);
  106.33  
  106.34  	std::string tooltip;
  106.35  	bool enable_show_directory = false;
  106.36 @@ -2377,7 +2374,7 @@
  106.37  	{
  106.38  		BOOL use_access_list = parcel->getParcelFlag(PF_USE_ACCESS_LIST);
  106.39  		BOOL use_group = parcel->getParcelFlag(PF_USE_ACCESS_GROUP);
  106.40 -		BOOL public_access = !use_access_list && !use_group;
  106.41 +		BOOL public_access = !use_access_list;
  106.42  		
  106.43  		getChild<LLUICtrl>("public_access")->setValue(public_access );
  106.44  		getChild<LLUICtrl>("GroupCheck")->setValue(use_group );
  106.45 @@ -2544,7 +2541,11 @@
  106.46  	getChildView("HoursSpin")->setEnabled(FALSE);
  106.47  	getChildView("AccessList")->setEnabled(FALSE);
  106.48  	getChildView("BannedList")->setEnabled(FALSE);
  106.49 -	
  106.50 +	getChildView("add_allowed")->setEnabled(FALSE);
  106.51 +	getChildView("remove_allowed")->setEnabled(FALSE);
  106.52 +	getChildView("add_banned")->setEnabled(FALSE);
  106.53 +	getChildView("remove_banned")->setEnabled(FALSE);
  106.54 +
  106.55  	LLParcel *parcel = mParcel->getParcel();
  106.56  	if (parcel)
  106.57  	{
  106.58 @@ -2582,7 +2583,6 @@
  106.59  			{
  106.60  				getChildView("Only Allow")->setToolTip(std::string());
  106.61  			}
  106.62 -			getChildView("GroupCheck")->setEnabled(FALSE);
  106.63  			getChildView("PassCheck")->setEnabled(FALSE);
  106.64  			getChildView("pass_combo")->setEnabled(FALSE);
  106.65  			getChildView("AccessList")->setEnabled(FALSE);
  106.66 @@ -2592,11 +2592,7 @@
  106.67  			getChildView("limit_payment")->setEnabled(FALSE);
  106.68  			getChildView("limit_age_verified")->setEnabled(FALSE);
  106.69  
  106.70 -			std::string group_name;
  106.71 -			if (gCacheName->getGroupName(parcel->getGroupID(), group_name))
  106.72 -			{			
  106.73 -				getChildView("GroupCheck")->setEnabled(can_manage_allowed);
  106.74 -			}
  106.75 +
  106.76  			BOOL group_access = getChild<LLUICtrl>("GroupCheck")->getValue().asBoolean();
  106.77  			BOOL sell_passes = getChild<LLUICtrl>("PassCheck")->getValue().asBoolean();
  106.78  			getChildView("PassCheck")->setEnabled(can_manage_allowed);
  106.79 @@ -2607,6 +2603,11 @@
  106.80  				getChildView("HoursSpin")->setEnabled(can_manage_allowed);
  106.81  			}
  106.82  		}
  106.83 +		std::string group_name;
  106.84 +		if (gCacheName->getGroupName(parcel->getGroupID(), group_name))
  106.85 +		{
  106.86 +			getChildView("GroupCheck")->setEnabled(can_manage_allowed);
  106.87 +		}
  106.88  		getChildView("AccessList")->setEnabled(can_manage_allowed);
  106.89  		S32 allowed_list_count = parcel->mAccessList.size();
  106.90  		getChildView("add_allowed")->setEnabled(can_manage_allowed && allowed_list_count < PARCEL_MAX_ACCESS_LIST);
  106.91 @@ -2652,17 +2653,6 @@
  106.92  	{
  106.93  		return;
  106.94  	}
  106.95 -
  106.96 -	// If we disabled public access, enable group access by default (if applicable)
  106.97 -	BOOL public_access = self->getChild<LLUICtrl>("public_access")->getValue().asBoolean();
  106.98 -	if (public_access == FALSE)
  106.99 -	{
 106.100 -		std::string group_name;
 106.101 -		if (gCacheName->getGroupName(parcel->getGroupID(), group_name))
 106.102 -		{
 106.103 -			self->getChild<LLUICtrl>("GroupCheck")->setValue(public_access ? FALSE : TRUE);
 106.104 -		}
 106.105 -	}
 106.106  	
 106.107  	onCommitAny(ctrl, userdata);
 106.108  }
 106.109 @@ -2697,7 +2687,6 @@
 106.110  	if (public_access)
 106.111  	{
 106.112  		use_access_list = FALSE;
 106.113 -		use_access_group = FALSE;
 106.114  		limit_payment = self->getChild<LLUICtrl>("limit_payment")->getValue().asBoolean();
 106.115  		limit_age_verified = self->getChild<LLUICtrl>("limit_age_verified")->getValue().asBoolean();
 106.116  	}
   107.1 --- a/indra/newview/llfloaterpreference.cpp	Thu Oct 17 18:26:04 2013 -0400
   107.2 +++ b/indra/newview/llfloaterpreference.cpp	Tue Nov 12 14:06:38 2013 -0500
   107.3 @@ -618,9 +618,12 @@
   107.4  	// hide translation settings floater
   107.5  	LLFloaterReg::hideInstance("prefs_translation");
   107.6  	
   107.7 -	// hide translation settings floater
   107.8 +	// hide autoreplace settings floater
   107.9  	LLFloaterReg::hideInstance("prefs_autoreplace");
  107.10  	
  107.11 +	// hide spellchecker settings folder
  107.12 +	LLFloaterReg::hideInstance("prefs_spellchecker");
  107.13 +	
  107.14  	// cancel hardware menu
  107.15  	LLFloaterHardwareSettings* hardware_settings = LLFloaterReg::getTypedInstance<LLFloaterHardwareSettings>("prefs_hardware_settings");
  107.16  	if (hardware_settings)
   108.1 --- a/indra/newview/llfloaterregioninfo.cpp	Thu Oct 17 18:26:04 2013 -0400
   108.2 +++ b/indra/newview/llfloaterregioninfo.cpp	Tue Nov 12 14:06:38 2013 -0500
   108.3 @@ -1734,7 +1734,7 @@
   108.4  			LLSD args;
   108.5  			args["NUM_ADDED"] = llformat("%d",ids.size());
   108.6  			args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
   108.7 -			args["LIST_TYPE"] = "Allowed Residents";
   108.8 +			args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents");
   108.9  			args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
  108.10  			LLNotificationsUtil::add("MaxAgentOnRegionBatch", args);
  108.11  			delete change_info;
  108.12 @@ -1750,7 +1750,7 @@
  108.13  			LLSD args;
  108.14  			args["NUM_ADDED"] = llformat("%d",ids.size());
  108.15  			args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
  108.16 -			args["LIST_TYPE"] = "Banned Residents";
  108.17 +			args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents");
  108.18  			args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
  108.19  			LLNotificationsUtil::add("MaxAgentOnRegionBatch", args);
  108.20  			delete change_info;
  108.21 @@ -2815,9 +2815,10 @@
  108.22  		}
  108.23  
  108.24  
  108.25 -		std::string msg = llformat("Banned residents: (%d, max %d)",
  108.26 -									totalBannedAgents,
  108.27 -									ESTATE_MAX_ACCESS_IDS);
  108.28 +		LLStringUtil::format_map_t args;
  108.29 +		args["[BANNEDAGENTS]"] = llformat("%d", totalBannedAgents);
  108.30 +		args["[MAXBANNED]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS);
  108.31 +		std::string msg = LLTrans::getString("RegionInfoBannedResidents", args);
  108.32  		panel->getChild<LLUICtrl>("ban_resident_label")->setValue(LLSD(msg));
  108.33  
  108.34  		if (banned_agent_name_list)
  108.35 @@ -2837,9 +2838,10 @@
  108.36  
  108.37  	if (access_flags & ESTATE_ACCESS_MANAGERS)
  108.38  	{
  108.39 -		std::string msg = llformat("Estate Managers: (%d, max %d)",
  108.40 -									num_estate_managers,
  108.41 -									ESTATE_MAX_MANAGERS);
  108.42 +		LLStringUtil::format_map_t args;
  108.43 +		args["[ESTATEMANAGERS]"] = llformat("%d", num_estate_managers);
  108.44 +		args["[MAXMANAGERS]"] = llformat("%d", ESTATE_MAX_MANAGERS);
  108.45 +		std::string msg = LLTrans::getString("RegionInfoEstateManagers", args);
  108.46  		panel->getChild<LLUICtrl>("estate_manager_label")->setValue(LLSD(msg));
  108.47  
  108.48  		LLNameListCtrl* estate_manager_name_list =
   109.1 --- a/indra/newview/llfloatersidepanelcontainer.cpp	Thu Oct 17 18:26:04 2013 -0400
   109.2 +++ b/indra/newview/llfloatersidepanelcontainer.cpp	Tue Nov 12 14:06:38 2013 -0500
   109.3 @@ -57,7 +57,7 @@
   109.4  	getChild<LLPanel>(sMainPanelName)->onOpen(key);
   109.5  }
   109.6  
   109.7 -void LLFloaterSidePanelContainer::onClickCloseBtn()
   109.8 +void LLFloaterSidePanelContainer::onClickCloseBtn(bool)
   109.9  {
  109.10  	LLPanelOutfitEdit* panel_outfit_edit =
  109.11  		dynamic_cast<LLPanelOutfitEdit*>(LLFloaterSidePanelContainer::getPanel("appearance", "panel_outfit_edit"));
   110.1 --- a/indra/newview/llfloatersidepanelcontainer.h	Thu Oct 17 18:26:04 2013 -0400
   110.2 +++ b/indra/newview/llfloatersidepanelcontainer.h	Tue Nov 12 14:06:38 2013 -0500
   110.3 @@ -51,7 +51,7 @@
   110.4  
   110.5  	/*virtual*/ void onOpen(const LLSD& key);
   110.6  
   110.7 -	/*virtual*/ void onClickCloseBtn();
   110.8 +	/*virtual*/ void onClickCloseBtn(bool app_quitting = false);
   110.9  
  110.10  	LLPanel* openChildPanel(const std::string& panel_name, const LLSD& params);
  110.11  
   111.1 --- a/indra/newview/llfloatersnapshot.cpp	Thu Oct 17 18:26:04 2013 -0400
   111.2 +++ b/indra/newview/llfloatersnapshot.cpp	Tue Nov 12 14:06:38 2013 -0500
   111.3 @@ -28,60 +28,23 @@
   111.4  
   111.5  #include "llfloatersnapshot.h"
   111.6  
   111.7 +#include "llagent.h"
   111.8 +#include "llfacebookconnect.h"
   111.9  #include "llfloaterreg.h"
  111.10 -
  111.11 -// Viewer includes
  111.12 -#include "llagent.h"
  111.13 -#include "llagentcamera.h"
  111.14 -#include "llcallbacklist.h"
  111.15 -#include "llcriticaldamp.h"
  111.16 -#include "llfloaterperms.h"
  111.17 -#include "llui.h"
  111.18 -#include "llfocusmgr.h"
  111.19 -#include "llbutton.h"
  111.20 +#include "llfloatersocial.h"
  111.21 +#include "llcheckboxctrl.h"
  111.22  #include "llcombobox.h"
  111.23 -#include "lleconomy.h"
  111.24 -#include "lllandmarkactions.h"
  111.25 -#include "llpanelsnapshot.h"
  111.26 +#include "llpostcard.h"
  111.27 +#include "llresmgr.h"		// LLLocale
  111.28 +#include "llsdserialize.h"
  111.29  #include "llsidetraypanelcontainer.h"
  111.30 -#include "llsliderctrl.h"
  111.31 +#include "llsnapshotlivepreview.h"
  111.32  #include "llspinctrl.h"
  111.33  #include "llviewercontrol.h"
  111.34 -#include "lluictrlfactory.h"
  111.35 -#include "llviewerstats.h"
  111.36 -#include "llviewercamera.h"
  111.37 -#include "llviewerwindow.h"
  111.38 -#include "llviewermenufile.h"	// upload_new_resource()
  111.39 -#include "llcheckboxctrl.h"
  111.40 -#include "llslurl.h"
  111.41  #include "lltoolfocus.h"
  111.42  #include "lltoolmgr.h"
  111.43 +#include "llwebprofile.h"
  111.44  #include "llwebsharing.h"
  111.45 -#include "llworld.h"
  111.46 -#include "llagentui.h"
  111.47 -
  111.48 -// Linden library includes
  111.49 -#include "llfontgl.h"
  111.50 -#include "llsys.h"
  111.51 -#include "llrender.h"
  111.52 -#include "v3dmath.h"
  111.53 -#include "llmath.h"
  111.54 -#include "lldir.h"
  111.55 -#include "llsdserialize.h"
  111.56 -#include "llgl.h"
  111.57 -#include "llglheaders.h"
  111.58 -#include "llimagejpeg.h"
  111.59 -#include "llimagepng.h"
  111.60 -#include "llimagebmp.h"
  111.61 -#include "llimagej2c.h"
  111.62 -#include "lllocalcliprect.h"
  111.63 -#include "llnotificationsutil.h"
  111.64 -#include "llpostcard.h"
  111.65 -#include "llresmgr.h"		// LLLocale
  111.66 -#include "llvfile.h"
  111.67 -#include "llvfs.h"
  111.68 -#include "llwebprofile.h"
  111.69 -#include "llwindow.h"
  111.70  
  111.71  ///----------------------------------------------------------------------------
  111.72  /// Local function declarations, constants, enums, and typedefs
  111.73 @@ -91,950 +54,13 @@
  111.74  
  111.75  const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
  111.76  
  111.77 -F32 SHINE_TIME = 0.5f;
  111.78 -F32 SHINE_WIDTH = 0.6f;
  111.79 -F32 SHINE_OPACITY = 0.3f;
  111.80 -F32 FALL_TIME = 0.6f;
  111.81 -S32 BORDER_WIDTH = 6;
  111.82 -
  111.83  const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte
  111.84  const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
  111.85  
  111.86  static LLDefaultChildRegistry::Register<LLSnapshotFloaterView> r("snapshot_floater_view");
  111.87  
  111.88 -///----------------------------------------------------------------------------
  111.89 -/// Class LLSnapshotLivePreview 
  111.90 -///----------------------------------------------------------------------------
  111.91 -class LLSnapshotLivePreview : public LLView
  111.92 -{
  111.93 -	LOG_CLASS(LLSnapshotLivePreview);
  111.94 -public:
  111.95 -	enum ESnapshotType
  111.96 -	{
  111.97 -		SNAPSHOT_POSTCARD,
  111.98 -		SNAPSHOT_TEXTURE,
  111.99 -		SNAPSHOT_LOCAL,
 111.100 -		SNAPSHOT_WEB
 111.101 -	};
 111.102  
 111.103  
 111.104 -	struct Params : public LLInitParam::Block<Params, LLView::Params>
 111.105 -	{
 111.106 -		Params()
 111.107 -		{
 111.108 -			name = "snapshot_live_preview";
 111.109 -			mouse_opaque = false;
 111.110 -		}
 111.111 -	};
 111.112 -
 111.113 -
 111.114 -	LLSnapshotLivePreview(const LLSnapshotLivePreview::Params& p);
 111.115 -	~LLSnapshotLivePreview();
 111.116 -
 111.117 -	/*virtual*/ void draw();
 111.118 -	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
 111.119 -	
 111.120 -	void setSize(S32 w, S32 h);
 111.121 -	void setWidth(S32 w) { mWidth[mCurImageIndex] = w; }
 111.122 -	void setHeight(S32 h) { mHeight[mCurImageIndex] = h; }
 111.123 -	void getSize(S32& w, S32& h) const;
 111.124 -	S32 getWidth() const { return mWidth[mCurImageIndex]; }
 111.125 -	S32 getHeight() const { return mHeight[mCurImageIndex]; }
 111.126 -	S32 getDataSize() const { return mDataSize; }
 111.127 -	void setMaxImageSize(S32 size) ;
 111.128 -	S32  getMaxImageSize() {return mMaxImageSize ;}
 111.129 -	
 111.130 -	ESnapshotType getSnapshotType() const { return mSnapshotType; }
 111.131 -	LLFloaterSnapshot::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; }
 111.132 -	BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; }
 111.133 -	BOOL isSnapshotActive() { return mSnapshotActive; }
 111.134 -	LLViewerTexture* getThumbnailImage() const { return mThumbnailImage ; }
 111.135 -	S32  getThumbnailWidth() const { return mThumbnailWidth ; }
 111.136 -	S32  getThumbnailHeight() const { return mThumbnailHeight ; }
 111.137 -	BOOL getThumbnailLock() const { return mThumbnailUpdateLock ; }
 111.138 -	BOOL getThumbnailUpToDate() const { return mThumbnailUpToDate ;}
 111.139 -	LLViewerTexture* getCurrentImage();
 111.140 -	F32 getImageAspect();
 111.141 -	F32 getAspect() ;
 111.142 -	const LLRect& getImageRect() const { return mImageRect[mCurImageIndex]; }
 111.143 -	BOOL isImageScaled() const { return mImageScaled[mCurImageIndex]; }
 111.144 -	void setImageScaled(BOOL scaled) { mImageScaled[mCurImageIndex] = scaled; }
 111.145 -	const LLVector3d& getPosTakenGlobal() const { return mPosTakenGlobal; }
 111.146 -	
 111.147 -	void setSnapshotType(ESnapshotType type) { mSnapshotType = type; }
 111.148 -	void setSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat type) { mSnapshotFormat = type; }
 111.149 -	void setSnapshotQuality(S32 quality);
 111.150 -	void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; }
 111.151 -	void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f);
 111.152 -	void saveWeb();
 111.153 -	void saveTexture();
 111.154 -	BOOL saveLocal();
 111.155 -
 111.156 -	LLPointer<LLImageFormatted>	getFormattedImage() const { return mFormattedImage; }
 111.157 -	LLPointer<LLImageRaw>		getEncodedImage() const { return mPreviewImageEncoded; }
 111.158 -
 111.159 -	/// Sets size of preview thumbnail image and thhe surrounding rect.
 111.160 -	BOOL setThumbnailImageSize() ;
 111.161 -	void generateThumbnailImage(BOOL force_update = FALSE) ;
 111.162 -	void resetThumbnailImage() { mThumbnailImage = NULL ; }
 111.163 -	void drawPreviewRect(S32 offset_x, S32 offset_y) ;
 111.164 -
 111.165 -	// Returns TRUE when snapshot generated, FALSE otherwise.
 111.166 -	static BOOL onIdle( void* snapshot_preview );
 111.167 -
 111.168 -	// callback for region name resolve
 111.169 -	void regionNameCallback(LLImageJPEG* snapshot, LLSD& metadata, const std::string& name, S32 x, S32 y, S32 z);
 111.170 -
 111.171 -private:
 111.172 -	LLColor4					mColor;
 111.173 -	LLPointer<LLViewerTexture>	mViewerImage[2]; //used to represent the scene when the frame is frozen.
 111.174 -	LLRect						mImageRect[2];
 111.175 -	S32							mWidth[2];
 111.176 -	S32							mHeight[2];
 111.177 -	BOOL						mImageScaled[2];
 111.178 -	S32                         mMaxImageSize ;
 111.179 -	
 111.180 -	//thumbnail image
 111.181 -	LLPointer<LLViewerTexture>	mThumbnailImage ;
 111.182 -	S32                         mThumbnailWidth ;
 111.183 -	S32                         mThumbnailHeight ;
 111.184 -	LLRect                      mPreviewRect ;
 111.185 -	BOOL                        mThumbnailUpdateLock ;
 111.186 -	BOOL                        mThumbnailUpToDate ;
 111.187 -
 111.188 -	S32							mCurImageIndex;
 111.189 -	LLPointer<LLImageRaw>		mPreviewImage;
 111.190 -	LLPointer<LLImageRaw>		mPreviewImageEncoded;
 111.191 -	LLPointer<LLImageFormatted>	mFormattedImage;
 111.192 -	LLFrameTimer				mSnapshotDelayTimer;
 111.193 -	S32							mShineCountdown;
 111.194 -	LLFrameTimer				mShineAnimTimer;
 111.195 -	F32							mFlashAlpha;
 111.196 -	BOOL						mNeedsFlash;
 111.197 -	LLVector3d					mPosTakenGlobal;
 111.198 -	S32							mSnapshotQuality;
 111.199 -	S32							mDataSize;
 111.200 -	ESnapshotType				mSnapshotType;
 111.201 -	LLFloaterSnapshot::ESnapshotFormat	mSnapshotFormat;
 111.202 -	BOOL						mSnapshotUpToDate;
 111.203 -	LLFrameTimer				mFallAnimTimer;
 111.204 -	LLVector3					mCameraPos;
 111.205 -	LLQuaternion				mCameraRot;
 111.206 -	BOOL						mSnapshotActive;
 111.207 -	LLViewerWindow::ESnapshotType mSnapshotBufferType;
 111.208 -
 111.209 -public:
 111.210 -	static std::set<LLSnapshotLivePreview*> sList;
 111.211 -	BOOL                        mKeepAspectRatio ;
 111.212 -};
 111.213 -
 111.214 -std::set<LLSnapshotLivePreview*> LLSnapshotLivePreview::sList;
 111.215 -
 111.216 -LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Params& p) 
 111.217 -:	LLView(p),
 111.218 -	mColor(1.f, 0.f, 0.f, 0.5f), 
 111.219 -	mCurImageIndex(0),
 111.220 -	mPreviewImage(NULL),
 111.221 -	mThumbnailImage(NULL) ,
 111.222 -	mThumbnailWidth(0),
 111.223 -	mThumbnailHeight(0),
 111.224 -	mPreviewImageEncoded(NULL),
 111.225 -	mFormattedImage(NULL),
 111.226 -	mShineCountdown(0),
 111.227 -	mFlashAlpha(0.f),
 111.228 -	mNeedsFlash(TRUE),
 111.229 -	mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")),
 111.230 -	mDataSize(0),
 111.231 -	mSnapshotType(SNAPSHOT_POSTCARD),
 111.232 -	mSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))),
 111.233 -	mSnapshotUpToDate(FALSE),
 111.234 -	mCameraPos(LLViewerCamera::getInstance()->getOrigin()),
 111.235 -	mCameraRot(LLViewerCamera::getInstance()->getQuaternion()),
 111.236 -	mSnapshotActive(FALSE),
 111.237 -	mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR)
 111.238 -{
 111.239 -	setSnapshotQuality(gSavedSettings.getS32("SnapshotQuality"));
 111.240 -	mSnapshotDelayTimer.setTimerExpirySec(0.0f);
 111.241 -	mSnapshotDelayTimer.start();
 111.242 -// 	gIdleCallbacks.addFunction( &LLSnapshotLivePreview::onIdle, (void*)this );
 111.243 -	sList.insert(this);
 111.244 -	setFollowsAll();
 111.245 -	mWidth[0] = gViewerWindow->getWindowWidthRaw();
 111.246 -	mWidth[1] = gViewerWindow->getWindowWidthRaw();
 111.247 -	mHeight[0] = gViewerWindow->getWindowHeightRaw();
 111.248 -	mHeight[1] = gViewerWindow->getWindowHeightRaw();
 111.249 -	mImageScaled[0] = FALSE;
 111.250 -	mImageScaled[1] = FALSE;
 111.251 -
 111.252 -	mMaxImageSize = MAX_SNAPSHOT_IMAGE_SIZE ;
 111.253 -	mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ;
 111.254 -	mThumbnailUpdateLock = FALSE ;
 111.255 -	mThumbnailUpToDate   = FALSE ;
 111.256 -}
 111.257 -
 111.258 -LLSnapshotLivePreview::~LLSnapshotLivePreview()
 111.259 -{
 111.260 -	// delete images
 111.261 -	mPreviewImage = NULL;
 111.262 -	mPreviewImageEncoded = NULL;
 111.263 -	mFormattedImage = NULL;
 111.264 -
 111.265 -// 	gIdleCallbacks.deleteFunction( &LLSnapshotLivePreview::onIdle, (void*)this );
 111.266 -	sList.erase(this);
 111.267 -}
 111.268 -
 111.269 -void LLSnapshotLivePreview::setMaxImageSize(S32 size) 
 111.270 -{
 111.271 -	if(size < MAX_SNAPSHOT_IMAGE_SIZE)
 111.272 -	{
 111.273 -		mMaxImageSize = size;
 111.274 -	}
 111.275 -	else
 111.276 -	{
 111.277 -		mMaxImageSize = MAX_SNAPSHOT_IMAGE_SIZE ;
 111.278 -	}
 111.279 -}
 111.280 -
 111.281 -LLViewerTexture* LLSnapshotLivePreview::getCurrentImage()
 111.282 -{
 111.283 -	return mViewerImage[mCurImageIndex];
 111.284 -}
 111.285 -
 111.286 -F32 LLSnapshotLivePreview::getAspect()
 111.287 -{
 111.288 -	F32 image_aspect_ratio = ((F32)getWidth()) / ((F32)getHeight());
 111.289 -	F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight());
 111.290 -
 111.291 -	if (!mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot"))
 111.292 -	{
 111.293 -		return image_aspect_ratio;
 111.294 -	}
 111.295 -	else
 111.296 -	{
 111.297 -		return window_aspect_ratio;
 111.298 -	}
 111.299 -}
 111.300 -
 111.301 -F32 LLSnapshotLivePreview::getImageAspect()
 111.302 -{
 111.303 -	if (!getCurrentImage())
 111.304 -	{
 111.305 -		return 0.f;
 111.306 -	}
 111.307 -
 111.308 -	return getAspect() ;	
 111.309 -}
 111.310 -
 111.311 -void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail, F32 delay) 
 111.312 -{
 111.313 -	// Invalidate current image.
 111.314 -	lldebugs << "updateSnapshot: mSnapshotUpToDate = " << getSnapshotUpToDate() << llendl;
 111.315 -	if (getSnapshotUpToDate())
 111.316 -	{
 111.317 -		S32 old_image_index = mCurImageIndex;
 111.318 -		mCurImageIndex = (mCurImageIndex + 1) % 2; 
 111.319 -		setSize(mWidth[old_image_index], mHeight[old_image_index]);
 111.320 -		mFallAnimTimer.start();		
 111.321 -	}
 111.322 -	mSnapshotUpToDate = FALSE; 		
 111.323 -
 111.324 -	// Update snapshot source rect depending on whether we keep the aspect ratio.
 111.325 -	LLRect& rect = mImageRect[mCurImageIndex];
 111.326 -	rect.set(0, getRect().getHeight(), getRect().getWidth(), 0);
 111.327 -
 111.328 -	F32 image_aspect_ratio = ((F32)getWidth()) / ((F32)getHeight());
 111.329 -	F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight());
 111.330 -
 111.331 -	if (mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot"))
 111.332 -	{
 111.333 -		if (image_aspect_ratio > window_aspect_ratio)
 111.334 -		{
 111.335 -			// trim off top and bottom
 111.336 -			S32 new_height = llround((F32)getRect().getWidth() / image_aspect_ratio); 
 111.337 -			rect.mBottom += (getRect().getHeight() - new_height) / 2;
 111.338 -			rect.mTop -= (getRect().getHeight() - new_height) / 2;
 111.339 -		}
 111.340 -		else if (image_aspect_ratio < window_aspect_ratio)
 111.341 -		{
 111.342 -			// trim off left and right
 111.343 -			S32 new_width = llround((F32)getRect().getHeight() * image_aspect_ratio); 
 111.344 -			rect.mLeft += (getRect().getWidth() - new_width) / 2;
 111.345 -			rect.mRight -= (getRect().getWidth() - new_width) / 2;
 111.346 -		}
 111.347 -	}
 111.348 -
 111.349 -	// Stop shining animation.
 111.350 -	mShineAnimTimer.stop();
 111.351 -
 111.352 -	// Update snapshot if requested.
 111.353 -	if (new_snapshot)
 111.354 -	{
 111.355 -		mSnapshotDelayTimer.start();
 111.356 -		mSnapshotDelayTimer.setTimerExpirySec(delay);
 111.357 -		LLFloaterSnapshot::preUpdate();
 111.358 -	}
 111.359 -
 111.360 -	// Update thumbnail if requested.
 111.361 -	if(new_thumbnail)
 111.362 -	{
 111.363 -		mThumbnailUpToDate = FALSE ;
 111.364 -	}
 111.365 -}
 111.366 -
 111.367 -void LLSnapshotLivePreview::setSnapshotQuality(S32 quality)
 111.368 -{
 111.369 -	llclamp(quality, 0, 100);
 111.370 -	if (quality != mSnapshotQuality)
 111.371 -	{
 111.372 -		mSnapshotQuality = quality;
 111.373 -		gSavedSettings.setS32("SnapshotQuality", quality);
 111.374 -		mSnapshotUpToDate = FALSE;
 111.375 -	}
 111.376 -}
 111.377 -
 111.378 -void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)
 111.379 -{
 111.380 -	F32 line_width ; 
 111.381 -	glGetFloatv(GL_LINE_WIDTH, &line_width) ;
 111.382 -	glLineWidth(2.0f * line_width) ;
 111.383 -	LLColor4 color(0.0f, 0.0f, 0.0f, 1.0f) ;
 111.384 -	gl_rect_2d( mPreviewRect.mLeft + offset_x, mPreviewRect.mTop + offset_y,
 111.385 -				mPreviewRect.mRight + offset_x, mPreviewRect.mBottom + offset_y, color, FALSE ) ;
 111.386 -	glLineWidth(line_width) ;
 111.387 -
 111.388 -	//draw four alpha rectangles to cover areas outside of the snapshot image
 111.389 -	if(!mKeepAspectRatio)
 111.390 -	{
 111.391 -		LLColor4 alpha_color(0.5f, 0.5f, 0.5f, 0.8f) ;
 111.392 -		S32 dwl = 0, dwr = 0 ;
 111.393 -		if(mThumbnailWidth > mPreviewRect.getWidth())
 111.394 -		{
 111.395 -			dwl = (mThumbnailWidth - mPreviewRect.getWidth()) >> 1 ;
 111.396 -			dwr = mThumbnailWidth - mPreviewRect.getWidth() - dwl ;
 111.397 -
 111.398 -			gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y,
 111.399 -				mPreviewRect.mLeft + offset_x, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ;
 111.400 -			gl_rect_2d( mPreviewRect.mRight + offset_x, mPreviewRect.mTop + offset_y,
 111.401 -				mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ;
 111.402 -		}
 111.403 -
 111.404 -		if(mThumbnailHeight > mPreviewRect.getHeight())
 111.405 -		{
 111.406 -			S32 dh = (mThumbnailHeight - mPreviewRect.getHeight()) >> 1 ;
 111.407 -			gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mBottom + offset_y ,
 111.408 -				mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y - dh, alpha_color, TRUE ) ;
 111.409 -
 111.410 -			dh = mThumbnailHeight - mPreviewRect.getHeight() - dh ;
 111.411 -			gl_rect_2d( mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y + dh,
 111.412 -				mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mTop + offset_y, alpha_color, TRUE ) ;
 111.413 -		}
 111.414 -	}
 111.415 -}
 111.416 -
 111.417 -//called when the frame is frozen.
 111.418 -void LLSnapshotLivePreview::draw()
 111.419 -{
 111.420 -	if (getCurrentImage() &&
 111.421 -	    mPreviewImageEncoded.notNull() &&
 111.422 -	    getSnapshotUpToDate())
 111.423 -	{
 111.424 -		LLColor4 bg_color(0.f, 0.f, 0.3f, 0.4f);
 111.425 -		gl_rect_2d(getRect(), bg_color);
 111.426 -		const LLRect& rect = getImageRect();
 111.427 -		LLRect shadow_rect = rect;
 111.428 -		shadow_rect.stretch(BORDER_WIDTH);
 111.429 -		gl_drop_shadow(shadow_rect.mLeft, shadow_rect.mTop, shadow_rect.mRight, shadow_rect.mBottom, LLColor4(0.f, 0.f, 0.f, mNeedsFlash ? 0.f :0.5f), 10);
 111.430 -
 111.431 -		LLColor4 image_color(1.f, 1.f, 1.f, 1.f);
 111.432 -		gGL.color4fv(image_color.mV);
 111.433 -		gGL.getTexUnit(0)->bind(getCurrentImage());
 111.434 -		// calculate UV scale
 111.435 -		F32 uv_width = isImageScaled() ? 1.f : llmin((F32)getWidth() / (F32)getCurrentImage()->getWidth(), 1.f);
 111.436 -		F32 uv_height = isImageScaled() ? 1.f : llmin((F32)getHeight() / (F32)getCurrentImage()->getHeight(), 1.f);
 111.437 -		gGL.pushMatrix();
 111.438 -		{
 111.439 -			gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom, 0.f);
 111.440 -			gGL.begin(LLRender::QUADS);
 111.441 -			{
 111.442 -				gGL.texCoord2f(uv_width, uv_height);
 111.443 -				gGL.vertex2i(rect.getWidth(), rect.getHeight() );
 111.444 -
 111.445 -				gGL.texCoord2f(0.f, uv_height);
 111.446 -				gGL.vertex2i(0, rect.getHeight() );
 111.447 -
 111.448 -				gGL.texCoord2f(0.f, 0.f);
 111.449 -				gGL.vertex2i(0, 0);
 111.450 -
 111.451 -				gGL.texCoord2f(uv_width, 0.f);
 111.452 -				gGL.vertex2i(rect.getWidth(), 0);
 111.453 -			}
 111.454 -			gGL.end();
 111.455 -		}
 111.456 -		gGL.popMatrix();
 111.457 -
 111.458 -		gGL.color4f(1.f, 1.f, 1.f, mFlashAlpha);
 111.459 -		gl_rect_2d(getRect());
 111.460 -		if (mNeedsFlash)
 111.461 -		{
 111.462 -			if (mFlashAlpha < 1.f)
 111.463 -			{
 111.464 -				mFlashAlpha = lerp(mFlashAlpha, 1.f, LLCriticalDamp::getInterpolant(0.02f));
 111.465 -			}
 111.466 -			else
 111.467 -			{
 111.468 -				mNeedsFlash = FALSE;
 111.469 -			}
 111.470 -		}
 111.471 -		else
 111.472 -		{
 111.473 -			mFlashAlpha = lerp(mFlashAlpha, 0.f, LLCriticalDamp::getInterpolant(0.15f));
 111.474 -		}
 111.475 -
 111.476 -		// Draw shining animation if appropriate.
 111.477 -		if (mShineCountdown > 0)
 111.478 -		{
 111.479 -			mShineCountdown--;
 111.480 -			if (mShineCountdown == 0)
 111.481 -			{
 111.482 -				mShineAnimTimer.start();
 111.483 -			}
 111.484 -		}
 111.485 -		else if (mShineAnimTimer.getStarted())
 111.486 -		{
 111.487 -			lldebugs << "Drawing shining animation" << llendl;
 111.488 -			F32 shine_interp = llmin(1.f, mShineAnimTimer.getElapsedTimeF32() / SHINE_TIME);
 111.489 -			
 111.490 -			// draw "shine" effect
 111.491 -			LLLocalClipRect clip(getLocalRect());
 111.492 -			{
 111.493 -				// draw diagonal stripe with gradient that passes over screen
 111.494 -				S32 x1 = gViewerWindow->getWindowWidthScaled() * llround((clamp_rescale(shine_interp, 0.f, 1.f, -1.f - SHINE_WIDTH, 1.f)));
 111.495 -				S32 x2 = x1 + llround(gViewerWindow->getWindowWidthScaled() * SHINE_WIDTH);
 111.496 -				S32 x3 = x2 + llround(gViewerWindow->getWindowWidthScaled() * SHINE_WIDTH);
 111.497 -				S32 y1 = 0;
 111.498 -				S32 y2 = gViewerWindow->getWindowHeightScaled();
 111.499 -
 111.500 -				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 111.501 -				gGL.begin(LLRender::QUADS);
 111.502 -				{
 111.503 -					gGL.color4f(1.f, 1.f, 1.f, 0.f);
 111.504 -					gGL.vertex2i(x1, y1);
 111.505 -					gGL.vertex2i(x1 + gViewerWindow->getWindowWidthScaled(), y2);
 111.506 -					gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY);
 111.507 -					gGL.vertex2i(x2 + gViewerWindow->getWindowWidthScaled(), y2);
 111.508 -					gGL.vertex2i(x2, y1);
 111.509 -
 111.510 -					gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY);
 111.511 -					gGL.vertex2i(x2, y1);
 111.512 -					gGL.vertex2i(x2 + gViewerWindow->getWindowWidthScaled(), y2);
 111.513 -					gGL.color4f(1.f, 1.f, 1.f, 0.f);
 111.514 -					gGL.vertex2i(x3 + gViewerWindow->getWindowWidthScaled(), y2);
 111.515 -					gGL.vertex2i(x3, y1);
 111.516 -				}
 111.517 -				gGL.end();
 111.518 -			}
 111.519 -
 111.520 -			// if we're at the end of the animation, stop
 111.521 -			if (shine_interp >= 1.f)
 111.522 -			{
 111.523 -				mShineAnimTimer.stop();
 111.524 -			}
 111.525 -		}
 111.526 -	}
 111.527 -
 111.528 -	// draw framing rectangle
 111.529 -	{
 111.530 -		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 111.531 -		gGL.color4f(1.f, 1.f, 1.f, 1.f);
 111.532 -		const LLRect& outline_rect = getImageRect();
 111.533 -		gGL.begin(LLRender::QUADS);
 111.534 -		{
 111.535 -			gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
 111.536 -			gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
 111.537 -			gGL.vertex2i(outline_rect.mRight, outline_rect.mTop);
 111.538 -			gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
 111.539 -
 111.540 -			gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom);
 111.541 -			gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom);
 111.542 -			gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
 111.543 -			gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
 111.544 -
 111.545 -			gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
 111.546 -			gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom);
 111.547 -			gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
 111.548 -			gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
 111.549 -
 111.550 -			gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom);
 111.551 -			gGL.vertex2i(outline_rect.mRight, outline_rect.mTop);
 111.552 -			gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
 111.553 -			gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
 111.554 -		}
 111.555 -		gGL.end();
 111.556 -	}
 111.557 -
 111.558 -	// draw old image dropping away
 111.559 -	if (mFallAnimTimer.getStarted())
 111.560 -	{
 111.561 -		S32 old_image_index = (mCurImageIndex + 1) % 2;
 111.562 -		if (mViewerImage[old_image_index].notNull() && mFallAnimTimer.getElapsedTimeF32() < FALL_TIME)
 111.563 -		{
 111.564 -			lldebugs << "Drawing fall animation" << llendl;
 111.565 -			F32 fall_interp = mFallAnimTimer.getElapsedTimeF32() / FALL_TIME;
 111.566 -			F32 alpha = clamp_rescale(fall_interp, 0.f, 1.f, 0.8f, 0.4f);
 111.567 -			LLColor4 image_color(1.f, 1.f, 1.f, alpha);
 111.568 -			gGL.color4fv(image_color.mV);
 111.569 -			gGL.getTexUnit(0)->bind(mViewerImage[old_image_index]);
 111.570 -			// calculate UV scale
 111.571 -			// *FIX get this to work with old image
 111.572 -			BOOL rescale = !mImageScaled[old_image_index] && mViewerImage[mCurImageIndex].notNull();
 111.573 -			F32 uv_width = rescale ? llmin((F32)mWidth[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f) : 1.f;
 111.574 -			F32 uv_height = rescale ? llmin((F32)mHeight[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f) : 1.f;
 111.575 -			gGL.pushMatrix();
 111.576 -			{
 111.577 -				LLRect& rect = mImageRect[old_image_index];
 111.578 -				gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom - llround(getRect().getHeight() * 2.f * (fall_interp * fall_interp)), 0.f);
 111.579 -				gGL.rotatef(-45.f * fall_interp, 0.f, 0.f, 1.f);
 111.580 -				gGL.begin(LLRender::QUADS);
 111.581 -				{
 111.582 -					gGL.texCoord2f(uv_width, uv_height);
 111.583 -					gGL.vertex2i(rect.getWidth(), rect.getHeight() );
 111.584 -
 111.585 -					gGL.texCoord2f(0.f, uv_height);
 111.586 -					gGL.vertex2i(0, rect.getHeight() );
 111.587 -
 111.588 -					gGL.texCoord2f(0.f, 0.f);
 111.589 -					gGL.vertex2i(0, 0);
 111.590 -
 111.591 -					gGL.texCoord2f(uv_width, 0.f);
 111.592 -					gGL.vertex2i(rect.getWidth(), 0);
 111.593 -				}
 111.594 -				gGL.end();
 111.595 -			}
 111.596 -			gGL.popMatrix();
 111.597 -		}
 111.598 -	}
 111.599 -}
 111.600 -
 111.601 -/*virtual*/ 
 111.602 -void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_parent)
 111.603 -{
 111.604 -	LLRect old_rect = getRect();
 111.605 -	LLView::reshape(width, height, called_from_parent);
 111.606 -	if (old_rect.getWidth() != width || old_rect.getHeight() != height)
 111.607 -	{
 111.608 -		lldebugs << "window reshaped, updating thumbnail" << llendl;
 111.609 -		updateSnapshot(FALSE, TRUE);
 111.610 -	}
 111.611 -}
 111.612 -
 111.613 -BOOL LLSnapshotLivePreview::setThumbnailImageSize()
 111.614 -{
 111.615 -	if(getWidth() < 10 || getHeight() < 10)
 111.616 -	{
 111.617 -		return FALSE ;
 111.618 -	}
 111.619 -	S32 window_width = gViewerWindow->getWindowWidthRaw() ;
 111.620 -	S32 window_height = gViewerWindow->getWindowHeightRaw() ;
 111.621 -
 111.622 -	F32 window_aspect_ratio = ((F32)window_width) / ((F32)window_height);
 111.623 -
 111.624 -	// UI size for thumbnail
 111.625 -	// *FIXME: the rect does not change, so maybe there's no need to recalculate max w/h.
 111.626 -	const LLRect& thumbnail_rect = LLFloaterSnapshot::getThumbnailPlaceholderRect();
 111.627 -	S32 max_width = thumbnail_rect.getWidth();
 111.628 -	S32 max_height = thumbnail_rect.getHeight();
 111.629 -
 111.630 -	if (window_aspect_ratio > (F32)max_width / max_height)
 111.631 -	{
 111.632 -		// image too wide, shrink to width
 111.633 -		mThumbnailWidth = max_width;
 111.634 -		mThumbnailHeight = llround((F32)max_width / window_aspect_ratio);
 111.635 -	}
 111.636 -	else
 111.637 -	{
 111.638 -		// image too tall, shrink to height
 111.639 -		mThumbnailHeight = max_height;
 111.640 -		mThumbnailWidth = llround((F32)max_height * window_aspect_ratio);
 111.641 -	}
 111.642 -	
 111.643 -	if(mThumbnailWidth > window_width || mThumbnailHeight > window_height)
 111.644 -	{
 111.645 -		return FALSE ;//if the window is too small, ignore thumbnail updating.
 111.646 -	}
 111.647 -
 111.648 -	S32 left = 0 , top = mThumbnailHeight, right = mThumbnailWidth, bottom = 0 ;
 111.649 -	if(!mKeepAspectRatio)
 111.650 -	{
 111.651 -		F32 ratio_x = (F32)getWidth() / window_width ;
 111.652 -		F32 ratio_y = (F32)getHeight() / window_height ;
 111.653 -
 111.654 -		//if(getWidth() > window_width ||
 111.655 -		//	getHeight() > window_height )
 111.656 -		{
 111.657 -			if(ratio_x > ratio_y)
 111.658 -			{
 111.659 -				top = (S32)(top * ratio_y / ratio_x) ;
 111.660 -			}
 111.661 -			else
 111.662 -			{
 111.663 -				right = (S32)(right * ratio_x / ratio_y) ;
 111.664 -			}			
 111.665 -		}
 111.666 -		//else
 111.667 -		//{
 111.668 -		//	right = (S32)(right * ratio_x) ;
 111.669 -		//	top = (S32)(top * ratio_y) ;
 111.670 -		//}
 111.671 -		left = (S32)((mThumbnailWidth - right) * 0.5f) ;
 111.672 -		bottom = (S32)((mThumbnailHeight - top) * 0.5f) ;
 111.673 -		top += bottom ;
 111.674 -		right += left ;
 111.675 -	}
 111.676 -	mPreviewRect.set(left - 1, top + 1, right + 1, bottom - 1) ;
 111.677 -
 111.678 -	return TRUE ;
 111.679 -}
 111.680 -
 111.681 -void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
 111.682 -{	
 111.683 -	if(mThumbnailUpdateLock) //in the process of updating
 111.684 -	{
 111.685 -		return ;
 111.686 -	}
 111.687 -	if(getThumbnailUpToDate() && !force_update)//already updated
 111.688 -	{
 111.689 -		return ;
 111.690 -	}
 111.691 -	if(getWidth() < 10 || getHeight() < 10)
 111.692 -	{
 111.693 -		return ;
 111.694 -	}
 111.695 -
 111.696 -	////lock updating
 111.697 -	mThumbnailUpdateLock = TRUE ;
 111.698 -
 111.699 -	if(!setThumbnailImageSize())
 111.700 -	{
 111.701 -		mThumbnailUpdateLock = FALSE ;
 111.702 -		mThumbnailUpToDate = TRUE ;
 111.703 -		return ;
 111.704 -	}
 111.705 -
 111.706 -	if(mThumbnailImage)
 111.707 -	{
 111.708 -		resetThumbnailImage() ;
 111.709 -	}		
 111.710 -
 111.711 -	LLPointer<LLImageRaw> raw = new LLImageRaw;
 111.712 -	if(!gViewerWindow->thumbnailSnapshot(raw,
 111.713 -							mThumbnailWidth, mThumbnailHeight,
 111.714 -							gSavedSettings.getBOOL("RenderUIInSnapshot"),
 111.715 -							FALSE,
 111.716 -							mSnapshotBufferType) )								
 111.717 -	{
 111.718 -		raw = NULL ;
 111.719 -	}
 111.720 -
 111.721 -	if(raw)
 111.722 -	{
 111.723 -		raw->expandToPowerOfTwo();
 111.724 -		mThumbnailImage = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); 		
 111.725 -		mThumbnailUpToDate = TRUE ;
 111.726 -	}
 111.727 -
 111.728 -	//unlock updating
 111.729 -	mThumbnailUpdateLock = FALSE ;		
 111.730 -}
 111.731 -
 111.732 -
 111.733 -// Called often. Checks whether it's time to grab a new snapshot and if so, does it.
 111.734 -// Returns TRUE if new snapshot generated, FALSE otherwise.
 111.735 -//static 
 111.736 -BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
 111.737 -{
 111.738 -	LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)snapshot_preview;
 111.739 -	if (previewp->getWidth() == 0 || previewp->getHeight() == 0)
 111.740 -	{
 111.741 -		llwarns << "Incorrect dimensions: " << previewp->getWidth() << "x" << previewp->getHeight() << llendl;
 111.742 -		return FALSE;
 111.743 -	}
 111.744 -
 111.745 -	// If we're in freeze-frame mode and camera has moved, update snapshot.
 111.746 -	LLVector3 new_camera_pos = LLViewerCamera::getInstance()->getOrigin();
 111.747 -	LLQuaternion new_camera_rot = LLViewerCamera::getInstance()->getQuaternion();
 111.748 -	if (gSavedSettings.getBOOL("FreezeTime") && 
 111.749 -		(new_camera_pos != previewp->mCameraPos || dot(new_camera_rot, previewp->mCameraRot) < 0.995f))
 111.750 -	{
 111.751 -		previewp->mCameraPos = new_camera_pos;
 111.752 -		previewp->mCameraRot = new_camera_rot;
 111.753 -		// request a new snapshot whenever the camera moves, with a time delay
 111.754 -		BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot");
 111.755 -		lldebugs << "camera moved, updating thumbnail" << llendl;
 111.756 -		previewp->updateSnapshot(
 111.757 -			autosnap, // whether a new snapshot is needed or merely invalidate the existing one
 111.758 -			FALSE, // or if 1st arg is false, whether to produce a new thumbnail image.
 111.759 -			autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f); // shutter delay if 1st arg is true.
 111.760 -	}
 111.761 -
 111.762 -	// see if it's time yet to snap the shot and bomb out otherwise.
 111.763 -	previewp->mSnapshotActive = 
 111.764 -		(previewp->mSnapshotDelayTimer.getStarted() &&	previewp->mSnapshotDelayTimer.hasExpired())
 111.765 -		&& !LLToolCamera::getInstance()->hasMouseCapture(); // don't take snapshots while ALT-zoom active
 111.766 -	if ( ! previewp->mSnapshotActive)
 111.767 -	{
 111.768 -		return FALSE;
 111.769 -	}
 111.770 -
 111.771 -	// time to produce a snapshot
 111.772 -	previewp->setThumbnailImageSize();
 111.773 -
 111.774 -	lldebugs << "producing snapshot" << llendl;
 111.775 -	if (!previewp->mPreviewImage)
 111.776 -	{
 111.777 -		previewp->mPreviewImage = new LLImageRaw;
 111.778 -	}
 111.779 -
 111.780 -	if (!previewp->mPreviewImageEncoded)
 111.781 -	{
 111.782 -		previewp->mPreviewImageEncoded = new LLImageRaw;
 111.783 -	}
 111.784 -
 111.785 -	previewp->setVisible(FALSE);
 111.786 -	previewp->setEnabled(FALSE);
 111.787 -	
 111.788 -	previewp->getWindow()->incBusyCount();
 111.789 -	previewp->setImageScaled(FALSE);
 111.790 -
 111.791 -	// grab the raw image and encode it into desired format
 111.792 -	if(gViewerWindow->rawSnapshot(
 111.793 -							previewp->mPreviewImage,
 111.794 -							previewp->getWidth(),
 111.795 -							previewp->getHeight(),
 111.796 -							previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"),
 111.797 -							previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE,
 111.798 -							gSavedSettings.getBOOL("RenderUIInSnapshot"),
 111.799 -							FALSE,
 111.800 -							previewp->mSnapshotBufferType,
 111.801 -							previewp->getMaxImageSize()))
 111.802 -	{
 111.803 -		previewp->mPreviewImageEncoded->resize(
 111.804 -			previewp->mPreviewImage->getWidth(), 
 111.805 -			previewp->mPreviewImage->getHeight(), 
 111.806 -			previewp->mPreviewImage->getComponents());
 111.807 -
 111.808 -		if(previewp->getSnapshotType() == SNAPSHOT_TEXTURE)
 111.809 -		{
 111.810 -			lldebugs << "Encoding new image of format J2C" << llendl;
 111.811 -			LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
 111.812 -			LLPointer<LLImageRaw> scaled = new LLImageRaw(
 111.813 -				previewp->mPreviewImage->getData(),
 111.814 -				previewp->mPreviewImage->getWidth(),
 111.815 -				previewp->mPreviewImage->getHeight(),
 111.816 -				previewp->mPreviewImage->getComponents());
 111.817 -		
 111.818 -			scaled->biasedScaleToPowerOfTwo(MAX_TEXTURE_SIZE);
 111.819 -			previewp->setImageScaled(TRUE);
 111.820 -			if (formatted->encode(scaled, 0.f))
 111.821 -			{
 111.822 -				previewp->mDataSize = formatted->getDataSize();
 111.823 -				formatted->decode(previewp->mPreviewImageEncoded, 0);
 111.824 -			}
 111.825 -		}
 111.826 -		else
 111.827 -		{
 111.828 -			// delete any existing image
 111.829 -			previewp->mFormattedImage = NULL;
 111.830 -			// now create the new one of the appropriate format.
 111.831 -			LLFloaterSnapshot::ESnapshotFormat format = previewp->getSnapshotFormat();
 111.832 -			lldebugs << "Encoding new image of format " << format << llendl;
 111.833 -
 111.834 -			switch(format)
 111.835 -			{
 111.836 -			case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
 111.837 -				previewp->mFormattedImage = new LLImagePNG(); 
 111.838 -				break;
 111.839 -			case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
 111.840 -				previewp->mFormattedImage = new LLImageJPEG(previewp->mSnapshotQuality); 
 111.841 -				break;
 111.842 -			case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:
 111.843 -				previewp->mFormattedImage = new LLImageBMP(); 
 111.844 -				break;
 111.845 -			}
 111.846 -			if (previewp->mFormattedImage->encode(previewp->mPreviewImage, 0))
 111.847 -			{
 111.848 -				previewp->mDataSize = previewp->mFormattedImage->getDataSize();
 111.849 -				// special case BMP to copy instead of decode otherwise decode will crash.
 111.850 -				if(format == LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP)
 111.851 -				{
 111.852 -					previewp->mPreviewImageEncoded->copy(previewp->mPreviewImage);
 111.853 -				}
 111.854 -				else
 111.855 -				{
 111.856 -					previewp->mFormattedImage->decode(previewp->mPreviewImageEncoded, 0);
 111.857 -				}
 111.858 -			}
 111.859 -		}
 111.860 -
 111.861 -		LLPointer<LLImageRaw> scaled = new LLImageRaw(
 111.862 -			previewp->mPreviewImageEncoded->getData(),
 111.863 -			previewp->mPreviewImageEncoded->getWidth(),
 111.864 -			previewp->mPreviewImageEncoded->getHeight(),
 111.865 -			previewp->mPreviewImageEncoded->getComponents());
 111.866 -		
 111.867 -		if(!scaled->isBufferInvalid())
 111.868 -		{
 111.869 -			// leave original image dimensions, just scale up texture buffer
 111.870 -			if (previewp->mPreviewImageEncoded->getWidth() > 1024 || previewp->mPreviewImageEncoded->getHeight() > 1024)
 111.871 -			{
 111.872 -				// go ahead and shrink image to appropriate power of 2 for display
 111.873 -				scaled->biasedScaleToPowerOfTwo(1024);
 111.874 -				previewp->setImageScaled(TRUE);
 111.875 -			}
 111.876 -			else
 111.877 -			{
 111.878 -				// expand image but keep original image data intact
 111.879 -				scaled->expandToPowerOfTwo(1024, FALSE);
 111.880 -			}
 111.881 -
 111.882 -			previewp->mViewerImage[previewp->mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE);
 111.883 -			LLPointer<LLViewerTexture> curr_preview_image = previewp->mViewerImage[previewp->mCurImageIndex];
 111.884 -			gGL.getTexUnit(0)->bind(curr_preview_image);
 111.885 -			if (previewp->getSnapshotType() != SNAPSHOT_TEXTURE)
 111.886 -			{
 111.887 -				curr_preview_image->setFilteringOption(LLTexUnit::TFO_POINT);
 111.888 -			}
 111.889 -			else
 111.890 -			{
 111.891 -				curr_preview_image->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
 111.892 -			}
 111.893 -			curr_preview_image->setAddressMode(LLTexUnit::TAM_CLAMP);
 111.894 -
 111.895 -			previewp->mSnapshotUpToDate = TRUE;
 111.896 -			previewp->generateThumbnailImage(TRUE) ;
 111.897 -
 111.898 -			previewp->mPosTakenGlobal = gAgentCamera.getCameraPositionGlobal();
 111.899 -			previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame
 111.900 -		}
 111.901 -	}
 111.902 -	previewp->getWindow()->decBusyCount();
 111.903 -	// only show fullscreen preview when in freeze frame mode
 111.904 -	previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame"));
 111.905 -	previewp->mSnapshotDelayTimer.stop();
 111.906 -	previewp->mSnapshotActive = FALSE;
 111.907 -
 111.908 -	if(!previewp->getThumbnailUpToDate())
 111.909 -	{
 111.910 -		previewp->generateThumbnailImage() ;
 111.911 -	}
 111.912 -	lldebugs << "done creating snapshot" << llendl;
 111.913 -	LLFloaterSnapshot::postUpdate();
 111.914 -
 111.915 -	return TRUE;
 111.916 -}
 111.917 -
 111.918 -void LLSnapshotLivePreview::setSize(S32 w, S32 h)
 111.919 -{
 111.920 -	lldebugs << "setSize(" << w << ", " << h << ")" << llendl;
 111.921 -	setWidth(w);
 111.922 -	setHeight(h);
 111.923 -}
 111.924 -
 111.925 -void LLSnapshotLivePreview::getSize(S32& w, S32& h) const
 111.926 -{
 111.927 -	w = getWidth();
 111.928 -	h = getHeight();
 111.929 -}
 111.930 -
 111.931 -void LLSnapshotLivePreview::saveTexture()
 111.932 -{
 111.933 -	lldebugs << "saving texture: " << mPreviewImage->getWidth() << "x" << mPreviewImage->getHeight() << llendl;
 111.934 -	// gen a new uuid for this asset
 111.935 -	LLTransactionID tid;
 111.936 -	tid.generate();
 111.937 -	LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
 111.938 -		
 111.939 -	LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
 111.940 -	LLPointer<LLImageRaw> scaled = new LLImageRaw(mPreviewImage->getData(),
 111.941 -												  mPreviewImage->getWidth(),
 111.942 -												  mPreviewImage->getHeight(),
 111.943 -												  mPreviewImage->getComponents());
 111.944 -	
 111.945 -	scaled->biasedScaleToPowerOfTwo(MAX_TEXTURE_SIZE);
 111.946 -	lldebugs << "scaled texture to " << scaled->getWidth() << "x" << scaled->getHeight() << llendl;
 111.947 -
 111.948 -	if (formatted->encode(scaled, 0.0f))
 111.949 -	{
 111.950 -		LLVFile::writeFile(formatted->getData(), formatted->getDataSize(), gVFS, new_asset_id, LLAssetType::AT_TEXTURE);
 111.951 -		std::string pos_string;
 111.952 -		LLAgentUI::buildLocationString(pos_string, LLAgentUI::LOCATION_FORMAT_FULL);
 111.953 -		std::string who_took_it;
 111.954 -		LLAgentUI::buildFullname(who_took_it);
 111.955 -		LLAssetStorage::LLStoreAssetCallback callback = NULL;
 111.956 -		S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
 111.957 -		void *userdata = NULL;
 111.958 -		upload_new_resource(tid,	// tid
 111.959 -				    LLAssetType::AT_TEXTURE,
 111.960 -				    "Snapshot : " + pos_string,
 111.961 -				    "Taken by " + who_took_it + " at " + pos_string,
 111.962 -				    0,
 111.963 -				    LLFolderType::FT_SNAPSHOT_CATEGORY,
 111.964 -				    LLInventoryType::IT_SNAPSHOT,
 111.965 -				    PERM_ALL,  // Note: Snapshots to inventory is a special case of content upload
 111.966 -				    LLFloaterPerms::getGroupPerms(), // that is more permissive than other uploads
 111.967 -				    LLFloaterPerms::getEveryonePerms(),
 111.968 -				    "Snapshot : " + pos_string,
 111.969 -				    callback, expected_upload_cost, userdata);
 111.970 -		gViewerWindow->playSnapshotAnimAndSound();
 111.971 -	}
 111.972 -	else
 111.973 -	{
 111.974 -		LLNotificationsUtil::add("ErrorEncodingSnapshot");
 111.975 -		llwarns << "Error encoding snapshot" << llendl;
 111.976 -	}
 111.977 -
 111.978 -	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT );
 111.979 -	
 111.980 -	mDataSize = 0;
 111.981 -}
 111.982 -
 111.983 -BOOL LLSnapshotLivePreview::saveLocal()
 111.984 -{
 111.985 -	BOOL success = gViewerWindow->saveImageNumbered(mFormattedImage);
 111.986 -
 111.987 -	if(success)
 111.988 -	{
 111.989 -		gViewerWindow->playSnapshotAnimAndSound();
 111.990 -	}
 111.991 -	return success;
 111.992 -}
 111.993 -
 111.994 -void LLSnapshotLivePreview::saveWeb()
 111.995 -{
 111.996 -	// *FIX: Will break if the window closes because of CloseSnapshotOnKeep!
 111.997 -	// Needs to pass on ownership of the image.
 111.998 -	LLImageJPEG* jpg = dynamic_cast<LLImageJPEG*>(mFormattedImage.get());
 111.999 -	if(!jpg)
111.1000 -	{
111.1001 -		llwarns << "Formatted image not a JPEG" << llendl;
111.1002 -		return;
111.1003 -	}
111.1004 -
111.1005 -	LLSD metadata;
111.1006 -	metadata["description"] = getChild<LLLineEditor>("description")->getText();
111.1007 -
111.1008 -	LLLandmarkActions::getRegionNameAndCoordsFromPosGlobal(gAgentCamera.getCameraPositionGlobal(),
111.1009 -		boost::bind(&LLSnapshotLivePreview::regionNameCallback, this, jpg, metadata, _1, _2, _3, _4));
111.1010 -
111.1011 -	gViewerWindow->playSnapshotAnimAndSound();
111.1012 -}
111.1013 -
111.1014 -void LLSnapshotLivePreview::regionNameCallback(LLImageJPEG* snapshot, LLSD& metadata, const std::string& name, S32 x, S32 y, S32 z)
111.1015 -{
111.1016 -	metadata["slurl"] = LLSLURL(name, LLVector3d(x, y, z)).getSLURLString();
111.1017 -
111.1018 -	LLWebSharing::instance().shareSnapshot(snapshot, metadata);
111.1019 -}
111.1020 -
111.1021  ///----------------------------------------------------------------------------
111.1022  /// Class LLFloaterSnapshot::Impl
111.1023  ///----------------------------------------------------------------------------
111.1024 @@ -2037,7 +1063,7 @@
111.1025  
111.1026  	getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
111.1027  	childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this);
111.1028 -
111.1029 +	
111.1030  	LLWebProfile::setImageUploadResultCallback(boost::bind(&LLFloaterSnapshot::Impl::onSnapshotUploadFinished, _1));
111.1031  	LLPostCard::setPostResultCallback(boost::bind(&LLFloaterSnapshot::Impl::onSendingPostcardFinished, _1));
111.1032  
111.1033 @@ -2070,6 +1096,9 @@
111.1034  	impl.updateControls(this);
111.1035  	impl.updateLayout(this);
111.1036  	
111.1037 +
111.1038 +	previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
111.1039 +
111.1040  	return TRUE;
111.1041  }
111.1042  
111.1043 @@ -2235,7 +1264,9 @@
111.1044  void LLFloaterSnapshot::update()
111.1045  {
111.1046  	LLFloaterSnapshot* inst = LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot");
111.1047 -	if (!inst)
111.1048 +	LLFloaterSocial* floater_social  = LLFloaterReg::findTypedInstance<LLFloaterSocial>("social"); 
111.1049 +
111.1050 +	if (!inst && !floater_social)
111.1051  		return;
111.1052  	
111.1053  	BOOL changed = FALSE;
111.1054 @@ -2245,7 +1276,8 @@
111.1055  	{
111.1056  		changed |= LLSnapshotLivePreview::onIdle(*iter);
111.1057  	}
111.1058 -	if(changed)
111.1059 +    
111.1060 +	if (inst && changed)
111.1061  	{
111.1062  		lldebugs << "changed" << llendl;
111.1063  		inst->impl.updateControls(inst);
   112.1 --- a/indra/newview/llfloatersnapshot.h	Thu Oct 17 18:26:04 2013 -0400
   112.2 +++ b/indra/newview/llfloatersnapshot.h	Tue Nov 12 14:06:38 2013 -0500
   112.3 @@ -27,7 +27,6 @@
   112.4  #ifndef LL_LLFLOATERSNAPSHOT_H
   112.5  #define LL_LLFLOATERSNAPSHOT_H
   112.6  
   112.7 -#include "llimage.h"
   112.8  #include "llfloater.h"
   112.9  
  112.10  class LLSpinCtrl;
   113.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   113.2 +++ b/indra/newview/llfloatersocial.cpp	Tue Nov 12 14:06:38 2013 -0500
   113.3 @@ -0,0 +1,920 @@
   113.4 +/** 
   113.5 +* @file llfloatersocial.cpp
   113.6 +* @brief Implementation of llfloatersocial
   113.7 +* @author Gilbert@lindenlab.com
   113.8 +*
   113.9 +* $LicenseInfo:firstyear=2013&license=viewerlgpl$
  113.10 +* Second Life Viewer Source Code
  113.11 +* Copyright (C) 2013, Linden Research, Inc.
  113.12 +*
  113.13 +* This library is free software; you can redistribute it and/or
  113.14 +* modify it under the terms of the GNU Lesser General Public
  113.15 +* License as published by the Free Software Foundation;
  113.16 +* version 2.1 of the License only.
  113.17 +*
  113.18 +* This library is distributed in the hope that it will be useful,
  113.19 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  113.20 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  113.21 +* Lesser General Public License for more details.
  113.22 +*
  113.23 +* You should have received a copy of the GNU Lesser General Public
  113.24 +* License along with this library; if not, write to the Free Software
  113.25 +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  113.26 +*
  113.27 +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  113.28 +* $/LicenseInfo$
  113.29 +*/
  113.30 +
  113.31 +#include "llviewerprecompiledheaders.h"
  113.32 +
  113.33 +#include "llfloatersocial.h"
  113.34 +
  113.35 +#include "llagent.h"
  113.36 +#include "llagentui.h"
  113.37 +#include "llcheckboxctrl.h"
  113.38 +#include "llcombobox.h"
  113.39 +#include "llfacebookconnect.h"
  113.40 +#include "llfloaterreg.h"
  113.41 +#include "lliconctrl.h"
  113.42 +#include "llresmgr.h"		// LLLocale
  113.43 +#include "llsdserialize.h"
  113.44 +#include "llloadingindicator.h"
  113.45 +#include "llplugincookiestore.h"
  113.46 +#include "llslurl.h"
  113.47 +#include "lltrans.h"
  113.48 +#include "llsnapshotlivepreview.h"
  113.49 +#include "llviewerregion.h"
  113.50 +#include "llviewercontrol.h"
  113.51 +#include "llviewermedia.h"
  113.52 +
  113.53 +static LLRegisterPanelClassWrapper<LLSocialStatusPanel> t_panel_status("llsocialstatuspanel");
  113.54 +static LLRegisterPanelClassWrapper<LLSocialPhotoPanel> t_panel_photo("llsocialphotopanel");
  113.55 +static LLRegisterPanelClassWrapper<LLSocialCheckinPanel> t_panel_checkin("llsocialcheckinpanel");
  113.56 +static LLRegisterPanelClassWrapper<LLSocialAccountPanel> t_panel_account("llsocialaccountpanel");
  113.57 +
  113.58 +const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte
  113.59 +const std::string DEFAULT_CHECKIN_LOCATION_URL = "http://maps.secondlife.com/";
  113.60 +const std::string DEFAULT_CHECKIN_ICON_URL = "http://map.secondlife.com.s3.amazonaws.com/map_placeholder.png";
  113.61 +const std::string DEFAULT_CHECKIN_QUERY_PARAMETERS = "?sourceid=slshare_checkin&utm_source=facebook&utm_medium=checkin&utm_campaign=slshare";
  113.62 +const std::string DEFAULT_PHOTO_QUERY_PARAMETERS = "?sourceid=slshare_photo&utm_source=facebook&utm_medium=photo&utm_campaign=slshare";
  113.63 +
  113.64 +std::string get_map_url()
  113.65 +{
  113.66 +    LLVector3d center_agent;
  113.67 +    if (gAgent.getRegion())
  113.68 +    {
  113.69 +        center_agent = gAgent.getRegion()->getCenterGlobal();
  113.70 +    }
  113.71 +    int x_pos = center_agent[0] / 256.0;
  113.72 +    int y_pos = center_agent[1] / 256.0;
  113.73 +    std::string map_url = gSavedSettings.getString("CurrentMapServerURL") + llformat("map-1-%d-%d-objects.jpg", x_pos, y_pos);
  113.74 +    return map_url;
  113.75 +}
  113.76 +
  113.77 +///////////////////////////
  113.78 +//LLSocialStatusPanel//////
  113.79 +///////////////////////////
  113.80 +
  113.81 +LLSocialStatusPanel::LLSocialStatusPanel() :
  113.82 +	mMessageTextEditor(NULL),
  113.83 +	mPostButton(NULL),
  113.84 +    mCancelButton(NULL)
  113.85 +{
  113.86 +	mCommitCallbackRegistrar.add("SocialSharing.SendStatus", boost::bind(&LLSocialStatusPanel::onSend, this));
  113.87 +}
  113.88 +
  113.89 +BOOL LLSocialStatusPanel::postBuild()
  113.90 +{
  113.91 +	mMessageTextEditor = getChild<LLUICtrl>("status_message");
  113.92 +	mPostButton = getChild<LLUICtrl>("post_status_btn");
  113.93 +	mCancelButton = getChild<LLUICtrl>("cancel_status_btn");
  113.94 +
  113.95 +	return LLPanel::postBuild();
  113.96 +}
  113.97 +
  113.98 +void LLSocialStatusPanel::draw()
  113.99 +{
 113.100 +    if (mMessageTextEditor && mPostButton && mCancelButton)
 113.101 +	{
 113.102 +        bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing());
 113.103 +        std::string message = mMessageTextEditor->getValue().asString();
 113.104 +        mMessageTextEditor->setEnabled(no_ongoing_connection);
 113.105 +        mCancelButton->setEnabled(no_ongoing_connection);
 113.106 +        mPostButton->setEnabled(no_ongoing_connection && !message.empty());
 113.107 +    }
 113.108 +
 113.109 +	LLPanel::draw();
 113.110 +}
 113.111 +
 113.112 +void LLSocialStatusPanel::onSend()
 113.113 +{
 113.114 +	LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialStatusPanel"); // just in case it is already listening
 113.115 +	LLEventPumps::instance().obtain("FacebookConnectState").listen("LLSocialStatusPanel", boost::bind(&LLSocialStatusPanel::onFacebookConnectStateChange, this, _1));
 113.116 +		
 113.117 +	// Connect to Facebook if necessary and then post
 113.118 +	if (LLFacebookConnect::instance().isConnected())
 113.119 +	{
 113.120 +		sendStatus();
 113.121 +	}
 113.122 +	else
 113.123 +	{
 113.124 +		LLFacebookConnect::instance().checkConnectionToFacebook(true);
 113.125 +	}
 113.126 +}
 113.127 +
 113.128 +bool LLSocialStatusPanel::onFacebookConnectStateChange(const LLSD& data)
 113.129 +{
 113.130 +	switch (data.get("enum").asInteger())
 113.131 +	{
 113.132 +		case LLFacebookConnect::FB_CONNECTED:
 113.133 +			sendStatus();
 113.134 +			break;
 113.135 +
 113.136 +		case LLFacebookConnect::FB_POSTED:
 113.137 +			LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialStatusPanel");
 113.138 +			clearAndClose();
 113.139 +			break;
 113.140 +	}
 113.141 +
 113.142 +	return false;
 113.143 +}
 113.144 +
 113.145 +void LLSocialStatusPanel::sendStatus()
 113.146 +{
 113.147 +	std::string message = mMessageTextEditor->getValue().asString();
 113.148 +	if (!message.empty())
 113.149 +	{
 113.150 +		LLFacebookConnect::instance().updateStatus(message);
 113.151 +	}
 113.152 +}
 113.153 +
 113.154 +void LLSocialStatusPanel::clearAndClose()
 113.155 +{
 113.156 +	mMessageTextEditor->setValue("");
 113.157 +
 113.158 +	LLFloater* floater = getParentByType<LLFloater>();
 113.159 +	if (floater)
 113.160 +	{
 113.161 +		floater->closeFloater();
 113.162 +	}
 113.163 +}
 113.164 +
 113.165 +///////////////////////////
 113.166 +//LLSocialPhotoPanel///////
 113.167 +///////////////////////////
 113.168 +
 113.169 +LLSocialPhotoPanel::LLSocialPhotoPanel() :
 113.170 +mSnapshotPanel(NULL),
 113.171 +mResolutionComboBox(NULL),
 113.172 +mRefreshBtn(NULL),
 113.173 +mWorkingLabel(NULL),
 113.174 +mThumbnailPlaceholder(NULL),
 113.175 +mCaptionTextBox(NULL),
 113.176 +mLocationCheckbox(NULL),
 113.177 +mPostButton(NULL)
 113.178 +{
 113.179 +	mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLSocialPhotoPanel::onSend, this));
 113.180 +	mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", boost::bind(&LLSocialPhotoPanel::onClickNewSnapshot, this));
 113.181 +}
 113.182 +
 113.183 +LLSocialPhotoPanel::~LLSocialPhotoPanel()
 113.184 +{
 113.185 +	if(mPreviewHandle.get())
 113.186 +	{
 113.187 +		mPreviewHandle.get()->die();
 113.188 +	}
 113.189 +}
 113.190 +
 113.191 +BOOL LLSocialPhotoPanel::postBuild()
 113.192 +{
 113.193 +	setVisibleCallback(boost::bind(&LLSocialPhotoPanel::onVisibilityChange, this, _2));
 113.194 +	
 113.195 +	mSnapshotPanel = getChild<LLUICtrl>("snapshot_panel");
 113.196 +	mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox");
 113.197 +	mResolutionComboBox->setCommitCallback(boost::bind(&LLSocialPhotoPanel::updateResolution, this, TRUE));
 113.198 +	mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
 113.199 +    mWorkingLabel = getChild<LLUICtrl>("working_lbl");
 113.200 +	mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
 113.201 +	mCaptionTextBox = getChild<LLUICtrl>("photo_caption");
 113.202 +	mLocationCheckbox = getChild<LLUICtrl>("add_location_cb");
 113.203 +	mPostButton = getChild<LLUICtrl>("post_photo_btn");
 113.204 +	mCancelButton = getChild<LLUICtrl>("cancel_photo_btn");
 113.205 +
 113.206 +	return LLPanel::postBuild();
 113.207 +}
 113.208 +
 113.209 +void LLSocialPhotoPanel::draw()
 113.210 +{ 
 113.211 +	LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
 113.212 +
 113.213 +    // Enable interaction only if no transaction with the service is on-going (prevent duplicated posts)
 113.214 +    bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing());
 113.215 +    mCancelButton->setEnabled(no_ongoing_connection);
 113.216 +    mCaptionTextBox->setEnabled(no_ongoing_connection);
 113.217 +    mResolutionComboBox->setEnabled(no_ongoing_connection);
 113.218 +    mRefreshBtn->setEnabled(no_ongoing_connection);
 113.219 +    mLocationCheckbox->setEnabled(no_ongoing_connection);
 113.220 +    
 113.221 +    // Display the preview if one is available
 113.222 +	if (previewp && previewp->getThumbnailImage())
 113.223 +	{
 113.224 +		const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect();
 113.225 +		const S32 thumbnail_w = previewp->getThumbnailWidth();
 113.226 +		const S32 thumbnail_h = previewp->getThumbnailHeight();
 113.227 +
 113.228 +		// calc preview offset within the preview rect
 113.229 +		const S32 local_offset_x = (thumbnail_rect.getWidth()  - thumbnail_w) / 2 ;
 113.230 +		const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2 ;
 113.231 +
 113.232 +		// calc preview offset within the floater rect
 113.233 +        // Hack : To get the full offset, we need to take into account each and every offset of each widgets up to the floater.
 113.234 +        // This is almost as arbitrary as using a fixed offset so that's what we do here for the sake of simplicity.
 113.235 +        // *TODO : Get the offset looking through the hierarchy of widgets, should be done in postBuild() so to avoid traversing the hierarchy each time.
 113.236 +		S32 offset_x = thumbnail_rect.mLeft + local_offset_x - 1;
 113.237 +		S32 offset_y = thumbnail_rect.mBottom + local_offset_y - 39;
 113.238 +        
 113.239 +		mSnapshotPanel->localPointToOtherView(offset_x, offset_y, &offset_x, &offset_y, getParentByType<LLFloater>());
 113.240 +        
 113.241 +		gGL.matrixMode(LLRender::MM_MODELVIEW);
 113.242 +		// Apply floater transparency to the texture unless the floater is focused.
 113.243 +		F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
 113.244 +		LLColor4 color = LLColor4::white;
 113.245 +		gl_draw_scaled_image(offset_x, offset_y, 
 113.246 +			thumbnail_w, thumbnail_h,
 113.247 +			previewp->getThumbnailImage(), color % alpha);
 113.248 +
 113.249 +		previewp->drawPreviewRect(offset_x, offset_y) ;
 113.250 +	}
 113.251 +
 113.252 +    // Update the visibility of the working (computing preview) label
 113.253 +    mWorkingLabel->setVisible(!(previewp && previewp->getSnapshotUpToDate()));
 113.254 +    
 113.255 +    // Enable Post if we have a preview to send and no on going connection being processed
 113.256 +    mPostButton->setEnabled(no_ongoing_connection && (previewp && previewp->getSnapshotUpToDate()));
 113.257 +    
 113.258 +    // Draw the rest of the panel on top of it
 113.259 +	LLPanel::draw();
 113.260 +}
 113.261 +
 113.262 +LLSnapshotLivePreview* LLSocialPhotoPanel::getPreviewView()
 113.263 +{
 113.264 +	LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
 113.265 +	return previewp;
 113.266 +}
 113.267 +
 113.268 +void LLSocialPhotoPanel::onVisibilityChange(const LLSD& new_visibility)
 113.269 +{
 113.270 +	bool visible = new_visibility.asBoolean();
 113.271 +	if (visible)
 113.272 +	{
 113.273 +		if (mPreviewHandle.get())
 113.274 +		{
 113.275 +			LLSnapshotLivePreview* preview = getPreviewView();
 113.276 +			if(preview)
 113.277 +			{
 113.278 +				lldebugs << "opened, updating snapshot" << llendl;
 113.279 +				preview->updateSnapshot(TRUE);
 113.280 +			}
 113.281 +		}
 113.282 +		else
 113.283 +		{
 113.284 +			LLRect full_screen_rect = getRootView()->getRect();
 113.285 +			LLSnapshotLivePreview::Params p;
 113.286 +			p.rect(full_screen_rect);
 113.287 +			LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
 113.288 +			mPreviewHandle = previewp->getHandle();	
 113.289 +
 113.290 +			previewp->setSnapshotType(previewp->SNAPSHOT_WEB);
 113.291 +			previewp->setSnapshotFormat(LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG);
 113.292 +			//previewp->setSnapshotQuality(98);
 113.293 +			previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect());
 113.294 +
 113.295 +			updateControls();
 113.296 +		}
 113.297 +	}
 113.298 +}
 113.299 +
 113.300 +void LLSocialPhotoPanel::onClickNewSnapshot()
 113.301 +{
 113.302 +	LLSnapshotLivePreview* previewp = getPreviewView();
 113.303 +	if (previewp)
 113.304 +	{
 113.305 +		//setStatus(Impl::STATUS_READY);
 113.306 +		lldebugs << "updating snapshot" << llendl;
 113.307 +		previewp->updateSnapshot(TRUE);
 113.308 +	}
 113.309 +}
 113.310 +
 113.311 +void LLSocialPhotoPanel::onSend()
 113.312 +{
 113.313 +	LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialPhotoPanel"); // just in case it is already listening
 113.314 +	LLEventPumps::instance().obtain("FacebookConnectState").listen("LLSocialPhotoPanel", boost::bind(&LLSocialPhotoPanel::onFacebookConnectStateChange, this, _1));
 113.315 +	
 113.316 +	// Connect to Facebook if necessary and then post
 113.317 +	if (LLFacebookConnect::instance().isConnected())
 113.318 +	{
 113.319 +		sendPhoto();
 113.320 +	}
 113.321 +	else
 113.322 +	{
 113.323 +		LLFacebookConnect::instance().checkConnectionToFacebook(true);
 113.324 +	}
 113.325 +}
 113.326 +
 113.327 +bool LLSocialPhotoPanel::onFacebookConnectStateChange(const LLSD& data)
 113.328 +{
 113.329 +	switch (data.get("enum").asInteger())
 113.330 +	{
 113.331 +		case LLFacebookConnect::FB_CONNECTED:
 113.332 +			sendPhoto();
 113.333 +			break;
 113.334 +
 113.335 +		case LLFacebookConnect::FB_POSTED:
 113.336 +			LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialPhotoPanel");
 113.337 +			clearAndClose();
 113.338 +			break;
 113.339 +	}
 113.340 +
 113.341 +	return false;
 113.342 +}
 113.343 +
 113.344 +void LLSocialPhotoPanel::sendPhoto()
 113.345 +{
 113.346 +	// Get the caption
 113.347 +	std::string caption = mCaptionTextBox->getValue().asString();
 113.348 +
 113.349 +	// Add the location if required
 113.350 +	bool add_location = mLocationCheckbox->getValue().asBoolean();
 113.351 +	if (add_location)
 113.352 +	{
 113.353 +		// Get the SLURL for the location
 113.354 +		LLSLURL slurl;
 113.355 +		LLAgentUI::buildSLURL(slurl);
 113.356 +		std::string slurl_string = slurl.getSLURLString();
 113.357 +
 113.358 +		// Add query parameters so Google Analytics can track incoming clicks!
 113.359 +		slurl_string += DEFAULT_PHOTO_QUERY_PARAMETERS;
 113.360 +
 113.361 +		// Add it to the caption (pretty crude, but we don't have a better option with photos)
 113.362 +		if (caption.empty())
 113.363 +			caption = slurl_string;
 113.364 +		else
 113.365 +			caption = caption + " " + slurl_string;
 113.366 +	}
 113.367 +
 113.368 +	// Get the image
 113.369 +	LLSnapshotLivePreview* previewp = getPreviewView();
 113.370 +	
 113.371 +	// Post to Facebook
 113.372 +	LLFacebookConnect::instance().sharePhoto(previewp->getFormattedImage(), caption);
 113.373 +
 113.374 +	updateControls();
 113.375 +}
 113.376 +
 113.377 +void LLSocialPhotoPanel::clearAndClose()
 113.378 +{
 113.379 +	mCaptionTextBox->setValue("");
 113.380 +
 113.381 +	LLFloater* floater = getParentByType<LLFloater>();
 113.382 +	if (floater)
 113.383 +	{
 113.384 +		floater->closeFloater();
 113.385 +	}
 113.386 +}
 113.387 +
 113.388 +void LLSocialPhotoPanel::updateControls()
 113.389 +{
 113.390 +	LLSnapshotLivePreview* previewp = getPreviewView();
 113.391 +	BOOL got_bytes = previewp && previewp->getDataSize() > 0;
 113.392 +	BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
 113.393 +	LLSnapshotLivePreview::ESnapshotType shot_type = (previewp ? previewp->getSnapshotType() : LLSnapshotLivePreview::SNAPSHOT_POSTCARD);
 113.394 +
 113.395 +	// *TODO: Separate maximum size for Web images from postcards
 113.396 +	lldebugs << "Is snapshot up-to-date? " << got_snap << llendl;
 113.397 +
 113.398 +	LLLocale locale(LLLocale::USER_LOCALE);
 113.399 +	std::string bytes_string;
 113.400 +	if (got_snap)
 113.401 +	{
 113.402 +		LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 );
 113.403 +	}
 113.404 +
 113.405 +	//getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : getString("unknown")); <---uses localized string
 113.406 +	getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : "unknown");
 113.407 +	getChild<LLUICtrl>("file_size_label")->setColor(
 113.408 +		shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD 
 113.409 +		&& got_bytes
 113.410 +		&& previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLUIColor(LLColor4::red) : LLUIColorTable::instance().getColor( "LabelTextColor" ));
 113.411 +
 113.412 +	updateResolution(FALSE);
 113.413 +}
 113.414 +
 113.415 +void LLSocialPhotoPanel::updateResolution(BOOL do_update)
 113.416 +{
 113.417 +	LLComboBox* combobox = static_cast<LLComboBox *>(mResolutionComboBox);
 113.418 +
 113.419 +	std::string sdstring = combobox->getSelectedValue();
 113.420 +	LLSD sdres;
 113.421 +	std::stringstream sstream(sdstring);
 113.422 +	LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
 113.423 +
 113.424 +	S32 width = sdres[0];
 113.425 +	S32 height = sdres[1];
 113.426 +
 113.427 +	LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
 113.428 +	if (previewp && combobox->getCurrentIndex() >= 0)
 113.429 +	{
 113.430 +		S32 original_width = 0 , original_height = 0 ;
 113.431 +		previewp->getSize(original_width, original_height) ;
 113.432 +
 113.433 +		if (width == 0 || height == 0)
 113.434 +		{
 113.435 +			// take resolution from current window size
 113.436 +			lldebugs << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << llendl;
 113.437 +			previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
 113.438 +		}
 113.439 +		else
 113.440 +		{
 113.441 +			// use the resolution from the selected pre-canned drop-down choice
 113.442 +			lldebugs << "Setting preview res selected from combo: " << width << "x" << height << llendl;
 113.443 +			previewp->setSize(width, height);
 113.444 +		}
 113.445 +
 113.446 +		checkAspectRatio(width);
 113.447 +
 113.448 +		previewp->getSize(width, height);
 113.449 +		
 113.450 +		if(original_width != width || original_height != height)
 113.451 +		{
 113.452 +			previewp->setSize(width, height);
 113.453 +
 113.454 +			// hide old preview as the aspect ratio could be wrong
 113.455 +			lldebugs << "updating thumbnail" << llendl;
 113.456 +			
 113.457 +			previewp->updateSnapshot(FALSE, TRUE);
 113.458 +			if(do_update)
 113.459 +			{
 113.460 +				lldebugs << "Will update controls" << llendl;
 113.461 +				updateControls();
 113.462 +                LLSocialPhotoPanel::onClickNewSnapshot();
 113.463 +			}
 113.464 +		}
 113.465 +		
 113.466 +	}
 113.467 +}
 113.468 +
 113.469 +void LLSocialPhotoPanel::checkAspectRatio(S32 index)
 113.470 +{
 113.471 +	LLSnapshotLivePreview *previewp = getPreviewView() ;
 113.472 +
 113.473 +	BOOL keep_aspect = FALSE;
 113.474 +
 113.475 +	if (0 == index) // current window size
 113.476 +	{
 113.477 +		keep_aspect = TRUE;
 113.478 +	}
 113.479 +	else // predefined resolution
 113.480 +	{
 113.481 +		keep_aspect = FALSE;
 113.482 +	}
 113.483 +
 113.484 +	if (previewp)
 113.485 +	{
 113.486 +		previewp->mKeepAspectRatio = keep_aspect;
 113.487 +	}
 113.488 +}
 113.489 +
 113.490 +LLUICtrl* LLSocialPhotoPanel::getRefreshBtn()
 113.491 +{
 113.492 +	return mRefreshBtn;
 113.493 +}
 113.494 +
 113.495 +////////////////////////
 113.496 +//LLSocialCheckinPanel//
 113.497 +////////////////////////
 113.498 +
 113.499 +LLSocialCheckinPanel::LLSocialCheckinPanel() :
 113.500 +    mMapUrl(""),
 113.501 +    mReloadingMapTexture(false)
 113.502 +{
 113.503 +	mCommitCallbackRegistrar.add("SocialSharing.SendCheckin", boost::bind(&LLSocialCheckinPanel::onSend, this));
 113.504 +}
 113.505 +
 113.506 +BOOL LLSocialCheckinPanel::postBuild()
 113.507 +{
 113.508 +    // Keep pointers to widgets so we don't traverse the UI hierarchy too often
 113.509 +	mPostButton = getChild<LLUICtrl>("post_place_btn");
 113.510 +	mCancelButton = getChild<LLUICtrl>("cancel_place_btn");
 113.511 +	mMessageTextEditor = getChild<LLUICtrl>("place_caption");
 113.512 +    mMapLoadingIndicator = getChild<LLUICtrl>("map_loading_indicator");
 113.513 +    mMapPlaceholder = getChild<LLIconCtrl>("map_placeholder");
 113.514 +    mMapDefault = getChild<LLIconCtrl>("map_default");
 113.515 +    mMapCheckBox = getChild<LLCheckBoxCtrl>("add_place_view_cb");
 113.516 +    
 113.517 +	return LLPanel::postBuild();
 113.518 +}
 113.519 +
 113.520 +void LLSocialCheckinPanel::draw()
 113.521 +{
 113.522 +    bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing());
 113.523 +    mPostButton->setEnabled(no_ongoing_connection);
 113.524 +    mCancelButton->setEnabled(no_ongoing_connection);
 113.525 +    mMessageTextEditor->setEnabled(no_ongoing_connection);
 113.526 +    mMapCheckBox->setEnabled(no_ongoing_connection);
 113.527 +
 113.528 +    std::string map_url = get_map_url();
 113.529 +    // Did we change location?
 113.530 +    if (map_url != mMapUrl)
 113.531 +    {
 113.532 +        mMapUrl = map_url;
 113.533 +        // Load the map tile
 113.534 +        mMapTexture = LLViewerTextureManager::getFetchedTextureFromUrl(mMapUrl, FTT_MAP_TILE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 113.535 +        mMapTexture->setBoostLevel(LLGLTexture::BOOST_MAP);
 113.536 +        mReloadingMapTexture = true;
 113.537 +        // In the meantime, put the "loading" indicator on, hide the tile map and disable the checkbox
 113.538 +        mMapLoadingIndicator->setVisible(true);
 113.539 +        mMapPlaceholder->setVisible(false);
 113.540 +    }
 113.541 +    // Are we done loading the map tile?
 113.542 +    if (mReloadingMapTexture && mMapTexture->isFullyLoaded())
 113.543 +    {
 113.544 +        // Don't do it again next time around
 113.545 +        mReloadingMapTexture = false;
 113.546 +        // Convert the map texture to the appropriate image object
 113.547 +        LLPointer<LLUIImage> ui_image = new LLUIImage(mMapUrl, mMapTexture);
 113.548 +        // Load the map widget with the correct map tile image
 113.549 +        mMapPlaceholder->setImage(ui_image);
 113.550 +        // Now hide the loading indicator, bring the tile in view and reenable the checkbox with its previous value
 113.551 +        mMapLoadingIndicator->setVisible(false);
 113.552 +        mMapPlaceholder->setVisible(true);
 113.553 +    }
 113.554 +    // Show the default icon if that's the checkbox value (the real one...)
 113.555 +    // This will hide/show the loading indicator and/or tile underneath
 113.556 +    mMapDefault->setVisible(!(mMapCheckBox->get()));
 113.557 +
 113.558 +	LLPanel::draw();
 113.559 +}
 113.560 +
 113.561 +void LLSocialCheckinPanel::onSend()
 113.562 +{
 113.563 +	LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialCheckinPanel"); // just in case it is already listening
 113.564 +	LLEventPumps::instance().obtain("FacebookConnectState").listen("LLSocialCheckinPanel", boost::bind(&LLSocialCheckinPanel::onFacebookConnectStateChange, this, _1));
 113.565 +	
 113.566 +	// Connect to Facebook if necessary and then post
 113.567 +	if (LLFacebookConnect::instance().isConnected())
 113.568 +	{
 113.569 +		sendCheckin();
 113.570 +	}
 113.571 +	else
 113.572 +	{
 113.573 +		LLFacebookConnect::instance().checkConnectionToFacebook(true);
 113.574 +	}
 113.575 +}
 113.576 +
 113.577 +bool LLSocialCheckinPanel::onFacebookConnectStateChange(const LLSD& data)
 113.578 +{
 113.579 +	switch (data.get("enum").asInteger())
 113.580 +	{
 113.581 +		case LLFacebookConnect::FB_CONNECTED:
 113.582 +			sendCheckin();
 113.583 +			break;
 113.584 +
 113.585 +		case LLFacebookConnect::FB_POSTED:
 113.586 +			LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialCheckinPanel");
 113.587 +			clearAndClose();
 113.588 +			break;
 113.589 +	}
 113.590 +
 113.591 +	return false;
 113.592 +}
 113.593 +
 113.594 +void LLSocialCheckinPanel::sendCheckin()
 113.595 +{
 113.596 +	// Get the location SLURL
 113.597 +	LLSLURL slurl;
 113.598 +	LLAgentUI::buildSLURL(slurl);
 113.599 +	std::string slurl_string = slurl.getSLURLString();
 113.600 +
 113.601 +	// Use a valid http:// URL if the scheme is secondlife:// 
 113.602 +	LLURI slurl_uri(slurl_string);
 113.603 +	if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
 113.604 +	{
 113.605 +		slurl_string = DEFAULT_CHECKIN_LOCATION_URL;
 113.606 +	}
 113.607 +
 113.608 +	// Add query parameters so Google Analytics can track incoming clicks!
 113.609 +	slurl_string += DEFAULT_CHECKIN_QUERY_PARAMETERS;
 113.610 +    
 113.611 +	// Get the region name
 113.612 +	std::string region_name = gAgent.getRegion()->getName();
 113.613 +    
 113.614 +	// Get the region description
 113.615 +	std::string description;
 113.616 +	LLAgentUI::buildLocationString(description, LLAgentUI::LOCATION_FORMAT_NORMAL_COORDS, gAgent.getPositionAgent());
 113.617 +    
 113.618 +	// Optionally add the region map view
 113.619 +	bool add_map_view = mMapCheckBox->getValue().asBoolean();
 113.620 +    std::string map_url = (add_map_view ? get_map_url() : DEFAULT_CHECKIN_ICON_URL);
 113.621 +    
 113.622 +	// Get the caption
 113.623 +	std::string caption = mMessageTextEditor->getValue().asString();
 113.624 +
 113.625 +	// Post to Facebook
 113.626 +	LLFacebookConnect::instance().postCheckin(slurl_string, region_name, description, map_url, caption);
 113.627 +}
 113.628 +
 113.629 +void LLSocialCheckinPanel::clearAndClose()
 113.630 +{
 113.631 +	mMessageTextEditor->setValue("");
 113.632 +
 113.633 +	LLFloater* floater = getParentByType<LLFloater>();
 113.634 +	if (floater)
 113.635 +	{
 113.636 +		floater->closeFloater();
 113.637 +	}
 113.638 +}
 113.639 +
 113.640 +///////////////////////////
 113.641 +//LLSocialAccountPanel//////
 113.642 +///////////////////////////
 113.643 +
 113.644 +LLSocialAccountPanel::LLSocialAccountPanel() : 
 113.645 +mAccountCaptionLabel(NULL),
 113.646 +mAccountNameLabel(NULL),
 113.647 +mPanelButtons(NULL),
 113.648 +mConnectButton(NULL),
 113.649 +mDisconnectButton(NULL)
 113.650 +{
 113.651 +	mCommitCallbackRegistrar.add("SocialSharing.Connect", boost::bind(&LLSocialAccountPanel::onConnect, this));
 113.652 +	mCommitCallbackRegistrar.add("SocialSharing.Disconnect", boost::bind(&LLSocialAccountPanel::onDisconnect, this));
 113.653 +
 113.654 +	setVisibleCallback(boost::bind(&LLSocialAccountPanel::onVisibilityChange, this, _2));
 113.655 +}
 113.656 +
 113.657 +BOOL LLSocialAccountPanel::postBuild()
 113.658 +{
 113.659 +	mAccountCaptionLabel = getChild<LLTextBox>("account_caption_label");
 113.660 +	mAccountNameLabel = getChild<LLTextBox>("account_name_label");
 113.661 +	mPanelButtons = getChild<LLUICtrl>("panel_buttons");
 113.662 +	mConnectButton = getChild<LLUICtrl>("connect_btn");
 113.663 +	mDisconnectButton = getChild<LLUICtrl>("disconnect_btn");
 113.664 +
 113.665 +	return LLPanel::postBuild();
 113.666 +}
 113.667 +
 113.668 +void LLSocialAccountPanel::draw()
 113.669 +{
 113.670 +	LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState();
 113.671 +
 113.672 +	//Disable the 'disconnect' button and the 'use another account' button when disconnecting in progress
 113.673 +	bool disconnecting = connection_state == LLFacebookConnect::FB_DISCONNECTING;
 113.674 +	mDisconnectButton->setEnabled(!disconnecting);
 113.675 +
 113.676 +	//Disable the 'connect' button when a connection is in progress
 113.677 +	bool connecting = connection_state == LLFacebookConnect::FB_CONNECTION_IN_PROGRESS;
 113.678 +	mConnectButton->setEnabled(!connecting);
 113.679 +
 113.680 +	LLPanel::draw();
 113.681 +}
 113.682 +
 113.683 +void LLSocialAccountPanel::onVisibilityChange(const LLSD& new_visibility)
 113.684 +{
 113.685 +	bool visible = new_visibility.asBoolean();
 113.686 +
 113.687 +	if(visible)
 113.688 +	{
 113.689 +		LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialAccountPanel");
 113.690 +		LLEventPumps::instance().obtain("FacebookConnectState").listen("LLSocialAccountPanel", boost::bind(&LLSocialAccountPanel::onFacebookConnectStateChange, this, _1));
 113.691 +
 113.692 +		LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLSocialAccountPanel");
 113.693 +		LLEventPumps::instance().obtain("FacebookConnectInfo").listen("LLSocialAccountPanel", boost::bind(&LLSocialAccountPanel::onFacebookConnectInfoChange, this));
 113.694 +
 113.695 +		//Connected
 113.696 +		if(LLFacebookConnect::instance().isConnected())
 113.697 +		{
 113.698 +			showConnectedLayout();
 113.699 +		}
 113.700 +		//Check if connected (show disconnected layout in meantime)
 113.701 +		else
 113.702 +		{
 113.703 +			showDisconnectedLayout();
 113.704 +		}
 113.705 +        if ((LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_NOT_CONNECTED) ||
 113.706 +            (LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_CONNECTION_FAILED))
 113.707 +        {
 113.708 +            LLFacebookConnect::instance().checkConnectionToFacebook();
 113.709 +        }
 113.710 +	}
 113.711 +	else
 113.712 +	{
 113.713 +		LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialAccountPanel");
 113.714 +		LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLSocialAccountPanel");
 113.715 +	}
 113.716 +}
 113.717 +
 113.718 +bool LLSocialAccountPanel::onFacebookConnectStateChange(const LLSD& data)
 113.719 +{
 113.720 +	if(LLFacebookConnect::instance().isConnected())
 113.721 +	{
 113.722 +		//In process of disconnecting so leave the layout as is
 113.723 +		if(data.get("enum").asInteger() != LLFacebookConnect::FB_DISCONNECTING)
 113.724 +		{
 113.725 +			showConnectedLayout();
 113.726 +		}
 113.727 +	}
 113.728 +	else
 113.729 +	{
 113.730 +		showDisconnectedLayout();
 113.731 +	}
 113.732 +
 113.733 +	return false;
 113.734 +}
 113.735 +
 113.736 +bool LLSocialAccountPanel::onFacebookConnectInfoChange()
 113.737 +{
 113.738 +	LLSD info = LLFacebookConnect::instance().getInfo();
 113.739 +	std::string clickable_name;
 113.740 +
 113.741 +	//Strings of format [http://www.somewebsite.com Click Me] become clickable text
 113.742 +	if(info.has("link") && info.has("name"))
 113.743 +	{
 113.744 +		clickable_name = "[" + info["link"].asString() + " " + info["name"].asString() + "]";
 113.745 +	}
 113.746 +
 113.747 +	mAccountNameLabel->setText(clickable_name);
 113.748 +
 113.749 +	return false;
 113.750 +}
 113.751 +
 113.752 +void LLSocialAccountPanel::showConnectButton()
 113.753 +{
 113.754 +	if(!mConnectButton->getVisible())
 113.755 +	{
 113.756 +		mConnectButton->setVisible(TRUE);
 113.757 +		mDisconnectButton->setVisible(FALSE);
 113.758 +	}
 113.759 +}
 113.760 +
 113.761 +void LLSocialAccountPanel::hideConnectButton()
 113.762 +{
 113.763 +	if(mConnectButton->getVisible())
 113.764 +	{
 113.765 +		mConnectButton->setVisible(FALSE);
 113.766 +		mDisconnectButton->setVisible(TRUE);
 113.767 +	}
 113.768 +}
 113.769 +
 113.770 +void LLSocialAccountPanel::showDisconnectedLayout()
 113.771 +{
 113.772 +	mAccountCaptionLabel->setText(getString("facebook_disconnected"));
 113.773 +	mAccountNameLabel->setText(std::string(""));
 113.774 +	showConnectButton();
 113.775 +}
 113.776 +
 113.777 +void LLSocialAccountPanel::showConnectedLayout()
 113.778 +{
 113.779 +	LLFacebookConnect::instance().loadFacebookInfo();
 113.780 +
 113.781 +	mAccountCaptionLabel->setText(getString("facebook_connected"));
 113.782 +	hideConnectButton();
 113.783 +}
 113.784 +
 113.785 +void LLSocialAccountPanel::onConnect()
 113.786 +{
 113.787 +	LLFacebookConnect::instance().checkConnectionToFacebook(true);
 113.788 +
 113.789 +	//Clear only the facebook browser cookies so that the facebook login screen appears
 113.790 +	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com"); 
 113.791 +}
 113.792 +
 113.793 +void LLSocialAccountPanel::onDisconnect()
 113.794 +{
 113.795 +	LLFacebookConnect::instance().disconnectFromFacebook();
 113.796 +
 113.797 +	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com"); 
 113.798 +}
 113.799 +
 113.800 +////////////////////////
 113.801 +//LLFloaterSocial///////
 113.802 +////////////////////////
 113.803 +
 113.804 +LLFloaterSocial::LLFloaterSocial(const LLSD& key) : LLFloater(key),
 113.805 +    mSocialPhotoPanel(NULL),
 113.806 +    mStatusErrorText(NULL),
 113.807 +    mStatusLoadingText(NULL),
 113.808 +    mStatusLoadingIndicator(NULL)
 113.809 +{
 113.810 +	mCommitCallbackRegistrar.add("SocialSharing.Cancel", boost::bind(&LLFloaterSocial::onCancel, this));
 113.811 +}
 113.812 +
 113.813 +void LLFloaterSocial::onCancel()
 113.814 +{
 113.815 +    closeFloater();
 113.816 +}
 113.817 +
 113.818 +BOOL LLFloaterSocial::postBuild()
 113.819 +{
 113.820 +    // Keep tab of the Photo Panel
 113.821 +	mSocialPhotoPanel = static_cast<LLSocialPhotoPanel*>(getChild<LLUICtrl>("panel_social_photo"));
 113.822 +    // Connection status widgets
 113.823 +    mStatusErrorText = getChild<LLTextBox>("connection_error_text");
 113.824 +    mStatusLoadingText = getChild<LLTextBox>("connection_loading_text");
 113.825 +    mStatusLoadingIndicator = getChild<LLUICtrl>("connection_loading_indicator");
 113.826 +	return LLFloater::postBuild();
 113.827 +}
 113.828 +
 113.829 +// static
 113.830 +void LLFloaterSocial::preUpdate()
 113.831 +{
 113.832 +	LLFloaterSocial* instance = LLFloaterReg::findTypedInstance<LLFloaterSocial>("social");
 113.833 +	if (instance)
 113.834 +	{
 113.835 +		//Will set file size text to 'unknown'
 113.836 +		instance->mSocialPhotoPanel->updateControls();
 113.837 +	}
 113.838 +}
 113.839 +
 113.840 +// static
 113.841 +void LLFloaterSocial::postUpdate()
 113.842 +{
 113.843 +	LLFloaterSocial* instance = LLFloaterReg::findTypedInstance<LLFloaterSocial>("social");
 113.844 +	if (instance)
 113.845 +	{
 113.846 +		//Will set the file size text
 113.847 +		instance->mSocialPhotoPanel->updateControls();
 113.848 +
 113.849 +		// The refresh button is initially hidden. We show it after the first update,
 113.850 +		// i.e. after snapshot is taken
 113.851 +		LLUICtrl * refresh_button = instance->mSocialPhotoPanel->getRefreshBtn();
 113.852 +
 113.853 +		if (!refresh_button->getVisible())
 113.854 +		{
 113.855 +			refresh_button->setVisible(true);
 113.856 +		}
 113.857 +		
 113.858 +	}
 113.859 +}
 113.860 +
 113.861 +void LLFloaterSocial::draw()
 113.862 +{
 113.863 +    if (mStatusErrorText && mStatusLoadingText && mStatusLoadingIndicator)
 113.864 +    {
 113.865 +        mStatusErrorText->setVisible(false);
 113.866 +        mStatusLoadingText->setVisible(false);
 113.867 +        mStatusLoadingIndicator->setVisible(false);
 113.868 +        LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState();
 113.869 +        std::string status_text;
 113.870 +        
 113.871 +        switch (connection_state)
 113.872 +        {
 113.873 +        case LLFacebookConnect::FB_NOT_CONNECTED:
 113.874 +            // No status displayed when first opening the panel and no connection done
 113.875 +        case LLFacebookConnect::FB_CONNECTED:
 113.876 +            // When successfully connected, no message is displayed
 113.877 +        case LLFacebookConnect::FB_POSTED:
 113.878 +            // No success message to show since we actually close the floater after successful posting completion
 113.879 +            break;
 113.880 +        case LLFacebookConnect::FB_CONNECTION_IN_PROGRESS:
 113.881 +            // Connection loading indicator
 113.882 +            mStatusLoadingText->setVisible(true);
 113.883 +            status_text = LLTrans::getString("SocialFacebookConnecting");
 113.884 +            mStatusLoadingText->setValue(status_text);
 113.885 +            mStatusLoadingIndicator->setVisible(true);
 113.886 +            break;
 113.887 +        case LLFacebookConnect::FB_POSTING:
 113.888 +            // Posting indicator
 113.889 +            mStatusLoadingText->setVisible(true);
 113.890 +            status_text = LLTrans::getString("SocialFacebookPosting");
 113.891 +            mStatusLoadingText->setValue(status_text);
 113.892 +            mStatusLoadingIndicator->setVisible(true);
 113.893 +			break;
 113.894 +        case LLFacebookConnect::FB_CONNECTION_FAILED:
 113.895 +            // Error connecting to the service
 113.896 +            mStatusErrorText->setVisible(true);
 113.897 +            status_text = LLTrans::getString("SocialFacebookErrorConnecting");
 113.898 +            mStatusErrorText->setValue(status_text);
 113.899 +            break;
 113.900 +        case LLFacebookConnect::FB_POST_FAILED:
 113.901 +            // Error posting to the service
 113.902 +            mStatusErrorText->setVisible(true);
 113.903 +            status_text = LLTrans::getString("SocialFacebookErrorPosting");
 113.904 +            mStatusErrorText->setValue(status_text);
 113.905 +            break;
 113.906 +		case LLFacebookConnect::FB_DISCONNECTING:
 113.907 +			// Disconnecting loading indicator
 113.908 +			mStatusLoadingText->setVisible(true);
 113.909 +			status_text = LLTrans::getString("SocialFacebookDisconnecting");
 113.910 +			mStatusLoadingText->setValue(status_text);
 113.911 +			mStatusLoadingIndicator->setVisible(true);
 113.912 +			break;
 113.913 +		case LLFacebookConnect::FB_DISCONNECT_FAILED:
 113.914 +			// Error disconnecting from the service
 113.915 +			mStatusErrorText->setVisible(true);
 113.916 +			status_text = LLTrans::getString("SocialFacebookErrorDisconnecting");
 113.917 +			mStatusErrorText->setValue(status_text);
 113.918 +			break;
 113.919 +        }
 113.920 +    }
 113.921 +	LLFloater::draw();
 113.922 +}
 113.923 +
   114.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   114.2 +++ b/indra/newview/llfloatersocial.h	Tue Nov 12 14:06:38 2013 -0500
   114.3 @@ -0,0 +1,165 @@
   114.4 +/** 
   114.5 +* @file   llfloatersocial.h
   114.6 +* @brief  Header file for llfloatersocial
   114.7 +* @author Gilbert@lindenlab.com
   114.8 +*
   114.9 +* $LicenseInfo:firstyear=2013&license=viewerlgpl$
  114.10 +* Second Life Viewer Source Code
  114.11 +* Copyright (C) 2013, Linden Research, Inc.
  114.12 +*
  114.13 +* This library is free software; you can redistribute it and/or
  114.14 +* modify it under the terms of the GNU Lesser General Public
  114.15 +* License as published by the Free Software Foundation;
  114.16 +* version 2.1 of the License only.
  114.17 +*
  114.18 +* This library is distributed in the hope that it will be useful,
  114.19 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  114.20 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  114.21 +* Lesser General Public License for more details.
  114.22 +*
  114.23 +* You should have received a copy of the GNU Lesser General Public
  114.24 +* License along with this library; if not, write to the Free Software
  114.25 +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  114.26 +*
  114.27 +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  114.28 +* $/LicenseInfo$
  114.29 +*/
  114.30 +#ifndef LL_LLFLOATERSOCIAL_H
  114.31 +#define LL_LLFLOATERSOCIAL_H
  114.32 +
  114.33 +#include "llfloater.h"
  114.34 +#include "lltextbox.h"
  114.35 +#include "llviewertexture.h"
  114.36 +
  114.37 +class LLIconCtrl;
  114.38 +class LLCheckBoxCtrl;
  114.39 +class LLSnapshotLivePreview;
  114.40 +
  114.41 +class LLSocialStatusPanel : public LLPanel
  114.42 +{
  114.43 +public:
  114.44 +    LLSocialStatusPanel();
  114.45 +	BOOL postBuild();
  114.46 +	void draw();
  114.47 +    void onSend();
  114.48 +	bool onFacebookConnectStateChange(const LLSD& data);
  114.49 +
  114.50 +	void sendStatus();
  114.51 +	void clearAndClose();
  114.52 +
  114.53 +private:
  114.54 +	LLUICtrl* mMessageTextEditor;
  114.55 +	LLUICtrl* mPostButton;
  114.56 +	LLUICtrl* mCancelButton;
  114.57 +};
  114.58 +
  114.59 +class LLSocialPhotoPanel : public LLPanel
  114.60 +{
  114.61 +public:
  114.62 +	LLSocialPhotoPanel();
  114.63 +	~LLSocialPhotoPanel();
  114.64 +
  114.65 +	BOOL postBuild();
  114.66 +	void draw();
  114.67 +
  114.68 +	LLSnapshotLivePreview* getPreviewView();
  114.69 +	void onVisibilityChange(const LLSD& new_visibility);
  114.70 +	void onClickNewSnapshot();
  114.71 +	void onSend();
  114.72 +	bool onFacebookConnectStateChange(const LLSD& data);
  114.73 +
  114.74 +	void sendPhoto();
  114.75 +	void clearAndClose();
  114.76 +
  114.77 +	void updateControls();
  114.78 +	void updateResolution(BOOL do_update);
  114.79 +	void checkAspectRatio(S32 index);
  114.80 +	LLUICtrl* getRefreshBtn();
  114.81 +
  114.82 +private:
  114.83 +	LLHandle<LLView> mPreviewHandle;
  114.84 +
  114.85 +	LLUICtrl * mSnapshotPanel;
  114.86 +	LLUICtrl * mResolutionComboBox;
  114.87 +	LLUICtrl * mRefreshBtn;
  114.88 +	LLUICtrl * mWorkingLabel;
  114.89 +	LLUICtrl * mThumbnailPlaceholder;
  114.90 +	LLUICtrl * mCaptionTextBox;
  114.91 +	LLUICtrl * mLocationCheckbox;
  114.92 +	LLUICtrl * mPostButton;
  114.93 +	LLUICtrl* mCancelButton;
  114.94 +};
  114.95 +
  114.96 +class LLSocialCheckinPanel : public LLPanel
  114.97 +{
  114.98 +public:
  114.99 +    LLSocialCheckinPanel();
 114.100 +	BOOL postBuild();
 114.101 +	void draw();
 114.102 +    void onSend();
 114.103 +	bool onFacebookConnectStateChange(const LLSD& data);
 114.104 +
 114.105 +	void sendCheckin();
 114.106 +	void clearAndClose();
 114.107 +
 114.108 +private:
 114.109 +    std::string mMapUrl;
 114.110 +    LLPointer<LLViewerFetchedTexture> mMapTexture;
 114.111 +	LLUICtrl* mPostButton;
 114.112 +	LLUICtrl* mCancelButton;
 114.113 +	LLUICtrl* mMessageTextEditor;
 114.114 +    LLUICtrl* mMapLoadingIndicator;
 114.115 +    LLIconCtrl* mMapPlaceholder;
 114.116 +    LLIconCtrl* mMapDefault;
 114.117 +    LLCheckBoxCtrl* mMapCheckBox;
 114.118 +    bool mReloadingMapTexture;
 114.119 +};
 114.120 +
 114.121 +class LLSocialAccountPanel : public LLPanel
 114.122 +{
 114.123 +public:
 114.124 +	LLSocialAccountPanel();
 114.125 +	BOOL postBuild();
 114.126 +	void draw();
 114.127 +
 114.128 +private:
 114.129 +	void onVisibilityChange(const LLSD& new_visibility);
 114.130 +	bool onFacebookConnectStateChange(const LLSD& data);
 114.131 +	bool onFacebookConnectInfoChange();
 114.132 +	void onConnect();
 114.133 +	void onUseAnotherAccount();
 114.134 +	void onDisconnect();
 114.135 +