diff options
Diffstat (limited to 'indra')
184 files changed, 4329 insertions, 4015 deletions
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 410d25ad97..24ea59ca49 100755 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -71,7 +71,6 @@ add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins) if (LINUX) add_subdirectory(${VIEWER_PREFIX}linux_crash_logger) - add_subdirectory(${VIEWER_PREFIX}linux_updater) if (INSTALL_PROPRIETARY) include(LLAppearanceUtility) add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR}) @@ -86,9 +85,8 @@ elseif (WINDOWS) if (EXISTS ${VIEWER_DIR}win_setup) add_subdirectory(${VIEWER_DIR}win_setup) endif (EXISTS ${VIEWER_DIR}win_setup) - add_subdirectory(${VIEWER_PREFIX}win_updater) - # add_dependencies(viewer windows-updater windows-setup windows-crash-logger) - add_dependencies(viewer windows-updater windows-crash-logger) + # add_dependencies(viewer windows-setup windows-crash-logger) + add_dependencies(viewer windows-crash-logger) elseif (SOLARIS) add_subdirectory(solaris_crash_logger) add_dependencies(viewer solaris-crash-logger) diff --git a/indra/cmake/00-COMPILE-LINK-RUN.txt b/indra/cmake/00-COMPILE-LINK-RUN.txt new file mode 100644 index 0000000000..d08cc2dc0c --- /dev/null +++ b/indra/cmake/00-COMPILE-LINK-RUN.txt @@ -0,0 +1,344 @@ + + A short guide to compiling, linking, running and debugging issues + in the viewer and its packaged libraries. + +Introduction + + A recent pass through some third-party libraries resulted in the + collection of a lot of information about how things should and + shouldn't be built in the viewer. Some of that is presented below + with hints and rules about doing things well. What's presented is + a guideline only. Not all suggestions are hard rules and you'll + find exceptions all over. Some exceptions arise from solid + reasoning, others may be legacy that hasn't been re-examined. + + Use good engineering judgement when applying this information. + +Compilation + + Windows Targets + + Significant compilation flags and defines follow: + + ---------------------------------------------------------------------------- + Option Release RelWithDebInfo Debug + ---------------------------------------------------------------------------- + wchar_t /Zc:wchar_t- " " + RTL type /MD /MD /MDd + FLoating Point /fp:fast " " + Debug Info /Zi (app/dll), /Z7 (lib) " " + Optimizer /O2 /Ob2 /GR /Od /Ob0 /GR /Od /GR + Incr. Link /INCREMENTAL:NO /INCREMENTAL /INCREMENTAL:NO + Debug /DEBUG /DEBUG /DEBUG + /OPT:REF + Ignore Libs LIBCMT LIBCMT LIBCMT;LIBCMTD;MSVCRT + Alignment Default " " + + Defines WIN32 " " + _WINDOWS " " + LL_RELEASE=1 LL_RELEASE=1 n/a + LL_RELEASE_FOR_DOWNLOAD=1 n/a n/a + NDEBUG NDEBUG _DEBUG + n/a n/a LL_DEBUG=1 + n/a LL_RELEASE_WITH_\ n/a + DEBUG_INFO=1 + n/a n/a _SCL_SECURE_NO_WARNINGS=1 + _SECURE_STL=0 _SECURE_STL=0 _SECURE_STL=0 + _HAS_ITERATOR_DEBUGGING=0 n/a n/a + LL_WINDOWS=1 " " + UNICODE " " + _UNICODE " " + WINVER=0x0501 " " + _WIN32_WINNT=0x0501 " " + LL_OS_DRAGDROP_ENABLED=1 " " + CARES_STATICLIB " " + LIB_NDOF=1 " " + + ---------------------------------------------------------------------------- + Notes: + + 1. /Zc:wchar_t-. Not certain where this comes from. It may be + due to a default set of compilation flags in Qt 4.X that then + propagates outward. In Qt 5.X, this setting is flipped back to + default (wchar_t is a built-in). Other options for dealing with + this include: + + http://msdn.microsoft.com/en-us/library/dh8che7s%28v=vs.110%29.aspx + + Recommend trying to stay with /Zc:wchar_t (the default) when + adding libraries. If incompatible, you'll typically get some + missing ostream '<<' operators or something similar in the stream + headers. + + 2. /Z7 (VC 7.0 compatibility symbols) gives us debug information + in the static libraries we build. Otherwise builds generate + vc100.pdb files all over the place which generally aren't useful. + DLL's and .EXEs are to get /Zi or /ZI with separate .PDB files. + These .PDB files can then be packaged up in symbol tarballs for + the crash dump analyzer or used in debugging. There are issues here + for VS 2013 (see below). + + + Mac Targets + + Fairly straightforward, optimization level is easily changed (may + be little or negative gain for -O3 and RelWithDebInfo should be + kicked up to 1 or 2. Boost debug symbols to dwarf-2 with a goal + of dwarf-2 in separate dSYM file when building .dylibs and + executables. + + ---------------------------------------------------------------------------- + Option Release RelWithDebInfo Debug + ---------------------------------------------------------------------------- + Strip Debug Symbols On " " + During Copy + + Generate Debug Syms On " " + + Level Debug Syms -gdwarf-2 " " + + Optimization -O3 -O0 -O0 + + PIC -fPIC -DPIC " " + + Defines LL_RELEASE=1 LL_RELEASE=1 n/a + LL_RELEASE_FOR_DOWNLOAD=1 n/a n/a + NDEBUG NDEBUG _DEBUG + n/a n/a LL_DEBUG=1 + n/a LL_RELEASE_WITH_\ n/a + DEBUG_INFO=1 + LL_DARWIN=1 " " + LL_OS_DRAGDROP_ENABLED=1 " " + CARES_STATICLIB " " + LIB_NDOF=1 " " + + ---------------------------------------------------------------------------- + Notes: + + 1. We’re also building dylibs in a somewhat unusual way. They’re + currently being generated with a link path of + ‘@executable_path/../Resources/<library>’. If we were to follow + the recommendations in dyld’s man page, we’d instead reference + ‘@loader_path/<library>’, use -rpath on the executable link + (pointing to the ‘Resources’ subdir of the main executable), and + be able to avoid some symlinking in the .app tree. + + 2. Use the -headerpad_max_install_names link option on all .dylibs. + + + Linux Targets + + Not much variety here. + + ---------------------------------------------------------------------------- + Option Release RelWithDebInfo Debug + ---------------------------------------------------------------------------- + Debug Level -g (-g0/1 better?) -g -g + During Copy + + Optimization -O2 -O0 -O0 + + PIC -fPIC " " + ---------------------------------------------------------------------------- + Notes: + + +Linking + + The library update work has generally moved in the direction of + preferring static libraries over dynamic (Qt4 being the notable + exception). It also mostly eliminated the extremely bad practice + of having multiple versions of a library built into an image. + + How bad was it? Very. Appalling. A nightmare. On Windows, at + least four versions of zlib (1.2.3, 1.2.5, 1.2.6, unknown), three + versions of Boost (1.45, 1.48, 1.52), two versions of OpenSSL + (0.9.8q, 1.0.0g) and three different builds of libexpat + 2.0.5/1.5.2 were used. Mac was worse with five builds or versions + of zlib, two of PCRE, two of c-ares, and three of OpenSSL. Linux + topped that by adding two builds of libpng. + + DO NOT ALLOW THIS TO HAPPEN AGAIN. It isn't enough to update a + library and then stuff a new triplet of S3 URLs into the viewer's + autobuild.xml. If you update a library you MUST: + + * Update the autobuild.xml of ALL consumers of the library. In + the case of zlib, that meant updating freetype, libpng, openssl, + libxml2, fontconfig, curl, Boost, SDL, llqtwebkit, google-mock and + colladadom. + + * Confirm by test and observation that the consumers actually use + your library rather than 'call home to mother' and find + system-supplied versions of your library. This may consist of + watching configuration scripts, probing with ldd/depends/otool, + pulling text out of binaries with 'strings'. The previously- + mentioned libraries all have a README.Linden file that gives + examples specific to the consumer library. + + * DO NOT RE-EXPORT LIBRARIES. Colladadom was the worst offender + of this rule. As a shared library, it was re-exporting part, but + not all, of Boost filesystem and system, some zlib, some PCRE, + some libxml2 and minizip. This meant that depending upon link- + time and run-time symbol resolution, data constructed with one + version of a library might be processed by a method built in a + second, incompatible version of the library. Switching colladadom + to a static library ended the re-export problem. + + * Preventing re-export is not sufficient. other libraries will + still be shipped as shared and they can still have Singleton and + Fragile Base Class issues. A DLL may be built with a static + archive of a library that has global data. That same static + archive might be linked into the application proper. An object + created with a method in the DLL may pass into a method in the + application where the archive's global data has a second instance + and no knowledge of the object. This is a failure due to an + assumption of Singleton global data which leads to some kind of + failure. This is the same effect as when, in Windows, both MSVCRT + and MSVCRTD get activated in a program. If you're lucky, some + asserts fail in that case having to do with file handle global + data. + + +Running + + Windows Debug Build. Seems to have been rendered nearly useless + by having the LL_CHECK_MEMORY define in llmemory.h calling + _CrtCheckMemory(). Viewer is almost useful disabling this in + llvoavatar code alone but not quite. + + +Futures + + Static Versus Dynamic Libraries + + One solution to the above linking problems is the use of static + libraries for everything. Single version, singleton instancing of + data, etc. But it's not the 1950's and we're not running our + applications on bare metal. Every platform comes with 100s of + libraries waiting to interfere with operations by breaking the + single-version and singleton-data assumption. + + Additionally, there are libraries that simply expect to be built + into shared libraries. Qt4 is one such. The version we're using + now, 4.7.1, is actually trying to disable both Webkit and plugin + modules because we're building it statically on Mac and Linux. + It's only because of configuration bugs that we're getting the + functionality out of it that we want. + + With enough libraries and a single, global namespace, eventually + there will be collisions and there may not be a warning. All it + takes is two programmers who thought that 'FILE * open_file(const + char *);' was a safe signature to use between compilation units in + their libraries and glorious debugging sessions are in your + future. Having debugged it, you will now become the proud owner + of a one-off version of one of those libraries that uses a special + symbol prefix which you will be maintaining forever. + + Lastly, we have some binary blobs that we must use as delivered. + Executables can be isolated at run-time if necessary. Shared + libraries are a different problem. They may bring their own + library dependencies that affect link- and run-time symbol + resolution and they'll impose that on us according to platform + rules. + + So, what to do? My natural bias for large software is to use + shared libraries for everything. It's a path to single-version + and singleton data and isolates namespaces and prevents + interactions. It also has some field serviceability benefits if + you need to debug some bizarre problem a user has. + + But there's a local preference for static. Here, my + rules-of-thumb are: + + * Static library used by default. + + * Shared library where the library must be built shared. + + * Shared library if that is the only means to enforce the + single-version and singleton-data requirements. + + * Shared library *on a case-by-case basis* if the library is also + provided by the platform and some benefit is plausible. (An + example of this is freetype/fontconfig on Linux. The .so + versions we build with, and incompletely ship, are inferior in + behavior to the platform libraries. By being shared libraries, + the platform-supplied option is available to all Linux users.) + + In all cases, beware of cmake which appears to collapse and move + library references in links. This can drastically affect symbol + resolution when there are multiple sources for a symbol. + + General + + VS 2013. The /Z7 flag is rumored to be somewhat broken in 2013. + But it also sounds like there are explicit controls to name .PDB + files associated with static archives. That would make this an + ideal time to switch to /Zi or /ZI everywhere with explicit naming + and bring all the .PDBs together. + + The embedded browser technology (e.g. Qt4 with Webkit) is the + 800-pound gorilla in the viewer. When starting any major work, + decide what changes you need here as those changes will propagate + outwards forcing many other decisions (cf: /Zc:wchar_t- flag). + + The current package structure (./include, ./lib/release, + ./lib/debug, etc.) really works against the conventions used by + configure-like programs. I wasted a lot of time getting each + library to work with our structure without having to go back to + automake/autoconf. For Linux and Mac (and even for Windows), a + structure like the following where each grouping is optional would + probably save some work: + + ./debug/bin + /include + /lib + ./debug/shared/bin + /include + /lib + ./debug/static/bin + /include + /lib + ./release/bin + /include + /lib + ... + + In zlib and openssl and in a few of the libraries that consume + them, I experimented with packaging both static and shared + libraries and then having the consumer library move the unwanted + pieces out of the way to use the library type of choice (see + restore_dylibs() and restore_sos() functions). It was a bit fussy + and simplicity and clarity are the keys to maintaining libraries + in the future. + + But it did suggest another approach. The idea is that every build + pre-stages inputs. Before anything is built, package pieces are + copied or symlinked from the 'stage/packages' area to the + 'stage/input' area. Builds then proceed with a single set of + -I/-L options for the dependencies. And products are built and + installed in a similar output staging structure for the next + consumer: + + stage/packages/<package>/[above structure] + stage/input/{bin,include,lib} + stage/<package>/[above structure] + + Next library project. I'd recommend working on the related set of + libexpat, apr, aprutil, xmlrpc-epi. We know libexpat has some + updates that should improve stability. Libapr consumes it and it + could use some /Z7 flag work to get rid of some 1000's of PDB + warnings and improve our debug symbols. + + Miscellany to be sorted out: + + * The packaging of libfreetype and libfontconfig on Linux. + Determine what the right thing is, do it. + + * Maybe do something with ICU4C. Qt5 will require it and a number + of our packages can consume it typically replacing iconv or some + other library. But it is a huge bolus of static data. It can be + trimmed, but still. + + * Revisit openssl. Package as a shared library? Replace with + LibreSSL when available? Start using platform-supplied crypto? + diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 6a0f7a214c..52b0f4e8b4 100755 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -62,7 +62,7 @@ if (WINDOWS) add_definitions( /DLL_WINDOWS=1 /DNOMINMAX - /DDOM_DYNAMIC +# /DDOM_DYNAMIC # For shared library colladadom /DUNICODE /D_UNICODE /GS diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake index 50ac27d402..25e54b7cbd 100755 --- a/indra/cmake/Boost.cmake +++ b/indra/cmake/Boost.cmake @@ -8,6 +8,7 @@ if (USESYSTEMLIBS) include(FindBoost) set(BOOST_CONTEXT_LIBRARY boost_context-mt) + set(BOOST_COROUTINE_LIBRARY boost_coroutine-mt) set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt) set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt) set(BOOST_REGEX_LIBRARY boost_regex-mt) @@ -17,10 +18,11 @@ if (USESYSTEMLIBS) else (USESYSTEMLIBS) use_prebuilt_binary(boost) set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) - set(BOOST_VERSION "1.52") + set(BOOST_VERSION "1.55") if (WINDOWS) if(MSVC80) + # This should be obsolete at this point set(BOOST_CONTEXT_LIBRARY optimized libboost_context-vc80-mt-${BOOST_VERSION} debug libboost_context-vc80-mt-gd-${BOOST_VERSION}) @@ -47,6 +49,9 @@ else (USESYSTEMLIBS) set(BOOST_CONTEXT_LIBRARY optimized libboost_context-mt debug libboost_context-mt-gd) + set(BOOST_COROUTINE_LIBRARY + optimized libboost_coroutine-mt + debug libboost_coroutine-mt-gd) set(BOOST_FILESYSTEM_LIBRARY optimized libboost_filesystem-mt debug libboost_filesystem-mt-gd) @@ -70,6 +75,9 @@ else (USESYSTEMLIBS) set(BOOST_CONTEXT_LIBRARY optimized boost_context-mt debug boost_context-mt-d) + set(BOOST_COROUTINE_LIBRARY + optimized boost_coroutine-mt + debug boost_coroutine-mt-d) set(BOOST_FILESYSTEM_LIBRARY optimized boost_filesystem-mt debug boost_filesystem-mt-d) @@ -92,6 +100,9 @@ else (USESYSTEMLIBS) set(BOOST_CONTEXT_LIBRARY optimized boost_context-mt debug boost_context-mt-d) + set(BOOST_COROUTINE_LIBRARY + optimized boost_coroutine-mt + debug boost_coroutine-mt-d) set(BOOST_FILESYSTEM_LIBRARY optimized boost_filesystem-mt debug boost_filesystem-mt-d) diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 4f1b6640c2..28202f85d6 100755 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -40,7 +40,6 @@ if(WINDOWS) libapriconv-1.dll ssleay32.dll libeay32.dll - libcollada14dom22-d.dll glod.dll libhunspell.dll ) @@ -53,7 +52,6 @@ if(WINDOWS) libapriconv-1.dll ssleay32.dll libeay32.dll - libcollada14dom22.dll glod.dll libhunspell.dll ) @@ -213,15 +211,12 @@ elseif(DARWIN) libapr-1.dylib libaprutil-1.0.dylib libaprutil-1.dylib + libexception_handler.dylib libexpat.1.5.2.dylib libexpat.dylib libGLOD.dylib - libllqtwebkit.dylib - libminizip.a - libndofdev.dylib libhunspell-1.3.0.dylib - libexception_handler.dylib - libcollada14dom.dylib + libndofdev.dylib ) if (FMODEX) @@ -259,35 +254,21 @@ elseif(LINUX) libapr-1.so.0 libaprutil-1.so.0 libatk-1.0.so - libboost_context-mt.so.${BOOST_VERSION}.0 - libboost_filesystem-mt.so.${BOOST_VERSION}.0 - libboost_program_options-mt.so.${BOOST_VERSION}.0 - libboost_regex-mt.so.${BOOST_VERSION}.0 - libboost_signals-mt.so.${BOOST_VERSION}.0 - libboost_system-mt.so.${BOOST_VERSION}.0 - libboost_thread-mt.so.${BOOST_VERSION}.0 - libcollada14dom.so - libcrypto.so.1.0.0 libdb-5.1.so libexpat.so libexpat.so.1 + libfreetype.so.6.6.2 libfreetype.so.6 libGLOD.so - libgmock_main.so - libgmock.so.0 libgmodule-2.0.so libgobject-2.0.so - libgtest_main.so - libgtest.so.0 libhunspell-1.3.so.0.0.0 - libminizip.so libopenal.so libopenjpeg.so - libssl.so libuuid.so.16 libuuid.so.16.0.22 - libssl.so.1.0.0 - libfontconfig.so.1.4.4 + libfontconfig.so.1.8.0 + libfontconfig.so.1 ) if (USE_TCMALLOC) diff --git a/indra/cmake/FreeType.cmake b/indra/cmake/FreeType.cmake index 02c5b37f28..a36485f6d0 100755 --- a/indra/cmake/FreeType.cmake +++ b/indra/cmake/FreeType.cmake @@ -7,7 +7,7 @@ if (USESYSTEMLIBS) pkg_check_modules(FREETYPE REQUIRED freetype2) else (USESYSTEMLIBS) use_prebuilt_binary(freetype) - set(FREETYPE_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) + set(FREETYPE_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/freetype2/) set(FREETYPE_LIBRARIES freetype) endif (USESYSTEMLIBS) diff --git a/indra/cmake/GoogleMock.cmake b/indra/cmake/GoogleMock.cmake index c4c96a9af7..cac072988e 100755 --- a/indra/cmake/GoogleMock.cmake +++ b/indra/cmake/GoogleMock.cmake @@ -2,7 +2,7 @@ include(Prebuilt) include(Linking) -use_prebuilt_binary(googlemock) +use_prebuilt_binary(gmock) set(GOOGLEMOCK_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) diff --git a/indra/cmake/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake index 67c2115237..93626f689f 100755 --- a/indra/cmake/LLPrimitive.cmake +++ b/indra/cmake/LLPrimitive.cmake @@ -6,32 +6,40 @@ include(Boost) use_prebuilt_binary(colladadom) use_prebuilt_binary(pcre) +use_prebuilt_binary(libxml2) set(LLPRIMITIVE_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llprimitive ) if (WINDOWS) - set(LLPRIMITIVE_LIBRARIES + set(LLPRIMITIVE_LIBRARIES debug llprimitive optimized llprimitive - debug libcollada14dom22-d - optimized libcollada14dom22 + debug libcollada14dom23-sd + optimized libcollada14dom23-s + libxml2_a + debug pcrecppd + optimized pcrecpp + debug pcred + optimized pcre ${BOOST_SYSTEM_LIBRARIES} ) -elseif (LINUX) - use_prebuilt_binary(libxml2) - set(LLPRIMITIVE_LIBRARIES +elseif (DARWIN) + set(LLPRIMITIVE_LIBRARIES llprimitive - collada14dom + debug collada14dom-d + optimized collada14dom minizip xml2 pcrecpp pcre + iconv # Required by libxml2 ) -else (WINDOWS) - set(LLPRIMITIVE_LIBRARIES +elseif (LINUX) + set(LLPRIMITIVE_LIBRARIES llprimitive - collada14dom + debug collada14dom-d + optimized collada14dom minizip xml2 pcrecpp diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake index b9c9e531fc..74fe3f1137 100755 --- a/indra/cmake/Linking.cmake +++ b/indra/cmake/Linking.cmake @@ -6,6 +6,7 @@ set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES") include(Variables) set(ARCH_PREBUILT_DIRS ${AUTOBUILD_INSTALL_DIR}/lib) +set(ARCH_PREBUILT_DIRS_PLUGINS ${AUTOBUILD_INSTALL_DIR}/plugins) set(ARCH_PREBUILT_DIRS_RELEASE ${AUTOBUILD_INSTALL_DIR}/lib/release) set(ARCH_PREBUILT_DIRS_DEBUG ${AUTOBUILD_INSTALL_DIR}/lib/debug) if (WINDOWS) diff --git a/indra/cmake/OpenSSL.cmake b/indra/cmake/OpenSSL.cmake index 5b469f74f9..eb548bdcc1 100755 --- a/indra/cmake/OpenSSL.cmake +++ b/indra/cmake/OpenSSL.cmake @@ -7,7 +7,7 @@ set(OpenSSL_FIND_REQUIRED ON) if (USESYSTEMLIBS) include(FindOpenSSL) else (USESYSTEMLIBS) - use_prebuilt_binary(openSSL) + use_prebuilt_binary(openssl) if (WINDOWS) set(OPENSSL_LIBRARIES ssleay32 libeay32) else (WINDOWS) @@ -17,7 +17,7 @@ else (USESYSTEMLIBS) endif (USESYSTEMLIBS) if (LINUX) - set(CRYPTO_LIBRARIES crypto) + set(CRYPTO_LIBRARIES crypto dl) elseif (DARWIN) set(CRYPTO_LIBRARIES crypto) endif (LINUX) diff --git a/indra/cmake/PNG.cmake b/indra/cmake/PNG.cmake index 173d59391e..248a875a19 100755 --- a/indra/cmake/PNG.cmake +++ b/indra/cmake/PNG.cmake @@ -9,13 +9,26 @@ if (USESYSTEMLIBS) else (USESYSTEMLIBS) use_prebuilt_binary(libpng) if (WINDOWS) - set(PNG_LIBRARIES libpng15) - set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng15) + set(PNG_LIBRARIES libpng16) + set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng16) elseif(DARWIN) - set(PNG_LIBRARIES png15) - set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng15) + set(PNG_LIBRARIES png16) + set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng16) else() - set(PNG_LIBRARIES png15) - set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng15) + # + # When we have updated static libraries in competition with older + # shared libraries and we want the former to win, we need to do some + # extra work. The *_PRELOAD_ARCHIVES settings are invoked early + # and will pull in the entire archive to the binary giving it + # priority in symbol resolution. Beware of cmake moving the + # achive load itself to another place on the link command line. If + # that happens, you can try something like -Wl,-lpng16 here to hide + # the archive. Also be aware that the linker will not tolerate a + # second whole-archive load of the archive. See viewer's + # CMakeLists.txt for more information. + # + set(PNG_PRELOAD_ARCHIVES -Wl,--whole-archive png16 -Wl,--no-whole-archive) + set(PNG_LIBRARIES png16) + set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng16) endif() endif (USESYSTEMLIBS) diff --git a/indra/cmake/WebKitLibPlugin.cmake b/indra/cmake/WebKitLibPlugin.cmake index 76f2c148db..f7c548a2fd 100755 --- a/indra/cmake/WebKitLibPlugin.cmake +++ b/indra/cmake/WebKitLibPlugin.cmake @@ -1,6 +1,7 @@ # -*- cmake -*- include(Linking) include(Prebuilt) +include(OpenSSL) if (USESYSTEMLIBS) # The minimal version, 4.4.3, is rather arbitrary: it's the version in Debian/Lenny. @@ -36,27 +37,32 @@ endif (USESYSTEMLIBS) if (WINDOWS) set(WEBKIT_PLUGIN_LIBRARIES - debug llqtwebkitd - debug QtWebKitd4 - debug QtOpenGLd4 - debug QtNetworkd4 - debug QtGuid4 - debug QtCored4 - debug qtmaind - optimized llqtwebkit - optimized QtWebKit4 - optimized QtOpenGL4 - optimized QtNetwork4 - optimized QtGui4 - optimized QtCore4 - optimized qtmain + debug llqtwebkitd + debug QtWebKitd4 + debug QtOpenGLd4 + debug QtNetworkd4 + debug QtGuid4 + debug QtCored4 + debug qtmaind + optimized llqtwebkit + optimized QtWebKit4 + optimized QtOpenGL4 + optimized QtNetwork4 + optimized QtGui4 + optimized QtCore4 + optimized qtmain ) elseif (DARWIN) set(WEBKIT_PLUGIN_LIBRARIES - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib - debug ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib - ) + ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.a + ${ARCH_PREBUILT_DIRS_RELEASE}/libQtWebKit.4.dylib + ${ARCH_PREBUILT_DIRS_RELEASE}/libQtOpenGL.4.dylib + ${ARCH_PREBUILT_DIRS_RELEASE}/libQtNetwork.4.dylib + ${ARCH_PREBUILT_DIRS_RELEASE}/libQtGui.4.dylib + ${ARCH_PREBUILT_DIRS_RELEASE}/libQtCore.4.dylib + ) elseif (LINUX) + # *HUH: What does this do? set(WEBKIT_PLUGIN_LIBRARIES ${LLQTWEBKIT_LIBRARY} ${QT_LIBRARIES} ${QT_PLUGIN_LIBRARIES}) set(WEBKIT_PLUGIN_LIBRARIES llqtwebkit @@ -68,9 +74,10 @@ elseif (LINUX) QtWebKit QtOpenGL QtNetwork + ${OPENSSL_LIBRARIES} QtGui QtCore - jscore +# jscore # qgif # qjpeg # jpeg diff --git a/indra/cmake/ZLIB.cmake b/indra/cmake/ZLIB.cmake index b99a8644c9..6cff0753b2 100755 --- a/indra/cmake/ZLIB.cmake +++ b/indra/cmake/ZLIB.cmake @@ -13,10 +13,23 @@ else (USESYSTEMLIBS) set(ZLIB_LIBRARIES debug zlibd optimized zlib) - else (WINDOWS) + elseif (LINUX) + # + # When we have updated static libraries in competition with older + # shared libraries and we want the former to win, we need to do some + # extra work. The *_PRELOAD_ARCHIVES settings are invoked early + # and will pull in the entire archive to the binary giving it + # priority in symbol resolution. Beware of cmake moving the + # achive load itself to another place on the link command line. If + # that happens, you can try something like -Wl,-lz here to hide + # the archive. Also be aware that the linker will not tolerate a + # second whole-archive load of the archive. See viewer's + # CMakeLists.txt for more information. + # + set(ZLIB_PRELOAD_ARCHIVES -Wl,--whole-archive z -Wl,--no-whole-archive) + set(ZLIB_LIBRARIES z) + elseif (DARWIN) set(ZLIB_LIBRARIES z) endif (WINDOWS) - if (WINDOWS OR LINUX) - set(ZLIB_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/zlib) - endif (WINDOWS OR LINUX) + set(ZLIB_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/zlib) endif (USESYSTEMLIBS) diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt index c63ad74682..6f2087d580 100755 --- a/indra/edit-me-to-trigger-new-build.txt +++ b/indra/edit-me-to-trigger-new-build.txt @@ -1 +1,2 @@ 2014-02-25 10:34 + diff --git a/indra/linux_updater/CMakeLists.txt b/indra/linux_updater/CMakeLists.txt deleted file mode 100644 index 4a9e82f9b6..0000000000 --- a/indra/linux_updater/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# -*- cmake -*- - -project(linux_updater) - -include(00-Common) -include(CURL) -include(CARes) -include(OpenSSL) -include(UI) -include(LLCommon) -include(LLMessage) -include(LLVFS) -include(LLXML) -include(LLUI) -include(Linking) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLVFS_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ${LLUI_INCLUDE_DIRS} - ${CURL_INCLUDE_DIRS} - ${CARES_INCLUDE_DIRS} - ${OPENSSL_INCLUDE_DIRS} - ${UI_INCLUDE_DIRS} - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLXML_SYSTEM_INCLUDE_DIRS} - ) - -set(linux_updater_SOURCE_FILES linux_updater.cpp) - -set(linux_updater_HEADER_FILES CMakeLists.txt) - -set_source_files_properties(${linux_updater_HEADER_FILES} - PROPERTIES HEADER_FILES_ONLY TRUE) - -list(APPEND linux_updater_SOURCE_FILES ${linux_updater_HEADER_FILES}) - -add_executable(linux-updater ${linux_updater_SOURCE_FILES}) - -target_link_libraries(linux-updater - ${CURL_LIBRARIES} - ${CARES_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${CRYPTO_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${UI_LIBRARIES} - ${LLXML_LIBRARIES} - ${LLUI_LIBRARIES} - ${LLVFS_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ) - -add_custom_target(linux-updater-target ALL - DEPENDS linux-updater) diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp deleted file mode 100644 index 5c94deba02..0000000000 --- a/indra/linux_updater/linux_updater.cpp +++ /dev/null @@ -1,926 +0,0 @@ -/** - * @file linux_updater.cpp - * @author Kyle Ambroff <ambroff@lindenlab.com>, Tofu Linden - * @brief Viewer update program for unix platforms that support GTK+ - * - * $LicenseInfo:firstyear=2008&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include <unistd.h> -#include <signal.h> -#include <errno.h> -#include <set> -#include <iostream> - -#include "linden_common.h" -#include "llerrorcontrol.h" -#include "llfile.h" -#include "lldir.h" -#include "lldiriterator.h" - -/*==========================================================================*| -// IQA-490: Use of LLTrans -- by this program at least -- appears to be buggy. -// With it, the 3.3.2 beta 1 linux-updater.bin crashes; without it seems stable. -#include "llxmlnode.h" -#include "lltrans.h" -|*==========================================================================*/ - -static class LLTrans -{ -public: - LLTrans(); - static std::string getString(const std::string& key); - -private: - std::string _getString(const std::string& key) const; - - typedef std::map<std::string, std::string> MessageMap; - MessageMap mMessages; -} sLLTransInstance; - -#include <curl/curl.h> -#include <map> -#include <boost/foreach.hpp> - -extern "C" { -#include <gtk/gtk.h> -} - -const guint UPDATE_PROGRESS_TIMEOUT = 100; -const guint UPDATE_PROGRESS_TEXT_TIMEOUT = 1000; -const guint ROTATE_IMAGE_TIMEOUT = 8000; - -typedef struct _updater_app_state { - std::string app_name; - std::string url; - std::string file; - std::string image_dir; - std::string dest_dir; - std::string strings_dirs; - std::string strings_file; - - LLDirIterator *image_dir_iter; - - GtkWidget *window; - GtkWidget *progress_bar; - GtkWidget *image; - - double progress_value; - bool activity_mode; - - guint image_rotation_timeout_id; - guint progress_update_timeout_id; - guint update_progress_text_timeout_id; - - bool failure; -} UpdaterAppState; - -// List of entries from strings.xml to always replace -static std::set<std::string> default_trans_args; -void init_default_trans_args() -{ - default_trans_args.insert("SECOND_LIFE"); // World - default_trans_args.insert("APP_NAME"); - default_trans_args.insert("SECOND_LIFE_GRID"); - default_trans_args.insert("SUPPORT_SITE"); -} - -bool translate_init(std::string comma_delim_path_list, - std::string base_xml_name) -{ - return true; -/*==========================================================================*| - init_default_trans_args(); - - // extract paths string vector from comma-delimited flat string - std::vector<std::string> paths; - LLStringUtil::getTokens(comma_delim_path_list, paths, ","); // split over ',' - - for(std::vector<std::string>::iterator it = paths.begin(), end_it = paths.end(); - it != end_it; - ++it) - { - (*it) = gDirUtilp->findSkinnedFilename(*it, base_xml_name); - } - - // suck the translation xml files into memory - LLXMLNodePtr root; - bool success = LLXMLNode::getLayeredXMLNode(root, paths); - if (!success) - { - // couldn't load string table XML - return false; - } - else - { - // get those strings out of the XML - LLTrans::parseStrings(root, default_trans_args); - return true; - } -|*==========================================================================*/ -} - - -void updater_app_ui_init(void); -void updater_app_quit(UpdaterAppState *app_state); -void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state); -std::string next_image_filename(std::string& image_path, LLDirIterator& iter); -void display_error(GtkWidget *parent, std::string title, std::string message); -BOOL install_package(std::string package_file, std::string destination); -BOOL spawn_viewer(UpdaterAppState *app_state); - -extern "C" { - void on_window_closed(GtkWidget *sender, GdkEvent *event, gpointer state); - gpointer worker_thread_cb(gpointer *data); - int download_progress_cb(gpointer data, double t, double d, double utotal, double ulnow); - gboolean rotate_image_cb(gpointer data); - gboolean progress_update_timeout(gpointer data); - gboolean update_progress_text_timeout(gpointer data); -} - -void updater_app_ui_init(UpdaterAppState *app_state) -{ - GtkWidget *vbox; - GtkWidget *summary_label; - GtkWidget *description_label; - GtkWidget *frame; - - llassert(app_state != NULL); - - // set up window and main container - std::string window_title = LLTrans::getString("UpdaterWindowTitle"); - app_state->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title(GTK_WINDOW(app_state->window), - window_title.c_str()); - gtk_window_set_resizable(GTK_WINDOW(app_state->window), FALSE); - gtk_window_set_position(GTK_WINDOW(app_state->window), - GTK_WIN_POS_CENTER_ALWAYS); - - gtk_container_set_border_width(GTK_CONTAINER(app_state->window), 12); - g_signal_connect(G_OBJECT(app_state->window), "delete-event", - G_CALLBACK(on_window_closed), app_state); - - vbox = gtk_vbox_new(FALSE, 6); - gtk_container_add(GTK_CONTAINER(app_state->window), vbox); - - // set top label - std::ostringstream label_ostr; - label_ostr << "<big><b>" - << LLTrans::getString("UpdaterNowUpdating") - << "</b></big>"; - - summary_label = gtk_label_new(NULL); - gtk_label_set_use_markup(GTK_LABEL(summary_label), TRUE); - gtk_label_set_markup(GTK_LABEL(summary_label), - label_ostr.str().c_str()); - gtk_misc_set_alignment(GTK_MISC(summary_label), 0, 0.5); - gtk_box_pack_start(GTK_BOX(vbox), summary_label, FALSE, FALSE, 0); - - // create the description label - description_label = gtk_label_new(LLTrans::getString("UpdaterUpdatingDescriptive").c_str()); - gtk_label_set_line_wrap(GTK_LABEL(description_label), TRUE); - gtk_misc_set_alignment(GTK_MISC(description_label), 0, 0.5); - gtk_box_pack_start(GTK_BOX(vbox), description_label, FALSE, FALSE, 0); - - // If an image path has been set, load the background images - if (!app_state->image_dir.empty()) { - frame = gtk_frame_new(NULL); - gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); - gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); - - // load the first image - app_state->image = gtk_image_new_from_file - (next_image_filename(app_state->image_dir, *app_state->image_dir_iter).c_str()); - gtk_widget_set_size_request(app_state->image, 340, 310); - gtk_container_add(GTK_CONTAINER(frame), app_state->image); - - // rotate the images every 5 seconds - app_state->image_rotation_timeout_id = g_timeout_add - (ROTATE_IMAGE_TIMEOUT, rotate_image_cb, app_state); - } - - // set up progress bar, and update it roughly every 1/10 of a second - app_state->progress_bar = gtk_progress_bar_new(); - gtk_progress_bar_set_text(GTK_PROGRESS_BAR(app_state->progress_bar), - LLTrans::getString("UpdaterProgressBarTextWithEllipses").c_str()); - gtk_box_pack_start(GTK_BOX(vbox), - app_state->progress_bar, FALSE, TRUE, 0); - app_state->progress_update_timeout_id = g_timeout_add - (UPDATE_PROGRESS_TIMEOUT, progress_update_timeout, app_state); - app_state->update_progress_text_timeout_id = g_timeout_add - (UPDATE_PROGRESS_TEXT_TIMEOUT, update_progress_text_timeout, app_state); - - gtk_widget_show_all(app_state->window); -} - -gboolean rotate_image_cb(gpointer data) -{ - UpdaterAppState *app_state; - std::string filename; - - llassert(data != NULL); - app_state = (UpdaterAppState *) data; - - filename = next_image_filename(app_state->image_dir, *app_state->image_dir_iter); - - gdk_threads_enter(); - gtk_image_set_from_file(GTK_IMAGE(app_state->image), filename.c_str()); - gdk_threads_leave(); - - return TRUE; -} - -std::string next_image_filename(std::string& image_path, LLDirIterator& iter) -{ - std::string image_filename; - iter.next(image_filename); - return gDirUtilp->add(image_path, image_filename); -} - -void on_window_closed(GtkWidget *sender, GdkEvent* event, gpointer data) -{ - UpdaterAppState *app_state; - - llassert(data != NULL); - app_state = (UpdaterAppState *) data; - - updater_app_quit(app_state); -} - -void updater_app_quit(UpdaterAppState *app_state) -{ - if (app_state != NULL) - { - g_source_remove(app_state->progress_update_timeout_id); - - if (!app_state->image_dir.empty()) - { - g_source_remove(app_state->image_rotation_timeout_id); - } - } - - gtk_main_quit(); -} - -void display_error(GtkWidget *parent, std::string title, std::string message) -{ - GtkWidget *dialog; - - dialog = gtk_message_dialog_new(GTK_WINDOW(parent), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - "%s", message.c_str()); - gtk_window_set_title(GTK_WINDOW(dialog), title.c_str()); - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); -} - -gpointer worker_thread_cb(gpointer data) -{ - UpdaterAppState *app_state; - CURL *curl; - CURLcode result; - FILE *package_file; - GError *error = NULL; - int fd; - - //g_return_val_if_fail (data != NULL, NULL); - app_state = (UpdaterAppState *) data; - - try { - - if(!app_state->url.empty()) - { - char* tmp_local_filename = NULL; - // create temporary file to store the package. - fd = g_file_open_tmp - ("secondlife-update-XXXXXX", &tmp_local_filename, &error); - if (error != NULL) - { - LL_ERRS() << "Unable to create temporary file: " - << error->message - << LL_ENDL; - - g_error_free(error); - throw 0; - } - - if(tmp_local_filename != NULL) - { - app_state->file = tmp_local_filename; - g_free(tmp_local_filename); - } - - package_file = fdopen(fd, "wb"); - if (package_file == NULL) - { - LL_ERRS() << "Failed to create temporary file: " - << app_state->file.c_str() - << LL_ENDL; - - gdk_threads_enter(); - display_error(app_state->window, - LLTrans::getString("UpdaterFailDownloadTitle"), - LLTrans::getString("UpdaterFailUpdateDescriptive")); - gdk_threads_leave(); - throw 0; - } - - // initialize curl and start downloading the package - LL_INFOS() << "Downloading package: " << app_state->url << LL_ENDL; - - curl = curl_easy_init(); - if (curl == NULL) - { - LL_ERRS() << "Failed to initialize libcurl" << LL_ENDL; - - gdk_threads_enter(); - display_error(app_state->window, - LLTrans::getString("UpdaterFailDownloadTitle"), - LLTrans::getString("UpdaterFailUpdateDescriptive")); - gdk_threads_leave(); - throw 0; - } - - curl_easy_setopt(curl, CURLOPT_URL, app_state->url.c_str()); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file); - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE); - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, - &download_progress_cb); - curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state); - - result = curl_easy_perform(curl); - fclose(package_file); - curl_easy_cleanup(curl); - - if (result) - { - LL_ERRS() << "Failed to download update: " - << app_state->url - << LL_ENDL; - - gdk_threads_enter(); - display_error(app_state->window, - LLTrans::getString("UpdaterFailDownloadTitle"), - LLTrans::getString("UpdaterFailUpdateDescriptive")); - gdk_threads_leave(); - - throw 0; - } - } - - // now pulse the progres bar back and forth while the package is - // being unpacked - gdk_threads_enter(); - std::string installing_msg = LLTrans::getString("UpdaterNowInstalling"); - gtk_progress_bar_set_text( - GTK_PROGRESS_BAR(app_state->progress_bar), - installing_msg.c_str()); - app_state->activity_mode = TRUE; - gdk_threads_leave(); - - // *TODO: if the destination is not writable, terminate this - // thread and show file chooser? - if (!install_package(app_state->file.c_str(), app_state->dest_dir)) - { - LL_WARNS() << "Failed to install package to destination: " - << app_state->dest_dir - << LL_ENDL; - - gdk_threads_enter(); - display_error(app_state->window, - LLTrans::getString("UpdaterFailInstallTitle"), - LLTrans::getString("UpdaterFailUpdateDescriptive")); - //"Failed to update " + app_state->app_name, - gdk_threads_leave(); - throw 0; - } - - // try to spawn the new viewer - if (!spawn_viewer(app_state)) - { - LL_WARNS() << "Viewer was not installed properly in : " - << app_state->dest_dir - << LL_ENDL; - - gdk_threads_enter(); - display_error(app_state->window, - LLTrans::getString("UpdaterFailStartTitle"), - LLTrans::getString("UpdaterFailUpdateDescriptive")); - gdk_threads_leave(); - throw 0; - } - } - catch (...) - { - app_state->failure = TRUE; - } - - gdk_threads_enter(); - updater_app_quit(app_state); - gdk_threads_leave(); - - return NULL; -} - - -gboolean less_anal_gspawnsync(gchar **argv, - gchar **stderr_output, - gint *child_exit_status, - GError **spawn_error) -{ - // store current SIGCHLD handler if there is one, replace with default - // handler to make glib happy - struct sigaction sigchld_backup; - struct sigaction sigchld_appease_glib; - sigchld_appease_glib.sa_handler = SIG_DFL; - sigemptyset(&sigchld_appease_glib.sa_mask); - sigchld_appease_glib.sa_flags = 0; - sigaction(SIGCHLD, &sigchld_appease_glib, &sigchld_backup); - - gboolean rtn = g_spawn_sync(NULL, - argv, - NULL, - (GSpawnFlags) (G_SPAWN_STDOUT_TO_DEV_NULL), - NULL, - NULL, - NULL, - stderr_output, - child_exit_status, - spawn_error); - - // restore SIGCHLD handler - sigaction(SIGCHLD, &sigchld_backup, NULL); - - return rtn; -} - - -// perform a rename, or perform a (prompted) root rename if that fails -int -rename_with_sudo_fallback(const std::string& filename, const std::string& newname) -{ - int rtncode = ::rename(filename.c_str(), newname.c_str()); - LL_DEBUGS() << "rename result is: " << rtncode << " / " << errno << LL_ENDL; - if (rtncode && (EACCES == errno || EPERM == errno || EXDEV == errno)) - { - LL_INFOS() << "Permission problem in rename, or moving between different mount points. Retrying as a mv under a sudo." << LL_ENDL; - // failed due to permissions, try again as a gksudo or kdesu mv wrapper hack - char *sudo_cmd = NULL; - sudo_cmd = g_find_program_in_path("gksudo"); - if (!sudo_cmd) - { - sudo_cmd = g_find_program_in_path("kdesu"); - } - if (sudo_cmd) - { - char *mv_cmd = NULL; - mv_cmd = g_find_program_in_path("mv"); - if (mv_cmd) - { - char *src_string_copy = g_strdup(filename.c_str()); - char *dst_string_copy = g_strdup(newname.c_str()); - char* argv[] = - { - sudo_cmd, - mv_cmd, - src_string_copy, - dst_string_copy, - NULL - }; - - gchar *stderr_output = NULL; - gint child_exit_status = 0; - GError *spawn_error = NULL; - if (!less_anal_gspawnsync(argv, &stderr_output, - &child_exit_status, &spawn_error)) - { - LL_WARNS() << "Failed to spawn child process: " - << spawn_error->message - << LL_ENDL; - } - else if (child_exit_status) - { - LL_WARNS() << "mv command failed: " - << (stderr_output ? stderr_output : "(no reason given)") - << LL_ENDL; - } - else - { - // everything looks good, clear the error code - rtncode = 0; - } - - g_free(src_string_copy); - g_free(dst_string_copy); - if (spawn_error) g_error_free(spawn_error); - } - } - } - return rtncode; -} - -gboolean install_package(std::string package_file, std::string destination) -{ - char *tar_cmd = NULL; - std::ostringstream command; - - // Find the absolute path to the 'tar' command. - tar_cmd = g_find_program_in_path("tar"); - if (!tar_cmd) - { - LL_ERRS() << "`tar' was not found in $PATH" << LL_ENDL; - return FALSE; - } - LL_INFOS() << "Found tar command: " << tar_cmd << LL_ENDL; - - // Unpack the tarball in a temporary place first, then move it to - // its final destination - std::string tmp_dest_dir = gDirUtilp->getTempFilename(); - if (LLFile::mkdir(tmp_dest_dir, 0744)) - { - LL_ERRS() << "Failed to create directory: " - << destination - << LL_ENDL; - - return FALSE; - } - - char *package_file_string_copy = g_strdup(package_file.c_str()); - char *tmp_dest_dir_string_copy = g_strdup(tmp_dest_dir.c_str()); - gchar *argv[8] = { - tar_cmd, - const_cast<gchar*>("--strip"), const_cast<gchar*>("1"), - const_cast<gchar*>("-xjf"), - package_file_string_copy, - const_cast<gchar*>("-C"), tmp_dest_dir_string_copy, - NULL, - }; - - LL_INFOS() << "Untarring package: " << package_file << LL_ENDL; - - // store current SIGCHLD handler if there is one, replace with default - // handler to make glib happy - struct sigaction sigchld_backup; - struct sigaction sigchld_appease_glib; - sigchld_appease_glib.sa_handler = SIG_DFL; - sigemptyset(&sigchld_appease_glib.sa_mask); - sigchld_appease_glib.sa_flags = 0; - sigaction(SIGCHLD, &sigchld_appease_glib, &sigchld_backup); - - gchar *stderr_output = NULL; - gint child_exit_status = 0; - GError *untar_error = NULL; - if (!less_anal_gspawnsync(argv, &stderr_output, - &child_exit_status, &untar_error)) - { - LL_WARNS() << "Failed to spawn child process: " - << untar_error->message - << LL_ENDL; - return FALSE; - } - - if (child_exit_status) - { - LL_WARNS() << "Untar command failed: " - << (stderr_output ? stderr_output : "(no reason given)") - << LL_ENDL; - return FALSE; - } - - g_free(tar_cmd); - g_free(package_file_string_copy); - g_free(tmp_dest_dir_string_copy); - g_free(stderr_output); - if (untar_error) g_error_free(untar_error); - - // move the existing package out of the way if it exists - if (gDirUtilp->fileExists(destination)) - { - std::string backup_dir = destination + ".backup"; - int oldcounter = 1; - while (gDirUtilp->fileExists(backup_dir)) - { - // find a foo.backup.N folder name that isn't taken yet - backup_dir = destination + ".backup." + llformat("%d", oldcounter); - ++oldcounter; - } - - if (rename_with_sudo_fallback(destination, backup_dir)) - { - LL_WARNS() << "Failed to move directory: '" - << destination << "' -> '" << backup_dir - << LL_ENDL; - return FALSE; - } - } - - // The package has been unpacked in a staging directory, now we just - // need to move it to its destination. - if (rename_with_sudo_fallback(tmp_dest_dir, destination)) - { - LL_WARNS() << "Failed to move installation to the destination: " - << destination - << LL_ENDL; - return FALSE; - } - - // \0/ Success! - return TRUE; -} - -gboolean progress_update_timeout(gpointer data) -{ - UpdaterAppState *app_state; - - llassert(data != NULL); - - app_state = (UpdaterAppState *) data; - - gdk_threads_enter(); - if (app_state->activity_mode) - { - gtk_progress_bar_pulse - (GTK_PROGRESS_BAR(app_state->progress_bar)); - } - else - { - gtk_progress_set_value(GTK_PROGRESS(app_state->progress_bar), - app_state->progress_value); - } - gdk_threads_leave(); - - return TRUE; -} - -gboolean update_progress_text_timeout(gpointer data) -{ - UpdaterAppState *app_state; - - llassert(data != NULL); - app_state = (UpdaterAppState *) data; - - if (app_state->activity_mode == TRUE) - { - // We no longer need this timeout, it will be removed. - return FALSE; - } - - if (!app_state->progress_value) - { - return TRUE; - } - - std::string progress_text = llformat((LLTrans::getString("UpdaterProgressBarText")+" (%.0f%%)").c_str(), app_state->progress_value); - - gdk_threads_enter(); - gtk_progress_bar_set_text(GTK_PROGRESS_BAR(app_state->progress_bar), - progress_text.c_str()); - gdk_threads_leave(); - - return TRUE; -} - -int download_progress_cb(gpointer data, - double t, - double d, - double utotal, - double ulnow) -{ - UpdaterAppState *app_state; - - llassert(data != NULL); - app_state = (UpdaterAppState *) data; - - if (t <= 0.0) - { - app_state->progress_value = 0; - } - else - { - app_state->progress_value = d * 100.0 / t; - } - return 0; -} - -BOOL spawn_viewer(UpdaterAppState *app_state) -{ - llassert(app_state != NULL); - - std::string cmd = app_state->dest_dir + "/secondlife"; - GError *error = NULL; - - // We want to spawn the Viewer on the same display as the updater app - gboolean success = gdk_spawn_command_line_on_screen - (gtk_widget_get_screen(app_state->window), cmd.c_str(), &error); - - if (!success) - { - LL_WARNS() << "Failed to launch viewer: " << error->message - << LL_ENDL; - } - - if (error) g_error_free(error); - - return success; -} - -void show_usage_and_exit() -{ - std::cout << "Usage: linux-updater <--url URL | --file FILE> --name NAME --dest PATH --stringsdir PATH1,PATH2 --stringsfile FILE" - << "[--image-dir PATH]" - << std::endl; - exit(1); -} - -void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state) -{ - int i; - - for (i = 1; i < argc; i++) - { - if ((!strcmp(argv[i], "--url")) && (++i < argc)) - { - app_state->url = argv[i]; - } - else if ((!strcmp(argv[i], "--file")) && (++i < argc)) - { - app_state->file = argv[i]; - } - else if ((!strcmp(argv[i], "--name")) && (++i < argc)) - { - app_state->app_name = argv[i]; - } - else if ((!strcmp(argv[i], "--image-dir")) && (++i < argc)) - { - app_state->image_dir = argv[i]; - app_state->image_dir_iter = new LLDirIterator(argv[i], "*.jpg"); - } - else if ((!strcmp(argv[i], "--dest")) && (++i < argc)) - { - app_state->dest_dir = argv[i]; - } - else if ((!strcmp(argv[i], "--stringsdir")) && (++i < argc)) - { - app_state->strings_dirs = argv[i]; - } - else if ((!strcmp(argv[i], "--stringsfile")) && (++i < argc)) - { - app_state->strings_file = argv[i]; - } - else - { - // show usage, an invalid option was given. - show_usage_and_exit(); - } - } - - if (app_state->app_name.empty() - || (app_state->url.empty() && app_state->file.empty()) - || app_state->dest_dir.empty()) - { - show_usage_and_exit(); - } - - app_state->progress_value = 0.0; - app_state->activity_mode = FALSE; - app_state->failure = FALSE; - - translate_init(app_state->strings_dirs, app_state->strings_file); -} - -int main(int argc, char **argv) -{ - UpdaterAppState* app_state = new UpdaterAppState; - - parse_args_and_init(argc, argv, app_state); - - // Initialize logger, and rename old log file - gDirUtilp->initAppDirs("SecondLife"); - LLError::initForApplication - (gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")); - std::string old_log_file = gDirUtilp->getExpandedFilename - (LL_PATH_LOGS, "updater.log.old"); - std::string log_file = - gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "updater.log"); - LLFile::rename(log_file, old_log_file); - LLError::logToFile(log_file); - - // initialize gthreads and gtk+ - if (!g_thread_supported()) - { - g_thread_init(NULL); - gdk_threads_init(); - } - - gtk_init(&argc, &argv); - - // create UI - updater_app_ui_init(app_state); - - //LL_INFOS() << "SAMPLE TRANSLATION IS: " << LLTrans::getString("LoginInProgress") << LL_ENDL; - - // create download thread - g_thread_create(GThreadFunc(worker_thread_cb), app_state, FALSE, NULL); - - gdk_threads_enter(); - gtk_main(); - gdk_threads_leave(); - - // Delete the file only if created from url download. - if(!app_state->url.empty() && !app_state->file.empty()) - { - if (gDirUtilp->fileExists(app_state->file)) - { - LLFile::remove(app_state->file); - } - } - - bool success = !app_state->failure; - delete app_state->image_dir_iter; - delete app_state; - return success ? 0 : 1; -} - -/***************************************************************************** -* Dummy LLTrans implementation (IQA-490) -*****************************************************************************/ -static LLTrans sStaticStrings; - -// lookup -std::string LLTrans::_getString(const std::string& key) const -{ - MessageMap::const_iterator found = mMessages.find(key); - if (found != mMessages.end()) - { - return found->second; - } - LL_WARNS("linux_updater") << "No message for key '" << key - << "' -- add to LLTrans::LLTrans() in linux_updater.cpp" - << LL_ENDL; - return key; -} - -// static lookup -std::string LLTrans::getString(const std::string& key) -{ - return sLLTransInstance._getString(key); -} - -// initialization -LLTrans::LLTrans() -{ - typedef std::pair<const char*, const char*> Pair; - static const Pair data[] = - { - Pair("UpdaterFailDownloadTitle", - "Failed to download update"), - Pair("UpdaterFailInstallTitle", - "Failed to install update"), - Pair("UpdaterFailStartTitle", - "Failed to start viewer"), - Pair("UpdaterFailUpdateDescriptive", - "An error occurred while updating Second Life. " - "Please download the latest version from www.secondlife.com."), - Pair("UpdaterNowInstalling", - "Installing Second Life..."), - Pair("UpdaterNowUpdating", - "Now updating Second Life..."), - Pair("UpdaterProgressBarText", - "Downloading update"), - Pair("UpdaterProgressBarTextWithEllipses", - "Downloading update..."), - Pair("UpdaterUpdatingDescriptive", - "Your Second Life Viewer is being updated to the latest release. " - "This may take some time, so please be patient."), - Pair("UpdaterWindowTitle", - "Second Life Update") - }; - - BOOST_FOREACH(Pair pair, data) - { - mMessages[pair.first] = pair.second; - } -} diff --git a/indra/llaudio/llaudiodecodemgr.h b/indra/llaudio/llaudiodecodemgr.h index 7a9b807d04..8228e20e8c 100755 --- a/indra/llaudio/llaudiodecodemgr.h +++ b/indra/llaudio/llaudiodecodemgr.h @@ -24,7 +24,7 @@ */ #ifndef LL_LLAUDIODECODEMGR_H -#define LL_LLAUDIODECODEMG_H +#define LL_LLAUDIODECODEMGR_H #include "stdtypes.h" diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 8eeb186936..763f5a3521 100755 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -301,7 +301,7 @@ if (LL_TESTS) LL_ADD_INTEGRATION_TEST(llunits "" "${test_libs}") LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}") LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}") - LL_ADD_INTEGRATION_TEST(lleventcoro "" "${test_libs};${BOOST_CONTEXT_LIBRARY}") + LL_ADD_INTEGRATION_TEST(lleventcoro "" "${test_libs};${BOOST_CONTEXT_LIBRARY};${BOOST_COROUTINE_LIBRARY};${BOOST_SYSTEM_LIBRARY}") LL_ADD_INTEGRATION_TEST(llprocess "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llleap "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llstreamqueue "" "${test_libs}") diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index db52f2b1f4..7d1d541a4b 100755 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -257,7 +257,8 @@ inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __ assert((bytes % sizeof(F32))== 0); ll_assert_aligned(src,16); ll_assert_aligned(dst,16); - assert((src < dst) ? ((src + bytes) < dst) : ((dst + bytes) < src)); + + assert((src < dst) ? ((src + bytes) <= dst) : ((dst + bytes) <= src)); assert(bytes%16==0); char* end = dst + bytes; diff --git a/indra/llmessage/lltransfermanager.cpp b/indra/llmessage/lltransfermanager.cpp index d6db20d7a3..ec7b21d8b6 100755 --- a/indra/llmessage/lltransfermanager.cpp +++ b/indra/llmessage/lltransfermanager.cpp @@ -1260,9 +1260,13 @@ bool LLTransferTarget::addDelayedPacket( size); #ifdef _DEBUG - if (mDelayedPacketMap.find(packet_id) != mDelayedPacketMap.end()) + transfer_packet_map::iterator iter = mDelayedPacketMap.find(packet_id); + if (iter != mDelayedPacketMap.end()) { - LL_ERRS() << "Packet ALREADY in delayed packet map!" << LL_ENDL; + if (!(iter->second->mSize == size) && !(iter->second->mDatap == datap)) + { + LL_ERRS() << "Packet ALREADY in delayed packet map!" << LL_ENDL; + } } #endif diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index 5e1f12996e..7f2224870d 100755 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -477,7 +477,8 @@ void LLToolTipMgr::show(const std::string& msg) void LLToolTipMgr::show(const LLToolTip::Params& params) { if (!params.styled_message.isProvided() - && (!params.message.isProvided() || params.message().empty())) return; + && (!params.message.isProvided() || params.message().empty()) + && !params.image.isProvided()) return; // fill in default tooltip params from tool_tip.xml LLToolTip::Params params_with_defaults(params); diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp deleted file mode 100644 index f533d47b18..0000000000 --- a/indra/mac_updater/mac_updater.cpp +++ /dev/null @@ -1,1266 +0,0 @@ -/** - * @file mac_updater.cpp - * @brief - * - * $LicenseInfo:firstyear=2006&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include <boost/format.hpp> - -#include <libgen.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include <curl/curl.h> -#include <pthread.h> - -#include "llerror.h" -#include "lltimer.h" -#include "lldir.h" -#include "llfile.h" - -#include "llstring.h" - -#include <Carbon/Carbon.h> - -#include "llerrorcontrol.h" - -#if LL_DARWIN -// FSPathMakeRef, FSObjectCopy, deprecations... -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - -enum -{ - kEventClassCustom = 'Cust', - kEventCustomProgress = 'Prog', - kEventParamCustomCurValue = 'Cur ', - kEventParamCustomMaxValue = 'Max ', - kEventParamCustomText = 'Text', - kEventCustomDone = 'Done', -}; - -WindowRef gWindow = NULL; -EventHandlerRef gEventHandler = NULL; -OSStatus gFailure = noErr; -Boolean gCancelled = false; - -const char *gUpdateURL; -const char *gProductName; -const char *gBundleID; -const char *gDmgFile; -const char *gMarkerPath; - -void *updatethreadproc(void*); - -pthread_t updatethread; - -OSStatus setProgress(int cur, int max) -{ - OSStatus err; - ControlRef progressBar = NULL; - ControlID id; - - id.signature = 'prog'; - id.id = 0; - - err = GetControlByID(gWindow, &id, &progressBar); - if(err == noErr) - { - Boolean indeterminate; - - if(max == 0) - { - indeterminate = true; - err = SetControlData(progressBar, kControlEntireControl, kControlProgressBarIndeterminateTag, sizeof(Boolean), (Ptr)&indeterminate); - } - else - { - double percentage = (double)cur / (double)max; - SetControlMinimum(progressBar, 0); - SetControlMaximum(progressBar, 100); - SetControlValue(progressBar, (SInt16)(percentage * 100)); - - indeterminate = false; - err = SetControlData(progressBar, kControlEntireControl, kControlProgressBarIndeterminateTag, sizeof(Boolean), (Ptr)&indeterminate); - - Draw1Control(progressBar); - } - } - - return(err); -} - -OSStatus setProgressText(CFStringRef text) -{ - OSStatus err; - ControlRef progressText = NULL; - ControlID id; - - id.signature = 'what'; - id.id = 0; - - err = GetControlByID(gWindow, &id, &progressText); - if(err == noErr) - { - err = SetControlData(progressText, kControlEntireControl, kControlStaticTextCFStringTag, sizeof(CFStringRef), (Ptr)&text); - Draw1Control(progressText); - } - - return(err); -} - -OSStatus sendProgress(long cur, long max, CFStringRef text = NULL) -{ - OSStatus result; - EventRef evt; - - result = CreateEvent( - NULL, - kEventClassCustom, - kEventCustomProgress, - 0, - kEventAttributeNone, - &evt); - - // This event needs to be targeted at the window so it goes to the window's handler. - if(result == noErr) - { - EventTargetRef target = GetWindowEventTarget(gWindow); - result = SetEventParameter ( - evt, - kEventParamPostTarget, - typeEventTargetRef, - sizeof(target), - &target); - } - - if(result == noErr) - { - result = SetEventParameter ( - evt, - kEventParamCustomCurValue, - typeLongInteger, - sizeof(cur), - &cur); - } - - if(result == noErr) - { - result = SetEventParameter ( - evt, - kEventParamCustomMaxValue, - typeLongInteger, - sizeof(max), - &max); - } - - if(result == noErr) - { - if(text != NULL) - { - result = SetEventParameter ( - evt, - kEventParamCustomText, - typeCFStringRef, - sizeof(text), - &text); - } - } - - if(result == noErr) - { - // Send the event - PostEventToQueue( - GetMainEventQueue(), - evt, - kEventPriorityStandard); - - } - - return(result); -} - -OSStatus sendDone(void) -{ - OSStatus result; - EventRef evt; - - result = CreateEvent( - NULL, - kEventClassCustom, - kEventCustomDone, - 0, - kEventAttributeNone, - &evt); - - // This event needs to be targeted at the window so it goes to the window's handler. - if(result == noErr) - { - EventTargetRef target = GetWindowEventTarget(gWindow); - result = SetEventParameter ( - evt, - kEventParamPostTarget, - typeEventTargetRef, - sizeof(target), - &target); - } - - if(result == noErr) - { - // Send the event - PostEventToQueue( - GetMainEventQueue(), - evt, - kEventPriorityStandard); - - } - - return(result); -} - -OSStatus dialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata) -{ - OSStatus result = eventNotHandledErr; - OSStatus err; - UInt32 evtClass = GetEventClass(event); - UInt32 evtKind = GetEventKind(event); - - if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess)) - { - HICommand cmd; - err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd); - - if(err == noErr) - { - switch(cmd.commandID) - { - case kHICommandCancel: - gCancelled = true; -// QuitAppModalLoopForWindow(gWindow); - result = noErr; - break; - } - } - } - else if((evtClass == kEventClassCustom) && (evtKind == kEventCustomProgress)) - { - // Request to update the progress dialog - long cur = 0; - long max = 0; - CFStringRef text = NULL; - (void) GetEventParameter(event, kEventParamCustomCurValue, typeLongInteger, NULL, sizeof(cur), NULL, &cur); - (void) GetEventParameter(event, kEventParamCustomMaxValue, typeLongInteger, NULL, sizeof(max), NULL, &max); - (void) GetEventParameter(event, kEventParamCustomText, typeCFStringRef, NULL, sizeof(text), NULL, &text); - - err = setProgress(cur, max); - if(err == noErr) - { - if(text != NULL) - { - setProgressText(text); - } - } - - result = noErr; - } - else if((evtClass == kEventClassCustom) && (evtKind == kEventCustomDone)) - { - // We're done. Exit the modal loop. - QuitAppModalLoopForWindow(gWindow); - result = noErr; - } - - return(result); -} - -#if 0 -size_t curl_download_callback(void *data, size_t size, size_t nmemb, - void *user_data) -{ - S32 bytes = size * nmemb; - char *cdata = (char *) data; - for (int i =0; i < bytes; i += 1) - { - gServerResponse.append(cdata[i]); - } - return bytes; -} -#endif - -int curl_progress_callback_func(void *clientp, - double dltotal, - double dlnow, - double ultotal, - double ulnow) -{ - int max = (int)(dltotal / 1024.0); - int cur = (int)(dlnow / 1024.0); - sendProgress(cur, max); - - if(gCancelled) - return(1); - - return(0); -} - -int parse_args(int argc, char **argv) -{ - int j; - - for (j = 1; j < argc; j++) - { - if ((!strcmp(argv[j], "-url")) && (++j < argc)) - { - gUpdateURL = argv[j]; - } - else if ((!strcmp(argv[j], "-name")) && (++j < argc)) - { - gProductName = argv[j]; - } - else if ((!strcmp(argv[j], "-bundleid")) && (++j < argc)) - { - gBundleID = argv[j]; - } - else if ((!strcmp(argv[j], "-dmg")) && (++j < argc)) - { - gDmgFile = argv[j]; - } - else if ((!strcmp(argv[j], "-marker")) && (++j < argc)) - { - gMarkerPath = argv[j];; - } - } - - return 0; -} - -int main(int argc, char **argv) -{ - // We assume that all the logs we're looking for reside on the current drive - gDirUtilp->initAppDirs("SecondLife"); - - LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")); - - // Rename current log file to ".old" - std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "updater.log.old"); - std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "updater.log"); - LLFile::rename(log_file.c_str(), old_log_file.c_str()); - - // Set the log file to updater.log - LLError::logToFile(log_file); - - ///////////////////////////////////////// - // - // Process command line arguments - // - gUpdateURL = NULL; - gProductName = NULL; - gBundleID = NULL; - gDmgFile = NULL; - gMarkerPath = NULL; - parse_args(argc, argv); - if ((gUpdateURL == NULL) && (gDmgFile == NULL)) - { - llinfos << "Usage: mac_updater -url <url> | -dmg <dmg file> [-name <product_name>] [-program <program_name>]" << llendl; - exit(1); - } - else - { - llinfos << "Update url is: " << gUpdateURL << llendl; - if (gProductName) - { - llinfos << "Product name is: " << gProductName << llendl; - } - else - { - gProductName = "Second Life"; - } - if (gBundleID) - { - llinfos << "Bundle ID is: " << gBundleID << llendl; - } - else - { - gBundleID = "com.secondlife.indra.viewer"; - } - } - - llinfos << "Starting " << gProductName << " Updater" << llendl; - - // Real UI... - OSStatus err; - IBNibRef nib = NULL; - - err = CreateNibReference(CFSTR("AutoUpdater"), &nib); - - char windowTitle[MAX_PATH]; /* Flawfinder: ignore */ - snprintf(windowTitle, sizeof(windowTitle), "%s Updater", gProductName); - CFStringRef windowTitleRef = NULL; - windowTitleRef = CFStringCreateWithCString(NULL, windowTitle, kCFStringEncodingUTF8); - - if(err == noErr) - { - err = CreateWindowFromNib(nib, CFSTR("Updater"), &gWindow); - } - - if (err == noErr) - { - err = SetWindowTitleWithCFString(gWindow, windowTitleRef); - } - CFRelease(windowTitleRef); - - if(err == noErr) - { - // Set up an event handler for the window. - EventTypeSpec handlerEvents[] = - { - { kEventClassCommand, kEventCommandProcess }, - { kEventClassCustom, kEventCustomProgress }, - { kEventClassCustom, kEventCustomDone } - }; - InstallStandardEventHandler(GetWindowEventTarget(gWindow)); - InstallWindowEventHandler( - gWindow, - NewEventHandlerUPP(dialogHandler), - GetEventTypeCount (handlerEvents), - handlerEvents, - 0, - &gEventHandler); - } - - if(err == noErr) - { - ShowWindow(gWindow); - SelectWindow(gWindow); - } - - if(err == noErr) - { - pthread_create(&updatethread, - NULL, - &updatethreadproc, - NULL); - - } - - if(err == noErr) - { - RunAppModalLoopForWindow(gWindow); - } - - void *threadresult; - - pthread_join(updatethread, &threadresult); - - if(!gCancelled && (gFailure != noErr)) - { - // Something went wrong. Since we always just tell the user to download a new version, we don't really care what. - AlertStdCFStringAlertParamRec params; - SInt16 retval_mac = 1; - DialogRef alert = NULL; - OSStatus err; - - params.version = kStdCFStringAlertVersionOne; - params.movable = false; - params.helpButton = false; - params.defaultText = (CFStringRef)kAlertDefaultOKText; - params.cancelText = 0; - params.otherText = 0; - params.defaultButton = 1; - params.cancelButton = 0; - params.position = kWindowDefaultPosition; - params.flags = 0; - - err = CreateStandardAlert( - kAlertStopAlert, - CFSTR("Error"), - CFSTR("An error occurred while updating Second Life. Please download the latest version from www.secondlife.com."), - ¶ms, - &alert); - - if(err == noErr) - { - err = RunStandardAlert( - alert, - NULL, - &retval_mac); - } - - if(gMarkerPath != 0) - { - // Create a install fail marker that can be used by the viewer to - // detect install problems. - std::ofstream stream(gMarkerPath); - if(stream) stream << -1; - } - exit(-1); - } else { - exit(0); - } - - if(gWindow != NULL) - { - DisposeWindow(gWindow); - } - - if(nib != NULL) - { - DisposeNibReference(nib); - } - - return 0; -} - -bool isDirWritable(FSRef &dir) -{ - bool result = false; - - // Test for a writable directory by creating a directory, then deleting it again. - // This is kinda lame, but will pretty much always give the right answer. - - OSStatus err = noErr; - char temp[PATH_MAX] = ""; /* Flawfinder: ignore */ - - err = FSRefMakePath(&dir, (UInt8*)temp, sizeof(temp)); - - if(err == noErr) - { - strncat(temp, "/.test_XXXXXX", (sizeof(temp) - strlen(temp)) - 1); - - if(mkdtemp(temp) != NULL) - { - // We were able to make the directory. This means the directory is writable. - result = true; - - // Clean up. - rmdir(temp); - } - } - -#if 0 - // This seemed like a good idea, but won't tell us if we're on a volume mounted read-only. - UInt8 perm; - err = FSGetUserPrivilegesPermissions(&targetParentRef, &perm, NULL); - if(err == noErr) - { - if(perm & kioACUserNoMakeChangesMask) - { - // Parent directory isn't writable. - llinfos << "Target parent directory not writable." << llendl; - err = -1; - replacingTarget = false; - } - } -#endif - - return result; -} - -static std::string HFSUniStr255_to_utf8str(const HFSUniStr255* src) -{ - llutf16string string16((U16*)&(src->unicode), src->length); - std::string result = utf16str_to_utf8str(string16); - return result; -} - -int restoreObject(const char* aside, const char* target, const char* path, const char* object) -{ - char source[PATH_MAX] = ""; /* Flawfinder: ignore */ - char dest[PATH_MAX] = ""; /* Flawfinder: ignore */ - snprintf(source, sizeof(source), "%s/%s/%s", aside, path, object); - snprintf(dest, sizeof(dest), "%s/%s", target, path); - FSRef sourceRef; - FSRef destRef; - OSStatus err; - err = FSPathMakeRef((UInt8 *)source, &sourceRef, NULL); - if(err != noErr) return false; - err = FSPathMakeRef((UInt8 *)dest, &destRef, NULL); - if(err != noErr) return false; - - llinfos << "Copying " << source << " to " << dest << llendl; - - err = FSCopyObjectSync( - &sourceRef, - &destRef, - NULL, - NULL, - kFSFileOperationOverwrite); - - if(err != noErr) return false; - return true; -} - -// Replace any mention of "Second Life" with the product name. -void filterFile(const char* filename) -{ - char temp[PATH_MAX] = ""; /* Flawfinder: ignore */ - // First copy the target's version, so we can run it through sed. - snprintf(temp, sizeof(temp), "cp '%s' '%s.tmp'", filename, filename); - system(temp); /* Flawfinder: ignore */ - - // Now run it through sed. - snprintf(temp, sizeof(temp), - "sed 's/Second Life/%s/g' '%s.tmp' > '%s'", gProductName, filename, filename); - system(temp); /* Flawfinder: ignore */ -} - -static bool isFSRefViewerBundle(FSRef *targetRef) -{ - bool result = false; - CFURLRef targetURL = NULL; - CFBundleRef targetBundle = NULL; - CFStringRef targetBundleID = NULL; - CFStringRef sourceBundleID = NULL; - - targetURL = CFURLCreateFromFSRef(NULL, targetRef); - - if(targetURL == NULL) - { - llinfos << "Error creating target URL." << llendl; - } - else - { - targetBundle = CFBundleCreate(NULL, targetURL); - } - - if(targetBundle == NULL) - { - llinfos << "Failed to create target bundle." << llendl; - } - else - { - targetBundleID = CFBundleGetIdentifier(targetBundle); - } - - if(targetBundleID == NULL) - { - llinfos << "Couldn't retrieve target bundle ID." << llendl; - } - else - { - sourceBundleID = CFStringCreateWithCString(NULL, gBundleID, kCFStringEncodingUTF8); - if(CFStringCompare(sourceBundleID, targetBundleID, 0) == kCFCompareEqualTo) - { - // This is the bundle we're looking for. - result = true; - } - else - { - llinfos << "Target bundle ID mismatch." << llendl; - } - } - - // Don't release targetBundleID -- since we don't retain it, it's released when targetBundle is released. - if(targetURL != NULL) - CFRelease(targetURL); - if(targetBundle != NULL) - CFRelease(targetBundle); - - return result; -} - -// Search through the directory specified by 'parent' for an item that appears to be a Second Life viewer. -static OSErr findAppBundleOnDiskImage(FSRef *parent, FSRef *app) -{ - FSIterator iterator; - bool found = false; - - OSErr err = FSOpenIterator( parent, kFSIterateFlat, &iterator ); - if(!err) - { - do - { - ItemCount actualObjects = 0; - Boolean containerChanged = false; - FSCatalogInfo info; - FSRef ref; - HFSUniStr255 unicodeName; - err = FSGetCatalogInfoBulk( - iterator, - 1, - &actualObjects, - &containerChanged, - kFSCatInfoNodeFlags, - &info, - &ref, - NULL, - &unicodeName ); - - if(actualObjects == 0) - break; - - if(!err) - { - // Call succeeded and not done with the iteration. - std::string name = HFSUniStr255_to_utf8str(&unicodeName); - - llinfos << "Considering \"" << name << "\"" << llendl; - - if(info.nodeFlags & kFSNodeIsDirectoryMask) - { - // This is a directory. See if it's a .app - if(name.find(".app") != std::string::npos) - { - // Looks promising. Check to see if it has the right bundle identifier. - if(isFSRefViewerBundle(&ref)) - { - llinfos << name << " is the one" << llendl; - // This is the one. Return it. - *app = ref; - found = true; - break; - } else { - llinfos << name << " is not the bundle we are looking for; move along" << llendl; - } - - } - } - } - } - while(!err); - - llinfos << "closing the iterator" << llendl; - - FSCloseIterator(iterator); - - llinfos << "closed" << llendl; - } - - if(!err && !found) - err = fnfErr; - - return err; -} - -void *updatethreadproc(void*) -{ - char tempDir[PATH_MAX] = ""; /* Flawfinder: ignore */ - FSRef tempDirRef; - char temp[PATH_MAX] = ""; /* Flawfinder: ignore */ - // *NOTE: This buffer length is used in a scanf() below. - char deviceNode[1024] = ""; /* Flawfinder: ignore */ - LLFILE *downloadFile = NULL; - OSStatus err; - ProcessSerialNumber psn; - char target[PATH_MAX] = ""; /* Flawfinder: ignore */ - FSRef targetRef; - FSRef targetParentRef; - FSVolumeRefNum targetVol; - FSRef trashFolderRef; - Boolean replacingTarget = false; - - memset(&tempDirRef, 0, sizeof(tempDirRef)); - memset(&targetRef, 0, sizeof(targetRef)); - memset(&targetParentRef, 0, sizeof(targetParentRef)); - - try - { - // Attempt to get a reference to the Second Life application bundle containing this updater. - // Any failures during this process will cause us to default to updating /Applications/Second Life.app - { - FSRef myBundle; - - err = GetCurrentProcess(&psn); - if(err == noErr) - { - err = GetProcessBundleLocation(&psn, &myBundle); - } - - if(err == noErr) - { - // Sanity check: Make sure the name of the item referenced by targetRef is "Second Life.app". - FSRefMakePath(&myBundle, (UInt8*)target, sizeof(target)); - - llinfos << "Updater bundle location: " << target << llendl; - } - - // Our bundle should be in Second Life.app/Contents/Resources/AutoUpdater.app - // so we need to go up 3 levels to get the path to the main application bundle. - if(err == noErr) - { - err = FSGetCatalogInfo(&myBundle, kFSCatInfoNone, NULL, NULL, NULL, &targetRef); - } - if(err == noErr) - { - err = FSGetCatalogInfo(&targetRef, kFSCatInfoNone, NULL, NULL, NULL, &targetRef); - } - if(err == noErr) - { - err = FSGetCatalogInfo(&targetRef, kFSCatInfoNone, NULL, NULL, NULL, &targetRef); - } - - // And once more to get the parent of the target - if(err == noErr) - { - err = FSGetCatalogInfo(&targetRef, kFSCatInfoNone, NULL, NULL, NULL, &targetParentRef); - } - - if(err == noErr) - { - FSRefMakePath(&targetRef, (UInt8*)target, sizeof(target)); - llinfos << "Path to target: " << target << llendl; - } - - // Sanity check: make sure the target is a bundle with the right identifier - if(err == noErr) - { - // Assume the worst... - err = -1; - - if(isFSRefViewerBundle(&targetRef)) - { - // This is the bundle we're looking for. - err = noErr; - replacingTarget = true; - } - } - - // Make sure the target's parent directory is writable. - if(err == noErr) - { - if(!isDirWritable(targetParentRef)) - { - // Parent directory isn't writable. - llinfos << "Target parent directory not writable." << llendl; - err = -1; - replacingTarget = false; - } - } - - if(err != noErr) - { - Boolean isDirectory; - llinfos << "Target search failed, defaulting to /Applications/" << gProductName << ".app." << llendl; - - // Set up the parent directory - err = FSPathMakeRef((UInt8*)"/Applications", &targetParentRef, &isDirectory); - if((err != noErr) || (!isDirectory)) - { - // We're so hosed. - llinfos << "Applications directory not found, giving up." << llendl; - throw 0; - } - - snprintf(target, sizeof(target), "/Applications/%s.app", gProductName); - - memset(&targetRef, 0, sizeof(targetRef)); - err = FSPathMakeRef((UInt8*)target, &targetRef, NULL); - if(err == fnfErr) - { - // This is fine, just means we're not replacing anything. - err = noErr; - replacingTarget = false; - } - else - { - replacingTarget = true; - } - - // Make sure the target's parent directory is writable. - if(err == noErr) - { - if(!isDirWritable(targetParentRef)) - { - // Parent directory isn't writable. - llinfos << "Target parent directory not writable." << llendl; - err = -1; - replacingTarget = false; - } - } - - } - - // If we haven't fixed all problems by this point, just bail. - if(err != noErr) - { - llinfos << "Unable to pick a target, giving up." << llendl; - throw 0; - } - } - - // Find the volID of the volume the target resides on - { - FSCatalogInfo info; - err = FSGetCatalogInfo( - &targetParentRef, - kFSCatInfoVolume, - &info, - NULL, - NULL, - NULL); - - if(err != noErr) - throw 0; - - targetVol = info.volume; - } - - // Find the temporary items and trash folders on that volume. - err = FSFindFolder( - targetVol, - kTrashFolderType, - true, - &trashFolderRef); - - if(err != noErr) - throw 0; - -#if 0 // *HACK for DEV-11935 see below for details. - - FSRef tempFolderRef; - - err = FSFindFolder( - targetVol, - kTemporaryFolderType, - true, - &tempFolderRef); - - if(err != noErr) - throw 0; - - err = FSRefMakePath(&tempFolderRef, (UInt8*)temp, sizeof(temp)); - - if(err != noErr) - throw 0; - -#else - - // *HACK for DEV-11935 the above kTemporaryFolderType query was giving - // back results with path names that seem to be too long to be used as - // mount points. I suspect this incompatibility was introduced in the - // Leopard 10.5.2 update, but I have not verified this. - char const HARDCODED_TMP[] = "/tmp"; - strncpy(temp, HARDCODED_TMP, sizeof(HARDCODED_TMP)); - -#endif // 0 *HACK for DEV-11935 - - // Skip downloading the file if the dmg was passed on the command line. - std::string dmgName; - if(gDmgFile != NULL) { - dmgName = basename((char *)gDmgFile); - char * dmgDir = dirname((char *)gDmgFile); - strncpy(tempDir, dmgDir, sizeof(tempDir)); - err = FSPathMakeRef((UInt8*)tempDir, &tempDirRef, NULL); - if(err != noErr) throw 0; - chdir(tempDir); - goto begin_install; - } else { - // Continue on to download file. - dmgName = "SecondLife.dmg"; - } - - - strncat(temp, "/SecondLifeUpdate_XXXXXX", (sizeof(temp) - strlen(temp)) - 1); - if(mkdtemp(temp) == NULL) - { - throw 0; - } - - strncpy(tempDir, temp, sizeof(tempDir)); - temp[sizeof(tempDir) - 1] = '\0'; - - llinfos << "tempDir is " << tempDir << llendl; - - err = FSPathMakeRef((UInt8*)tempDir, &tempDirRef, NULL); - - if(err != noErr) - throw 0; - - chdir(tempDir); - - snprintf(temp, sizeof(temp), "SecondLife.dmg"); - - downloadFile = LLFile::fopen(temp, "wb"); /* Flawfinder: ignore */ - if(downloadFile == NULL) - { - throw 0; - } - - { - CURL *curl = curl_easy_init(); - - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); - // curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &curl_download_callback); - curl_easy_setopt(curl, CURLOPT_FILE, downloadFile); - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, &curl_progress_callback_func); - curl_easy_setopt(curl, CURLOPT_URL, gUpdateURL); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); - - sendProgress(0, 1, CFSTR("Downloading...")); - - CURLcode result = curl_easy_perform(curl); - - curl_easy_cleanup(curl); - - if(gCancelled) - { - llinfos << "User cancel, bailing out."<< llendl; - throw 0; - } - - if(result != CURLE_OK) - { - llinfos << "Error " << result << " while downloading disk image."<< llendl; - throw 0; - } - - fclose(downloadFile); - downloadFile = NULL; - } - - begin_install: - sendProgress(0, 0, CFSTR("Mounting image...")); - LLFile::mkdir("mnt", 0700); - - // NOTE: we could add -private at the end of this command line to keep the image from showing up in the Finder, - // but if our cleanup fails, this makes it much harder for the user to unmount the image. - std::string mountOutput; - boost::format cmdFormat("hdiutil attach %s -mountpoint mnt"); - cmdFormat % dmgName; - FILE* mounter = popen(cmdFormat.str().c_str(), "r"); /* Flawfinder: ignore */ - - if(mounter == NULL) - { - llinfos << "Failed to mount disk image, exiting."<< llendl; - throw 0; - } - - // We need to scan the output from hdiutil to find the device node it uses to attach the disk image. - // If we don't have this information, we can't detach it later. - while(mounter != NULL) - { - size_t len = fread(temp, 1, sizeof(temp)-1, mounter); - temp[len] = 0; - mountOutput.append(temp); - if(len < sizeof(temp)-1) - { - // End of file or error. - int result = pclose(mounter); - if(result != 0) - { - // NOTE: We used to abort here, but pclose() started returning - // -1, possibly when the size of the DMG passed a certain point - llinfos << "Unexpected result closing pipe: " << result << llendl; - } - mounter = NULL; - } - } - - if(!mountOutput.empty()) - { - const char *s = mountOutput.c_str(); - const char *prefix = "/dev/"; - char *sub = strstr(s, prefix); - - if(sub != NULL) - { - sub += strlen(prefix); /* Flawfinder: ignore */ - sscanf(sub, "%1023s", deviceNode); /* Flawfinder: ignore */ - } - } - - if(deviceNode[0] != 0) - { - llinfos << "Disk image attached on /dev/" << deviceNode << llendl; - } - else - { - llinfos << "Disk image device node not found!" << llendl; - throw 0; - } - - // Get an FSRef to the new application on the disk image - FSRef sourceRef; - FSRef mountRef; - snprintf(temp, sizeof(temp), "%s/mnt", tempDir); - - llinfos << "Disk image mount point is: " << temp << llendl; - - err = FSPathMakeRef((UInt8 *)temp, &mountRef, NULL); - if(err != noErr) - { - llinfos << "Couldn't make FSRef to disk image mount point." << llendl; - throw 0; - } - - sendProgress(0, 0, CFSTR("Searching for the app bundle...")); - err = findAppBundleOnDiskImage(&mountRef, &sourceRef); - if(err != noErr) - { - llinfos << "Couldn't find application bundle on mounted disk image." << llendl; - throw 0; - } - else - { - llinfos << "found the bundle." << llendl; - } - - sendProgress(0, 0, CFSTR("Preparing to copy files...")); - - FSRef asideRef; - char aside[MAX_PATH]; /* Flawfinder: ignore */ - - // this will hold the name of the destination target - CFStringRef appNameRef; - - if(replacingTarget) - { - // Get the name of the target we're replacing - HFSUniStr255 appNameUniStr; - err = FSGetCatalogInfo(&targetRef, 0, NULL, &appNameUniStr, NULL, NULL); - if(err != noErr) - throw 0; - appNameRef = FSCreateStringFromHFSUniStr(NULL, &appNameUniStr); - - // Move aside old version (into work directory) - err = FSMoveObject(&targetRef, &tempDirRef, &asideRef); - if(err != noErr) - { - llwarns << "failed to move aside old version (error code " << - err << ")" << llendl; - throw 0; - } - - // Grab the path for later use. - err = FSRefMakePath(&asideRef, (UInt8*)aside, sizeof(aside)); - } - else - { - // Construct the name of the target based on the product name - char appName[MAX_PATH]; /* Flawfinder: ignore */ - snprintf(appName, sizeof(appName), "%s.app", gProductName); - appNameRef = CFStringCreateWithCString(NULL, appName, kCFStringEncodingUTF8); - } - - sendProgress(0, 0, CFSTR("Copying files...")); - - llinfos << "Starting copy..." << llendl; - - // Copy the new version from the disk image to the target location. - err = FSCopyObjectSync( - &sourceRef, - &targetParentRef, - appNameRef, - &targetRef, - kFSFileOperationDefaultOptions); - - // Grab the path for later use. - err = FSRefMakePath(&targetRef, (UInt8*)target, sizeof(target)); - if(err != noErr) - throw 0; - - llinfos << "Copy complete. Target = " << target << llendl; - - if(err != noErr) - { - // Something went wrong during the copy. Attempt to put the old version back and bail. - (void)FSDeleteObject(&targetRef); - if(replacingTarget) - { - (void)FSMoveObject(&asideRef, &targetParentRef, NULL); - } - throw 0; - } - else - { - // The update has succeeded. Clear the cache directory. - - sendProgress(0, 0, CFSTR("Clearing cache...")); - - llinfos << "Clearing cache..." << llendl; - - gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*"); - - llinfos << "Clear complete." << llendl; - - } - } - catch(...) - { - if(!gCancelled) - if(gFailure == noErr) - gFailure = -1; - } - - // Failures from here on out are all non-fatal and not reported. - sendProgress(0, 3, CFSTR("Cleaning up...")); - - // Close disk image file if necessary - if(downloadFile != NULL) - { - llinfos << "Closing download file." << llendl; - - fclose(downloadFile); - downloadFile = NULL; - } - - sendProgress(1, 3); - // Unmount image - if(deviceNode[0] != 0) - { - llinfos << "Detaching disk image." << llendl; - - snprintf(temp, sizeof(temp), "hdiutil detach '%s'", deviceNode); - system(temp); /* Flawfinder: ignore */ - } - - sendProgress(2, 3); - - // Move work directory to the trash - if(tempDir[0] != 0) - { - llinfos << "Moving work directory to the trash." << llendl; - - FSRef trashRef; - OSStatus err = FSMoveObjectToTrashSync(&tempDirRef, &trashRef, 0); - if(err != noErr) { - llwarns << "failed to move files to trash, (error code " << - err << ")" << llendl; - } - } - - if(!gCancelled && !gFailure && (target[0] != 0)) - { - llinfos << "Touching application bundle." << llendl; - - snprintf(temp, sizeof(temp), "touch '%s'", target); - system(temp); /* Flawfinder: ignore */ - - llinfos << "Launching updated application." << llendl; - - snprintf(temp, sizeof(temp), "open '%s'", target); - system(temp); /* Flawfinder: ignore */ - } - - sendDone(); - - return(NULL); -} - -#if LL_DARWIN -#pragma GCC diagnostic warning "-Wdeprecated-declarations" -#endif diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp index 93d2a8fa6e..ff1ed8bfbc 100755 --- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp +++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp @@ -28,26 +28,26 @@ #include "linden_common.h" -#if defined(LL_DARWIN) - #include <QuickTime/QuickTime.h> -#elif defined(LL_WINDOWS) - #include "llwin32headers.h" - #include "MacTypes.h" - #include "QTML.h" - #include "Movies.h" - #include "QDoffscreen.h" - #include "FixMath.h" - #include "QTLoadLibraryUtils.h" -#endif - #include "llgl.h" - + #include "llplugininstance.h" #include "llpluginmessage.h" #include "llpluginmessageclasses.h" #include "media_plugin_base.h" - + #if LL_QUICKTIME_ENABLED + +#if defined(LL_DARWIN) +#include <QuickTime/QuickTime.h> +#elif defined(LL_WINDOWS) +#include "llwin32headers.h" +#include "MacTypes.h" +#include "QTML.h" +#include "Movies.h" +#include "QDoffscreen.h" +#include "FixMath.h" +#include "QTLoadLibraryUtils.h" +#endif diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/webkit/CMakeLists.txt index 0c1c3d800e..5a8fe90bdd 100755 --- a/indra/media_plugins/webkit/CMakeLists.txt +++ b/indra/media_plugins/webkit/CMakeLists.txt @@ -121,12 +121,12 @@ if (DARWIN) ) # copy the webkit dylib to the build directory - add_custom_command( - TARGET media_plugin_webkit POST_BUILD -# OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/libllqtwebkit.dylib - COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ - DEPENDS media_plugin_webkit ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib - ) +# add_custom_command( +# TARGET media_plugin_webkit POST_BUILD +# # OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/libllqtwebkit.dylib +# COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ +# DEPENDS media_plugin_webkit ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib +# ) endif (DARWIN) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 142665525f..279d98e5c0 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -47,6 +47,8 @@ include(VisualLeakDetector) include(GLOD) include(CMakeCopyIfDifferent) include(LLAppearance) +include(PNG) +include(ZLIB) if (NOT HAVOK_TPV) # When using HAVOK_TPV, the library is precompiled, so no need for this @@ -236,6 +238,7 @@ set(viewer_SOURCE_FILES llfloatergesture.cpp llfloatergodtools.cpp llfloatergotoline.cpp + llfloatergroupbulkban.cpp llfloatergroupinvite.cpp llfloatergroups.cpp llfloaterhandler.cpp @@ -410,6 +413,8 @@ set(viewer_SOURCE_FILES llpanelface.cpp llpanelgenerictip.cpp llpanelgroup.cpp + llpanelgroupbulk.cpp + llpanelgroupbulkban.cpp llpanelgroupgeneral.cpp llpanelgroupinvite.cpp llpanelgrouplandmoney.cpp @@ -837,6 +842,7 @@ set(viewer_HEADER_FILES llfloatergesture.h llfloatergodtools.h llfloatergotoline.h + llfloatergroupbulkban.h llfloatergroupinvite.h llfloatergroups.h llfloaterhandler.h @@ -1004,6 +1010,9 @@ set(viewer_HEADER_FILES llpanelface.h llpanelgenerictip.h llpanelgroup.h + llpanelgroupbulk.h + llpanelgroupbulkimpl.h + llpanelgroupbulkban.h llpanelgroupgeneral.h llpanelgroupinvite.h llpanelgrouplandmoney.h @@ -1758,7 +1767,6 @@ if (WINDOWS) media_plugin_webkit winmm_shim windows-crash-logger - windows-updater ) if (FMODEX) @@ -1804,7 +1812,6 @@ if (WINDOWS) add_dependencies(${VIEWER_BINARY_NAME} SLPlugin - windows-updater windows-crash-logger ) @@ -1884,13 +1891,37 @@ else (WINDOWS) ) endif (WINDOWS) -# *NOTE - this list is very sensitive to ordering, test carefully on all +# *NOTE: - this list is very sensitive to ordering, test carefully on all # platforms if you change the releative order of the entries here. # In particular, cmake 2.6.4 (when buidling with linux/makefile generators) # appears to sometimes de-duplicate redundantly listed dependencies improperly. # To work around this, higher level modules should be listed before the modules # that they depend upon. -brad +# +# *NOTE: On mixing system shared libraries and updated static archives. +# We use a number of libraries that have an existence as system libraries, +# internal-use libraries and applications libraries. The most-referenced +# one of these being libz where you can find four or more versions in play +# at once. On Linux, libz can be found at link and run time via a number +# of paths: +# +# => -lfreetype +# => libz.so.1 (on install machine, not build) +# => -lSDL +# => libz.so.1 (on install machine, not build) +# => -lgdk-x11-2.0 +# => libz.so.1 +# => -lz +# +# We generally want the newest version of the library to provide all symbol +# resolution. To that end, when using static archives, the *_PRELOAD_ARCHIVES +# variables, PNG_PRELOAD_ARCHIVES and ZLIB_PRELOAD_ARCHIVES, get the archives +# dumped into the target binary and runtime lookup will find the most +# modern version. + target_link_libraries(${VIEWER_BINARY_NAME} + ${PNG_PRELOAD_ARCHIVES} + ${ZLIB_PRELOAD_ARCHIVES} ${UPDATER_LIBRARIES} ${GOOGLE_PERFTOOLS_LIBRARIES} ${LLAUDIO_LIBRARIES} @@ -1917,6 +1948,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${BOOST_PROGRAM_OPTIONS_LIBRARY} ${BOOST_REGEX_LIBRARY} ${BOOST_CONTEXT_LIBRARY} + ${BOOST_COROUTINE_LIBRARY} ${DBUSGLIB_LIBRARIES} ${OPENGL_LIBRARIES} ${FMODWRAPPER_LIBRARY} # must come after LLAudio diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 214b521fe2..03d7b8fb9b 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -3.7.13 +3.7.15 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index aaf12272f4..cab7af8a32 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6118,16 +6118,16 @@ <integer>0</integer> </map> <key>MemoryLogFrequency</key> - <map> - <key>Comment</key> - <string>Seconds between display of Memory in log (0 for never)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>600.0</real> - </map> + <map> + <key>Comment</key> + <string>Seconds between display of Memory in log (0 for never)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>30.0</real> + </map> <key>MemoryPrivatePoolEnabled</key> <map> <key>Comment</key> diff --git a/indra/newview/icons/beta/secondlife_128.png b/indra/newview/icons/beta/secondlife_128.png Binary files differindex fa42aa764b..af5ae63335 100755 --- a/indra/newview/icons/beta/secondlife_128.png +++ b/indra/newview/icons/beta/secondlife_128.png diff --git a/indra/newview/icons/beta/secondlife_16.png b/indra/newview/icons/beta/secondlife_16.png Binary files differindex ff648cf3fc..9e6305d98f 100755 --- a/indra/newview/icons/beta/secondlife_16.png +++ b/indra/newview/icons/beta/secondlife_16.png diff --git a/indra/newview/icons/beta/secondlife_256.png b/indra/newview/icons/beta/secondlife_256.png Binary files differindex 245e2c3e9f..b0814fc180 100755 --- a/indra/newview/icons/beta/secondlife_256.png +++ b/indra/newview/icons/beta/secondlife_256.png diff --git a/indra/newview/icons/beta/secondlife_32.png b/indra/newview/icons/beta/secondlife_32.png Binary files differindex fd7f46bf4d..a00b3cf53c 100755 --- a/indra/newview/icons/beta/secondlife_32.png +++ b/indra/newview/icons/beta/secondlife_32.png diff --git a/indra/newview/icons/beta/secondlife_48.png b/indra/newview/icons/beta/secondlife_48.png Binary files differindex cc3a795e2b..551587b1cd 100755 --- a/indra/newview/icons/beta/secondlife_48.png +++ b/indra/newview/icons/beta/secondlife_48.png diff --git a/indra/newview/icons/beta/secondlife_512.png b/indra/newview/icons/beta/secondlife_512.png Binary files differindex a959bd9a9e..99226de74e 100755 --- a/indra/newview/icons/beta/secondlife_512.png +++ b/indra/newview/icons/beta/secondlife_512.png diff --git a/indra/newview/icons/project/secondlife_128.png b/indra/newview/icons/project/secondlife_128.png Binary files differindex d67b8228f9..b1b4997306 100755 --- a/indra/newview/icons/project/secondlife_128.png +++ b/indra/newview/icons/project/secondlife_128.png diff --git a/indra/newview/icons/project/secondlife_16.png b/indra/newview/icons/project/secondlife_16.png Binary files differindex 91493a033c..7d3d74b534 100755 --- a/indra/newview/icons/project/secondlife_16.png +++ b/indra/newview/icons/project/secondlife_16.png diff --git a/indra/newview/icons/project/secondlife_256.png b/indra/newview/icons/project/secondlife_256.png Binary files differindex cccfaf7cba..88ad959275 100755 --- a/indra/newview/icons/project/secondlife_256.png +++ b/indra/newview/icons/project/secondlife_256.png diff --git a/indra/newview/icons/project/secondlife_32.png b/indra/newview/icons/project/secondlife_32.png Binary files differindex ad7b33f789..e55f75e1dd 100755 --- a/indra/newview/icons/project/secondlife_32.png +++ b/indra/newview/icons/project/secondlife_32.png diff --git a/indra/newview/icons/project/secondlife_48.png b/indra/newview/icons/project/secondlife_48.png Binary files differindex 104a931fbc..c29703e164 100755 --- a/indra/newview/icons/project/secondlife_48.png +++ b/indra/newview/icons/project/secondlife_48.png diff --git a/indra/newview/icons/project/secondlife_512.png b/indra/newview/icons/project/secondlife_512.png Binary files differindex 74e2fa9bc6..4fa3474d70 100755 --- a/indra/newview/icons/project/secondlife_512.png +++ b/indra/newview/icons/project/secondlife_512.png diff --git a/indra/newview/icons/release/secondlife_128.png b/indra/newview/icons/release/secondlife_128.png Binary files differindex bcf94dcae8..4c9544f498 100755 --- a/indra/newview/icons/release/secondlife_128.png +++ b/indra/newview/icons/release/secondlife_128.png diff --git a/indra/newview/icons/release/secondlife_16.png b/indra/newview/icons/release/secondlife_16.png Binary files differindex 90311ea8b0..bb3168b8be 100755 --- a/indra/newview/icons/release/secondlife_16.png +++ b/indra/newview/icons/release/secondlife_16.png diff --git a/indra/newview/icons/release/secondlife_256.png b/indra/newview/icons/release/secondlife_256.png Binary files differindex a89fb4c74f..bece338a90 100755 --- a/indra/newview/icons/release/secondlife_256.png +++ b/indra/newview/icons/release/secondlife_256.png diff --git a/indra/newview/icons/release/secondlife_32.png b/indra/newview/icons/release/secondlife_32.png Binary files differindex 530e8fc80c..736359c147 100755 --- a/indra/newview/icons/release/secondlife_32.png +++ b/indra/newview/icons/release/secondlife_32.png diff --git a/indra/newview/icons/release/secondlife_48.png b/indra/newview/icons/release/secondlife_48.png Binary files differindex cb33c51f8a..07d39ae585 100755 --- a/indra/newview/icons/release/secondlife_48.png +++ b/indra/newview/icons/release/secondlife_48.png diff --git a/indra/newview/icons/release/secondlife_512.png b/indra/newview/icons/release/secondlife_512.png Binary files differindex f291e60586..53d1643f45 100755 --- a/indra/newview/icons/release/secondlife_512.png +++ b/indra/newview/icons/release/secondlife_512.png diff --git a/indra/newview/icons/test/secondlife_128.png b/indra/newview/icons/test/secondlife_128.png Binary files differindex 019f65db28..486772b6d3 100755 --- a/indra/newview/icons/test/secondlife_128.png +++ b/indra/newview/icons/test/secondlife_128.png diff --git a/indra/newview/icons/test/secondlife_16.png b/indra/newview/icons/test/secondlife_16.png Binary files differindex 91493a033c..7d3d74b534 100755 --- a/indra/newview/icons/test/secondlife_16.png +++ b/indra/newview/icons/test/secondlife_16.png diff --git a/indra/newview/icons/test/secondlife_256.png b/indra/newview/icons/test/secondlife_256.png Binary files differindex f402424c51..56c781788d 100755 --- a/indra/newview/icons/test/secondlife_256.png +++ b/indra/newview/icons/test/secondlife_256.png diff --git a/indra/newview/icons/test/secondlife_32.png b/indra/newview/icons/test/secondlife_32.png Binary files differindex 80d6efe13d..476029db61 100755 --- a/indra/newview/icons/test/secondlife_32.png +++ b/indra/newview/icons/test/secondlife_32.png diff --git a/indra/newview/icons/test/secondlife_48.png b/indra/newview/icons/test/secondlife_48.png Binary files differindex bba938feba..d7de7849f9 100755 --- a/indra/newview/icons/test/secondlife_48.png +++ b/indra/newview/icons/test/secondlife_48.png diff --git a/indra/newview/icons/test/secondlife_512.png b/indra/newview/icons/test/secondlife_512.png Binary files differindex 10ff65312b..a4b1e4974c 100755 --- a/indra/newview/icons/test/secondlife_512.png +++ b/indra/newview/icons/test/secondlife_512.png diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index 74b77f760d..6e32ce60ec 100755 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -51,6 +51,7 @@ LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& u mConvType(CONV_UNKNOWN), mLastActiveTime(0.0), mDisplayModeratorOptions(false), + mDisplayGroupBanOptions(false), mAvatarNameCacheConnection() { } @@ -63,6 +64,7 @@ LLConversationItem::LLConversationItem(const LLUUID& uuid, LLFolderViewModelInte mConvType(CONV_UNKNOWN), mLastActiveTime(0.0), mDisplayModeratorOptions(false), + mDisplayGroupBanOptions(false), mAvatarNameCacheConnection() { } @@ -75,6 +77,7 @@ LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_mod mConvType(CONV_UNKNOWN), mLastActiveTime(0.0), mDisplayModeratorOptions(false), + mDisplayGroupBanOptions(false), mAvatarNameCacheConnection() { } @@ -159,6 +162,12 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32 items.push_back(std::string("ModerateVoiceMute")); items.push_back(std::string("ModerateVoiceUnmute")); } + + if ((getType() != CONV_SESSION_1_ON_1) && mDisplayGroupBanOptions) + { + items.push_back(std::string("Group Ban Separator")); + items.push_back(std::string("BanMember")); + } } } diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index dc74506c53..56e1a26709 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -143,6 +143,7 @@ protected: bool mNeedsRefresh; // Flag signaling to the view that something changed for this item F64 mLastActiveTime; bool mDisplayModeratorOptions; + bool mDisplayGroupBanOptions; boost::signals2::connection mAvatarNameCacheConnection; }; @@ -206,6 +207,7 @@ public: void dumpDebugData(); void setModeratorOptionsVisible(bool visible) { mDisplayModeratorOptions = visible; } void setDisplayModeratorRole(bool displayRole); + void setGroupBanVisible(bool visible) { mDisplayGroupBanOptions = visible; } private: void onAvatarNameCache(const LLAvatarName& av_name); // callback used by fetchAvatarName diff --git a/indra/newview/llfloatergroupbulkban.cpp b/indra/newview/llfloatergroupbulkban.cpp new file mode 100644 index 0000000000..54a2283b13 --- /dev/null +++ b/indra/newview/llfloatergroupbulkban.cpp @@ -0,0 +1,134 @@ +/** +* @file llfloatergroupbulkban.cpp +* @brief Floater to ban Residents from a group. +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatergroupbulkban.h" +#include "llpanelgroupbulkban.h" +#include "lltrans.h" +#include "lldraghandle.h" + + +class LLFloaterGroupBulkBan::impl +{ +public: + impl(const LLUUID& group_id) : mGroupID(group_id), mBulkBanPanelp(NULL) {} + ~impl() {} + + static void closeFloater(void* data); + +public: + LLUUID mGroupID; + LLPanelGroupBulkBan* mBulkBanPanelp; + + static std::map<LLUUID, LLFloaterGroupBulkBan*> sInstances; +}; + +// +// Globals +// +std::map<LLUUID, LLFloaterGroupBulkBan*> LLFloaterGroupBulkBan::impl::sInstances; + +void LLFloaterGroupBulkBan::impl::closeFloater(void* data) +{ + LLFloaterGroupBulkBan* floaterp = (LLFloaterGroupBulkBan*)data; + if(floaterp) + floaterp->closeFloater(); +} + +//----------------------------------------------------------------------------- +// Implementation +//----------------------------------------------------------------------------- +LLFloaterGroupBulkBan::LLFloaterGroupBulkBan(const LLUUID& group_id/*=LLUUID::null*/) + : LLFloater(group_id) +{ + S32 floater_header_size = getHeaderHeight(); + LLRect contents; + + mImpl = new impl(group_id); + mImpl->mBulkBanPanelp = new LLPanelGroupBulkBan(group_id); + + contents = mImpl->mBulkBanPanelp->getRect(); + contents.mTop -= floater_header_size; + + setTitle(mImpl->mBulkBanPanelp->getString("GroupBulkBan")); + mImpl->mBulkBanPanelp->setCloseCallback(impl::closeFloater, this); + mImpl->mBulkBanPanelp->setRect(contents); + + addChild(mImpl->mBulkBanPanelp); +} + +LLFloaterGroupBulkBan::~LLFloaterGroupBulkBan() +{ + if(mImpl->mGroupID.notNull()) + { + impl::sInstances.erase(mImpl->mGroupID); + } + + delete mImpl->mBulkBanPanelp; + delete mImpl; +} + +void LLFloaterGroupBulkBan::showForGroup(const LLUUID& group_id, uuid_vec_t* agent_ids) +{ + const LLFloater::Params& floater_params = LLFloater::getDefaultParams(); + S32 floater_header_size = floater_params.header_height; + LLRect contents; + + // Make sure group_id isn't null + if (group_id.isNull()) + { + llwarns << "LLFloaterGroupInvite::showForGroup with null group_id!" << llendl; + return; + } + + // If we don't have a floater for this group, create one. + LLFloaterGroupBulkBan* fgb = get_if_there(impl::sInstances, + group_id, + (LLFloaterGroupBulkBan*)NULL); + if (!fgb) + { + fgb = new LLFloaterGroupBulkBan(group_id); + contents = fgb->mImpl->mBulkBanPanelp->getRect(); + contents.mTop += floater_header_size; + fgb->setRect(contents); + fgb->getDragHandle()->setRect(contents); + fgb->getDragHandle()->setTitle(fgb->mImpl->mBulkBanPanelp->getString("GroupBulkBan")); + + impl::sInstances[group_id] = fgb; + + fgb->mImpl->mBulkBanPanelp->clear(); + } + + if (agent_ids != NULL) + { + fgb->mImpl->mBulkBanPanelp->addUsers(*agent_ids); + } + + fgb->center(); + fgb->openFloater(); + fgb->mImpl->mBulkBanPanelp->update(); +} diff --git a/indra/newview/llfloatergroupbulkban.h b/indra/newview/llfloatergroupbulkban.h new file mode 100644 index 0000000000..5b680a1ba4 --- /dev/null +++ b/indra/newview/llfloatergroupbulkban.h @@ -0,0 +1,48 @@ +/** +* @file llfloatergroupbulkban.h +* @brief This floater is a wrapper for LLPanelGroupBulkBan, which +* is used to ban Residents from a specific group. +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#ifndef LL_LLFLOATERGROUPBULKBAN_H +#define LL_LLFLOATERGROUPBULKBAN_H + +#include "llfloater.h" +#include "lluuid.h" + +class LLFloaterGroupBulkBan : public LLFloater +{ +public: + virtual ~LLFloaterGroupBulkBan(); + + static void showForGroup(const LLUUID& group_id, uuid_vec_t* agent_ids = NULL); + +protected: + LLFloaterGroupBulkBan(const LLUUID& group_id = LLUUID::null); + + class impl; + impl* mImpl; +}; + +#endif // LL_LLFLOATERGROUPBULKBAN_H diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index ebb44561da..be8195b5ee 100755 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -532,6 +532,7 @@ void LLFloaterIMContainer::draw() { LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model); participant_model->setModeratorOptionsVisible(isGroupModerator() && participant_model->getUUID() != gAgentID); + participant_model->setGroupBanVisible(haveAbilityToBan() && participant_model->getUUID() != gAgentID); current_participant_model++; } @@ -1150,6 +1151,10 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec { toggleAllowTextChat(userID); } + else if ("ban_member" == command) + { + banSelectedMember(userID); + } } else if (selectedIDS.size() > 1) { @@ -1271,6 +1276,22 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata) uuid_vec_t uuids; getParticipantUUIDs(uuids); + + //If there is group or ad-hoc chat in multiselection, everything needs to be disabled + if(uuids.size() > 1) + { + const std::set<LLFolderViewItem*> selectedItems = mConversationsRoot->getSelectionList(); + LLConversationItem * conversationItem; + for(std::set<LLFolderViewItem*>::const_iterator it = selectedItems.begin(); it != selectedItems.end(); ++it) + { + conversationItem = static_cast<LLConversationItem *>((*it)->getViewModelItem()); + if((conversationItem->getType() == LLConversationItem::CONV_SESSION_GROUP) || (conversationItem->getType() == LLConversationItem::CONV_SESSION_AD_HOC)) + { + return false; + } + } + } + if ("conversation_log" == item) { return gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0; @@ -1376,6 +1397,10 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v { return LLAvatarActions::canCall(); } + else if ("can_open_voice_conversation" == item) + { + return is_single_select && LLAvatarActions::canCall(); + } else if ("can_zoom_in" == item) { return is_single_select && gObjectList.findObject(single_id); @@ -1388,6 +1413,10 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v { return LLAvatarActions::canOfferTeleport(uuids); } + else if ("can_ban_member" == item) + { + return canBanSelectedMember(single_id); + } else if (("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute" == item) || ("can_unmute" == item)) { // *TODO : get that out of here... @@ -1810,6 +1839,95 @@ bool LLFloaterIMContainer::isGroupModerator() return false; } +bool LLFloaterIMContainer::haveAbilityToBan() +{ + LLSpeakerMgr * speaker_manager = getSpeakerMgrForSelectedParticipant(); + if (NULL == speaker_manager) + { + LL_WARNS() << "Speaker manager is missing" << LL_ENDL; + return false; + } + LLUUID group_uuid = speaker_manager->getSessionID(); + + return gAgent.isInGroup(group_uuid) && gAgent.hasPowerInGroup(group_uuid, GP_GROUP_BAN_ACCESS); +} + +bool LLFloaterIMContainer::canBanSelectedMember(const LLUUID& participant_uuid) +{ + LLSpeakerMgr * speaker_manager = getSpeakerMgrForSelectedParticipant(); + if (NULL == speaker_manager) + { + LL_WARNS() << "Speaker manager is missing" << LL_ENDL; + return false; + } + LLUUID group_uuid = speaker_manager->getSessionID(); + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_uuid); + if(!gdatap) + { + LL_WARNS("Groups") << "Unable to get group data for group " << group_uuid << LL_ENDL; + return false; + } + + if (!gdatap->mMembers.size()) + { + return false; + } + + LLGroupMgrGroupData::member_list_t::iterator mi = gdatap->mMembers.find((participant_uuid)); + if (mi == gdatap->mMembers.end()) + { + return false; + } + + LLGroupMemberData* member_data = (*mi).second; + // Is the member an owner? + if ( member_data && member_data->isInRole(gdatap->mOwnerRole) ) + { + return false; + } + + if( gAgent.hasPowerInGroup(group_uuid, GP_ROLE_REMOVE_MEMBER) && + gAgent.hasPowerInGroup(group_uuid, GP_GROUP_BAN_ACCESS) ) + { + return true; + } + + return false; +} + +void LLFloaterIMContainer::banSelectedMember(const LLUUID& participant_uuid) +{ + LLSpeakerMgr * speaker_manager = getSpeakerMgrForSelectedParticipant(); + if (NULL == speaker_manager) + { + LL_WARNS() << "Speaker manager is missing" << LL_ENDL; + return; + } + + LLUUID group_uuid = speaker_manager->getSessionID(); + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_uuid); + if(!gdatap) + { + LL_WARNS("Groups") << "Unable to get group data for group " << group_uuid << LL_ENDL; + return; + } + std::vector<LLUUID> ids; + ids.push_back(participant_uuid); + + LLGroupBanData ban_data; + gdatap->createBanEntry(participant_uuid, ban_data); + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, group_uuid, LLGroupMgr::BAN_CREATE, ids); + LLGroupMgr::getInstance()->sendGroupMemberEjects(group_uuid, ids); + LLGroupMgr::getInstance()->sendGroupMembersRequest(group_uuid); + LLSD args; + std::string name; + gCacheName->getFullName(participant_uuid, name); + args["AVATAR_NAME"] = name; + args["GROUP_NAME"] = gdatap->mName; + LLNotifications::instance().add(LLNotification::Params("EjectAvatarFromGroup").substitutions(args)); + +} + void LLFloaterIMContainer::moderateVoice(const std::string& command, const LLUUID& userID) { if (!gAgent.getRegion()) return; diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index f6d973b9b3..5ea9fd399b 100755 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -167,12 +167,16 @@ private: LLSpeaker * getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp); LLSpeakerMgr * getSpeakerMgrForSelectedParticipant(); bool isGroupModerator(); + bool haveAbilityToBan(); + bool canBanSelectedMember(const LLUUID& participant_uuid); + LLUUID getGroupUIIDForSelectedParticipant(); bool isMuted(const LLUUID& avatar_id); void moderateVoice(const std::string& command, const LLUUID& userID); void moderateVoiceAllParticipants(bool unmute); void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute); void toggleAllowTextChat(const LLUUID& participant_uuid); void toggleMute(const LLUUID& participant_id, U32 flags); + void banSelectedMember(const LLUUID& participant_uuid); void openNearbyChat(); bool isParticipantListExpanded(); diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 7213064746..d01c089eaf 100755 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -1517,6 +1517,8 @@ void LLPanelLandObjects::onClickRefresh(void* userdata) LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); if (!region) return; + self->mBtnRefresh->setEnabled(false); + // ready the list for results self->mOwnerList->deleteAllItems(); self->mOwnerList->setCommentText(LLTrans::getString("Searching")); @@ -1576,6 +1578,7 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo { msg->getU32("DataExtended", "TimeStamp", most_recent_time, i); } + if (owner_id.isNull()) { continue; @@ -1611,10 +1614,10 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo item_params.columns.add().value(LLDate((time_t)most_recent_time)).font(FONT).column("mostrecent").type("date"); self->mOwnerList->addNameItemRow(item_params); - LL_DEBUGS() << "object owner " << owner_id << " (" << (is_group_owned ? "group" : "agent") << ") owns " << object_count << " objects." << LL_ENDL; } + // check for no results if (0 == self->mOwnerList->getItemCount()) { @@ -1624,6 +1627,8 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo { self->mOwnerList->setEnabled(TRUE); } + + self->mBtnRefresh->setEnabled(true); } // static diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 5e9b25b474..a2af9da670 100755 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -481,6 +481,17 @@ void LLFloaterRegionInfo::refresh() } } +void LLFloaterRegionInfo::enableTopButtons() +{ + getChildView("top_colliders_btn")->setEnabled(true); + getChildView("top_scripts_btn")->setEnabled(true); +} + +void LLFloaterRegionInfo::disableTopButtons() +{ + getChildView("top_colliders_btn")->setEnabled(false); + getChildView("top_scripts_btn")->setEnabled(false); +} ///---------------------------------------------------------------------------- /// Local class implementation @@ -1033,6 +1044,11 @@ void LLPanelRegionDebugInfo::onClickTopColliders(void* data) if(!instance) return; LLFloaterReg::showInstance("top_objects"); instance->clearList(); + instance->disableRefreshBtn(); + + self->getChildView("top_colliders_btn")->setEnabled(false); + self->getChildView("top_scripts_btn")->setEnabled(false); + self->sendEstateOwnerMessage(gMessageSystem, "colliders", invoice, strings); } @@ -1047,6 +1063,11 @@ void LLPanelRegionDebugInfo::onClickTopScripts(void* data) if(!instance) return; LLFloaterReg::showInstance("top_objects"); instance->clearList(); + instance->disableRefreshBtn(); + + self->getChildView("top_colliders_btn")->setEnabled(false); + self->getChildView("top_scripts_btn")->setEnabled(false); + self->sendEstateOwnerMessage(gMessageSystem, "scripts", invoice, strings); } diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 5bc4273d5f..792f60ebc8 100755 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -96,6 +96,8 @@ public: void requestRegionInfo(); void requestMeshRezInfo(); + void enableTopButtons(); + void disableTopButtons(); private: diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index 7530c72dd2..d604b8619a 100755 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -50,6 +50,7 @@ #include "llviewerregion.h" #include "lluictrlfactory.h" #include "llviewerwindow.h" +#include "llfloaterregioninfo.h" //LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL; @@ -207,7 +208,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) columns[column_num++]["font"] = "SANSSERIF"; columns[column_num]["column"] = "location"; - columns[column_num]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z); + columns[column_num]["value"] = llformat("<%0.f, %0.f, %0.f>", location_x, location_y, location_z); columns[column_num++]["font"] = "SANSSERIF"; columns[column_num]["column"] = "parcel"; @@ -257,6 +258,8 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) format.setArg("[COUNT]", llformat("%d", total_count)); format.setArg("[TIME]", llformat("%0.3f", mtotalScore)); getChild<LLUICtrl>("title_text")->setValue(LLSD(format)); + list->setColumnLabel("URLs", getString("URLs")); + list->setColumnLabel("memory", getString("memory")); } else { @@ -268,6 +271,13 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) format.setArg("[COUNT]", llformat("%d", total_count)); getChild<LLUICtrl>("title_text")->setValue(LLSD(format)); } + + LLFloaterRegionInfo* region_info_floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info"); + if(region_info_floater) + { + region_info_floater->enableTopButtons(); + } + getChildView("refresh_btn")->setEnabled(true); } void LLFloaterTopObjects::onCommitObjectsList() @@ -453,12 +463,24 @@ void LLFloaterTopObjects::onRefresh() msg->addStringFast(_PREHASH_Filter, filter); msg->addS32Fast(_PREHASH_ParcelLocalID, 0); + LLFloaterRegionInfo* region_info_floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info"); + if(region_info_floater) + { + region_info_floater->disableTopButtons(); + } + disableRefreshBtn(); + msg->sendReliable(gAgent.getRegionHost()); mFilter.clear(); mFlags = 0; } +void LLFloaterTopObjects::disableRefreshBtn() +{ + getChildView("refresh_btn")->setEnabled(false); +} + void LLFloaterTopObjects::onGetByObjectName() { mFlags = STAT_FILTER_BY_OBJECT; diff --git a/indra/newview/llfloatertopobjects.h b/indra/newview/llfloatertopobjects.h index 28d2aa58e2..dbbe9ac521 100755 --- a/indra/newview/llfloatertopobjects.h +++ b/indra/newview/llfloatertopobjects.h @@ -66,6 +66,7 @@ public: void onRefresh(); static void setMode(U32 mode); + void disableRefreshBtn(); private: LLFloaterTopObjects(const LLSD& key); diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index f514729aa1..913efd6434 100755 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -149,7 +149,7 @@ public: void changed(LLGroupChange gc) { - if (gc == GC_MEMBER_DATA && !mRequestProcessed) + if (gc == GC_PROPERTIES && !mRequestProcessed) { LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupId); if (!gdatap) @@ -159,9 +159,6 @@ public: else if (!gdatap->isMemberDataComplete()) { LL_WARNS() << "LLGroupMgr::getInstance()->getGroupData()->isMemberDataComplete() was FALSE" << LL_ENDL; - } - else - { processGroupData(); mRequestProcessed = true; } diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index d5b817ce76..56e671d902 100755 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -234,11 +234,11 @@ LLGroupMgrGroupData::LLGroupMgrGroupData(const LLUUID& id) : mMemberCount(0), mRoleCount(0), mReceivedRoleMemberPairs(0), - mMemberDataComplete(FALSE), - mRoleDataComplete(FALSE), - mRoleMemberDataComplete(FALSE), - mGroupPropertiesDataComplete(FALSE), - mPendingRoleMemberRequest(FALSE), + mMemberDataComplete(false), + mRoleDataComplete(false), + mRoleMemberDataComplete(false), + mGroupPropertiesDataComplete(false), + mPendingRoleMemberRequest(false), mAccessTime(0.0f) { mMemberVersion.generate(); @@ -427,7 +427,7 @@ void LLGroupMgrGroupData::removeMemberData() delete mi->second; } mMembers.clear(); - mMemberDataComplete = FALSE; + mMemberDataComplete = false; mMemberVersion.generate(); } @@ -449,8 +449,8 @@ void LLGroupMgrGroupData::removeRoleData() } mRoles.clear(); mReceivedRoleMemberPairs = 0; - mRoleDataComplete = FALSE; - mRoleMemberDataComplete = FALSE; + mRoleDataComplete = false; + mRoleMemberDataComplete= false; } void LLGroupMgrGroupData::removeRoleMemberData() @@ -474,7 +474,7 @@ void LLGroupMgrGroupData::removeRoleMemberData() } mReceivedRoleMemberPairs = 0; - mRoleMemberDataComplete = FALSE; + mRoleMemberDataComplete= false; } LLGroupMgrGroupData::~LLGroupMgrGroupData() @@ -750,6 +750,20 @@ void LLGroupMgrGroupData::cancelRoleChanges() // Clear out all changes! mRoleChanges.clear(); } + +void LLGroupMgrGroupData::createBanEntry(const LLUUID& ban_id, const LLGroupBanData& ban_data) +{ + mBanList[ban_id] = ban_data; +} + +void LLGroupMgrGroupData::removeBanEntry(const LLUUID& ban_id) +{ + mBanList.erase(ban_id); +} + + + + // // LLGroupMgr // @@ -959,12 +973,12 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data) if (group_datap->mMembers.size() == (U32)group_datap->mMemberCount) { - group_datap->mMemberDataComplete = TRUE; + group_datap->mMemberDataComplete = true; group_datap->mMemberRequestID.setNull(); // We don't want to make role-member data requests until we have all the members if (group_datap->mPendingRoleMemberRequest) { - group_datap->mPendingRoleMemberRequest = FALSE; + group_datap->mPendingRoleMemberRequest = false; LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_datap->mID); } } @@ -1034,7 +1048,7 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data) group_datap->mMemberCount = num_group_members; group_datap->mRoleCount = num_group_roles + 1; // Add the everyone role. - group_datap->mGroupPropertiesDataComplete = TRUE; + group_datap->mGroupPropertiesDataComplete = true; group_datap->mChanged = TRUE; LLGroupMgr::getInstance()->notifyObservers(GC_PROPERTIES); @@ -1111,12 +1125,12 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data) if (group_datap->mRoles.size() == (U32)group_datap->mRoleCount) { - group_datap->mRoleDataComplete = TRUE; + group_datap->mRoleDataComplete = true; group_datap->mRoleDataRequestID.setNull(); // We don't want to make role-member data requests until we have all the role data if (group_datap->mPendingRoleMemberRequest) { - group_datap->mPendingRoleMemberRequest = FALSE; + group_datap->mPendingRoleMemberRequest = false; LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_datap->mID); } } @@ -1225,7 +1239,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data) } } - group_datap->mRoleMemberDataComplete = TRUE; + group_datap->mRoleMemberDataComplete= true; group_datap->mRoleMembersRequestID.setNull(); } @@ -1849,6 +1863,138 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id, // Responder class for capability group management +class GroupBanDataResponder : public LLHTTPClient::Responder +{ +public: + GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh=false); + virtual ~GroupBanDataResponder() {} + virtual void httpSuccess(); + virtual void httpFailure(); +private: + LLUUID mGroupID; + BOOL mForceRefresh; +}; + +GroupBanDataResponder::GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh) : + mGroupID(gropup_id), + mForceRefresh(force_refresh) +{} + +void GroupBanDataResponder::httpFailure() +{ + LL_WARNS("GrpMgr") << "Error receiving group member data [status:" + << mStatus << "]: " << mContent << LL_ENDL; +} + +void GroupBanDataResponder::httpSuccess() +{ + if (mContent.has("ban_list")) + { + // group ban data received + LLGroupMgr::processGroupBanRequest(mContent); + } + else if (mForceRefresh) + { + // no ban data received, refreshing data after successful operation + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID); + } +} + +void LLGroupMgr::sendGroupBanRequest( EBanRequestType request_type, + const LLUUID& group_id, + U32 ban_action, /* = BAN_NO_ACTION */ + const std::vector<LLUUID> ban_list) /* = std::vector<LLUUID>() */ +{ + LLViewerRegion* currentRegion = gAgent.getRegion(); + if(!currentRegion) + { + LL_WARNS("GrpMgr") << "Agent does not have a current region. Uh-oh!" << LL_ENDL; + return; + } + + // Check to make sure we have our capabilities + if(!currentRegion->capabilitiesReceived()) + { + LL_WARNS("GrpMgr") << " Capabilities not received!" << LL_ENDL; + return; + } + + // Get our capability + std::string cap_url = currentRegion->getCapability("GroupAPIv1"); + if(cap_url.empty()) + { + return; + } + cap_url += "?group_id=" + group_id.asString(); + + LLSD body = LLSD::emptyMap(); + body["ban_action"] = (LLSD::Integer)(ban_action & ~BAN_UPDATE); + // Add our list of potential banned residents to the list + body["ban_ids"] = LLSD::emptyArray(); + LLSD ban_entry; + + uuid_vec_t::const_iterator iter = ban_list.begin(); + for(;iter != ban_list.end(); ++iter) + { + ban_entry = (*iter); + body["ban_ids"].append(ban_entry); + } + + LLHTTPClient::ResponderPtr grp_ban_responder = new GroupBanDataResponder(group_id, ban_action & BAN_UPDATE); + switch(request_type) + { + case REQUEST_GET: + LLHTTPClient::get(cap_url, grp_ban_responder); + break; + case REQUEST_POST: + LLHTTPClient::post(cap_url, body, grp_ban_responder); + break; + case REQUEST_PUT: + case REQUEST_DEL: + break; + } +} + + +void LLGroupMgr::processGroupBanRequest(const LLSD& content) +{ + // Did we get anything in content? + if(!content.size()) + { + LL_WARNS("GrpMgr") << "No group member data received." << LL_ENDL; + return; + } + + LLUUID group_id = content["group_id"].asUUID(); + + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id); + if (!gdatap) + return; + + LLSD::map_const_iterator i = content["ban_list"].beginMap(); + LLSD::map_const_iterator iEnd = content["ban_list"].endMap(); + for(;i != iEnd; ++i) + { + const LLUUID ban_id(i->first); + LLSD ban_entry(i->second); + + LLGroupBanData ban_data; + if(ban_entry.has("ban_date")) + { + ban_data.mBanDate = ban_entry["ban_date"].asDate(); + // TODO: Ban Reason + } + + gdatap->createBanEntry(ban_id, ban_data); + } + + gdatap->mChanged = TRUE; + LLGroupMgr::getInstance()->notifyObservers(GC_BANLIST); +} + + + +// Responder class for capability group management class GroupMemberDataResponder : public LLHTTPClient::Responder { LOG_CLASS(GroupMemberDataResponder); @@ -1941,7 +2087,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content) if(num_members < 1) return; - LLUUID group_id = content["group_id"].asUUID(); + LLUUID group_id = content["group_id"].asUUID(); LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id); if(!group_datap) @@ -2008,6 +2154,22 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content) online_status, is_owner); + LLGroupMemberData* member_old = group_datap->mMembers[member_id]; + if (member_old && group_datap->mRoleMemberDataComplete) + { + LLGroupMemberData::role_list_t::iterator rit = member_old->roleBegin(); + LLGroupMemberData::role_list_t::iterator end = member_old->roleEnd(); + + for ( ; rit != end; ++rit) + { + data->addRole((*rit).first,(*rit).second); + } + } + else + { + group_datap->mRoleMemberDataComplete = false; + } + group_datap->mMembers[member_id] = data; } @@ -2024,12 +2186,12 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content) LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id); - group_datap->mMemberDataComplete = TRUE; + group_datap->mMemberDataComplete = true; group_datap->mMemberRequestID.setNull(); // Make the role-member data request - if (group_datap->mPendingRoleMemberRequest) + if (group_datap->mPendingRoleMemberRequest || !group_datap->mRoleMemberDataComplete) { - group_datap->mPendingRoleMemberRequest = FALSE; + group_datap->mPendingRoleMemberRequest = false; LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_id); } diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index 9b62ecac48..2e94e8d9a0 100755 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -33,8 +33,10 @@ #include <string> #include <map> +// Forward Declarations class LLMessageSystem; - +class LLGroupRoleData; +class LLGroupMgr; enum LLGroupChange { @@ -43,9 +45,12 @@ enum LLGroupChange GC_ROLE_DATA, GC_ROLE_MEMBER_DATA, GC_TITLES, + GC_BANLIST, GC_ALL }; +const U32 GB_MAX_BANNED_AGENTS = 500; + class LLGroupMgrObserver { public: @@ -65,8 +70,6 @@ public: virtual void changed(const LLUUID& group_id, LLGroupChange gc) = 0; }; -class LLGroupRoleData; - class LLGroupMemberData { friend class LLGroupMgrGroupData; @@ -201,6 +204,17 @@ struct lluuid_pair_less } }; + +struct LLGroupBanData +{ + LLGroupBanData(): mBanDate() {} + ~LLGroupBanData() {} + + LLDate mBanDate; + // TODO: std:string ban_reason; +}; + + struct LLGroupTitle { std::string mTitle; @@ -208,8 +222,6 @@ struct LLGroupTitle BOOL mSelected; }; -class LLGroupMgr; - class LLGroupMgrGroupData { friend class LLGroupMgr; @@ -239,11 +251,11 @@ public: void recalcAllAgentPowers(); void recalcAgentPowers(const LLUUID& agent_id); - BOOL isMemberDataComplete() { return mMemberDataComplete; } - BOOL isRoleDataComplete() { return mRoleDataComplete; } - BOOL isRoleMemberDataComplete() { return mRoleMemberDataComplete; } - BOOL isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; } - + bool isMemberDataComplete() { return mMemberDataComplete; } + bool isRoleDataComplete() { return mRoleDataComplete; } + bool isRoleMemberDataComplete() { return mRoleMemberDataComplete; } + bool isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; } + bool isSingleMemberNotOwner(); F32 getAccessTime() const { return mAccessTime; } @@ -251,17 +263,26 @@ public: const LLUUID& getMemberVersion() const { return mMemberVersion; } + void clearBanList() { mBanList.clear(); } + void getBanList(const LLUUID& group_id, LLGroupBanData& ban_data); + const LLGroupBanData& getBanEntry(const LLUUID& ban_id) { return mBanList[ban_id]; } + + void createBanEntry(const LLUUID& ban_id, const LLGroupBanData& ban_data = LLGroupBanData()); + void removeBanEntry(const LLUUID& ban_id); + + public: typedef std::map<LLUUID,LLGroupMemberData*> member_list_t; typedef std::map<LLUUID,LLGroupRoleData*> role_list_t; typedef std::map<lluuid_pair,LLRoleMemberChange,lluuid_pair_less> change_map_t; typedef std::map<LLUUID,LLRoleData> role_data_map_t; + typedef std::map<LLUUID,LLGroupBanData> ban_list_t; + member_list_t mMembers; role_list_t mRoles; - - change_map_t mRoleMemberChanges; role_data_map_t mRoleChanges; + ban_list_t mBanList; std::vector<LLGroupTitle> mTitles; @@ -292,12 +313,12 @@ private: LLUUID mTitlesRequestID; U32 mReceivedRoleMemberPairs; - BOOL mMemberDataComplete; - BOOL mRoleDataComplete; - BOOL mRoleMemberDataComplete; - BOOL mGroupPropertiesDataComplete; + bool mMemberDataComplete; + bool mRoleDataComplete; + bool mRoleMemberDataComplete; + bool mGroupPropertiesDataComplete; - BOOL mPendingRoleMemberRequest; + bool mPendingRoleMemberRequest; F32 mAccessTime; // Generate a new ID every time mMembers @@ -325,6 +346,23 @@ class LLGroupMgr : public LLSingleton<LLGroupMgr> LOG_CLASS(LLGroupMgr); public: + enum EBanRequestType + { + REQUEST_GET = 0, + REQUEST_POST, + REQUEST_PUT, + REQUEST_DEL + }; + + enum EBanRequestAction + { + BAN_NO_ACTION = 0, + BAN_CREATE = 1, + BAN_DELETE = 2, + BAN_UPDATE = 4 + }; + +public: LLGroupMgr(); ~LLGroupMgr(); @@ -357,8 +395,14 @@ public: static void sendGroupMemberInvites(const LLUUID& group_id, std::map<LLUUID,LLUUID>& role_member_pairs); static void sendGroupMemberEjects(const LLUUID& group_id, uuid_vec_t& member_ids); + + static void sendGroupBanRequest(EBanRequestType request_type, + const LLUUID& group_id, + U32 ban_action = BAN_NO_ACTION, + const uuid_vec_t ban_list = uuid_vec_t()); + + static void processGroupBanRequest(const LLSD& content); - // BAKER void sendCapGroupMembersRequest(const LLUUID& group_id); static void processCapGroupMembersRequest(const LLSD& content); @@ -403,4 +447,3 @@ private: #endif - diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 000eee3317..0bbb4aeeff 100755 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -37,6 +37,7 @@ #include "llfolderview.h" #include "llinventorybridge.h" #include "llviewerfoldertype.h" +#include "llradiogroup.h" // linden library includes #include "llclipboard.h" @@ -51,6 +52,7 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p) mMinDate(p.date_range.min_date), mMaxDate(p.date_range.max_date), mHoursAgo(p.hours_ago), + mDateSearchDirection(p.date_search_direction), mShowFolderState(p.show_folder_state), mPermissions(p.permissions), mFilterTypes(p.types), @@ -209,6 +211,7 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInvent { const U16 HOURS_TO_SECONDS = 3600; time_t earliest = time_corrected() - mFilterOps.mHoursAgo * HOURS_TO_SECONDS; + if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest) { earliest = mFilterOps.mMinDate; @@ -217,9 +220,19 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInvent { earliest = 0; } - if (listener->getCreationDate() < earliest || - listener->getCreationDate() > mFilterOps.mMaxDate) - return FALSE; + + if (FILTERDATEDIRECTION_NEWER == mFilterOps.mDateSearchDirection || isSinceLogoff()) + { + if (listener->getCreationDate() < earliest || + listener->getCreationDate() > mFilterOps.mMaxDate) + return FALSE; + } + else + { + if (listener->getCreationDate() > earliest || + listener->getCreationDate() > mFilterOps.mMaxDate) + return FALSE; + } } //////////////////////////////////////////////////////////////////////////////// @@ -629,11 +642,22 @@ void LLInventoryFilter::setHoursAgo(U32 hours) bool are_date_limits_valid = mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max(); bool is_increasing = hours > mFilterOps.mHoursAgo; + bool is_decreasing = hours < mFilterOps.mHoursAgo; bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo && !isSinceLogoff(); // *NOTE: need to cache last filter time, in case filter goes stale - BOOL less_restrictive = (are_date_limits_valid && ((is_increasing && mFilterOps.mHoursAgo)) || !hours); - BOOL more_restrictive = (are_date_limits_valid && (!is_increasing && hours) || is_increasing_from_zero); + BOOL less_restrictive; + BOOL more_restrictive; + if (FILTERDATEDIRECTION_NEWER == mFilterOps.mDateSearchDirection) + { + less_restrictive = (are_date_limits_valid && ((is_increasing && mFilterOps.mHoursAgo)) || !hours); + more_restrictive = (are_date_limits_valid && (!is_increasing && hours) || is_increasing_from_zero); + } + else + { + less_restrictive = (are_date_limits_valid && ((is_decreasing && mFilterOps.mHoursAgo)) || !hours); + more_restrictive = (are_date_limits_valid && (!is_decreasing && hours) || is_increasing_from_zero); + } mFilterOps.mHoursAgo = hours; mFilterOps.mMinDate = time_min(); @@ -662,6 +686,20 @@ void LLInventoryFilter::setHoursAgo(U32 hours) } } +void LLInventoryFilter::setDateSearchDirection(U32 direction) +{ + if (direction != mFilterOps.mDateSearchDirection) + { + mFilterOps.mDateSearchDirection = direction; + setModified(FILTER_RESTART); + } +} + +U32 LLInventoryFilter::getDateSearchDirection() const +{ + return mFilterOps.mDateSearchDirection; +} + void LLInventoryFilter::setFilterLinks(U64 filter_links) { if (mFilterOps.mFilterLinks != filter_links) @@ -926,6 +964,7 @@ LLInventoryFilter& LLInventoryFilter::operator=( const LLInventoryFilter& othe setFilterObjectTypes(other.getFilterObjectTypes()); setDateRange(other.getMinDate(), other.getMaxDate()); setHoursAgo(other.getHoursAgo()); + setDateSearchDirection(other.getDateSearchDirection()); setShowFolderState(other.getShowFolderState()); setFilterPermissions(other.getFilterPermissions()); setFilterSubString(other.getFilterSubString()); @@ -945,6 +984,7 @@ void LLInventoryFilter::toParams(Params& params) const params.filter_ops.date_range.min_date = getMinDate(); params.filter_ops.date_range.max_date = getMaxDate(); params.filter_ops.hours_ago = getHoursAgo(); + params.filter_ops.date_search_direction = getDateSearchDirection(); params.filter_ops.show_folder_state = getShowFolderState(); params.filter_ops.permissions = getFilterPermissions(); params.substring = getFilterSubString(); @@ -966,6 +1006,7 @@ void LLInventoryFilter::fromParams(const Params& params) } setDateRange(params.filter_ops.date_range.min_date, params.filter_ops.date_range.max_date); setHoursAgo(params.filter_ops.hours_ago); + setDateSearchDirection(params.filter_ops.date_search_direction); setShowFolderState(params.filter_ops.show_folder_state); setFilterPermissions(params.filter_ops.permissions); setFilterSubString(params.substring); diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index ce516af0b9..0d3d3889cb 100755 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -55,6 +55,12 @@ public: FILTERTYPE_EMPTYFOLDERS = 0x1 << 5 // pass if folder is not a system folder to be hidden if }; + enum EFilterDateDirection + { + FILTERDATEDIRECTION_NEWER, + FILTERDATEDIRECTION_OLDER + }; + enum EFilterLink { FILTERLINK_INCLUDE_LINKS, // show links too @@ -94,7 +100,8 @@ public: Optional<EFilterLink> links; Optional<LLUUID> uuid; Optional<DateRange> date_range; - Optional<S32> hours_ago; + Optional<U32> hours_ago; + Optional<U32> date_search_direction; Optional<EFolderShow> show_folder_state; Optional<PermissionMask> permissions; @@ -107,6 +114,7 @@ public: uuid("uuid"), date_range("date_range"), hours_ago("hours_ago", 0), + date_search_direction("date_search_direction", FILTERDATEDIRECTION_NEWER), show_folder_state("show_folder_state", SHOW_NON_EMPTY_FOLDERS), permissions("permissions", PERM_NONE) {} @@ -124,6 +132,7 @@ public: time_t mMinDate, mMaxDate; U32 mHoursAgo; + U32 mDateSearchDirection; EFolderShow mShowFolderState; PermissionMask mPermissions; @@ -177,6 +186,8 @@ public: void setHoursAgo(U32 hours); U32 getHoursAgo() const; + void setDateSearchDirection(U32 direction); + U32 getDateSearchDirection() const; void setFilterLinks(U64 filter_link); U64 getFilterLinks() const; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index a4a85e2e8d..db5be2cef5 100755 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -400,6 +400,11 @@ void LLInventoryPanel::setHoursAgo(U32 hours) getFilter().setHoursAgo(hours); } +void LLInventoryPanel::setDateSearchDirection(U32 direction) +{ + getFilter().setDateSearchDirection(direction); +} + void LLInventoryPanel::setFilterLinks(U64 filter_links) { getFilter().setFilterLinks(filter_links); diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 91c3efd8f0..a490dfce5d 100755 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -173,6 +173,7 @@ public: const std::string getFilterSubString(); void setSinceLogoff(BOOL sl); void setHoursAgo(U32 hours); + void setDateSearchDirection(U32 direction); BOOL getSinceLogoff(); void setFilterLinks(U64 filter_links); diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 91866e5ca2..54e4c6c1da 100755 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -64,7 +64,8 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p) mNameColumnIndex(p.name_column.column_index), mNameColumn(p.name_column.column_name), mAllowCallingCardDrop(p.allow_calling_card_drop), - mShortNames(p.short_names) + mShortNames(p.short_names), + mPendingLookupsRemaining(0) {} // public @@ -337,6 +338,17 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( mAvatarNameCacheConnections.erase(it); } mAvatarNameCacheConnections[id] = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, suffix, item->getHandle())); + + if(mPendingLookupsRemaining <= 0) + { + // BAKER TODO: + // We might get into a state where mPendingLookupsRemaining might + // go negative. So just reset it right now and figure out if it's + // possible later :) + mPendingLookupsRemaining = 0; + mNameListCompleteSignal(false); + } + mPendingLookupsRemaining++; } break; } @@ -388,6 +400,8 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id) { selectNthItem(idx); // not sure whether this is needed, taken from previous implementation deleteSingleItem(idx); + + mPendingLookupsRemaining--; } } @@ -429,6 +443,23 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, } } + ////////////////////////////////////////////////////////////////////////// + // BAKER - FIX NameListCtrl + //if (mPendingLookupsRemaining <= 0) + { + // We might get into a state where mPendingLookupsRemaining might + // go negative. So just reset it right now and figure out if it's + // possible later :) + //mPendingLookupsRemaining = 0; + + mNameListCompleteSignal(true); + } + //else + { + // mPendingLookupsRemaining--; + } + ////////////////////////////////////////////////////////////////////////// + dirtyColumns(); } diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 4ed260d847..2c40eeaaca 100755 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -67,6 +67,7 @@ class LLNameListCtrl : public LLScrollListCtrl, public LLInstanceTracker<LLNameListCtrl> { public: + typedef boost::signals2::signal<void(bool)> namelist_complete_signal_t; typedef enum e_name_type { @@ -156,7 +157,7 @@ public: /*virtual*/ void updateColumns(bool force_update); - /*virtual*/ void mouseOverHighlightNthItem( S32 index ); + /*virtual*/ void mouseOverHighlightNthItem( S32 index ); private: void showInspector(const LLUUID& avatar_id, bool is_group); void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, LLHandle<LLNameListItem> item); @@ -168,6 +169,16 @@ private: bool mShortNames; // display name only, no SLID typedef std::map<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t; avatar_name_cache_connection_map_t mAvatarNameCacheConnections; + + S32 mPendingLookupsRemaining; + namelist_complete_signal_t mNameListCompleteSignal; + +public: + boost::signals2::connection setOnNameListCompleteCallback(boost::function<void(bool)> onNameListCompleteCallback) + { + return mNameListCompleteSignal.connect(onNameListCompleteCallback); + } + }; diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp new file mode 100644 index 0000000000..1eafc5bd64 --- /dev/null +++ b/indra/newview/llpanelgroupbulk.cpp @@ -0,0 +1,421 @@ +/** +* @file llpanelgroupbulk.cpp +* @brief Implementation of llpanelgroupbulk +* @author Baker@lindenlab.com +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelgroupbulk.h" +#include "llpanelgroupbulkimpl.h" + +#include "llagent.h" +#include "llavatarnamecache.h" +#include "llfloateravatarpicker.h" +#include "llbutton.h" +#include "llcallingcard.h" +#include "llcombobox.h" +#include "llgroupactions.h" +#include "llgroupmgr.h" +#include "llnamelistctrl.h" +#include "llnotificationsutil.h" +#include "llscrolllistitem.h" +#include "llspinctrl.h" +#include "lltextbox.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "lluictrlfactory.h" +#include "llviewerwindow.h" + + +////////////////////////////////////////////////////////////////////////// +// Implementation of llpanelgroupbulkimpl.h functions +////////////////////////////////////////////////////////////////////////// +LLPanelGroupBulkImpl::LLPanelGroupBulkImpl(const LLUUID& group_id) : + mGroupID(group_id), + mBulkAgentList(NULL), + mOKButton(NULL), + mRemoveButton(NULL), + mGroupName(NULL), + mLoadingText(), + mTooManySelected(), + mCloseCallback(NULL), + mCloseCallbackUserData(NULL), + mAvatarNameCacheConnection(), + mRoleNames(NULL), + mOwnerWarning(), + mAlreadyInGroup(), + mConfirmedOwnerInvite(false), + mListFullNotificationSent(false) +{} + +LLPanelGroupBulkImpl::~LLPanelGroupBulkImpl() +{ + if(mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } +} + +void LLPanelGroupBulkImpl::callbackClickAdd(void* userdata) +{ + LLPanelGroupBulk* panelp = (LLPanelGroupBulk*)userdata; + + if(panelp) + { + //Right now this is hard coded with some knowledge that it is part + //of a floater since the avatar picker needs to be added as a dependent + //floater to the parent floater. + //Soon the avatar picker will be embedded into this panel + //instead of being it's own separate floater. But that is next week. + //This will do for now. -jwolk May 10, 2006 + LLView* button = panelp->findChild<LLButton>("add_button"); + LLFloater* root_floater = gFloaterView->getParentFloater(panelp); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( + boost::bind(callbackAddUsers, _1, panelp->mImplementation), TRUE, FALSE, FALSE, root_floater->getName(), button); + if(picker) + { + root_floater->addDependentFloater(picker); + } + } +} + +void LLPanelGroupBulkImpl::callbackClickRemove(void* userdata) +{ + LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*)userdata; + if (selfp) + selfp->handleRemove(); +} + +void LLPanelGroupBulkImpl::callbackClickCancel(void* userdata) +{ + LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*)userdata; + if(selfp) + (*(selfp->mCloseCallback))(selfp->mCloseCallbackUserData); +} + +void LLPanelGroupBulkImpl::callbackSelect(LLUICtrl* ctrl, void* userdata) +{ + LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*)userdata; + if (selfp) + selfp->handleSelection(); +} + +void LLPanelGroupBulkImpl::callbackAddUsers(const uuid_vec_t& agent_ids, void* user_data) +{ + std::vector<std::string> names; + for (S32 i = 0; i < (S32)agent_ids.size(); i++) + { + LLAvatarName av_name; + if (LLAvatarNameCache::get(agent_ids[i], &av_name)) + { + onAvatarNameCache(agent_ids[i], av_name, user_data); + } + else + { + LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*) user_data; + if (selfp) + { + if (selfp->mAvatarNameCacheConnection.connected()) + { + selfp->mAvatarNameCacheConnection.disconnect(); + } + // *TODO : Add a callback per avatar name being fetched. + selfp->mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_ids[i],boost::bind(onAvatarNameCache, _1, _2, user_data)); + } + } + } +} + +void LLPanelGroupBulkImpl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, void* user_data) +{ + LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*) user_data; + + if (selfp) + { + if (selfp->mAvatarNameCacheConnection.connected()) + { + selfp->mAvatarNameCacheConnection.disconnect(); + } + std::vector<std::string> names; + uuid_vec_t agent_ids; + agent_ids.push_back(agent_id); + names.push_back(av_name.getCompleteName()); + + selfp->addUsers(names, agent_ids); + } +} + +void LLPanelGroupBulkImpl::handleRemove() +{ + std::vector<LLScrollListItem*> selection = mBulkAgentList->getAllSelected(); + if (selection.empty()) + return; + + std::vector<LLScrollListItem*>::iterator iter; + for(iter = selection.begin(); iter != selection.end(); ++iter) + { + mInviteeIDs.erase((*iter)->getUUID()); + } + + mBulkAgentList->deleteSelectedItems(); + mRemoveButton->setEnabled(FALSE); + + if( mOKButton && mOKButton->getEnabled() && + mBulkAgentList->isEmpty()) + { + mOKButton->setEnabled(FALSE); + } +} + +void LLPanelGroupBulkImpl::handleSelection() +{ + std::vector<LLScrollListItem*> selection = mBulkAgentList->getAllSelected(); + if (selection.empty()) + mRemoveButton->setEnabled(FALSE); + else + mRemoveButton->setEnabled(TRUE); +} + +void LLPanelGroupBulkImpl::addUsers(const std::vector<std::string>& names, const uuid_vec_t& agent_ids) +{ + std::string name; + LLUUID id; + + if(mListFullNotificationSent) + { + return; + } + + if( !mListFullNotificationSent && + (names.size() + mInviteeIDs.size() > MAX_GROUP_INVITES)) + { + mListFullNotificationSent = true; + + // Fail! Show a warning and don't add any names. + LLSD msg; + msg["MESSAGE"] = mTooManySelected; + LLNotificationsUtil::add("GenericAlert", msg); + return; + } + + for (S32 i = 0; i < (S32)names.size(); ++i) + { + name = names[i]; + id = agent_ids[i]; + + if(mInviteeIDs.find(id) != mInviteeIDs.end()) + { + continue; + } + + //add the name to the names list + LLSD row; + row["id"] = id; + row["columns"][0]["value"] = name; + + mBulkAgentList->addElement(row); + mInviteeIDs.insert(id); + + // We've successfully added someone to the list. + if(mOKButton && !mOKButton->getEnabled()) + mOKButton->setEnabled(TRUE); + } +} + +void LLPanelGroupBulkImpl::setGroupName(std::string name) +{ + if(mGroupName) + mGroupName->setText(name); +} + + +LLPanelGroupBulk::LLPanelGroupBulk(const LLUUID& group_id) : + LLPanel(), + mImplementation(new LLPanelGroupBulkImpl(group_id)), + mPendingGroupPropertiesUpdate(false), + mPendingRoleDataUpdate(false), + mPendingMemberDataUpdate(false) +{} + +LLPanelGroupBulk::~LLPanelGroupBulk() +{ + delete mImplementation; +} + +void LLPanelGroupBulk::clear() +{ + mImplementation->mInviteeIDs.clear(); + + if(mImplementation->mBulkAgentList) + mImplementation->mBulkAgentList->deleteAllItems(); + + if(mImplementation->mOKButton) + mImplementation->mOKButton->setEnabled(FALSE); +} + +void LLPanelGroupBulk::update() +{ + updateGroupName(); + updateGroupData(); +} + +void LLPanelGroupBulk::draw() +{ + LLPanel::draw(); + update(); +} + +void LLPanelGroupBulk::updateGroupName() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID); + + if( gdatap && + gdatap->isGroupPropertiesDataComplete()) + { + // Only do work if the current group name differs + if(mImplementation->mGroupName->getText().compare(gdatap->mName) != 0) + mImplementation->setGroupName(gdatap->mName); + } + else + { + mImplementation->setGroupName(mImplementation->mLoadingText); + } +} + +void LLPanelGroupBulk::updateGroupData() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID); + if(gdatap && gdatap->isGroupPropertiesDataComplete()) + { + mPendingGroupPropertiesUpdate = false; + } + else + { + if(!mPendingGroupPropertiesUpdate) + { + mPendingGroupPropertiesUpdate = true; + LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID); + } + } + + if(gdatap && gdatap->isRoleDataComplete()) + { + mPendingRoleDataUpdate = false; + } + else + { + if(!mPendingRoleDataUpdate) + { + mPendingRoleDataUpdate = true; + LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); + } + } + + if(gdatap && gdatap->isMemberDataComplete()) + { + mPendingMemberDataUpdate = false; + } + else + { + if(!mPendingMemberDataUpdate) + { + mPendingMemberDataUpdate = true; + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); + } + } +} + +void LLPanelGroupBulk::addUserCallback(const LLUUID& id, const LLAvatarName& av_name) +{ + std::vector<std::string> names; + uuid_vec_t agent_ids; + agent_ids.push_back(id); + names.push_back(av_name.getAccountName()); + + mImplementation->addUsers(names, agent_ids); +} + +void LLPanelGroupBulk::setCloseCallback(void (*close_callback)(void*), void* data) +{ + mImplementation->mCloseCallback = close_callback; + mImplementation->mCloseCallbackUserData = data; +} + +void LLPanelGroupBulk::addUsers(uuid_vec_t& agent_ids) +{ + std::vector<std::string> names; + for (S32 i = 0; i < (S32)agent_ids.size(); i++) + { + std::string fullname; + LLUUID agent_id = agent_ids[i]; + LLViewerObject* dest = gObjectList.findObject(agent_id); + if(dest && dest->isAvatar()) + { + LLNameValue* nvfirst = dest->getNVPair("FirstName"); + LLNameValue* nvlast = dest->getNVPair("LastName"); + if(nvfirst && nvlast) + { + fullname = LLCacheName::buildFullName( + nvfirst->getString(), nvlast->getString()); + + } + if (!fullname.empty()) + { + names.push_back(fullname); + } + else + { + llwarns << "llPanelGroupBulk: Selected avatar has no name: " << dest->getID() << llendl; + names.push_back("(Unknown)"); + } + } + else + { + //looks like user try to invite offline friend + //for offline avatar_id gObjectList.findObject() will return null + //so we need to do this additional search in avatar tracker, see EXT-4732 + if (LLAvatarTracker::instance().isBuddy(agent_id)) + { + LLAvatarName av_name; + if (!LLAvatarNameCache::get(agent_id, &av_name)) + { + // actually it should happen, just in case + LLAvatarNameCache::get(LLUUID(agent_id), boost::bind(&LLPanelGroupBulk::addUserCallback, this, _1, _2)); + // for this special case! + //when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence + // removed id will be added in callback + agent_ids.erase(agent_ids.begin() + i); + } + else + { + names.push_back(av_name.getAccountName()); + } + } + } + } + mImplementation->mListFullNotificationSent = false; + mImplementation->addUsers(names, agent_ids); +} + diff --git a/indra/newview/llpanelgroupbulk.h b/indra/newview/llpanelgroupbulk.h new file mode 100644 index 0000000000..25ae71ab86 --- /dev/null +++ b/indra/newview/llpanelgroupbulk.h @@ -0,0 +1,74 @@ +/** +* @file llpanelgroupbulk.h +* @brief Header file for llpanelgroupbulk +* @author Baker@lindenlab.com +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ +#ifndef LL_LLPANELGROUPBULK_H +#define LL_LLPANELGROUPBULK_H + +#include "llpanel.h" +#include "lluuid.h" + +class LLAvatarName; +class LLGroupMgrGroupData; +class LLPanelGroupBulkImpl; + +// Base panel class for bulk group invite / ban floaters +class LLPanelGroupBulk : public LLPanel +{ +public: + LLPanelGroupBulk(const LLUUID& group_id); + /*virtual*/ ~LLPanelGroupBulk(); + +public: + static void callbackClickSubmit(void* userdata) {} + virtual void submit() = 0; + +public: + virtual void clear(); + virtual void update(); + virtual void draw(); + +protected: + virtual void updateGroupName(); + virtual void updateGroupData(); + +public: + // this callback is being used to add a user whose fullname isn't been loaded before invoking of addUsers(). + virtual void addUserCallback(const LLUUID& id, const LLAvatarName& av_name); + virtual void setCloseCallback(void (*close_callback)(void*), void* data); + + virtual void addUsers(uuid_vec_t& agent_ids); + +public: + LLPanelGroupBulkImpl* mImplementation; + +protected: + bool mPendingGroupPropertiesUpdate; + bool mPendingRoleDataUpdate; + bool mPendingMemberDataUpdate; +}; + +#endif // LL_LLPANELGROUPBULK_H + diff --git a/indra/newview/llpanelgroupbulkban.cpp b/indra/newview/llpanelgroupbulkban.cpp new file mode 100644 index 0000000000..cf1f0bc32f --- /dev/null +++ b/indra/newview/llpanelgroupbulkban.cpp @@ -0,0 +1,259 @@ +/** +* @file llpanelgroupbulkban.cpp +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelgroupbulkban.h" +#include "llpanelgroupbulk.h" +#include "llpanelgroupbulkimpl.h" + +#include "llagent.h" +#include "llavatarnamecache.h" +#include "llavataractions.h" +#include "llfloateravatarpicker.h" +#include "llbutton.h" +#include "llcallingcard.h" +#include "llcombobox.h" +#include "llgroupactions.h" +#include "llgroupmgr.h" +#include "llnamelistctrl.h" +#include "llnotificationsutil.h" +#include "llscrolllistitem.h" +#include "llslurl.h" +#include "llspinctrl.h" +#include "lltextbox.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "lluictrlfactory.h" +#include "llviewerwindow.h" + +#include <boost/foreach.hpp> + +LLPanelGroupBulkBan::LLPanelGroupBulkBan(const LLUUID& group_id) : LLPanelGroupBulk(group_id) +{ + // Pass on construction of this panel to the control factory. + buildFromFile( "panel_group_bulk_ban.xml"); +} + +BOOL LLPanelGroupBulkBan::postBuild() +{ + BOOL recurse = TRUE; + + mImplementation->mLoadingText = getString("loading"); + mImplementation->mGroupName = getChild<LLTextBox>("group_name_text", recurse); + mImplementation->mBulkAgentList = getChild<LLNameListCtrl>("banned_agent_list", recurse); + if ( mImplementation->mBulkAgentList ) + { + mImplementation->mBulkAgentList->setCommitOnSelectionChange(TRUE); + mImplementation->mBulkAgentList->setCommitCallback(LLPanelGroupBulkImpl::callbackSelect, mImplementation); + } + + LLButton* button = getChild<LLButton>("add_button", recurse); + if ( button ) + { + // default to opening avatarpicker automatically + // (*impl::callbackClickAdd)((void*)this); + button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickAdd, this); + } + + mImplementation->mRemoveButton = + getChild<LLButton>("remove_button", recurse); + if ( mImplementation->mRemoveButton ) + { + mImplementation->mRemoveButton->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove, mImplementation); + mImplementation->mRemoveButton->setEnabled(FALSE); + } + + mImplementation->mOKButton = + getChild<LLButton>("ban_button", recurse); + if ( mImplementation->mOKButton ) + { + mImplementation->mOKButton->setClickedCallback(LLPanelGroupBulkBan::callbackClickSubmit, this); + mImplementation->mOKButton->setEnabled(FALSE); + } + + button = getChild<LLButton>("cancel_button", recurse); + if ( button ) + { + button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation); + } + + mImplementation->mTooManySelected = getString("ban_selection_too_large"); + mImplementation->mBanNotPermitted = getString("ban_not_permitted"); + mImplementation->mBanLimitFail = getString("ban_limit_fail"); + mImplementation->mCannotBanYourself = getString("cant_ban_yourself"); + + update(); + return TRUE; +} + +// TODO: Refactor the shitty callback functions with void* -- just use boost::bind to call submit() instead. +void LLPanelGroupBulkBan::callbackClickSubmit(void* userdata) +{ + LLPanelGroupBulkBan* selfp = (LLPanelGroupBulkBan*)userdata; + + if(selfp) + selfp->submit(); +} + + +void LLPanelGroupBulkBan::submit() +{ + if (!gAgent.hasPowerInGroup(mImplementation->mGroupID, GP_GROUP_BAN_ACCESS)) + { + // Fail! Agent no longer have ban rights. Permissions could have changed after button was pressed. + LLSD msg; + msg["MESSAGE"] = mImplementation->mBanNotPermitted; + LLNotificationsUtil::add("GenericAlert", msg); + (*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData); + return; + } + LLGroupMgrGroupData * group_datap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID); + if (group_datap && group_datap->mBanList.size() >= GB_MAX_BANNED_AGENTS) + { + // Fail! Size limit exceeded. List could have updated after button was pressed. + LLSD msg; + msg["MESSAGE"] = mImplementation->mBanLimitFail; + LLNotificationsUtil::add("GenericAlert", msg); + (*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData); + return; + } + std::vector<LLUUID> banned_agent_list; + std::vector<LLScrollListItem*> agents = mImplementation->mBulkAgentList->getAllData(); + std::vector<LLScrollListItem*>::iterator iter = agents.begin(); + for(;iter != agents.end(); ++iter) + { + LLScrollListItem* agent = *iter; + banned_agent_list.push_back(agent->getUUID()); + } + + const S32 MAX_BANS_PER_REQUEST = 100; // Max bans per request. 100 to match server cap. + if (banned_agent_list.size() > MAX_BANS_PER_REQUEST) + { + // Fail! + LLSD msg; + msg["MESSAGE"] = mImplementation->mTooManySelected; + LLNotificationsUtil::add("GenericAlert", msg); + (*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData); + return; + } + + // remove already banned users and yourself from request. + std::vector<LLAvatarName> banned_avatar_names; + std::vector<LLAvatarName> out_of_limit_names; + bool banning_self = FALSE; + std::vector<LLUUID>::iterator conflict = std::find(banned_agent_list.begin(), banned_agent_list.end(), gAgent.getID()); + if (conflict != banned_agent_list.end()) + { + banned_agent_list.erase(conflict); + banning_self = TRUE; + } + if (group_datap) + { + BOOST_FOREACH(const LLGroupMgrGroupData::ban_list_t::value_type& group_ban_pair, group_datap->mBanList) + { + const LLUUID& group_ban_agent_id = group_ban_pair.first; + std::vector<LLUUID>::iterator conflict = std::find(banned_agent_list.begin(), banned_agent_list.end(), group_ban_agent_id); + if (conflict != banned_agent_list.end()) + { + LLAvatarName av_name; + LLAvatarNameCache::get(group_ban_agent_id, &av_name); + banned_avatar_names.push_back(av_name); + + banned_agent_list.erase(conflict); + if (banned_agent_list.size() == 0) + { + break; + } + } + } + // this check should always be the last one before we send the request. + // Otherwise we have a possibility of cutting more then we need to. + if (banned_agent_list.size() > GB_MAX_BANNED_AGENTS - group_datap->mBanList.size()) + { + std::vector<LLUUID>::iterator exeedes_limit = banned_agent_list.begin() + GB_MAX_BANNED_AGENTS - group_datap->mBanList.size(); + for (std::vector<LLUUID>::iterator itor = exeedes_limit ; + itor != banned_agent_list.end(); ++itor) + { + LLAvatarName av_name; + LLAvatarNameCache::get(*itor, &av_name); + out_of_limit_names.push_back(av_name); + } + banned_agent_list.erase(exeedes_limit,banned_agent_list.end()); + } + } + + // sending request and ejecting members + if (banned_agent_list.size() != 0) + { + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, mImplementation->mGroupID, LLGroupMgr::BAN_CREATE | LLGroupMgr::BAN_UPDATE, banned_agent_list); + LLGroupMgr::getInstance()->sendGroupMemberEjects(mImplementation->mGroupID, banned_agent_list); + } + + // building notification + if (banned_avatar_names.size() > 0 || banning_self || out_of_limit_names.size() > 0) + { + std::string reasons; + if(banned_avatar_names.size() > 0) + { + reasons = "\n " + buildResidentsArgument(banned_avatar_names, "residents_already_banned"); + } + + if(banning_self) + { + reasons += "\n " + mImplementation->mCannotBanYourself; + } + + if(out_of_limit_names.size() > 0) + { + reasons += "\n " + buildResidentsArgument(out_of_limit_names, "ban_limit_reached"); + } + + LLStringUtil::format_map_t msg_args; + msg_args["[REASONS]"] = reasons; + LLSD msg; + if (banned_agent_list.size() == 0) + { + msg["MESSAGE"] = getString("ban_failed", msg_args); + } + else + { + msg["MESSAGE"] = getString("partial_ban", msg_args); + } + LLNotificationsUtil::add("GenericAlert", msg); + } + + //then close + (*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData); +} + +std::string LLPanelGroupBulkBan::buildResidentsArgument(std::vector<LLAvatarName> avatar_names, const std::string &format) +{ + std::string names_string; + LLAvatarActions::buildResidentsString(avatar_names, names_string); + LLStringUtil::format_map_t args; + args["[RESIDENTS]"] = names_string; + return getString(format, args); +} diff --git a/indra/newview/llpanelgroupbulkban.h b/indra/newview/llpanelgroupbulkban.h new file mode 100644 index 0000000000..9060d275f9 --- /dev/null +++ b/indra/newview/llpanelgroupbulkban.h @@ -0,0 +1,49 @@ +/** +* @file llpanelgroupbulkban.h +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#ifndef LL_LLPANELGROUPBULKBAN_H +#define LL_LLPANELGROUPBULKBAN_H + +#include "llpanel.h" +#include "lluuid.h" +#include "llpanelgroupbulk.h" + +class LLAvatarName; + +class LLPanelGroupBulkBan : public LLPanelGroupBulk +{ +public: + LLPanelGroupBulkBan(const LLUUID& group_id); + ~LLPanelGroupBulkBan() {} + + virtual BOOL postBuild(); + + static void callbackClickSubmit(void* userdata); + virtual void submit(); +private: + std::string buildResidentsArgument(std::vector<LLAvatarName> avatar_names, const std::string &format); +}; + +#endif // LL_LLPANELGROUPBULKBAN_H diff --git a/indra/newview/llpanelgroupbulkimpl.h b/indra/newview/llpanelgroupbulkimpl.h new file mode 100644 index 0000000000..d3a48e5a9a --- /dev/null +++ b/indra/newview/llpanelgroupbulkimpl.h @@ -0,0 +1,99 @@ +/** +* @file llpanelgroupbulkimpl.h +* @brief Class definition for implementation class of LLPanelGroupBulk +* @author Baker@lindenlab.com +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ +#ifndef LL_LLPANELGROUPBULKIMPL_H +#define LL_LLPANELGROUPBULKIMPL_H + +#include "llpanel.h" +#include "lluuid.h" + +class LLAvatarName; +class LLNameListCtrl; +class LLTextBox; +class LLComboBox; + +////////////////////////////////////////////////////////////////////////// +// Implementation found in llpanelgroupbulk.cpp +////////////////////////////////////////////////////////////////////////// +class LLPanelGroupBulkImpl +{ +public: + LLPanelGroupBulkImpl(const LLUUID& group_id); + ~LLPanelGroupBulkImpl(); + + static void callbackClickAdd(void* userdata); + static void callbackClickRemove(void* userdata); + + static void callbackClickCancel(void* userdata); + + static void callbackSelect(LLUICtrl* ctrl, void* userdata); + static void callbackAddUsers(const uuid_vec_t& agent_ids, void* user_data); + + static void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, void* user_data); + + void handleRemove(); + void handleSelection(); + + void addUsers(const std::vector<std::string>& names, const uuid_vec_t& agent_ids); + void setGroupName(std::string name); + + +public: + static const S32 MAX_GROUP_INVITES = 100; // Max invites per request. 100 to match server cap. + + + LLUUID mGroupID; + + LLNameListCtrl* mBulkAgentList; + LLButton* mOKButton; + LLButton* mRemoveButton; + LLTextBox* mGroupName; + + std::string mLoadingText; + std::string mTooManySelected; + std::string mBanNotPermitted; + std::string mBanLimitFail; + std::string mCannotBanYourself; + + std::set<LLUUID> mInviteeIDs; + + void (*mCloseCallback)(void* data); + void* mCloseCallbackUserData; + boost::signals2::connection mAvatarNameCacheConnection; + + // The following are for the LLPanelGroupInvite subclass only. + // These aren't needed for LLPanelGroupBulkBan, but if we have to add another + // group bulk floater for some reason, we'll have these objects too. +public: + LLComboBox* mRoleNames; + std::string mOwnerWarning; + std::string mAlreadyInGroup; + bool mConfirmedOwnerInvite; + bool mListFullNotificationSent; +}; + +#endif // LL_LLPANELGROUPBULKIMPL_H + diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index dd13e8abf4..236ad861a5 100755 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -260,7 +260,7 @@ void LLPanelGroupInvite::impl::addRoleNames(LLGroupMgrGroupData* gdatap) //else if they have the limited add to roles power //we add every role the user is in //else we just add to everyone - bool is_owner = member_data->isInRole(gdatap->mOwnerRole); + bool is_owner = member_data->isOwner(); bool can_assign_any = gAgent.hasPowerInGroup(mGroupID, GP_ROLE_ASSIGN_MEMBER); bool can_assign_limited = gAgent.hasPowerInGroup(mGroupID, @@ -492,7 +492,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids) } else { - LL_WARNS() << "llPanelGroupInvite: Selected avatar has no name: " << dest->getID() << LL_ENDL; + llwarns << "llPanelGroupInvite: Selected avatar has no name: " << dest->getID() << llendl; names.push_back("(Unknown)"); } } @@ -579,7 +579,7 @@ void LLPanelGroupInvite::updateLists() { waiting = true; } - if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete()) + if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete() && gdatap->isRoleMemberDataComplete()) { if ( mImplementation->mRoleNames ) { @@ -607,6 +607,7 @@ void LLPanelGroupInvite::updateLists() { LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); + LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); } mPendingUpdate = TRUE; @@ -654,7 +655,7 @@ BOOL LLPanelGroupInvite::postBuild() } mImplementation->mOKButton = - getChild<LLButton>("ok_button", recurse); + getChild<LLButton>("invite_button", recurse); if ( mImplementation->mOKButton ) { mImplementation->mOKButton->setClickedCallback(impl::callbackClickOK, mImplementation); diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 9ca3d7e96e..1d7ba4d741 100755 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llpanelgrouproles.cpp * @brief Panel for roles information about a particular group. * @@ -32,6 +32,7 @@ #include "llavatarnamecache.h" #include "llbutton.h" #include "llfiltereditor.h" +#include "llfloatergroupbulkban.h" #include "llfloatergroupinvite.h" #include "llavataractions.h" #include "lliconctrl.h" @@ -109,8 +110,10 @@ bool agentCanAddToRole(const LLUUID& group_id, return false; } -// static +// LLPanelGroupRoles ///////////////////////////////////////////////////// + +// static LLPanelGroupRoles::LLPanelGroupRoles() : LLPanelGroupTab(), mCurrentTab(NULL), @@ -297,7 +300,6 @@ bool LLPanelGroupRoles::onModalClose(const LLSD& notification, const LLSD& respo return false; } - bool LLPanelGroupRoles::apply(std::string& mesg) { // Pass this along to the currently visible sub tab. @@ -334,7 +336,6 @@ void LLPanelGroupRoles::update(LLGroupChange gc) { if (mGroupID.isNull()) return; - LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel(); if (panelp) { @@ -351,39 +352,33 @@ void LLPanelGroupRoles::activate() { // Start requesting member and role data if needed. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); - //if (!gdatap || mFirstUse) + if (!gdatap || !gdatap->isMemberDataComplete() ) { - // Check member data. - - if (!gdatap || !gdatap->isMemberDataComplete() ) - { - LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); - } - - // Check role data. - if (!gdatap || !gdatap->isRoleDataComplete() ) - { - // Mildly hackish - clear all pending changes - cancel(); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); + } - LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID); - } + if (!gdatap || !gdatap->isRoleDataComplete() ) + { + // Mildly hackish - clear all pending changes + cancel(); - // Check role-member mapping data. - if (!gdatap || !gdatap->isRoleMemberDataComplete() ) - { - LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID); - } + LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID); + } - // Need this to get base group member powers - if (!gdatap || !gdatap->isGroupPropertiesDataComplete() ) - { - LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID); - } + // Check role-member mapping data. + if (!gdatap || !gdatap->isRoleMemberDataComplete() ) + { + LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID); + } - mFirstUse = FALSE; + // Need this to get base group member powers + if (!gdatap || !gdatap->isGroupPropertiesDataComplete() ) + { + LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID); } + mFirstUse = FALSE; + LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel(); if (panelp) panelp->activate(); } @@ -412,15 +407,38 @@ BOOL LLPanelGroupRoles::hasModal() return panelp->hasModal(); } +void LLPanelGroupRoles::setGroupID(const LLUUID& id) +{ + LLPanelGroupTab::setGroupID(id); + + LLPanelGroupMembersSubTab* group_members_tab = findChild<LLPanelGroupMembersSubTab>("members_sub_tab"); + LLPanelGroupRolesSubTab* group_roles_tab = findChild<LLPanelGroupRolesSubTab>("roles_sub_tab"); + LLPanelGroupActionsSubTab* group_actions_tab = findChild<LLPanelGroupActionsSubTab>("actions_sub_tab"); + LLPanelGroupBanListSubTab* group_ban_tab = findChild<LLPanelGroupBanListSubTab>("banlist_sub_tab"); + + if(group_members_tab) group_members_tab->setGroupID(id); + if(group_roles_tab) group_roles_tab->setGroupID(id); + if(group_actions_tab) group_actions_tab->setGroupID(id); + if(group_ban_tab) group_ban_tab->setGroupID(id); + + LLButton* button = getChild<LLButton>("member_invite"); + if ( button ) + button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_INVITE)); + + if(mSubTabContainer) + mSubTabContainer->selectTab(1); + group_roles_tab->mFirstOpen = TRUE; + activate(); +} + -//////////////////////////// -// LLPanelGroupSubTab -//////////////////////////// +// LLPanelGroupSubTab //////////////////////////////////////////////////// LLPanelGroupSubTab::LLPanelGroupSubTab() : LLPanelGroupTab(), mHeader(NULL), mFooter(NULL), mActivated(false), + mHasGroupBanPower(false), mSearchEditor(NULL) { } @@ -542,9 +560,10 @@ void LLPanelGroupSubTab::buildActionsList(LLScrollListCtrl* ctrl, return; } + mHasGroupBanPower = false; + std::vector<LLRoleActionSet*>::iterator ras_it = LLGroupMgr::getInstance()->mRoleActionSets.begin(); std::vector<LLRoleActionSet*>::iterator ras_end = LLGroupMgr::getInstance()->mRoleActionSets.end(); - for ( ; ras_it != ras_end; ++ras_it) { buildActionCategory(ctrl, @@ -674,6 +693,31 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl, row["columns"][column_index]["value"] = (*ra_it)->mDescription; row["columns"][column_index]["font"] = "SANSSERIF_SMALL"; + if(mHasGroupBanPower) + { + // The ban ability is being set. Prevent these abilities from being manipulated + if((*ra_it)->mPowerBit == GP_MEMBER_EJECT) + { + row["enabled"] = false; + } + else if((*ra_it)->mPowerBit == GP_ROLE_REMOVE_MEMBER) + { + row["enabled"] = false; + } + } + else + { + // The ban ability is not set. Allow these abilities to be manipulated + if((*ra_it)->mPowerBit == GP_MEMBER_EJECT) + { + row["enabled"] = true; + } + else if((*ra_it)->mPowerBit == GP_ROLE_REMOVE_MEMBER) + { + row["enabled"] = true; + } + } + LLScrollListItem* item = ctrl->addElement(row, ADD_BOTTOM, (*ra_it)); if (-1 != check_box_index) @@ -709,6 +753,15 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl, check->setTentative(TRUE); } } + + // Regardless of whether or not this ability is allowed by all or some, we want to prevent + // the group managers from accidentally disabling either of the two additional abilities + // tied with GP_GROUP_BAN_ACCESS. + if( (allowed_by_all & GP_GROUP_BAN_ACCESS) == GP_GROUP_BAN_ACCESS || + (allowed_by_some & GP_GROUP_BAN_ACCESS) == GP_GROUP_BAN_ACCESS) + { + mHasGroupBanPower = true; + } } } @@ -728,11 +781,8 @@ void LLPanelGroupSubTab::setFooterEnabled(BOOL enable) } } -//////////////////////////// -// LLPanelGroupMembersSubTab -//////////////////////////// - +// LLPanelGroupMembersSubTab ///////////////////////////////////////////// static LLPanelInjector<LLPanelGroupMembersSubTab> t_panel_group_members_subtab("panel_group_members_subtab"); LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab() @@ -813,6 +863,13 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) mEjectBtn->setEnabled(FALSE); } + mBanBtn = parent->getChild<LLButton>("member_ban", recurse); + if(mBanBtn) + { + mBanBtn->setClickedCallback(onBanMember, this); + mBanBtn->setEnabled(FALSE); + } + return TRUE; } @@ -826,34 +883,6 @@ void LLPanelGroupMembersSubTab::setGroupID(const LLUUID& id) LLPanelGroupSubTab::setGroupID(id); } -void LLPanelGroupRolesSubTab::setGroupID(const LLUUID& id) -{ - if(mRolesList) mRolesList->deleteAllItems(); - if(mAssignedMembersList) mAssignedMembersList->deleteAllItems(); - if(mAllowedActionsList) mAllowedActionsList->deleteAllItems(); - - if(mRoleName) mRoleName->clear(); - if(mRoleDescription) mRoleDescription->clear(); - if(mRoleTitle) mRoleTitle->clear(); - - mHasRoleChange = FALSE; - - setFooterEnabled(FALSE); - - LLPanelGroupSubTab::setGroupID(id); -} -void LLPanelGroupActionsSubTab::setGroupID(const LLUUID& id) -{ - if(mActionList) mActionList->deleteAllItems(); - if(mActionRoles) mActionRoles->deleteAllItems(); - if(mActionMembers) mActionMembers->deleteAllItems(); - - if(mActionDescription) mActionDescription->clear(); - - LLPanelGroupSubTab::setGroupID(id); -} - - // static void LLPanelGroupMembersSubTab::onMemberSelect(LLUICtrl* ctrl, void* user_data) { @@ -882,7 +911,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() // Build a vector of all selected members, and gather allowed actions. uuid_vec_t selected_members; - U64 allowed_by_all = 0xffffffffffffLL; + U64 allowed_by_all = GP_ALL_POWERS; //0xFFFFffffFFFFffffLL; U64 allowed_by_some = 0; std::vector<LLScrollListItem*>::iterator itor; @@ -919,8 +948,8 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() LLGroupMgrGroupData::role_list_t::iterator iter = gdatap->mRoles.begin(); LLGroupMgrGroupData::role_list_t::iterator end = gdatap->mRoles.end(); - BOOL can_eject_members = gAgent.hasPowerInGroup(mGroupID, - GP_MEMBER_EJECT); + BOOL can_ban_members = gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS); + BOOL can_eject_members = gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_EJECT); BOOL member_is_owner = FALSE; for( ; iter != end; ++iter) @@ -967,6 +996,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() { // Can't remove other owners. cb_enable = FALSE; + can_ban_members = FALSE; break; } } @@ -986,14 +1016,14 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() } // If anyone selected is in any role besides 'Everyone' then they can't be ejected. - if (role_id.notNull() && (count > 0)) - { + if (role_id.notNull() && (count > 0)) + { can_eject_members = FALSE; - if (role_id == gdatap->mOwnerRole) - { - member_is_owner = TRUE; - } - } + if (role_id == gdatap->mOwnerRole) + { + member_is_owner = TRUE; + } + } LLRoleData rd; if (gdatap->getRoleData(role_id,rd)) @@ -1050,7 +1080,10 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() mAssignedRolesList->setEnabled(TRUE); if (gAgent.isGodlike()) + { can_eject_members = TRUE; + // can_ban_members = TRUE; + } if (!can_eject_members && !member_is_owner) { @@ -1063,10 +1096,41 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() if ( member_data && member_data->isInRole(gdatap->mOwnerRole) ) { can_eject_members = TRUE; + //can_ban_members = TRUE; } } + + } + + // ... or we can eject them because we have all the requisite powers... + if( gAgent.hasPowerInGroup(mGroupID, GP_ROLE_REMOVE_MEMBER) && + !member_is_owner) + { + if( gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_EJECT)) + { + can_eject_members = TRUE; + } + + if( gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS)) + { + can_ban_members = TRUE; + } } + + uuid_vec_t::const_iterator member_iter = selected_members.begin(); + uuid_vec_t::const_iterator member_end = selected_members.end(); + for ( ; member_iter != member_end; ++member_iter) + { + // Don't count the agent. + if ((*member_iter) == gAgent.getID()) + { + can_eject_members = FALSE; + can_ban_members = FALSE; + } + } + + mBanBtn->setEnabled(can_ban_members); mEjectBtn->setEnabled(can_eject_members); } @@ -1104,61 +1168,26 @@ void LLPanelGroupMembersSubTab::onEjectMembers(void *userdata) } void LLPanelGroupMembersSubTab::handleEjectMembers() -{ +{ + //send down an eject message + uuid_vec_t selected_members; + std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected(); if (selection.empty()) return; - - S32 selection_count = selection.size(); - if (selection_count == 1) - { - LLSD args; - LLUUID selected_avatar = mMembersList->getValue().asUUID(); - std::string fullname = LLSLURL("agent", selected_avatar, "inspect").getSLURLString(); - args["AVATAR_NAME"] = fullname; - LLSD payload; - LLNotificationsUtil::add("EjectGroupMemberWarning", - args, - payload, - boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2)); - } - else - { - LLSD args; - args["COUNT"] = llformat("%d", selection_count); - LLSD payload; - LLNotificationsUtil::add("EjectGroupMembersWarning", - args, - payload, - boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2)); - } -} -bool LLPanelGroupMembersSubTab::handleEjectCallback(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (0 == option) // Eject button + std::vector<LLScrollListItem*>::iterator itor; + for (itor = selection.begin() ; + itor != selection.end(); ++itor) { - //send down an eject message - uuid_vec_t selected_members; - - std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected(); - if (selection.empty()) return false; - - std::vector<LLScrollListItem*>::iterator itor; - for (itor = selection.begin() ; - itor != selection.end(); ++itor) - { - LLUUID member_id = (*itor)->getUUID(); - selected_members.push_back( member_id ); - } - - mMembersList->deleteSelectedItems(); - - sendEjectNotifications(mGroupID, selected_members); - - LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID, selected_members); + LLUUID member_id = (*itor)->getUUID(); + selected_members.push_back( member_id ); } - return false; + + mMembersList->deleteSelectedItems(); + + sendEjectNotifications(mGroupID, selected_members); + + LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID, selected_members); } void LLPanelGroupMembersSubTab::sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members) @@ -1186,12 +1215,11 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id, //add that the user is requesting to change the roles for selected //members - U64 powers_all_have = 0xffffffffffffLL; + U64 powers_all_have = GP_ALL_POWERS; U64 powers_some_have = 0; BOOL is_owner_role = ( gdatap->mOwnerRole == role_id ); LLUUID member_id; - std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected(); if (selection.empty()) @@ -1202,7 +1230,6 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id, for (std::vector<LLScrollListItem*>::iterator itor = selection.begin() ; itor != selection.end(); ++itor) { - member_id = (*itor)->getUUID(); //see if we requested a change for this member before @@ -1268,7 +1295,6 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id, FALSE); } - // static void LLPanelGroupMembersSubTab::onRoleCheck(LLUICtrl* ctrl, void* user_data) { @@ -1307,6 +1333,15 @@ void LLPanelGroupMembersSubTab::activate() update(GC_ALL); mActivated = true; } + else + { + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + // Members can be removed outside of this tab, checking changes + if (!gdatap || (gdatap->isMemberDataComplete() && gdatap->mMembers.size() != mMembersList->getItemCount())) + { + update(GC_MEMBER_DATA); + } + } } void LLPanelGroupMembersSubTab::deactivate() @@ -1701,13 +1736,12 @@ void LLPanelGroupMembersSubTab::updateMembers() return; } - //cleanup list only for first iretation + //cleanup list only for first iteration if(mMemberProgress == gdatap->mMembers.begin()) { mMembersList->deleteAllItems(); } - LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end(); LLTimer update_time; @@ -1764,12 +1798,44 @@ void LLPanelGroupMembersSubTab::updateMembers() handleMemberSelect(); } +void LLPanelGroupMembersSubTab::onBanMember(void* user_data) +{ + LLPanelGroupMembersSubTab* self = static_cast<LLPanelGroupMembersSubTab*>(user_data); + self->handleBanMember(); +} +void LLPanelGroupMembersSubTab::handleBanMember() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + if(!gdatap) + { + LL_WARNS("Groups") << "Unable to get group data for group " << mGroupID << LL_ENDL; + return; + } -//////////////////////////// -// LLPanelGroupRolesSubTab -//////////////////////////// + std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected(); + if(selection.empty()) + { + return; + } + uuid_vec_t ban_ids; + std::vector<LLScrollListItem*>::iterator itor; + for(itor = selection.begin(); itor != selection.end(); ++itor) + { + LLUUID ban_id = (*itor)->getUUID(); + ban_ids.push_back(ban_id); + + LLGroupBanData ban_data; + gdatap->createBanEntry(ban_id, ban_data); + } + + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, mGroupID, LLGroupMgr::BAN_CREATE, ban_ids); + handleEjectMembers(); +} + + +// LLPanelGroupRolesSubTab /////////////////////////////////////////////// static LLPanelInjector<LLPanelGroupRolesSubTab> t_panel_group_roles_subtab("panel_group_roles_subtab"); LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab() @@ -1783,7 +1849,7 @@ LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab() mMemberVisibleCheck(NULL), mDeleteRoleButton(NULL), mCreateRoleButton(NULL), - + mFirstOpen(TRUE), mHasRoleChange(FALSE) { } @@ -1885,6 +1951,7 @@ void LLPanelGroupRolesSubTab::deactivate() LL_DEBUGS() << "LLPanelGroupRolesSubTab::deactivate()" << LL_ENDL; LLPanelGroupSubTab::deactivate(); + mFirstOpen = FALSE; } bool LLPanelGroupRolesSubTab::needsApply(std::string& mesg) @@ -1892,6 +1959,12 @@ bool LLPanelGroupRolesSubTab::needsApply(std::string& mesg) LL_DEBUGS() << "LLPanelGroupRolesSubTab::needsApply()" << LL_ENDL; LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + if(!gdatap) + { + llwarns << "Unable to get group data for group " << mGroupID << llendl; + return false; + } + return (mHasRoleChange // Text changed in current role || (gdatap && gdatap->pendingRoleChanges())); // Pending role changes in the group @@ -1902,7 +1975,7 @@ bool LLPanelGroupRolesSubTab::apply(std::string& mesg) LL_DEBUGS() << "LLPanelGroupRolesSubTab::apply()" << LL_ENDL; saveRoleChanges(true); - + mFirstOpen = FALSE; LLGroupMgr::getInstance()->sendGroupRoleChanges(mGroupID); notifyObservers(); @@ -2039,14 +2112,17 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc) } } - if (!gdatap || !gdatap->isMemberDataComplete()) + if(!mFirstOpen) { - LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); - } - - if (!gdatap || !gdatap->isRoleMemberDataComplete()) - { - LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID); + if (!gdatap || !gdatap->isMemberDataComplete()) + { + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); + } + + if (!gdatap || !gdatap->isRoleMemberDataComplete()) + { + LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID); + } } if ((GC_ROLE_MEMBER_DATA == gc || GC_MEMBER_DATA == gc) @@ -2062,6 +2138,9 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc) void LLPanelGroupRolesSubTab::onRoleSelect(LLUICtrl* ctrl, void* user_data) { LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data); + if (!self) + return; + self->handleRoleSelect(); } @@ -2241,40 +2320,115 @@ void LLPanelGroupRolesSubTab::handleActionCheck(LLUICtrl* ctrl, bool force) LLRoleAction* rap = (LLRoleAction*)action_item->getUserdata(); U64 power = rap->mPowerBit; - if (check->get()) + bool isEnablingAbility = check->get(); + LLRoleData rd; + LLSD args; + + if (isEnablingAbility && + !force && + ((GP_ROLE_ASSIGN_MEMBER == power) || (GP_ROLE_CHANGE_ACTIONS == power) )) { - if (!force && ( (GP_ROLE_ASSIGN_MEMBER == power) - || (GP_ROLE_CHANGE_ACTIONS == power) )) - { - // Uncheck the item, for now. It will be - // checked if they click 'Yes', below. - check->set(FALSE); + // Uncheck the item, for now. It will be + // checked if they click 'Yes', below. + check->set(FALSE); - LLRoleData rd; - LLSD args; + LLRoleData rd; + LLSD args; - if ( gdatap->getRoleData(role_id, rd) ) + if ( gdatap->getRoleData(role_id, rd) ) + { + args["ACTION_NAME"] = rap->mDescription; + args["ROLE_NAME"] = rd.mRoleName; + mHasModal = TRUE; + std::string warning = "AssignDangerousActionWarning"; + if (GP_ROLE_CHANGE_ACTIONS == power) { - args["ACTION_NAME"] = rap->mDescription; - args["ROLE_NAME"] = rd.mRoleName; - mHasModal = TRUE; - std::string warning = "AssignDangerousActionWarning"; - if (GP_ROLE_CHANGE_ACTIONS == power) - { - warning = "AssignDangerousAbilityWarning"; - } - LLNotificationsUtil::add(warning, args, LLSD(), boost::bind(&LLPanelGroupRolesSubTab::addActionCB, this, _1, _2, check)); + warning = "AssignDangerousAbilityWarning"; } - else - { + LLNotificationsUtil::add(warning, args, LLSD(), boost::bind(&LLPanelGroupRolesSubTab::addActionCB, this, _1, _2, check)); + } + else + { LL_WARNS() << "Unable to look up role information for role id: " << role_id << LL_ENDL; + } + } + + if(GP_GROUP_BAN_ACCESS == power) + { + std::string warning = isEnablingAbility ? "AssignBanAbilityWarning" : "RemoveBanAbilityWarning"; + + ////////////////////////////////////////////////////////////////////////// + // Get role data for both GP_ROLE_REMOVE_MEMBER and GP_MEMBER_EJECT + // Add description and role name to LLSD + // Pop up dialog saying "Yo, you also granted these other abilities when you did this!" + if ( gdatap->getRoleData(role_id, rd) ) + { + args["ACTION_NAME"] = rap->mDescription; + args["ROLE_NAME"] = rd.mRoleName; + mHasModal = TRUE; + + std::vector<LLScrollListItem*> all_data = mAllowedActionsList->getAllData(); + std::vector<LLScrollListItem*>::iterator ad_it = all_data.begin(); + std::vector<LLScrollListItem*>::iterator ad_end = all_data.end(); + LLRoleAction* adp; + for( ; ad_it != ad_end; ++ad_it) + { + adp = (LLRoleAction*)(*ad_it)->getUserdata(); + if(adp->mPowerBit == GP_MEMBER_EJECT) + { + args["ACTION_NAME_2"] = adp->mDescription; + } + else if(adp->mPowerBit == GP_ROLE_REMOVE_MEMBER) + { + args["ACTION_NAME_3"] = adp->mDescription; + } } + + LLNotificationsUtil::add(warning, args); } else { - gdatap->addRolePower(role_id,power); + llwarns << "Unable to look up role information for role id: " + << role_id << llendl; + } + + ////////////////////////////////////////////////////////////////////////// + + LLGroupMgrGroupData::role_list_t::iterator rit = gdatap->mRoles.find(role_id); + U64 current_role_powers = GP_NO_POWERS; + if (rit != gdatap->mRoles.end()) + { + current_role_powers = ((*rit).second->getRoleData().mRolePowers); + } + + if(isEnablingAbility) + { + power |= (GP_ROLE_REMOVE_MEMBER | GP_MEMBER_EJECT); + current_role_powers |= power; } + else + { + current_role_powers &= ~GP_GROUP_BAN_ACCESS; + } + + mAllowedActionsList->deleteAllItems(); + buildActionsList( mAllowedActionsList, + current_role_powers, + current_role_powers, + boost::bind(&LLPanelGroupRolesSubTab::handleActionCheck, this, _1, false), + TRUE, + FALSE, + FALSE); + + } + + ////////////////////////////////////////////////////////////////////////// + // Adding non-specific ability to role + ////////////////////////////////////////////////////////////////////////// + if(isEnablingAbility) + { + gdatap->addRolePower(role_id, power); } else { @@ -2283,6 +2437,7 @@ void LLPanelGroupRolesSubTab::handleActionCheck(LLUICtrl* ctrl, bool force) mHasRoleChange = TRUE; notifyObservers(); + } bool LLPanelGroupRolesSubTab::addActionCB(const LLSD& notification, const LLSD& response, LLCheckBoxCtrl* check) @@ -2302,7 +2457,6 @@ bool LLPanelGroupRolesSubTab::addActionCB(const LLSD& notification, const LLSD& return false; } - // static void LLPanelGroupRolesSubTab::onPropertiesKey(LLLineEditor* ctrl, void* user_data) { @@ -2480,13 +2634,28 @@ void LLPanelGroupRolesSubTab::saveRoleChanges(bool select_saved_role) mHasRoleChange = FALSE; } } -//////////////////////////// -// LLPanelGroupActionsSubTab -//////////////////////////// -static LLPanelInjector<LLPanelGroupActionsSubTab> t_panel_group_actions_subtab("panel_group_actions_subtab"); +void LLPanelGroupRolesSubTab::setGroupID(const LLUUID& id) +{ + if(mRolesList) mRolesList->deleteAllItems(); + if(mAssignedMembersList) mAssignedMembersList->deleteAllItems(); + if(mAllowedActionsList) mAllowedActionsList->deleteAllItems(); + + if(mRoleName) mRoleName->clear(); + if(mRoleDescription) mRoleDescription->clear(); + if(mRoleTitle) mRoleTitle->clear(); + + mHasRoleChange = FALSE; + + setFooterEnabled(FALSE); + + LLPanelGroupSubTab::setGroupID(id); +} +// LLPanelGroupActionsSubTab ///////////////////////////////////////////// +static LLPanelInjector<LLPanelGroupActionsSubTab> t_panel_group_actions_subtab("panel_group_actions_subtab"); + LLPanelGroupActionsSubTab::LLPanelGroupActionsSubTab() : LLPanelGroupSubTab() { @@ -2659,26 +2828,298 @@ void LLPanelGroupActionsSubTab::handleActionSelect() } } -void LLPanelGroupRoles::setGroupID(const LLUUID& id) +void LLPanelGroupActionsSubTab::setGroupID(const LLUUID& id) { - LLPanelGroupTab::setGroupID(id); + if(mActionList) mActionList->deleteAllItems(); + if(mActionRoles) mActionRoles->deleteAllItems(); + if(mActionMembers) mActionMembers->deleteAllItems(); + + if(mActionDescription) mActionDescription->clear(); + + LLPanelGroupSubTab::setGroupID(id); +} + + +// LLPanelGroupBanListSubTab ///////////////////////////////////////////// +static LLPanelInjector<LLPanelGroupBanListSubTab> t_panel_group_ban_subtab("panel_group_banlist_subtab"); + +LLPanelGroupBanListSubTab::LLPanelGroupBanListSubTab() + : LLPanelGroupSubTab(), + mBanList(NULL), + mCreateBanButton(NULL), + mDeleteBanButton(NULL) +{} + +BOOL LLPanelGroupBanListSubTab::postBuildSubTab(LLView* root) +{ + LLPanelGroupSubTab::postBuildSubTab(root); + + // Upcast parent so we can ask it for sibling controls. + LLPanelGroupRoles* parent = (LLPanelGroupRoles*)root; + + // Look recursively from the parent to find all our widgets. + bool recurse = true; - LLPanelGroupMembersSubTab* group_members_tab = findChild<LLPanelGroupMembersSubTab>("members_sub_tab"); - LLPanelGroupRolesSubTab* group_roles_tab = findChild<LLPanelGroupRolesSubTab>("roles_sub_tab"); - LLPanelGroupActionsSubTab* group_actions_tab = findChild<LLPanelGroupActionsSubTab>("actions_sub_tab"); + mHeader = parent->getChild<LLPanel>("banlist_header", recurse); + mFooter = parent->getChild<LLPanel>("banlist_footer", recurse); + + mBanList = parent->getChild<LLNameListCtrl>("ban_list", recurse); + + mCreateBanButton = parent->getChild<LLButton>("ban_create", recurse); + mDeleteBanButton = parent->getChild<LLButton>("ban_delete", recurse); + mRefreshBanListButton = parent->getChild<LLButton>("ban_refresh", recurse); + mBanCountText = parent->getChild<LLTextBase>("ban_count", recurse); - if(group_members_tab) group_members_tab->setGroupID(id); - if(group_roles_tab) group_roles_tab->setGroupID(id); - if(group_actions_tab) group_actions_tab->setGroupID(id); + if(!mBanList || !mCreateBanButton || !mDeleteBanButton || !mRefreshBanListButton || !mBanCountText) + return FALSE; - LLButton* button = getChild<LLButton>("member_invite"); - if ( button ) - button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_INVITE)); + mBanList->setCommitOnSelectionChange(TRUE); + mBanList->setCommitCallback(onBanEntrySelect, this); - if(mSubTabContainer) - mSubTabContainer->selectTab(1); + mCreateBanButton->setClickedCallback(onCreateBanEntry, this); + mCreateBanButton->setEnabled(FALSE); - activate(); + mDeleteBanButton->setClickedCallback(onDeleteBanEntry, this); + mDeleteBanButton->setEnabled(FALSE); + + mRefreshBanListButton->setClickedCallback(onRefreshBanList, this); + mRefreshBanListButton->setEnabled(FALSE); + + setBanCount(0); + + mBanList->setOnNameListCompleteCallback(boost::bind(&LLPanelGroupBanListSubTab::onBanListCompleted, this, _1)); + + populateBanList(); + + setFooterEnabled(FALSE); + return TRUE; } +void LLPanelGroupBanListSubTab::activate() +{ + LLPanelGroupSubTab::activate(); + + mBanList->deselectAllItems(); + mDeleteBanButton->setEnabled(FALSE); + LLGroupMgrGroupData * group_datap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + if (group_datap) + { + mCreateBanButton->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS) && + group_datap->mBanList.size() < GB_MAX_BANNED_AGENTS); + setBanCount(group_datap->mBanList.size()); + } + else + { + mCreateBanButton->setEnabled(FALSE); + setBanCount(0); + } + + // BAKER: Should I really request everytime activate() is called? + // Perhaps I should only do it on a force refresh, or if an action on the list happens... + // Because it's not going to live-update the list anyway... You'd have to refresh if you + // wanted to see someone else's additions anyway... + // + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID); + + setFooterEnabled(FALSE); + update(GC_ALL); +} + +void LLPanelGroupBanListSubTab::update(LLGroupChange gc) +{ + populateBanList(); +} + +void LLPanelGroupBanListSubTab::draw() +{ + LLPanelGroupSubTab::draw(); + + // BAKER: Might be good to put it here instead of update, maybe.. See how often draw gets hit. + //if( + // populateBanList(); +} + +void LLPanelGroupBanListSubTab::onBanEntrySelect(LLUICtrl* ctrl, void* user_data) +{ + LLPanelGroupBanListSubTab* self = static_cast<LLPanelGroupBanListSubTab*>(user_data); + if (!self) + return; + + self->handleBanEntrySelect(); +} + +void LLPanelGroupBanListSubTab::handleBanEntrySelect() +{ + if (gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS)) + { + mDeleteBanButton->setEnabled(TRUE); + } +} + +void LLPanelGroupBanListSubTab::onCreateBanEntry(void* user_data) +{ + LLPanelGroupBanListSubTab* self = static_cast<LLPanelGroupBanListSubTab*>(user_data); + if (!self) + return; + + self->handleCreateBanEntry(); +} + +void LLPanelGroupBanListSubTab::handleCreateBanEntry() +{ + LLFloaterGroupBulkBan::showForGroup(mGroupID); + //populateBanList(); +} + +void LLPanelGroupBanListSubTab::onDeleteBanEntry(void* user_data) +{ + LLPanelGroupBanListSubTab* self = static_cast<LLPanelGroupBanListSubTab*>(user_data); + if (!self) + return; + + self->handleDeleteBanEntry(); +} + +void LLPanelGroupBanListSubTab::handleDeleteBanEntry() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + if(!gdatap) + { + LL_WARNS("Groups") << "Unable to get group data for group " << mGroupID << LL_ENDL; + return; + } + + std::vector<LLScrollListItem*> selection = mBanList->getAllSelected(); + if(selection.empty()) + { + return; + } + + bool can_ban_members = false; + if (gAgent.isGodlike() || + gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS)) + { + can_ban_members = true; + } + + // Owners can ban anyone in the group. + LLGroupMgrGroupData::member_list_t::iterator mi = gdatap->mMembers.find(gAgent.getID()); + if (mi != gdatap->mMembers.end()) + { + LLGroupMemberData* member_data = (*mi).second; + if ( member_data && member_data->isInRole(gdatap->mOwnerRole) ) + { + can_ban_members = true; + } + } + + if(!can_ban_members) + return; + + std::vector<LLUUID> ban_ids; + std::vector<LLScrollListItem*>::iterator itor; + for(itor = selection.begin(); itor != selection.end(); ++itor) + { + LLUUID ban_id = (*itor)->getUUID(); + ban_ids.push_back(ban_id); + + gdatap->removeBanEntry(ban_id); + mBanList->removeNameItem(ban_id); + + // Removing an item removes the selection, we shouldn't be able to click + // the button anymore until we reselect another entry. + mDeleteBanButton->setEnabled(FALSE); + } + + // update ban-count related elements + mCreateBanButton->setEnabled(TRUE); + setBanCount(gdatap->mBanList.size()); + + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, mGroupID, LLGroupMgr::BAN_DELETE, ban_ids); +} + +void LLPanelGroupBanListSubTab::onRefreshBanList(void* user_data) +{ + LLPanelGroupBanListSubTab* self = static_cast<LLPanelGroupBanListSubTab*>(user_data); + if (!self) + return; + + self->handleRefreshBanList(); +} + +void LLPanelGroupBanListSubTab::handleRefreshBanList() +{ + mRefreshBanListButton->setEnabled(FALSE); + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID); +} + +void LLPanelGroupBanListSubTab::onBanListCompleted(bool isComplete) +{ + if(isComplete) + { + mRefreshBanListButton->setEnabled(TRUE); + populateBanList(); + } +} + +void LLPanelGroupBanListSubTab::setBanCount(U32 ban_count) +{ + LLStringUtil::format_map_t args; + args["[COUNT]"] = llformat("%d", ban_count); + args["[LIMIT]"] = llformat("%d", GB_MAX_BANNED_AGENTS); + mBanCountText->setText(getString("ban_count_template", args)); +} + +void LLPanelGroupBanListSubTab::populateBanList() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + if(!gdatap) + { + LL_WARNS("Groups") << "Unable to get group data for group " << mGroupID << LL_ENDL; + return; + } + + mBanList->deleteAllItems(); + std::map<LLUUID,LLGroupBanData>::const_iterator entry = gdatap->mBanList.begin(); + for(; entry != gdatap->mBanList.end(); entry++) + { + LLNameListCtrl::NameItem ban_entry; + ban_entry.value = entry->first; + LLGroupBanData bd = entry->second; + + ban_entry.columns.add().column("name").font.name("SANSSERIF_SMALL").style("NORMAL"); + + // Baker TODO: MAINT- + // Check out utc_to_pacific_time() + + std::string ban_date_str = bd.mBanDate.toHTTPDateString("%Y/%m/%d"); +// time_t utc_time; +// utc_time = time_corrected(); +// LLSD substitution; +// substitution["datetime"] = (S32) utc_time; +// LLStringUtil::format (ban_date_str, substitution); + + //LL_INFOS("BAKER") << "[BAKER] BAN_DATE: " << bd.mBanDate.toHTTPDateString("%Y/%m/%d") << LL_ENDL; + //LL_INFOS("BAKER") << "[BAKER] BAN_DATE_MODIFIED: " << ban_date_str << LL_ENDL; + + //ban_entry.columns.add().column("ban_date").value(ban_date_str.font.name("SANSSERIF_SMALL").style("NORMAL"); + ban_entry.columns.add().column("ban_date").value(bd.mBanDate.toHTTPDateString("%Y/%m/%d")).font.name("SANSSERIF_SMALL").style("NORMAL"); + + mBanList->addNameItemRow(ban_entry); + } + + mRefreshBanListButton->setEnabled(TRUE); + mCreateBanButton->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS) && + gdatap->mBanList.size() < GB_MAX_BANNED_AGENTS); + setBanCount(gdatap->mBanList.size()); +} + +void LLPanelGroupBanListSubTab::setGroupID(const LLUUID& id) +{ + if(mBanList) + mBanList->deleteAllItems(); + + setFooterEnabled(FALSE); + LLPanelGroupSubTab::setGroupID(id); +} diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index baa2d40c7e..540b24ada6 100755 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -39,11 +39,9 @@ class LLScrollListCtrl; class LLScrollListItem; class LLTextEditor; -// Forward declare for friend usage. -//virtual BOOL LLPanelGroupSubTab::postBuildSubTab(LLView*); - typedef std::map<std::string,std::string> icon_map_t; + class LLPanelGroupRoles : public LLPanelGroupTab { public: @@ -92,6 +90,7 @@ protected: std::string mWantApplyMesg; }; + class LLPanelGroupSubTab : public LLPanelGroupTab { public: @@ -143,10 +142,14 @@ protected: icon_map_t mActionIcons; bool mActivated; - + + bool mHasGroupBanPower; // Used to communicate between action sets due to the dependency between + // GP_GROUP_BAN_ACCESS and GP_EJECT_MEMBER and GP_ROLE_REMOVE_MEMBER + void setOthersVisible(BOOL b); }; + class LLPanelGroupMembersSubTab : public LLPanelGroupSubTab { public: @@ -173,6 +176,10 @@ public: void handleRoleCheck(const LLUUID& role_id, LLRoleMemberChangeType type); + static void onBanMember(void* user_data); + void handleBanMember(); + + void applyMemberChanges(); bool addOwnerCB(const LLSD& notification, const LLSD& response); @@ -206,6 +213,7 @@ protected: LLScrollListCtrl* mAssignedRolesList; LLScrollListCtrl* mAllowedActionsList; LLButton* mEjectBtn; + LLButton* mBanBtn; BOOL mChanged; BOOL mPendingMemberUpdate; @@ -219,6 +227,7 @@ protected: avatar_name_cache_connection_map_t mAvatarNameCacheConnections; }; + class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab { public: @@ -241,7 +250,7 @@ public: static void onActionCheck(LLUICtrl*, void*); bool addActionCB(const LLSD& notification, const LLSD& response, LLCheckBoxCtrl* check); - + static void onPropertiesKey(LLLineEditor*, void*); void onDescriptionKeyStroke(LLTextEditor* caller); @@ -260,6 +269,9 @@ public: void saveRoleChanges(bool select_saved_role); virtual void setGroupID(const LLUUID& id); + + BOOL mFirstOpen; + protected: void handleActionCheck(LLUICtrl* ctrl, bool force); LLSD createRoleItem(const LLUUID& role_id, std::string name, std::string title, S32 members); @@ -281,6 +293,7 @@ protected: std::string mRemoveEveryoneTxt; }; + class LLPanelGroupActionsSubTab : public LLPanelGroupSubTab { public: @@ -308,4 +321,46 @@ protected: }; +class LLPanelGroupBanListSubTab : public LLPanelGroupSubTab +{ +public: + LLPanelGroupBanListSubTab(); + virtual ~LLPanelGroupBanListSubTab() {} + + virtual BOOL postBuildSubTab(LLView* root); + + virtual void activate(); + virtual void update(LLGroupChange gc); + virtual void draw(); + + static void onBanEntrySelect(LLUICtrl* ctrl, void* user_data); + void handleBanEntrySelect(); + + static void onCreateBanEntry(void* user_data); + void handleCreateBanEntry(); + + static void onDeleteBanEntry(void* user_data); + void handleDeleteBanEntry(); + + static void onRefreshBanList(void* user_data); + void handleRefreshBanList(); + + void onBanListCompleted(bool isComplete); + +protected: + void setBanCount(U32 ban_count); + void populateBanList(); + +public: + virtual void setGroupID(const LLUUID& id); + +protected: + LLNameListCtrl* mBanList; + LLButton* mCreateBanButton; + LLButton* mDeleteBanButton; + LLButton* mRefreshBanListButton; + LLTextBase* mBanCountText; + +}; + #endif // LL_LLPANELGROUPROLES_H diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index b02298090a..6c8765c62d 100755 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -55,6 +55,7 @@ #include "llviewertexturelist.h" #include "llsidepanelinventory.h" #include "llfolderview.h" +#include "llradiogroup.h" const std::string FILTERS_FILENAME("filters.xml"); @@ -82,6 +83,7 @@ public: void updateElementsFromFilter(); BOOL getCheckShowEmpty(); BOOL getCheckSinceLogoff(); + U32 getDateSearchDirection(); static void onTimeAgo(LLUICtrl*, void *); static void onCloseBtn(void* user_data); @@ -700,6 +702,30 @@ void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data) if ( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() ) { self->getChild<LLUICtrl>("check_since_logoff")->setValue(false); + + U32 days = (U32)self->mSpinSinceDays->get(); + U32 hours = (U32)self->mSpinSinceHours->get(); + if (hours >= 24) + { + // Try to handle both cases of spinner clicking and text input in a sensible fashion as best as possible. + // There is no way to tell if someone has clicked the spinner to get to 24 or input 24 manually, so in + // this case add to days. Any value > 24 means they have input the hours manually, so do not add to the + // current day value. + if (24 == hours) // Got to 24 via spinner clicking or text input of 24 + { + days = days + hours / 24; + } + else // Text input, so do not add to days + { + days = hours / 24; + } + hours = (U32)hours % 24; + self->mSpinSinceHours->setFocus(false); + self->mSpinSinceDays->setFocus(false); + self->mSpinSinceDays->set((F32)days); + self->mSpinSinceHours->set((F32)hours); + self->mSpinSinceHours->setFocus(true); + } } } @@ -719,6 +745,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter() std::string filter_string = mFilter->getFilterSubString(); LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState(); U32 hours = mFilter->getHoursAgo(); + U32 date_search_direction = mFilter->getDateSearchDirection(); // update the ui elements setTitle(mFilter->getName()); @@ -740,6 +767,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter() getChild<LLUICtrl>("check_since_logoff")->setValue(mFilter->isSinceLogoff()); mSpinSinceHours->set((F32)(hours % 24)); mSpinSinceDays->set((F32)(hours / 24)); + getChild<LLRadioGroup>("date_search_direction")->setSelectedIndex(date_search_direction); } void LLFloaterInventoryFinder::draw() @@ -840,17 +868,23 @@ void LLFloaterInventoryFinder::draw() } U32 days = (U32)mSpinSinceDays->get(); U32 hours = (U32)mSpinSinceHours->get(); - if (hours > 24) + if (hours >= 24) { - days += hours / 24; + days = hours / 24; hours = (U32)hours % 24; + // A UI element that has focus will not display a new value set to it + mSpinSinceHours->setFocus(false); + mSpinSinceDays->setFocus(false); mSpinSinceDays->set((F32)days); mSpinSinceHours->set((F32)hours); + mSpinSinceHours->setFocus(true); } hours += days * 24; + mPanelMainInventory->getPanel()->setHoursAgo(hours); mPanelMainInventory->getPanel()->setSinceLogoff(getCheckSinceLogoff()); mPanelMainInventory->setFilterTextFromFilter(); + mPanelMainInventory->getPanel()->setDateSearchDirection(getDateSearchDirection()); LLPanel::draw(); } @@ -865,6 +899,11 @@ BOOL LLFloaterInventoryFinder::getCheckSinceLogoff() return getChild<LLUICtrl>("check_since_logoff")->getValue(); } +U32 LLFloaterInventoryFinder::getDateSearchDirection() +{ + return getChild<LLRadioGroup>("date_search_direction")->getSelectedIndex(); +} + void LLFloaterInventoryFinder::onCloseBtn(void* user_data) { LLFloaterInventoryFinder* finderp = (LLFloaterInventoryFinder*)user_data; diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 0817b677bc..ed91d277dd 100755 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -488,8 +488,9 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, gCacheName->getGroup(parcel->getGroupID(), boost::bind(&LLPanelPlaceInfo::onNameCache, mRegionGroupText, _2)); - gCacheName->getGroup(parcel->getGroupID(), - boost::bind(&LLPanelPlaceInfo::onNameCache, mParcelOwner, _2)); + std::string owner = + LLSLURL("group", parcel->getGroupID(), "inspect").getSLURLString(); + mParcelOwner->setText(owner); } else { diff --git a/indra/newview/llsyntaxid.cpp b/indra/newview/llsyntaxid.cpp index b1194dcd1b..a763d42a8d 100644 --- a/indra/newview/llsyntaxid.cpp +++ b/indra/newview/llsyntaxid.cpp @@ -47,23 +47,22 @@ public: LL_DEBUGS("SyntaxLSL") << "Instantiating with file saving to: '" << filespec << "'" << LL_ENDL; } - virtual void errorWithContent(U32 status, - const std::string& reason, - const LLSD& content) + /* virtual */ void httpFailure() { - LL_WARNS("SyntaxLSL") << "failed to fetch syntax file [status:" << status << "]: " << content << LL_ENDL; + LL_WARNS("SyntaxLSL") << "failed to fetch syntax file [status:" << getStatus() << "]: " << getContent() << LL_ENDL; } - virtual void result(const LLSD& content_ref) + /* virtual */ void httpSuccess() { // Continue only if a valid LLSD object was returned. - if (content_ref.isMap()) + const LLSD& content = getContent(); + if (content.isMap()) { - if (LLSyntaxIdLSL::getInstance()->isSupportedVersion(content_ref)) + if (LLSyntaxIdLSL::getInstance()->isSupportedVersion(content)) { - LLSyntaxIdLSL::getInstance()->setKeywordsXml(content_ref); + LLSyntaxIdLSL::getInstance()->setKeywordsXml(content); - cacheFile(content_ref); + cacheFile(content); LLSyntaxIdLSL::getInstance()->handleFileFetched(mFileSpec); } else diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 9ea46cab68..d9a874be49 100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2012-2013, Linden Research, Inc. + * Copyright (C) 2012-2014, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -244,6 +244,13 @@ LLTrace::EventStatHandle<F64Milliseconds > LLTextureFetch::sCacheReadLatency("te static const S32 HTTP_REQUESTS_IN_QUEUE_HIGH_WATER = 40; // Maximum requests to have active in HTTP static const S32 HTTP_REQUESTS_IN_QUEUE_LOW_WATER = 20; // Active level at which to refill +// BUG-3323/SH-4375 +// *NOTE: This is a heuristic value. Texture fetches have a habit of using a +// value of 32MB to indicate 'get the rest of the image'. Certain ISPs and +// network equipment get confused when they see this in a Range: header. So, +// if the request end is beyond this value, we issue an open-ended Range: +// request (e.g. 'Range: <start>-') which seems to fix the problem. +static const S32 HTTP_REQUESTS_RANGE_END_MAX = 20000000; ////////////////////////////////////////////////////////////////////////////// @@ -266,6 +273,9 @@ static const char* e_state_name[] = "DONE" }; +// Log scope +static const char * const LOG_TXT = "Texture"; + class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler { @@ -926,7 +936,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, calcWorkPriority(); mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL; -// LL_INFOS() << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL; +// LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL; if (!mFetcher->mDebugPause) { U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH; @@ -937,7 +947,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, LLTextureFetchWorker::~LLTextureFetchWorker() { -// LL_INFOS() << "Destroy: " << mID +// LL_INFOS(LOG_TXT) << "Destroy: " << mID // << " Decoded=" << mDecodedDiscard // << " Requested=" << mRequestedDiscard // << " Desired=" << mDesiredDiscard << LL_ENDL; @@ -1001,7 +1011,7 @@ void LLTextureFetchWorker::setupPacketData() mFirstPacket = (data_size - FIRST_PACKET_SIZE) / MAX_IMG_PACKET_SIZE + 1; if (FIRST_PACKET_SIZE + (mFirstPacket-1) * MAX_IMG_PACKET_SIZE != data_size) { - LL_WARNS() << "Bad CACHED TEXTURE size: " << data_size << " removing." << LL_ENDL; + LL_WARNS(LOG_TXT) << "Bad CACHED TEXTURE size: " << data_size << " removing." << LL_ENDL; removeFromCache(); resetFormattedData(); clearPackets(); @@ -1124,14 +1134,14 @@ bool LLTextureFetchWorker::doWork(S32 param) { if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR) { - LL_DEBUGS("Texture") << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL; + LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL; return true; // abort } } if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP) { //nowhere to get data, abort. - LL_WARNS("Texture") << mID << " abort, nowhere to get data" << LL_ENDL; + LL_WARNS(LOG_TXT) << mID << " abort, nowhere to get data" << LL_ENDL; return true ; } @@ -1177,8 +1187,8 @@ bool LLTextureFetchWorker::doWork(S32 param) setState(LOAD_FROM_TEXTURE_CACHE); mInCache = FALSE; mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE); // min desired size is TEXTURE_CACHE_ENTRY_SIZE - LL_DEBUGS("Texture") << mID << ": Priority: " << llformat("%8.0f",mImagePriority) - << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; + LL_DEBUGS(LOG_TXT) << mID << ": Priority: " << llformat("%8.0f",mImagePriority) + << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; // fall through } @@ -1246,7 +1256,7 @@ bool LLTextureFetchWorker::doWork(S32 param) // //This should never happen // - LL_DEBUGS("Texture") << mID << " this should never happen" << LL_ENDL; + LL_DEBUGS(LOG_TXT) << mID << " this should never happen" << LL_ENDL; return false; } } @@ -1267,15 +1277,15 @@ bool LLTextureFetchWorker::doWork(S32 param) mLoadedDiscard = mDesiredDiscard; if (mLoadedDiscard < 0) { - LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard - << ", should be >=0" << LL_ENDL; + LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard + << ", should be >=0" << LL_ENDL; } setState(DECODE_IMAGE); mInCache = TRUE; mWriteToCacheState = NOT_WRITE ; - LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize() - << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight()) - << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; + LL_DEBUGS(LOG_TXT) << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize() + << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight()) + << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(1)); } else @@ -1283,13 +1293,13 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mUrl.compare(0, 7, "file://") == 0) { // failed to load local file, we're done. - LL_WARNS("Texture") << mID << ": abort, failed to load local file " << mUrl << LL_ENDL; + LL_WARNS(LOG_TXT) << mID << ": abort, failed to load local file " << mUrl << LL_ENDL; return true; } // need more data else { - LL_DEBUGS("Texture") << mID << ": Not in Cache" << LL_ENDL; + LL_DEBUGS(LOG_TXT) << mID << ": Not in Cache" << LL_ENDL; setState(LOAD_FROM_NETWORK); } @@ -1306,11 +1316,11 @@ bool LLTextureFetchWorker::doWork(S32 param) { if (wait_seconds <= 0.0) { - LL_INFOS() << mID << " retrying now" << LL_ENDL; + LL_INFOS(LOG_TXT) << mID << " retrying now" << LL_ENDL; } else { - //LL_INFOS() << mID << " waiting to retry for " << wait_seconds << " seconds" << LL_ENDL; + //LL_INFOS(LOG_TXT) << mID << " waiting to retry for " << wait_seconds << " seconds" << LL_ENDL; return false; } } @@ -1333,20 +1343,23 @@ bool LLTextureFetchWorker::doWork(S32 param) { if (mFTType != FTT_DEFAULT) { - LL_WARNS() << "trying to seek a non-default texture on the sim. Bad!" << LL_ENDL; + LL_WARNS(LOG_TXT) << "trying to seek a non-default texture on the sim. Bad!" << LL_ENDL; } setUrl(http_url + "/?texture_id=" + mID.asString().c_str()); + LL_DEBUGS("Texture") << "Texture URL " << mUrl << LL_ENDL; mWriteToCacheState = CAN_WRITE ; //because this texture has a fixed texture id. } else { mCanUseHTTP = false ; + LL_DEBUGS("Texture") << "Texture not available via HTTP: no URL " << mUrl << LL_ENDL; } } else { // This will happen if not logged in or if a region deoes not have HTTP Texture enabled - //LL_WARNS() << "Region not found for host: " << mHost << LL_ENDL; + //LL_WARNS(LOG_TXT) << "Region not found for host: " << mHost << LL_ENDL; + LL_DEBUGS("Texture") << "Texture not available via HTTP: no region " << mUrl << LL_ENDL; mCanUseHTTP = false; } } @@ -1400,20 +1413,20 @@ bool LLTextureFetchWorker::doWork(S32 param) } if (processSimulatorPackets()) { - LL_DEBUGS("Texture") << mID << ": Loaded from Sim. Bytes: " << mFormattedImage->getDataSize() << LL_ENDL; + LL_DEBUGS(LOG_TXT) << mID << ": Loaded from Sim. Bytes: " << mFormattedImage->getDataSize() << LL_ENDL; mFetcher->removeFromNetworkQueue(this, false); if (mFormattedImage.isNull() || !mFormattedImage->getDataSize()) { // processSimulatorPackets() failed -// LL_WARNS() << "processSimulatorPackets() failed to load buffer" << LL_ENDL; - LL_WARNS("Texture") << mID << " processSimulatorPackets() failed to load buffer" << LL_ENDL; +// LL_WARNS(LOG_TXT) << "processSimulatorPackets() failed to load buffer" << LL_ENDL; + LL_WARNS(LOG_TXT) << mID << " processSimulatorPackets() failed to load buffer" << LL_ENDL; return true; // failed } setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); if (mLoadedDiscard < 0) { - LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard - << ", should be >=0" << LL_ENDL; + LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard + << ", should be >=0" << LL_ENDL; } setState(DECODE_IMAGE); mWriteToCacheState = SHOULD_WRITE; @@ -1463,7 +1476,7 @@ bool LLTextureFetchWorker::doWork(S32 param) if (! mCanUseHTTP) { releaseHttpSemaphore(); - LL_WARNS("Texture") << mID << " abort: SEND_HTTP_REQ but !mCanUseHTTP" << LL_ENDL; + LL_WARNS(LOG_TXT) << mID << " abort: SEND_HTTP_REQ but !mCanUseHTTP" << LL_ENDL; return true; // abort } @@ -1482,8 +1495,8 @@ bool LLTextureFetchWorker::doWork(S32 param) setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); if (mLoadedDiscard < 0) { - LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard - << ", should be >=0" << LL_ENDL; + LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard + << ", should be >=0" << LL_ENDL; } setState(DECODE_IMAGE); releaseHttpSemaphore(); @@ -1492,7 +1505,7 @@ bool LLTextureFetchWorker::doWork(S32 param) else { releaseHttpSemaphore(); - LL_WARNS("Texture") << mID << " SEND_HTTP_REQ abort: cur_size " << cur_size << " <=0" << LL_ENDL; + LL_WARNS(LOG_TXT) << mID << " SEND_HTTP_REQ abort: cur_size " << cur_size << " <=0" << LL_ENDL; return true; // abort. } } @@ -1523,10 +1536,10 @@ bool LLTextureFetchWorker::doWork(S32 param) mLoaded = FALSE; mGetStatus = LLCore::HttpStatus(); mGetReason.clear(); - LL_DEBUGS("Texture") << "HTTP GET: " << mID << " Offset: " << mRequestedOffset - << " Bytes: " << mRequestedSize - << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << mFetcher->mMaxBandwidth - << LL_ENDL; + LL_DEBUGS(LOG_TXT) << "HTTP GET: " << mID << " Offset: " << mRequestedOffset + << " Bytes: " << mRequestedSize + << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << mFetcher->mMaxBandwidth + << LL_ENDL; // Will call callbackHttpGet when curl request completes // Only server bake images use the returned headers currently, for getting retry-after field. @@ -1535,14 +1548,16 @@ bool LLTextureFetchWorker::doWork(S32 param) mWorkPriority, mUrl, mRequestedOffset, - mRequestedSize, + (mRequestedOffset + mRequestedSize) > HTTP_REQUESTS_RANGE_END_MAX + ? 0 + : mRequestedSize, options, mFetcher->mHttpHeaders, this); } if (LLCORE_HTTP_HANDLE_INVALID == mHttpHandle) { - LL_WARNS() << "HTTP GET request failed for " << mID << LL_ENDL; + LL_WARNS(LOG_TXT) << "HTTP GET request failed for " << mID << LL_ENDL; resetFormattedData(); releaseHttpSemaphore(); return true; // failed @@ -1570,7 +1585,7 @@ bool LLTextureFetchWorker::doWork(S32 param) { if (mFTType != FTT_MAP_TILE) { - LL_WARNS() << "Texture missing from server (404): " << mUrl << LL_ENDL; + LL_WARNS(LOG_TXT) << "Texture missing from server (404): " << mUrl << LL_ENDL; } if(mWriteToCacheState == NOT_WRITE) //map tiles or server bakes @@ -1579,7 +1594,7 @@ bool LLTextureFetchWorker::doWork(S32 param) releaseHttpSemaphore(); if (mFTType != FTT_MAP_TILE) { - LL_WARNS("Texture") << mID << " abort: WAIT_HTTP_REQ not found" << LL_ENDL; + LL_WARNS(LOG_TXT) << mID << " abort: WAIT_HTTP_REQ not found" << LL_ENDL; } return true; } @@ -1597,11 +1612,11 @@ bool LLTextureFetchWorker::doWork(S32 param) } else if (http_service_unavail == mGetStatus) { - LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL; - LL_INFOS() << "503: HTTP GET failed for: " << mUrl - << " Status: " << mGetStatus.toHex() - << " Reason: '" << mGetReason << "'" - << LL_ENDL; + LL_INFOS_ONCE(LOG_TXT) << "Texture server busy (503): " << mUrl << LL_ENDL; + LL_INFOS(LOG_TXT) << "503: HTTP GET failed for: " << mUrl + << " Status: " << mGetStatus.toHex() + << " Reason: '" << mGetReason << "'" + << LL_ENDL; } else if (http_not_sat == mGetStatus) { @@ -1610,10 +1625,10 @@ bool LLTextureFetchWorker::doWork(S32 param) } else { - LL_INFOS() << "HTTP GET failed for: " << mUrl - << " Status: " << mGetStatus.toTerseString() - << " Reason: '" << mGetReason << "'" - << LL_ENDL; + LL_INFOS(LOG_TXT) << "HTTP GET failed for: " << mUrl + << " Status: " << mGetStatus.toTerseString() + << " Reason: '" << mGetReason << "'" + << LL_ENDL; } if (mFTType != FTT_SERVER_BAKE) @@ -1627,8 +1642,8 @@ bool LLTextureFetchWorker::doWork(S32 param) setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); if (mLoadedDiscard < 0) { - LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard - << ", should be >=0" << LL_ENDL; + LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard + << ", should be >=0" << LL_ENDL; } setState(DECODE_IMAGE); releaseHttpSemaphore(); @@ -1639,7 +1654,7 @@ bool LLTextureFetchWorker::doWork(S32 param) resetFormattedData(); setState(DONE); releaseHttpSemaphore(); - LL_WARNS("Texture") << mID << " abort: fail harder" << LL_ENDL; + LL_WARNS(LOG_TXT) << mID << " abort: fail harder" << LL_ENDL; return true; // failed } @@ -1663,7 +1678,7 @@ bool LLTextureFetchWorker::doWork(S32 param) // abort. setState(DONE); - LL_WARNS("Texture") << mID << " abort: no data received" << LL_ENDL; + LL_WARNS(LOG_TXT) << mID << " abort: no data received" << LL_ENDL; releaseHttpSemaphore(); return true; } @@ -1679,8 +1694,8 @@ bool LLTextureFetchWorker::doWork(S32 param) // Get back into alignment. if (mHttpReplyOffset > cur_size) { - LL_WARNS("Texture") << "Partial HTTP response produces break in image data for texture " - << mID << ". Aborting load." << LL_ENDL; + LL_WARNS(LOG_TXT) << "Partial HTTP response produces break in image data for texture " + << mID << ". Aborting load." << LL_ENDL; setState(DONE); releaseHttpSemaphore(); return true; @@ -1731,8 +1746,8 @@ bool LLTextureFetchWorker::doWork(S32 param) mLoadedDiscard = mRequestedDiscard; if (mLoadedDiscard < 0) { - LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard - << ", should be >=0" << LL_ENDL; + LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard + << ", should be >=0" << LL_ENDL; } setState(DECODE_IMAGE); if (mWriteToCacheState != NOT_WRITE) @@ -1773,26 +1788,26 @@ bool LLTextureFetchWorker::doWork(S32 param) { // We aborted, don't decode setState(DONE); - LL_DEBUGS("Texture") << mID << " DECODE_IMAGE abort: desired discard " << mDesiredDiscard << "<0" << LL_ENDL; + LL_DEBUGS(LOG_TXT) << mID << " DECODE_IMAGE abort: desired discard " << mDesiredDiscard << "<0" << LL_ENDL; return true; } if (mFormattedImage->getDataSize() <= 0) { - LL_WARNS() << "Decode entered with invalid mFormattedImage. ID = " << mID << LL_ENDL; + LL_WARNS(LOG_TXT) << "Decode entered with invalid mFormattedImage. ID = " << mID << LL_ENDL; //abort, don't decode setState(DONE); - LL_DEBUGS("Texture") << mID << " DECODE_IMAGE abort: (mFormattedImage->getDataSize() <= 0)" << LL_ENDL; + LL_DEBUGS(LOG_TXT) << mID << " DECODE_IMAGE abort: (mFormattedImage->getDataSize() <= 0)" << LL_ENDL; return true; } if (mLoadedDiscard < 0) { - LL_WARNS() << "Decode entered with invalid mLoadedDiscard. ID = " << mID << LL_ENDL; + LL_WARNS(LOG_TXT) << "Decode entered with invalid mLoadedDiscard. ID = " << mID << LL_ENDL; //abort, don't decode setState(DONE); - LL_DEBUGS("Texture") << mID << " DECODE_IMAGE abort: mLoadedDiscard < 0" << LL_ENDL; + LL_DEBUGS(LOG_TXT) << mID << " DECODE_IMAGE abort: mLoadedDiscard < 0" << LL_ENDL; return true; } @@ -1803,8 +1818,8 @@ bool LLTextureFetchWorker::doWork(S32 param) U32 image_priority = LLWorkerThread::PRIORITY_NORMAL | mWorkPriority; mDecoded = FALSE; setState(DECODE_IMAGE_UPDATE); - LL_DEBUGS("Texture") << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard - << " All Data: " << mHaveAllData << LL_ENDL; + LL_DEBUGS(LOG_TXT) << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard + << " All Data: " << mHaveAllData << LL_ENDL; mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, image_priority, discard, mNeedsAux, new DecodeResponder(mFetcher, mID, this)); // fall though @@ -1821,11 +1836,11 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mDecodedDiscard < 0) { - LL_DEBUGS("Texture") << mID << ": Failed to Decode." << LL_ENDL; + LL_DEBUGS(LOG_TXT) << mID << ": Failed to Decode." << LL_ENDL; if (mCachedSize > 0 && !mInLocalCache && mRetryAttempt == 0) { // Cache file should be deleted, try again - LL_WARNS() << mID << ": Decode of cached file failed (removed), retrying" << LL_ENDL; + LL_WARNS(LOG_TXT) << mID << ": Decode of cached file failed (removed), retrying" << LL_ENDL; llassert_always(mDecodeHandle == 0); mFormattedImage = NULL; ++mRetryAttempt; @@ -1835,15 +1850,15 @@ bool LLTextureFetchWorker::doWork(S32 param) } else { -// LL_WARNS() << "UNABLE TO LOAD TEXTURE: " << mID << " RETRIES: " << mRetryAttempt << LL_ENDL; +// LL_WARNS(LOG_TXT) << "UNABLE TO LOAD TEXTURE: " << mID << " RETRIES: " << mRetryAttempt << LL_ENDL; setState(DONE); // failed } } else { llassert_always(mRawImage.notNull()); - LL_DEBUGS("Texture") << mID << ": Decoded. Discard: " << mDecodedDiscard - << " Raw Image: " << llformat("%dx%d",mRawImage->getWidth(),mRawImage->getHeight()) << LL_ENDL; + LL_DEBUGS(LOG_TXT) << mID << ": Decoded. Discard: " << mDecodedDiscard + << " Raw Image: " << llformat("%dx%d",mRawImage->getWidth(),mRawImage->getHeight()) << LL_ENDL; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); setState(WRITE_TO_CACHE); } @@ -1915,9 +1930,9 @@ bool LLTextureFetchWorker::doWork(S32 param) { // More data was requested, return to INIT setState(INIT); - LL_DEBUGS("Texture") << mID << " more data requested, returning to INIT: " - << " mDecodedDiscard " << mDecodedDiscard << ">= 0 && mDesiredDiscard " << mDesiredDiscard - << "<" << " mDecodedDiscard " << mDecodedDiscard << LL_ENDL; + LL_DEBUGS(LOG_TXT) << mID << " more data requested, returning to INIT: " + << " mDecodedDiscard " << mDecodedDiscard << ">= 0 && mDesiredDiscard " << mDesiredDiscard + << "<" << " mDecodedDiscard " << mDecodedDiscard << LL_ENDL; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); return false; } @@ -1957,8 +1972,8 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe F32 rate = fake_failure_rate; if (mFTType == FTT_SERVER_BAKE && (fake_failure_rate > 0.0) && (rand_val < fake_failure_rate)) { - LL_WARNS() << mID << " for debugging, setting fake failure status for texture " << mID - << " (rand was " << rand_val << "/" << rate << ")" << LL_ENDL; + LL_WARNS(LOG_TXT) << mID << " for debugging, setting fake failure status for texture " << mID + << " (rand was " << rand_val << "/" << rate << ")" << LL_ENDL; response->setStatus(LLCore::HttpStatus(503)); } bool success = true; @@ -1966,12 +1981,12 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe LLCore::HttpStatus status(response->getStatus()); if (!status && (mFTType == FTT_SERVER_BAKE)) { - LL_INFOS() << mID << " state " << e_state_name[mState] << LL_ENDL; + LL_INFOS(LOG_TXT) << mID << " state " << e_state_name[mState] << LL_ENDL; mFetchRetryPolicy.onFailure(response); F32 retry_after; if (mFetchRetryPolicy.shouldRetry(retry_after)) { - LL_INFOS() << mID << " will retry after " << retry_after << " seconds, resetting state to LOAD_FROM_NETWORK" << LL_ENDL; + LL_INFOS(LOG_TXT) << mID << " will retry after " << retry_after << " seconds, resetting state to LOAD_FROM_NETWORK" << LL_ENDL; mFetcher->removeFromHTTPQueue(mID, S32Bytes(0)); std::string reason(status.toString()); setGetStatus(status, reason); @@ -1981,7 +1996,7 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe } else { - LL_INFOS() << mID << " will not retry" << LL_ENDL; + LL_INFOS(LOG_TXT) << mID << " will not retry" << LL_ENDL; } } else @@ -1989,30 +2004,20 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe mFetchRetryPolicy.onSuccess(); } - LL_DEBUGS("Texture") << "HTTP COMPLETE: " << mID - << " status: " << status.toTerseString() - << " '" << status.toString() << "'" - << LL_ENDL; - -// unsigned int offset(0), length(0), full_length(0); -// response->getRange(&offset, &length, &full_length); -// LL_WARNS() << "HTTP COMPLETE: " << mID << " handle: " << handle -// << " status: " << status.toULong() << " '" << status.toString() << "'" -// << " req offset: " << mRequestedOffset << " req length: " << mRequestedSize -// << " offset: " << offset << " length: " << length -// << LL_ENDL; - std::string reason(status.toString()); setGetStatus(status, reason); + LL_DEBUGS(LOG_TXT) << "HTTP COMPLETE: " << mID + << " status: " << status.toTerseString() + << " '" << reason << "'" + << LL_ENDL; + if (! status) { success = false; if (mFTType != FTT_MAP_TILE) // missing map tiles are normal, don't complain about them. { - std::string reason(status.toString()); - setGetStatus(status, reason); - LL_WARNS() << "CURL GET FAILED, status: " << status.toTerseString() - << " reason: " << reason << LL_ENDL; + LL_WARNS(LOG_TXT) << "CURL GET FAILED, status: " << status.toTerseString() + << " reason: " << reason << LL_ENDL; } } else @@ -2223,13 +2228,13 @@ S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response, if (mState != WAIT_HTTP_REQ) { - LL_WARNS() << "callbackHttpGet for unrequested fetch worker: " << mID - << " req=" << mSentRequest << " state= " << mState << LL_ENDL; + LL_WARNS(LOG_TXT) << "callbackHttpGet for unrequested fetch worker: " << mID + << " req=" << mSentRequest << " state= " << mState << LL_ENDL; return data_size; } if (mLoaded) { - LL_WARNS() << "Duplicate callback for " << mID.asString() << LL_ENDL; + LL_WARNS(LOG_TXT) << "Duplicate callback for " << mID.asString() << LL_ENDL; return data_size ; // ignore duplicate callback } if (success) @@ -2238,7 +2243,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response, LLCore::BufferArray * body(response->getBody()); data_size = body ? body->size() : 0; - LL_DEBUGS("Texture") << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << LL_ENDL; + LL_DEBUGS(LOG_TXT) << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << LL_ENDL; if (data_size > 0) { LLViewerStatsRecorder::instance().textureFetch(data_size); @@ -2278,10 +2283,10 @@ S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response, // response body becomes the entire dataset. if (data_size <= mRequestedOffset) { - LL_WARNS("Texture") << "Fetched entire texture " << mID - << " when it was expected to be marked complete. mImageSize: " - << mFileSize << " datasize: " << mFormattedImage->getDataSize() - << LL_ENDL; + LL_WARNS(LOG_TXT) << "Fetched entire texture " << mID + << " when it was expected to be marked complete. mImageSize: " + << mFileSize << " datasize: " << mFormattedImage->getDataSize() + << LL_ENDL; } mHaveAllData = TRUE; llassert_always(mDecodeHandle == 0); @@ -2294,7 +2299,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response, else if (data_size > mRequestedSize) { // *TODO: This shouldn't be happening any more (REALLY don't expect this anymore) - LL_WARNS() << "data_size = " << data_size << " > requested: " << mRequestedSize << LL_ENDL; + LL_WARNS(LOG_TXT) << "data_size = " << data_size << " > requested: " << mRequestedSize << LL_ENDL; mHaveAllData = TRUE; llassert_always(mDecodeHandle == 0); mFormattedImage = NULL; // discard any previous data we had @@ -2329,7 +2334,7 @@ void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* ima LLMutexLock lock(&mWorkMutex); // +Mw if (mState != LOAD_FROM_TEXTURE_CACHE) { -// LL_WARNS() << "Read callback for " << mID << " with state = " << mState << LL_ENDL; +// LL_WARNS(LOG_TXT) << "Read callback for " << mID << " with state = " << mState << LL_ENDL; return; } if (success) @@ -2354,7 +2359,7 @@ void LLTextureFetchWorker::callbackCacheWrite(bool success) LLMutexLock lock(&mWorkMutex); // +Mw if (mState != WAIT_ON_WRITE) { -// LL_WARNS() << "Write callback for " << mID << " with state = " << mState << LL_ENDL; +// LL_WARNS(LOG_TXT) << "Write callback for " << mID << " with state = " << mState << LL_ENDL; return; } mWritten = TRUE; @@ -2373,7 +2378,7 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag } if (mState != DECODE_IMAGE_UPDATE) { -// LL_WARNS() << "Decode callback for " << mID << " with state = " << mState << LL_ENDL; +// LL_WARNS(LOG_TXT) << "Decode callback for " << mID << " with state = " << mState << LL_ENDL; mDecodeHandle = 0; return; } @@ -2386,17 +2391,17 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag mRawImage = raw; mAuxImage = aux; mDecodedDiscard = mFormattedImage->getDiscardLevel(); - LL_DEBUGS("Texture") << mID << ": Decode Finished. Discard: " << mDecodedDiscard - << " Raw Image: " << llformat("%dx%d",mRawImage->getWidth(),mRawImage->getHeight()) << LL_ENDL; + LL_DEBUGS(LOG_TXT) << mID << ": Decode Finished. Discard: " << mDecodedDiscard + << " Raw Image: " << llformat("%dx%d",mRawImage->getWidth(),mRawImage->getHeight()) << LL_ENDL; } else { - LL_WARNS() << "DECODE FAILED: " << mID << " Discard: " << (S32)mFormattedImage->getDiscardLevel() << LL_ENDL; + LL_WARNS(LOG_TXT) << "DECODE FAILED: " << mID << " Discard: " << (S32)mFormattedImage->getDiscardLevel() << LL_ENDL; removeFromCache(); mDecodedDiscard = -1; // Redundant, here for clarity and paranoia } mDecoded = TRUE; -// LL_INFOS() << mID << " : DECODE COMPLETE " << LL_ENDL; +// LL_INFOS(LOG_TXT) << mID << " : DECODE COMPLETE " << LL_ENDL; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); mCacheReadTime = mCacheReadTimer.getElapsedTimeF32(); } // -Mw @@ -2583,8 +2588,8 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const { if (worker->mHost != host) { - LL_WARNS() << "LLTextureFetch::createRequest " << id << " called with multiple hosts: " - << host << " != " << worker->mHost << LL_ENDL; + LL_WARNS(LOG_TXT) << "LLTextureFetch::createRequest " << id << " called with multiple hosts: " + << host << " != " << worker->mHost << LL_ENDL; removeRequest(worker, true); worker = NULL; return false; @@ -2601,13 +2606,13 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const llassert(!url.empty() && (!exten.empty() && LLImageBase::getCodecFromExtension(exten) != IMG_CODEC_J2C)); // Do full requests for baked textures to reduce interim blurring. - LL_DEBUGS("Texture") << "full request for " << id << " texture is FTT_SERVER_BAKE" << LL_ENDL; + LL_DEBUGS(LOG_TXT) << "full request for " << id << " texture is FTT_SERVER_BAKE" << LL_ENDL; desired_size = MAX_IMAGE_DATA_SIZE; desired_discard = 0; } else if (!url.empty() && (!exten.empty() && LLImageBase::getCodecFromExtension(exten) != IMG_CODEC_J2C)) { - LL_DEBUGS("Texture") << "full request for " << id << " exten is not J2C: " << exten << LL_ENDL; + LL_DEBUGS(LOG_TXT) << "full request for " << id << " exten is not J2C: " << exten << LL_ENDL; // Only do partial requests for J2C at the moment desired_size = MAX_IMAGE_DATA_SIZE; desired_discard = 0; @@ -2648,7 +2653,9 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const worker->setImagePriority(priority); worker->setDesiredDiscard(desired_discard, desired_size); worker->setCanUseHTTP(can_use_http); - worker->setUrl(url); + + //MAINT-4184 url is always empty. Do not set with it. + if (!worker->haveWork()) { worker->setState(LLTextureFetchWorker::INIT); @@ -2675,8 +2682,8 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const worker->unlockWorkMutex(); // -Mw } - LL_DEBUGS("Texture") << "REQUESTED: " << id << " f_type " << fttype_to_string(f_type) - << " Discard: " << desired_discard << " size " << desired_size << LL_ENDL; + LL_DEBUGS(LOG_TXT) << "REQUESTED: " << id << " f_type " << fttype_to_string(f_type) + << " Discard: " << desired_discard << " size " << desired_size << LL_ENDL; return true; } @@ -2871,7 +2878,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, // Should only happen if we set mDebugPause... if (!mDebugPause) { -// LL_WARNS() << "Adding work for inactive worker: " << id << LL_ENDL; +// LL_WARNS(LOG_TXT) << "Adding work for inactive worker: " << id << LL_ENDL; worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); } } @@ -2888,7 +2895,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, record(sCacheReadLatency, cache_read_time); } res = true; - LL_DEBUGS("Texture") << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL; + LL_DEBUGS(LOG_TXT) << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL; worker->unlockWorkMutex(); // -Mw } else @@ -2993,9 +3000,9 @@ void LLTextureFetch::commonUpdate() LLCore::HttpStatus status = mHttpRequest->update(0); if (! status) { - LL_INFOS_ONCE("Texture") << "Problem during HTTP servicing. Reason: " - << status.toString() - << LL_ENDL; + LL_INFOS_ONCE(LOG_TXT) << "Problem during HTTP servicing. Reason: " + << status.toString() + << LL_ENDL; } } @@ -3075,11 +3082,11 @@ void LLTextureFetch::startThread() // Threads: Ttf void LLTextureFetch::endThread() { - LL_INFOS("Texture") << "CacheReads: " << mTotalCacheReadCount - << ", CacheWrites: " << mTotalCacheWriteCount - << ", ResWaits: " << mTotalResourceWaitCount - << ", TotalHTTPReq: " << getTotalNumHTTPRequests() - << LL_ENDL; + LL_INFOS(LOG_TXT) << "CacheReads: " << mTotalCacheReadCount + << ", CacheWrites: " << mTotalCacheWriteCount + << ", ResWaits: " << mTotalResourceWaitCount + << ", TotalHTTPReq: " << getTotalNumHTTPRequests() + << LL_ENDL; } // Threads: Ttf @@ -3108,7 +3115,7 @@ void LLTextureFetch::threadedUpdate() S32 q = mCurlGetRequest->getQueued(); if (q > 0) { - LL_INFOS() << "Queued gets: " << q << LL_ENDL; + LL_INFOS(LOG_TXT) << "Queued gets: " << q << LL_ENDL; info_timer.reset(); } } @@ -3157,7 +3164,7 @@ void LLTextureFetch::sendRequestListToSimulators() (req->mState != LLTextureFetchWorker::LOAD_FROM_SIMULATOR)) { // We already received our URL, remove from the queue - LL_WARNS() << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << LL_ENDL; + LL_WARNS(LOG_TXT) << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << LL_ENDL; mNetworkQueue.erase(curiter); continue; } @@ -3225,7 +3232,7 @@ void LLTextureFetch::sendRequestListToSimulators() gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, req->mImagePriority); gMessageSystem->addU32Fast(_PREHASH_Packet, packet); gMessageSystem->addU8Fast(_PREHASH_Type, req->mType); -// LL_INFOS() << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard +// LL_INFOS(LOG_TXT) << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard // << " Packet: " << packet << " Priority: " << req->mImagePriority << LL_ENDL; static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false); @@ -3247,7 +3254,7 @@ void LLTextureFetch::sendRequestListToSimulators() sim_request_count++; if (sim_request_count >= IMAGES_PER_REQUEST) { -// LL_INFOS() << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL; +// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL; gMessageSystem->sendSemiReliable(host, NULL, NULL); sim_request_count = 0; @@ -3256,7 +3263,7 @@ void LLTextureFetch::sendRequestListToSimulators() } if (gMessageSystem && sim_request_count > 0 && sim_request_count < IMAGES_PER_REQUEST) { -// LL_INFOS() << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL; +// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL; gMessageSystem->sendSemiReliable(host, NULL, NULL); sim_request_count = 0; } @@ -3292,7 +3299,7 @@ void LLTextureFetch::sendRequestListToSimulators() gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0); gMessageSystem->addU32Fast(_PREHASH_Packet, 0); gMessageSystem->addU8Fast(_PREHASH_Type, 0); -// LL_INFOS() << "CANCELING IMAGE REQUEST: " << (*iter2) << LL_ENDL; +// LL_INFOS(LOG_TXT) << "CANCELING IMAGE REQUEST: " << (*iter2) << LL_ENDL; request_count++; if (request_count >= IMAGES_PER_REQUEST) @@ -3320,12 +3327,12 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size) mRequestedTimer.reset(); if (index >= mTotalPackets) { -// LL_WARNS() << "Received Image Packet " << index << " > max: " << mTotalPackets << " for image: " << mID << LL_ENDL; +// LL_WARNS(LOG_TXT) << "Received Image Packet " << index << " > max: " << mTotalPackets << " for image: " << mID << LL_ENDL; return false; } if (index > 0 && index < mTotalPackets-1 && size != MAX_IMG_PACKET_SIZE) { -// LL_WARNS() << "Received bad sized packet: " << index << ", " << size << " != " << MAX_IMG_PACKET_SIZE << " for image: " << mID << LL_ENDL; +// LL_WARNS(LOG_TXT) << "Received bad sized packet: " << index << ", " << size << " != " << MAX_IMG_PACKET_SIZE << " for image: " << mID << LL_ENDL; return false; } @@ -3335,7 +3342,7 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size) } else if (mPackets[index] != NULL) { -// LL_WARNS() << "Received duplicate packet: " << index << " for image: " << mID << LL_ENDL; +// LL_WARNS(LOG_TXT) << "Received duplicate packet: " << index << " for image: " << mID << LL_ENDL; return false; } @@ -3355,7 +3362,7 @@ void LLTextureFetchWorker::setState(e_state new_state) // blurry images fairly frequently. Presumably this is an // indication of some subtle timing or locking issue. -// LL_INFOS("Texture") << "id: " << mID << " FTType: " << mFTType << " disc: " << mDesiredDiscard << " sz: " << mDesiredSize << " state: " << e_state_name[mState] << " => " << e_state_name[new_state] << LL_ENDL; +// LL_INFOS(LOG_TXT) << "id: " << mID << " FTType: " << mFTType << " disc: " << mDesiredDiscard << " sz: " << mDesiredSize << " state: " << e_state_name[mState] << " => " << e_state_name[new_state] << LL_ENDL; } mState = new_state; } @@ -3371,13 +3378,13 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 if (!worker) { -// LL_WARNS() << "Received header for non active worker: " << id << LL_ENDL; +// LL_WARNS(LOG_TXT) << "Received header for non active worker: " << id << LL_ENDL; res = false; } else if (worker->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK || worker->mSentRequest != LLTextureFetchWorker::SENT_SIM) { -// LL_WARNS() << "receiveImageHeader for worker: " << id +// LL_WARNS(LOG_TXT) << "receiveImageHeader for worker: " << id // << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState] // << " sent: " << worker->mSentRequest << LL_ENDL; res = false; @@ -3385,12 +3392,12 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 else if (worker->mLastPacket != -1) { // check to see if we've gotten this packet before -// LL_WARNS() << "Received duplicate header for: " << id << LL_ENDL; +// LL_WARNS(LOG_TXT) << "Received duplicate header for: " << id << LL_ENDL; res = false; } else if (!data_size) { -// LL_WARNS() << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL; +// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL; res = false; } if (!res) @@ -3432,17 +3439,17 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1 if (!worker) { -// LL_WARNS() << "Received packet " << packet_num << " for non active worker: " << id << LL_ENDL; +// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " for non active worker: " << id << LL_ENDL; res = false; } else if (worker->mLastPacket == -1) { -// LL_WARNS() << "Received packet " << packet_num << " before header for: " << id << LL_ENDL; +// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " before header for: " << id << LL_ENDL; res = false; } else if (!data_size) { -// LL_WARNS() << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL; +// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL; res = false; } if (!res) @@ -3470,7 +3477,7 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1 } else { -// LL_WARNS() << "receiveImagePacket " << packet_num << "/" << worker->mLastPacket << " for worker: " << id +// LL_WARNS(LOG_TXT) << "receiveImagePacket " << packet_num << "/" << worker->mLastPacket << " for worker: " << id // << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState] << LL_ENDL; removeFromNetworkQueue(worker, true); // failsafe } @@ -3563,33 +3570,33 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r void LLTextureFetch::dump() { - LL_INFOS() << "LLTextureFetch REQUESTS:" << LL_ENDL; + LL_INFOS(LOG_TXT) << "LLTextureFetch REQUESTS:" << LL_ENDL; for (request_queue_t::iterator iter = mRequestQueue.begin(); iter != mRequestQueue.end(); ++iter) { LLQueuedThread::QueuedRequest* qreq = *iter; LLWorkerThread::WorkRequest* wreq = (LLWorkerThread::WorkRequest*)qreq; LLTextureFetchWorker* worker = (LLTextureFetchWorker*)wreq->getWorkerClass(); - LL_INFOS() << " ID: " << worker->mID - << " PRI: " << llformat("0x%08x",wreq->getPriority()) - << " STATE: " << worker->sStateDescs[worker->mState] - << LL_ENDL; + LL_INFOS(LOG_TXT) << " ID: " << worker->mID + << " PRI: " << llformat("0x%08x",wreq->getPriority()) + << " STATE: " << worker->sStateDescs[worker->mState] + << LL_ENDL; } - LL_INFOS() << "LLTextureFetch ACTIVE_HTTP:" << LL_ENDL; + LL_INFOS(LOG_TXT) << "LLTextureFetch ACTIVE_HTTP:" << LL_ENDL; for (queue_t::const_iterator iter(mHTTPTextureQueue.begin()); mHTTPTextureQueue.end() != iter; ++iter) { - LL_INFOS() << " ID: " << (*iter) << LL_ENDL; + LL_INFOS(LOG_TXT) << " ID: " << (*iter) << LL_ENDL; } - LL_INFOS() << "LLTextureFetch WAIT_HTTP_RESOURCE:" << LL_ENDL; + LL_INFOS(LOG_TXT) << "LLTextureFetch WAIT_HTTP_RESOURCE:" << LL_ENDL; for (wait_http_res_queue_t::const_iterator iter(mHttpWaitResource.begin()); mHttpWaitResource.end() != iter; ++iter) { - LL_INFOS() << " ID: " << (*iter) << LL_ENDL; + LL_INFOS(LOG_TXT) << " ID: " << (*iter) << LL_ENDL; } } @@ -3714,10 +3721,10 @@ void LLTextureFetch::releaseHttpWaiters() { // Not in expected state, remove it, try the next one worker->unlockWorkMutex(); // -Mw - LL_WARNS("Texture") << "Resource-waited texture " << worker->mID - << " in unexpected state: " << worker->mState - << ". Removing from wait list." - << LL_ENDL; + LL_WARNS(LOG_TXT) << "Resource-waited texture " << worker->mID + << " in unexpected state: " << worker->mState + << ". Removing from wait list." + << LL_ENDL; removeHttpWaiter(worker->mID); continue; } @@ -3884,14 +3891,14 @@ public: if (status) { - LL_DEBUGS("Texture") << "Successfully delivered asset metrics to grid." - << LL_ENDL; + LL_DEBUGS(LOG_TXT) << "Successfully delivered asset metrics to grid." + << LL_ENDL; } else { - LL_WARNS("Texture") << "Error delivering asset metrics to grid. Status: " - << status.toTerseString() - << ", Reason: " << status.toString() << LL_ENDL; + LL_WARNS(LOG_TXT) << "Error delivering asset metrics to grid. Status: " + << status.toTerseString() + << ", Reason: " << status.toString() << LL_ENDL; } } }; // end class AssetReportHandler @@ -4502,14 +4509,14 @@ void LLTextureFetchDebugger::debugHTTP() LLViewerRegion* region = gAgent.getRegion(); if (!region) { - LL_INFOS() << "Fetch Debugger : Current region undefined. Cannot fetch textures through HTTP." << LL_ENDL; + LL_INFOS(LOG_TXT) << "Fetch Debugger : Current region undefined. Cannot fetch textures through HTTP." << LL_ENDL; return; } mHTTPUrl = region->getHttpUrl(); if (mHTTPUrl.empty()) { - LL_INFOS() << "Fetch Debugger : Current region URL undefined. Cannot fetch textures through HTTP." << LL_ENDL; + LL_INFOS(LOG_TXT) << "Fetch Debugger : Current region URL undefined. Cannot fetch textures through HTTP." << LL_ENDL; return; } @@ -4580,15 +4587,15 @@ S32 LLTextureFetchDebugger::fillCurlQueue() // Failed to queue request, log it and mark it done. LLCore::HttpStatus status(mFetcher->getHttpRequest().getStatus()); - LL_WARNS("Texture") << "Couldn't issue HTTP request in debugger for texture " - << mFetchingHistory[i].mID - << ", status: " << status.toTerseString() - << " reason: " << status.toString() - << LL_ENDL; + LL_WARNS(LOG_TXT) << "Couldn't issue HTTP request in debugger for texture " + << mFetchingHistory[i].mID + << ", status: " << status.toTerseString() + << " reason: " << status.toString() + << LL_ENDL; mFetchingHistory[i].mCurlState = FetchEntry::CURL_DONE; } } - //LL_INFOS() << "Fetch Debugger : Having " << mNbCurlRequests << " requests through the curl thread." << LL_ENDL; + //LL_INFOS(LOG_TXT) << "Fetch Debugger : Having " << mNbCurlRequests << " requests through the curl thread." << LL_ENDL; return mNbCurlRequests; } @@ -4890,7 +4897,7 @@ void LLTextureFetchDebugger::onCompleted(LLCore::HttpHandle handle, LLCore::Http handle_fetch_map_t::iterator iter(mHandleToFetchIndex.find(handle)); if (mHandleToFetchIndex.end() == iter) { - LL_INFOS() << "Fetch Debugger : Couldn't find handle " << handle << " in fetch list." << LL_ENDL; + LL_INFOS(LOG_TXT) << "Fetch Debugger : Couldn't find handle " << handle << " in fetch list." << LL_ENDL; return; } @@ -4898,7 +4905,7 @@ void LLTextureFetchDebugger::onCompleted(LLCore::HttpHandle handle, LLCore::Http mHandleToFetchIndex.erase(iter); if (fetch_ind >= mFetchingHistory.size() || mFetchingHistory[fetch_ind].mHttpHandle != handle) { - LL_INFOS() << "Fetch Debugger : Handle and fetch object in disagreement. Punting." << LL_ENDL; + LL_INFOS(LOG_TXT) << "Fetch Debugger : Handle and fetch object in disagreement. Punting." << LL_ENDL; } else { @@ -4948,7 +4955,7 @@ void LLTextureFetchDebugger::callbackHTTP(FetchEntry & fetch, LLCore::HttpRespon S32 data_size = ba ? ba->size() : 0; fetch.mCurlReceivedSize += data_size; - //LL_INFOS() << "Fetch Debugger : got results for " << fetch.mID << ", data_size = " << data_size << ", received = " << fetch.mCurlReceivedSize << ", requested = " << fetch.mRequestedSize << ", partial = " << partial << LL_ENDL; + //LL_INFOS(LOG_TXT) << "Fetch Debugger : got results for " << fetch.mID << ", data_size = " << data_size << ", received = " << fetch.mCurlReceivedSize << ", requested = " << fetch.mRequestedSize << ", partial = " << partial << LL_ENDL; if ((fetch.mCurlReceivedSize >= fetch.mRequestedSize) || !partial || (fetch.mRequestedSize == 600)) { U8* d_buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size); @@ -4974,9 +4981,9 @@ void LLTextureFetchDebugger::callbackHTTP(FetchEntry & fetch, LLCore::HttpRespon } else //failed { - LL_INFOS() << "Fetch Debugger : CURL GET FAILED, ID = " << fetch.mID - << ", status: " << status.toTerseString() - << " reason: " << status.toString() << LL_ENDL; + LL_INFOS(LOG_TXT) << "Fetch Debugger : CURL GET FAILED, ID = " << fetch.mID + << ", status: " << status.toTerseString() + << " reason: " << status.toString() << LL_ENDL; } } diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index aa1f680a1e..4f0413a2e4 100755 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -563,7 +563,7 @@ void LLGLTexMemBar::draw() //---------------------------------------------------------------------------- - text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d RAW:%d HTP:%d DEC:%d CRE:%d", + text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d RAW:%d HTP:%d DEC:%d CRE:%d ", gTextureList.getNumImages(), LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(), LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount, @@ -585,7 +585,7 @@ void LLGLTexMemBar::draw() color = bandwidth > max_bandwidth ? LLColor4::red : bandwidth > max_bandwidth*.75f ? LLColor4::yellow : text_color; color[VALPHA] = text_color[VALPHA]; text = llformat("BW:%.0f/%.0f",bandwidth.value(), max_bandwidth.value()); - LLFontGL::getFontMonospace()->renderUTF8(text, 0, x_right, v_offset + line_height*2, + LLFontGL::getFontMonospace()->renderUTF8(text, 0, x_right, v_offset + line_height*3, color, LLFontGL::LEFT, LLFontGL::TOP); // Mesh status line diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 9d5c3c4d4a..332d04a1f4 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -5747,83 +5747,101 @@ bool handle_special_notification(std::string notificationID, LLSD& llsdBlock) } // some of the server notifications need special handling. This is where we do that. -bool handle_teleport_access_blocked(LLSD& llsdBlock) +bool handle_teleport_access_blocked(LLSD& llsdBlock, const std::string & notificationID, const std::string & defaultMessage) { - std::string notificationID("TeleportEntryAccessBlocked"); U8 regionAccess = static_cast<U8>(llsdBlock["_region_access"].asInteger()); std::string regionMaturity = LLViewerRegion::accessToString(regionAccess); LLStringUtil::toLower(regionMaturity); llsdBlock["REGIONMATURITY"] = regionMaturity; bool returnValue = false; - LLNotificationPtr maturityLevelNotification; - std::string notifySuffix = "_Notify"; - if (regionAccess == SIM_ACCESS_MATURE) - { - if (gAgent.isTeen()) - { - gAgent.clearTeleportRequest(); - maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); - returnValue = true; + LLNotificationPtr tp_failure_notification; + std::string notifySuffix; - notifySuffix = "_NotifyAdultsOnly"; - } - else if (gAgent.prefersPG()) + if (notificationID == std::string("TeleportEntryAccessBlocked")) + { + notifySuffix = "_Notify"; + if (regionAccess == SIM_ACCESS_MATURE) { - if (gAgent.hasRestartableFailedTeleportRequest()) + if (gAgent.isTeen()) { - maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback); + gAgent.clearTeleportRequest(); + tp_failure_notification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; + } + else if (gAgent.prefersPG()) + { + if (gAgent.hasRestartableFailedTeleportRequest()) + { + tp_failure_notification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback); + returnValue = true; + } + else + { + gAgent.clearTeleportRequest(); + tp_failure_notification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } } else { gAgent.clearTeleportRequest(); - maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + tp_failure_notification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); returnValue = true; } } - else - { - gAgent.clearTeleportRequest(); - maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); - returnValue = true; - } - } - else if (regionAccess == SIM_ACCESS_ADULT) - { - if (!gAgent.isAdult()) - { - gAgent.clearTeleportRequest(); - maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); - returnValue = true; - - notifySuffix = "_NotifyAdultsOnly"; - } - else if (gAgent.prefersPG() || gAgent.prefersMature()) + else if (regionAccess == SIM_ACCESS_ADULT) { - if (gAgent.hasRestartableFailedTeleportRequest()) + if (!gAgent.isAdult()) { - maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback); + gAgent.clearTeleportRequest(); + tp_failure_notification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; + } + else if (gAgent.prefersPG() || gAgent.prefersMature()) + { + if (gAgent.hasRestartableFailedTeleportRequest()) + { + tp_failure_notification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback); + returnValue = true; + } + else + { + gAgent.clearTeleportRequest(); + tp_failure_notification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } } else { gAgent.clearTeleportRequest(); - maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + tp_failure_notification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); returnValue = true; } } - else + } // End of special handling for "TeleportEntryAccessBlocked" + else + { // Normal case, no message munging + gAgent.clearTeleportRequest(); + if (LLNotifications::getInstance()->templateExists(notificationID)) { - gAgent.clearTeleportRequest(); - maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); - returnValue = true; + tp_failure_notification = LLNotificationsUtil::add(notificationID, llsdBlock, llsdBlock); } + else + { + llsdBlock["MESSAGE"] = defaultMessage; + tp_failure_notification = LLNotificationsUtil::add("GenericAlertOK", llsdBlock); } + returnValue = true; + } - if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored()) + if ((tp_failure_notification == NULL) || tp_failure_notification->isIgnored()) { - // Given a simple notification if no maturityLevelNotification is set or it is ignore + // Given a simple notification if no tp_failure_notification is set or it is ignore LLNotificationsUtil::add(notificationID + notifySuffix, llsdBlock); } @@ -6039,8 +6057,8 @@ void process_alert_core(const std::string& message, BOOL modal) std::string alert_name(message.substr(ALERT_PREFIX.length())); if (!handle_special_alerts(alert_name)) { - LLNotificationsUtil::add(alert_name); - } + LLNotificationsUtil::add(alert_name); + } } else if (message.find(NOTIFY_PREFIX) == 0) { @@ -6062,10 +6080,10 @@ void process_alert_core(const std::string& message, BOOL modal) LLFloaterRegionRestarting::close(); } - std::string new_msg =LLNotifications::instance().getGlobalString(text); - args["MESSAGE"] = new_msg; - LLNotificationsUtil::add("SystemMessage", args); - } + std::string new_msg =LLNotifications::instance().getGlobalString(text); + args["MESSAGE"] = new_msg; + LLNotificationsUtil::add("SystemMessage", args); + } else if (modal) { LLSD args; @@ -6648,8 +6666,8 @@ std::string formatted_time(const time_t& the_time) void process_teleport_failed(LLMessageSystem *msg, void**) { - std::string reason; - std::string big_reason; + std::string message_id; // Tag from server, like "RegionEntryAccessBlocked" + std::string big_reason; // Actual message to display LLSD args; // Let the interested parties know that teleport failed. @@ -6659,16 +6677,16 @@ void process_teleport_failed(LLMessageSystem *msg, void**) if (msg->has(_PREHASH_AlertInfo) && msg->getSizeFast(_PREHASH_AlertInfo, _PREHASH_Message) > 0) { // Get the message ID - msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, reason); - big_reason = LLAgent::sTeleportErrorMessages[reason]; + msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, message_id); + big_reason = LLAgent::sTeleportErrorMessages[message_id]; if ( big_reason.size() > 0 ) { // Substitute verbose reason from the local map args["REASON"] = big_reason; } else { // Nothing found in the map - use what the server returned in the original message block - msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason); - args["REASON"] = reason; + msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, big_reason); + args["REASON"] = big_reason; } LLSD llsd_block; @@ -6684,7 +6702,7 @@ void process_teleport_failed(LLMessageSystem *msg, void**) else { // change notification name in this special case - if (handle_teleport_access_blocked(llsd_block)) + if (handle_teleport_access_blocked(llsd_block, message_id, args["REASON"])) { if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE ) { @@ -6697,17 +6715,17 @@ void process_teleport_failed(LLMessageSystem *msg, void**) } else - { - msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason); + { // Extra message payload not found - use what the simulator sent + msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, message_id); - big_reason = LLAgent::sTeleportErrorMessages[reason]; + big_reason = LLAgent::sTeleportErrorMessages[message_id]; if ( big_reason.size() > 0 ) { // Substitute verbose reason from the local map args["REASON"] = big_reason; } else { // Nothing found in the map - use what the server returned - args["REASON"] = reason; + args["REASON"] = message_id; } } diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 673913c4f2..11cbf3fc24 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -285,8 +285,8 @@ private: { regionp->setCapability(iter->first, iter->second); - LL_DEBUGS("AppInit", "Capabilities") << "got capability for " - << iter->first << LL_ENDL; + LL_DEBUGS("AppInit", "Capabilities") + << "Capability '" << iter->first << "' is '" << iter->second << "'" << LL_ENDL; /* HACK we're waiting for the ServerReleaseNotes */ if (iter->first == "ServerReleaseNotes" && regionp->getReleaseNotesRequested()) @@ -2708,6 +2708,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("GetObjectCost"); capabilityNames.append("GetObjectPhysicsData"); capabilityNames.append("GetTexture"); + capabilityNames.append("GroupAPIv1"); capabilityNames.append("GroupMemberData"); capabilityNames.append("GroupProposalBallot"); capabilityNames.append("HomeLocation"); diff --git a/indra/newview/roles_constants.h b/indra/newview/roles_constants.h index effd15ea72..8fd7978fa1 100755..100644 --- a/indra/newview/roles_constants.h +++ b/indra/newview/roles_constants.h @@ -53,98 +53,100 @@ enum LLRoleChangeType // KNOWN HOLES: use these for any single bit powers you need // bit 0x1 << 46 -// bit 0x1 << 49 and above +// bit 0x1 << 52 and above // These powers were removed to make group roles simpler // bit 0x1 << 41 (GP_ACCOUNTING_VIEW) // bit 0x1 << 46 (GP_PROPOSAL_VIEW) const U64 GP_NO_POWERS = 0x0; -const U64 GP_ALL_POWERS = 0xFFFFFFFFFFFFFFFFLL; +const U64 GP_ALL_POWERS = 0xFFFFffffFFFFffffLL; // Membership -const U64 GP_MEMBER_INVITE = 0x1 << 1; // Invite member -const U64 GP_MEMBER_EJECT = 0x1 << 2; // Eject member from group -const U64 GP_MEMBER_OPTIONS = 0x1 << 3; // Toggle "Open enrollment" and change "Signup Fee" -const U64 GP_MEMBER_VISIBLE_IN_DIR = 0x1LL << 47; +const U64 GP_MEMBER_INVITE = 0x1LL << 1; // Invite member +const U64 GP_MEMBER_EJECT = 0x1LL << 2; // Eject member from group +const U64 GP_MEMBER_OPTIONS = 0x1LL << 3; // Toggle "Open enrollment" and change "Signup Fee" +const U64 GP_MEMBER_VISIBLE_IN_DIR = 0x1LL << 47; // Roles -const U64 GP_ROLE_CREATE = 0x1 << 4; // Create new roles -const U64 GP_ROLE_DELETE = 0x1 << 5; // Delete roles -const U64 GP_ROLE_PROPERTIES = 0x1 << 6; // Change Role Names, Titles, and Descriptions (Of roles the user is in, only, or any role in group?) -const U64 GP_ROLE_ASSIGN_MEMBER_LIMITED = 0x1 << 7; // Assign Member to a Role that the assigner is in -const U64 GP_ROLE_ASSIGN_MEMBER = 0x1 << 8; // Assign Member to Role -const U64 GP_ROLE_REMOVE_MEMBER = 0x1 << 9; // Remove Member from Role -const U64 GP_ROLE_CHANGE_ACTIONS = 0x1 << 10; // Change actions a role can perform +const U64 GP_ROLE_CREATE = 0x1LL << 4; // Create new roles +const U64 GP_ROLE_DELETE = 0x1LL << 5; // Delete roles +const U64 GP_ROLE_PROPERTIES = 0x1LL << 6; // Change Role Names, Titles, and Descriptions (Of roles the user is in, only, or any role in group?) +const U64 GP_ROLE_ASSIGN_MEMBER_LIMITED = 0x1LL << 7; // Assign Member to a Role that the assigner is in +const U64 GP_ROLE_ASSIGN_MEMBER = 0x1LL << 8; // Assign Member to Role +const U64 GP_ROLE_REMOVE_MEMBER = 0x1LL << 9; // Remove Member from Role +const U64 GP_ROLE_CHANGE_ACTIONS = 0x1LL << 10; // Change actions a role can perform // Group Identity -const U64 GP_GROUP_CHANGE_IDENTITY = 0x1 << 11; // Charter, insignia, 'Show In Group List', 'Publish on the web', 'Mature', all 'Show Member In Group Profile' checkboxes +const U64 GP_GROUP_CHANGE_IDENTITY = 0x1LL << 11; // Charter, insignia, 'Show In Group List', 'Publish on the web', 'Mature', all 'Show Member In Group Profile' checkboxes // Parcel Management -const U64 GP_LAND_DEED = 0x1 << 12; // Deed Land and Buy Land for Group -const U64 GP_LAND_RELEASE = 0x1 << 13; // Release Land (to Gov. Linden) -const U64 GP_LAND_SET_SALE_INFO = 0x1 << 14; // Set for sale info (Toggle "For Sale", Set Price, Set Target, Toggle "Sell objects with the land") -const U64 GP_LAND_DIVIDE_JOIN = 0x1 << 15; // Divide and Join Parcels +const U64 GP_LAND_DEED = 0x1LL << 12; // Deed Land and Buy Land for Group +const U64 GP_LAND_RELEASE = 0x1LL << 13; // Release Land (to Gov. Linden) +const U64 GP_LAND_SET_SALE_INFO = 0x1LL << 14; // Set for sale info (Toggle "For Sale", Set Price, Set Target, Toggle "Sell objects with the land") +const U64 GP_LAND_DIVIDE_JOIN = 0x1LL << 15; // Divide and Join Parcels // Parcel Identity -const U64 GP_LAND_FIND_PLACES = 0x1 << 17; // Toggle "Show in Find Places" and Set Category. -const U64 GP_LAND_CHANGE_IDENTITY = 0x1 << 18; // Change Parcel Identity: Parcel Name, Parcel Description, Snapshot, 'Publish on the web', and 'Mature' checkbox -const U64 GP_LAND_SET_LANDING_POINT = 0x1 << 19; // Set Landing Point +const U64 GP_LAND_FIND_PLACES = 0x1LL << 17; // Toggle "Show in Find Places" and Set Category. +const U64 GP_LAND_CHANGE_IDENTITY = 0x1LL << 18; // Change Parcel Identity: Parcel Name, Parcel Description, Snapshot, 'Publish on the web', and 'Mature' checkbox +const U64 GP_LAND_SET_LANDING_POINT = 0x1LL << 19; // Set Landing Point // Parcel Settings -const U64 GP_LAND_CHANGE_MEDIA = 0x1 << 20; // Change Media Settings -const U64 GP_LAND_EDIT = 0x1 << 21; // Toggle Edit Land -const U64 GP_LAND_OPTIONS = 0x1 << 22; // Toggle Set Home Point, Fly, Outside Scripts, Create/Edit Objects, Landmark, and Damage checkboxes +const U64 GP_LAND_CHANGE_MEDIA = 0x1LL << 20; // Change Media Settings +const U64 GP_LAND_EDIT = 0x1LL << 21; // Toggle Edit Land +const U64 GP_LAND_OPTIONS = 0x1LL << 22; // Toggle Set Home Point, Fly, Outside Scripts, Create/Edit Objects, Landmark, and Damage checkboxes // Parcel Powers -const U64 GP_LAND_ALLOW_EDIT_LAND = 0x1 << 23; // Bypass Edit Land Restriction -const U64 GP_LAND_ALLOW_FLY = 0x1 << 24; // Bypass Fly Restriction -const U64 GP_LAND_ALLOW_CREATE = 0x1 << 25; // Bypass Create/Edit Objects Restriction -const U64 GP_LAND_ALLOW_LANDMARK = 0x1 << 26; // Bypass Landmark Restriction -const U64 GP_LAND_ALLOW_SET_HOME = 0x1 << 28; // Bypass Set Home Point Restriction -const U64 GP_LAND_ALLOW_HOLD_EVENT = 0x1LL << 41; // Allowed to hold events on group-owned land - +const U64 GP_LAND_ALLOW_EDIT_LAND = 0x1LL << 23; // Bypass Edit Land Restriction +const U64 GP_LAND_ALLOW_FLY = 0x1LL << 24; // Bypass Fly Restriction +const U64 GP_LAND_ALLOW_CREATE = 0x1LL << 25; // Bypass Create/Edit Objects Restriction +const U64 GP_LAND_ALLOW_LANDMARK = 0x1LL << 26; // Bypass Landmark Restriction +const U64 GP_LAND_ALLOW_SET_HOME = 0x1LL << 28; // Bypass Set Home Point Restriction +const U64 GP_LAND_ALLOW_HOLD_EVENT = 0x1LL << 41; // Allowed to hold events on group-owned land // Parcel Access -const U64 GP_LAND_MANAGE_ALLOWED = 0x1 << 29; // Manage Allowed List -const U64 GP_LAND_MANAGE_BANNED = 0x1 << 30; // Manage Banned List -const U64 GP_LAND_MANAGE_PASSES = 0x1LL << 31; // Change Sell Pass Settings -const U64 GP_LAND_ADMIN = 0x1LL << 32; // Eject and Freeze Users on the land +const U64 GP_LAND_MANAGE_ALLOWED = 0x1LL << 29; // Manage Allowed List +const U64 GP_LAND_MANAGE_BANNED = 0x1LL << 30; // Manage Banned List +const U64 GP_LAND_MANAGE_PASSES = 0x1LL << 31; // Change Sell Pass Settings +const U64 GP_LAND_ADMIN = 0x1LL << 32; // Eject and Freeze Users on the land // Parcel Content -const U64 GP_LAND_RETURN_GROUP_SET = 0x1LL << 33; // Return objects on parcel that are set to group -const U64 GP_LAND_RETURN_NON_GROUP = 0x1LL << 34; // Return objects on parcel that are not set to group -const U64 GP_LAND_RETURN_GROUP_OWNED= 0x1LL << 48; // Return objects on parcel that are owned by the group +const U64 GP_LAND_RETURN_GROUP_SET = 0x1LL << 33; // Return objects on parcel that are set to group +const U64 GP_LAND_RETURN_NON_GROUP = 0x1LL << 34; // Return objects on parcel that are not set to group +const U64 GP_LAND_RETURN_GROUP_OWNED = 0x1LL << 48; // Return objects on parcel that are owned by the group // Select a power-bit based on an object's relationship to a parcel. const U64 GP_LAND_RETURN = GP_LAND_RETURN_GROUP_OWNED | GP_LAND_RETURN_GROUP_SET | GP_LAND_RETURN_NON_GROUP; -const U64 GP_LAND_GARDENING = 0x1LL << 35; // Parcel Gardening - plant and move linden trees +const U64 GP_LAND_GARDENING = 0x1LL << 35; // Parcel Gardening - plant and move linden trees // Object Management -const U64 GP_OBJECT_DEED = 0x1LL << 36; // Deed Object -const U64 GP_OBJECT_MANIPULATE = 0x1LL << 38; // Manipulate Group Owned Objects (Move, Copy, Mod) -const U64 GP_OBJECT_SET_SALE = 0x1LL << 39; // Set Group Owned Object for Sale +const U64 GP_OBJECT_DEED = 0x1LL << 36; // Deed Object +const U64 GP_OBJECT_MANIPULATE = 0x1LL << 38; // Manipulate Group Owned Objects (Move, Copy, Mod) +const U64 GP_OBJECT_SET_SALE = 0x1LL << 39; // Set Group Owned Object for Sale // Accounting -const U64 GP_ACCOUNTING_ACCOUNTABLE = 0x1LL << 40; // Pay Group Liabilities and Receive Group Dividends +const U64 GP_ACCOUNTING_ACCOUNTABLE = 0x1LL << 40; // Pay Group Liabilities and Receive Group Dividends // Notices -const U64 GP_NOTICES_SEND = 0x1LL << 42; // Send Notices -const U64 GP_NOTICES_RECEIVE = 0x1LL << 43; // Receive Notices and View Notice History +const U64 GP_NOTICES_SEND = 0x1LL << 42; // Send Notices +const U64 GP_NOTICES_RECEIVE = 0x1LL << 43; // Receive Notices and View Notice History // Proposals // TODO: _DEPRECATED suffix as part of vote removal - DEV-24856: -const U64 GP_PROPOSAL_START = 0x1LL << 44; // Start Proposal +const U64 GP_PROPOSAL_START = 0x1LL << 44; // Start Proposal // TODO: _DEPRECATED suffix as part of vote removal - DEV-24856: -const U64 GP_PROPOSAL_VOTE = 0x1LL << 45; // Vote on Proposal +const U64 GP_PROPOSAL_VOTE = 0x1LL << 45; // Vote on Proposal // Group chat moderation related -const U64 GP_SESSION_JOIN = 0x1LL << 16; //can join session -const U64 GP_SESSION_VOICE = 0x1LL << 27; //can hear/talk -const U64 GP_SESSION_MODERATOR = 0x1LL << 37; //can mute people's session +const U64 GP_SESSION_JOIN = 0x1LL << 16; //can join session +const U64 GP_SESSION_VOICE = 0x1LL << 27; //can hear/talk +const U64 GP_SESSION_MODERATOR = 0x1LL << 37; //can mute people's session + +// Group Banning +const U64 GP_GROUP_BAN_ACCESS = 0x1LL << 51; // Allows access to ban / un-ban agents from a group. const U64 GP_DEFAULT_MEMBER = GP_ACCOUNTING_ACCOUNTABLE | GP_LAND_ALLOW_SET_HOME diff --git a/indra/newview/skins/default/textures/bottomtray/ChatBarHandle.png b/indra/newview/skins/default/textures/bottomtray/ChatBarHandle.png Binary files differindex 8b58db0cba..50239c8af8 100755 --- a/indra/newview/skins/default/textures/bottomtray/ChatBarHandle.png +++ b/indra/newview/skins/default/textures/bottomtray/ChatBarHandle.png diff --git a/indra/newview/skins/default/textures/bottomtray/Move_Fly_Off.png b/indra/newview/skins/default/textures/bottomtray/Move_Fly_Off.png Binary files differindex 9e7291d6fb..fade065ce7 100755 --- a/indra/newview/skins/default/textures/bottomtray/Move_Fly_Off.png +++ b/indra/newview/skins/default/textures/bottomtray/Move_Fly_Off.png diff --git a/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png b/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png Binary files differindex 0ac5b72b8f..eb2f3dbaa4 100755 --- a/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png +++ b/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png diff --git a/indra/newview/skins/default/textures/bottomtray/Snapshot_Off.png b/indra/newview/skins/default/textures/bottomtray/Snapshot_Off.png Binary files differindex d7ec04237b..4ab4bbe4af 100755 --- a/indra/newview/skins/default/textures/bottomtray/Snapshot_Off.png +++ b/indra/newview/skins/default/textures/bottomtray/Snapshot_Off.png diff --git a/indra/newview/skins/default/textures/down_arrow.png b/indra/newview/skins/default/textures/down_arrow.png Binary files differindex 155f80c97e..21a0fc5ec0 100755 --- a/indra/newview/skins/default/textures/down_arrow.png +++ b/indra/newview/skins/default/textures/down_arrow.png diff --git a/indra/newview/skins/default/textures/icons/Edit_Wrench.png b/indra/newview/skins/default/textures/icons/Edit_Wrench.png Binary files differindex edb40b9c96..42f8466969 100755 --- a/indra/newview/skins/default/textures/icons/Edit_Wrench.png +++ b/indra/newview/skins/default/textures/icons/Edit_Wrench.png diff --git a/indra/newview/skins/default/textures/icons/Generic_Group_Large.png b/indra/newview/skins/default/textures/icons/Generic_Group_Large.png Binary files differindex 75833eccf3..46ee6dfe2c 100755 --- a/indra/newview/skins/default/textures/icons/Generic_Group_Large.png +++ b/indra/newview/skins/default/textures/icons/Generic_Group_Large.png diff --git a/indra/newview/skins/default/textures/icons/Generic_Person.png b/indra/newview/skins/default/textures/icons/Generic_Person.png Binary files differindex 45b491ab59..e1411354af 100755 --- a/indra/newview/skins/default/textures/icons/Generic_Person.png +++ b/indra/newview/skins/default/textures/icons/Generic_Person.png diff --git a/indra/newview/skins/default/textures/icons/Hierarchy_View_On.png b/indra/newview/skins/default/textures/icons/Hierarchy_View_On.png Binary files differindex 296311e797..ae8c8b4c1a 100755 --- a/indra/newview/skins/default/textures/icons/Hierarchy_View_On.png +++ b/indra/newview/skins/default/textures/icons/Hierarchy_View_On.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Link.png b/indra/newview/skins/default/textures/icons/Inv_Link.png Binary files differindex c1543dacb5..26bf4086fb 100755 --- a/indra/newview/skins/default/textures/icons/Inv_Link.png +++ b/indra/newview/skins/default/textures/icons/Inv_Link.png diff --git a/indra/newview/skins/default/textures/icons/Inv_LostClosed.png b/indra/newview/skins/default/textures/icons/Inv_LostClosed.png Binary files differindex a800217e0d..42b5c88fdd 100755 --- a/indra/newview/skins/default/textures/icons/Inv_LostClosed.png +++ b/indra/newview/skins/default/textures/icons/Inv_LostClosed.png diff --git a/indra/newview/skins/default/textures/icons/Inv_LostOpen.png b/indra/newview/skins/default/textures/icons/Inv_LostOpen.png Binary files differindex 8c4a1a9ac0..a52168d6c7 100755 --- a/indra/newview/skins/default/textures/icons/Inv_LostOpen.png +++ b/indra/newview/skins/default/textures/icons/Inv_LostOpen.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Mesh.png b/indra/newview/skins/default/textures/icons/Inv_Mesh.png Binary files differindex f1f21f7941..77e52264c3 100755 --- a/indra/newview/skins/default/textures/icons/Inv_Mesh.png +++ b/indra/newview/skins/default/textures/icons/Inv_Mesh.png diff --git a/indra/newview/skins/default/textures/icons/Inv_SysClosed.png b/indra/newview/skins/default/textures/icons/Inv_SysClosed.png Binary files differindex dcf998449f..57eafc4047 100755 --- a/indra/newview/skins/default/textures/icons/Inv_SysClosed.png +++ b/indra/newview/skins/default/textures/icons/Inv_SysClosed.png diff --git a/indra/newview/skins/default/textures/icons/Inv_SysOpen.png b/indra/newview/skins/default/textures/icons/Inv_SysOpen.png Binary files differindex 0efd403c95..b080688e55 100755 --- a/indra/newview/skins/default/textures/icons/Inv_SysOpen.png +++ b/indra/newview/skins/default/textures/icons/Inv_SysOpen.png diff --git a/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png b/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png Binary files differindex c5201e6f9a..7a958c1ec0 100755 --- a/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png +++ b/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png diff --git a/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png b/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png Binary files differindex 4a886a3f37..11e6bf33bc 100755 --- a/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png +++ b/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png diff --git a/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Dark.png Binary files differindex e0b18b2451..af65873cb6 100755 --- a/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Dark.png +++ b/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Dark.png diff --git a/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Light.png b/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Light.png Binary files differindex 101aaa42b1..6ceb9d3d8f 100755 --- a/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Light.png +++ b/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Light.png diff --git a/indra/newview/skins/default/textures/icons/Parcel_Fly_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_Fly_Dark.png Binary files differindex c27f18e3c7..7084e2f591 100755 --- a/indra/newview/skins/default/textures/icons/Parcel_Fly_Dark.png +++ b/indra/newview/skins/default/textures/icons/Parcel_Fly_Dark.png diff --git a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Dark.png Binary files differindex 956e02b14d..60d056b573 100755 --- a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Dark.png +++ b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Dark.png diff --git a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Light.png b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Light.png Binary files differindex 434caeda8b..d004b0f750 100755 --- a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Light.png +++ b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Light.png diff --git a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Dark.png Binary files differindex 064687ed0f..eed28765f7 100755 --- a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Dark.png +++ b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Dark.png diff --git a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Light.png b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Light.png Binary files differindex 5465650d0c..e35de3c2fa 100755 --- a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Light.png +++ b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Light.png diff --git a/indra/newview/skins/default/textures/icons/Person_Check.png b/indra/newview/skins/default/textures/icons/Person_Check.png Binary files differindex f8638540d4..d40eafe793 100755 --- a/indra/newview/skins/default/textures/icons/Person_Check.png +++ b/indra/newview/skins/default/textures/icons/Person_Check.png diff --git a/indra/newview/skins/default/textures/icons/Person_Star.png b/indra/newview/skins/default/textures/icons/Person_Star.png Binary files differindex ad10580ac4..e02935672f 100755 --- a/indra/newview/skins/default/textures/icons/Person_Star.png +++ b/indra/newview/skins/default/textures/icons/Person_Star.png diff --git a/indra/newview/skins/default/textures/icons/SL_Logo.png b/indra/newview/skins/default/textures/icons/SL_Logo.png Binary files differindex 8342d7cfee..5e376c72f9 100755 --- a/indra/newview/skins/default/textures/icons/SL_Logo.png +++ b/indra/newview/skins/default/textures/icons/SL_Logo.png diff --git a/indra/newview/skins/default/textures/icons/Shop.png b/indra/newview/skins/default/textures/icons/Shop.png Binary files differindex 81c13eeabd..8977c49195 100755 --- a/indra/newview/skins/default/textures/icons/Shop.png +++ b/indra/newview/skins/default/textures/icons/Shop.png diff --git a/indra/newview/skins/default/textures/icons/Web_Profile_Off.png b/indra/newview/skins/default/textures/icons/Web_Profile_Off.png Binary files differindex f5fb774a6f..5716dd6d22 100755 --- a/indra/newview/skins/default/textures/icons/Web_Profile_Off.png +++ b/indra/newview/skins/default/textures/icons/Web_Profile_Off.png diff --git a/indra/newview/skins/default/textures/icons/back_arrow_off.png b/indra/newview/skins/default/textures/icons/back_arrow_off.png Binary files differindex 422f67cf83..e7cea49d73 100755 --- a/indra/newview/skins/default/textures/icons/back_arrow_off.png +++ b/indra/newview/skins/default/textures/icons/back_arrow_off.png diff --git a/indra/newview/skins/default/textures/icons/back_arrow_over.png b/indra/newview/skins/default/textures/icons/back_arrow_over.png Binary files differindex b4cc170f37..4e5a93a25f 100755 --- a/indra/newview/skins/default/textures/icons/back_arrow_over.png +++ b/indra/newview/skins/default/textures/icons/back_arrow_over.png diff --git a/indra/newview/skins/default/textures/icons/back_arrow_press.png b/indra/newview/skins/default/textures/icons/back_arrow_press.png Binary files differindex a9e2f326a7..289b8c20e6 100755 --- a/indra/newview/skins/default/textures/icons/back_arrow_press.png +++ b/indra/newview/skins/default/textures/icons/back_arrow_press.png diff --git a/indra/newview/skins/default/textures/icons/check_mark.png b/indra/newview/skins/default/textures/icons/check_mark.png Binary files differindex 2c05297f4f..4d927cb29e 100755 --- a/indra/newview/skins/default/textures/icons/check_mark.png +++ b/indra/newview/skins/default/textures/icons/check_mark.png diff --git a/indra/newview/skins/default/textures/icons/pop_up_caution.png b/indra/newview/skins/default/textures/icons/pop_up_caution.png Binary files differindex 78b681cb33..8364bcc328 100755 --- a/indra/newview/skins/default/textures/icons/pop_up_caution.png +++ b/indra/newview/skins/default/textures/icons/pop_up_caution.png diff --git a/indra/newview/skins/default/textures/menu_separator.png b/indra/newview/skins/default/textures/menu_separator.png Binary files differindex 89dcdcdff5..7bb27c499d 100755 --- a/indra/newview/skins/default/textures/menu_separator.png +++ b/indra/newview/skins/default/textures/menu_separator.png diff --git a/indra/newview/skins/default/textures/model_wizard/progress_bar_bg.png b/indra/newview/skins/default/textures/model_wizard/progress_bar_bg.png Binary files differindex d0b213cdc5..7c6920205f 100755 --- a/indra/newview/skins/default/textures/model_wizard/progress_bar_bg.png +++ b/indra/newview/skins/default/textures/model_wizard/progress_bar_bg.png diff --git a/indra/newview/skins/default/textures/model_wizard/progress_light.png b/indra/newview/skins/default/textures/model_wizard/progress_light.png Binary files differindex 019344f812..c8ab151c44 100755 --- a/indra/newview/skins/default/textures/model_wizard/progress_light.png +++ b/indra/newview/skins/default/textures/model_wizard/progress_light.png diff --git a/indra/newview/skins/default/textures/navbar/Search.png b/indra/newview/skins/default/textures/navbar/Search.png Binary files differindex 0d0e330bc7..4c29e57f7b 100755 --- a/indra/newview/skins/default/textures/navbar/Search.png +++ b/indra/newview/skins/default/textures/navbar/Search.png diff --git a/indra/newview/skins/default/textures/navbar/separator.png b/indra/newview/skins/default/textures/navbar/separator.png Binary files differindex b93e5791a7..c1d74e5a64 100755 --- a/indra/newview/skins/default/textures/navbar/separator.png +++ b/indra/newview/skins/default/textures/navbar/separator.png diff --git a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Foreground.png b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Foreground.png Binary files differindex 50c01062a5..4e59042e33 100755 --- a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Foreground.png +++ b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Foreground.png diff --git a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Press.png b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Press.png Binary files differindex bf2065cd37..be7b298bb8 100755 --- a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Press.png +++ b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Press.png diff --git a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Foreground.png b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Foreground.png Binary files differindex 8b48258142..1e234ff09b 100755 --- a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Foreground.png +++ b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Foreground.png diff --git a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Press.png b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Press.png Binary files differindex 09efe779fe..48c78b453d 100755 --- a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Press.png +++ b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Press.png diff --git a/indra/newview/skins/default/textures/toolbar_icons/facebook.png b/indra/newview/skins/default/textures/toolbar_icons/facebook.png Binary files differindex b960b834dc..ae524b643f 100644 --- a/indra/newview/skins/default/textures/toolbar_icons/facebook.png +++ b/indra/newview/skins/default/textures/toolbar_icons/facebook.png diff --git a/indra/newview/skins/default/textures/toolbar_icons/mini_cart.png b/indra/newview/skins/default/textures/toolbar_icons/mini_cart.png Binary files differindex 9fcf46794d..9eeb1d4e09 100755 --- a/indra/newview/skins/default/textures/toolbar_icons/mini_cart.png +++ b/indra/newview/skins/default/textures/toolbar_icons/mini_cart.png diff --git a/indra/newview/skins/default/textures/up_arrow.png b/indra/newview/skins/default/textures/up_arrow.png Binary files differindex fe68ad49dc..76f839510e 100755 --- a/indra/newview/skins/default/textures/up_arrow.png +++ b/indra/newview/skins/default/textures/up_arrow.png diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Down.png b/indra/newview/skins/default/textures/widgets/Arrow_Down.png Binary files differindex e10f6472eb..cb4eea953c 100755 --- a/indra/newview/skins/default/textures/widgets/Arrow_Down.png +++ b/indra/newview/skins/default/textures/widgets/Arrow_Down.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Disabled.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Disabled.png Binary files differindex c7c0eaa96b..3897e16801 100755 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Disabled.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Disabled.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.png Binary files differindex 4a73c254fc..95a4a36c9d 100755 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.png Binary files differindex 6fb5c432de..20d1ebf53d 100755 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.png Binary files differindex fa18517933..63f4b503e2 100755 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Disabled.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Disabled.png Binary files differindex bed1a701bd..d570f77f6d 100755 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Disabled.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Disabled.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.png Binary files differindex 57ce9af574..28a002b118 100755 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.png Binary files differindex 2c43022f0e..a195e80b0e 100755 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.png Binary files differindex 6b8c1baca4..9863ee32cb 100755 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Disabled.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Disabled.png Binary files differindex 51505e80c5..2ffbc4a16f 100755 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Disabled.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Disabled.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.png Binary files differindex 9f93efbd93..ce47da169b 100755 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.png Binary files differindex 3a4ec1a315..2225150983 100755 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.png Binary files differindex 1f1b4c2ed5..2d541d0f70 100755 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.png diff --git a/indra/newview/skins/default/textures/widgets/Tooltip.png b/indra/newview/skins/default/textures/widgets/Tooltip.png Binary files differindex f989ac9083..3c4d6a965d 100755 --- a/indra/newview/skins/default/textures/widgets/Tooltip.png +++ b/indra/newview/skins/default/textures/widgets/Tooltip.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png Binary files differindex 2292b79eda..3534b716fd 100755 --- a/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png +++ b/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Help_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Help_Foreground.png Binary files differindex 1a514742d3..177c0675bb 100755 --- a/indra/newview/skins/default/textures/windows/Icon_Help_Foreground.png +++ b/indra/newview/skins/default/textures/windows/Icon_Help_Foreground.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Help_Press.png b/indra/newview/skins/default/textures/windows/Icon_Help_Press.png Binary files differindex 7478644b6a..aa21a1c789 100755 --- a/indra/newview/skins/default/textures/windows/Icon_Help_Press.png +++ b/indra/newview/skins/default/textures/windows/Icon_Help_Press.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Minimize_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Minimize_Foreground.png Binary files differindex 9f72a5422b..a98a3a98c2 100755 --- a/indra/newview/skins/default/textures/windows/Icon_Minimize_Foreground.png +++ b/indra/newview/skins/default/textures/windows/Icon_Minimize_Foreground.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Minimize_Press.png b/indra/newview/skins/default/textures/windows/Icon_Minimize_Press.png Binary files differindex 07db8be1b0..5df0e7691c 100755 --- a/indra/newview/skins/default/textures/windows/Icon_Minimize_Press.png +++ b/indra/newview/skins/default/textures/windows/Icon_Minimize_Press.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.png Binary files differindex 1e753aaf1d..b4d4ef01fc 100755 --- a/indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.png +++ b/indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.png diff --git a/indra/newview/skins/default/textures/windows/Icon_Restore_Press.png b/indra/newview/skins/default/textures/windows/Icon_Restore_Press.png Binary files differindex be66b05230..0d0238dc32 100755 --- a/indra/newview/skins/default/textures/windows/Icon_Restore_Press.png +++ b/indra/newview/skins/default/textures/windows/Icon_Restore_Press.png diff --git a/indra/newview/skins/default/textures/windows/hint_arrow_down.png b/indra/newview/skins/default/textures/windows/hint_arrow_down.png Binary files differindex ddadef0978..0cb5a819ec 100755 --- a/indra/newview/skins/default/textures/windows/hint_arrow_down.png +++ b/indra/newview/skins/default/textures/windows/hint_arrow_down.png diff --git a/indra/newview/skins/default/textures/windows/hint_arrow_left.png b/indra/newview/skins/default/textures/windows/hint_arrow_left.png Binary files differindex 2794b967e8..45204d9132 100755 --- a/indra/newview/skins/default/textures/windows/hint_arrow_left.png +++ b/indra/newview/skins/default/textures/windows/hint_arrow_left.png diff --git a/indra/newview/skins/default/textures/windows/hint_arrow_lower_left.png b/indra/newview/skins/default/textures/windows/hint_arrow_lower_left.png Binary files differindex 0dfc99898d..3e3ae9f42d 100755 --- a/indra/newview/skins/default/textures/windows/hint_arrow_lower_left.png +++ b/indra/newview/skins/default/textures/windows/hint_arrow_lower_left.png diff --git a/indra/newview/skins/default/textures/windows/hint_arrow_right.png b/indra/newview/skins/default/textures/windows/hint_arrow_right.png Binary files differindex 7ac57f805b..3fe7a773c3 100755 --- a/indra/newview/skins/default/textures/windows/hint_arrow_right.png +++ b/indra/newview/skins/default/textures/windows/hint_arrow_right.png diff --git a/indra/newview/skins/default/textures/windows/hint_arrow_up.png b/indra/newview/skins/default/textures/windows/hint_arrow_up.png Binary files differindex bb3e1c07fa..44f003dc63 100755 --- a/indra/newview/skins/default/textures/windows/hint_arrow_up.png +++ b/indra/newview/skins/default/textures/windows/hint_arrow_up.png diff --git a/indra/newview/skins/default/textures/windows/hint_background.png b/indra/newview/skins/default/textures/windows/hint_background.png Binary files differindex cfac5deacb..e25f354347 100755 --- a/indra/newview/skins/default/textures/windows/hint_background.png +++ b/indra/newview/skins/default/textures/windows/hint_background.png diff --git a/indra/newview/skins/default/textures/windows/yellow_gradient.png b/indra/newview/skins/default/textures/windows/yellow_gradient.png Binary files differindex 5fd847aaef..5bd21b4297 100755 --- a/indra/newview/skins/default/textures/windows/yellow_gradient.png +++ b/indra/newview/skins/default/textures/windows/yellow_gradient.png diff --git a/indra/newview/skins/default/textures/world/CameraDragDot.png b/indra/newview/skins/default/textures/world/CameraDragDot.png Binary files differindex 57698e1956..2ccf098e0f 100755 --- a/indra/newview/skins/default/textures/world/CameraDragDot.png +++ b/indra/newview/skins/default/textures/world/CameraDragDot.png diff --git a/indra/newview/skins/default/textures/world/NoEntryLines.png b/indra/newview/skins/default/textures/world/NoEntryLines.png Binary files differindex 18e270bde5..d7496b8bd0 100755 --- a/indra/newview/skins/default/textures/world/NoEntryLines.png +++ b/indra/newview/skins/default/textures/world/NoEntryLines.png diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index 9668cfa526..ef2f158a86 100755 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -72,7 +72,7 @@ Second Life is brought to you by the Lindens: top_pad="10" width="435" word_wrap="true"> -Philip, Andrew, Doug, Richard, Phoenix, Ian, Mark, Robin, Dan, Char, Ryan, Eric, Jim, Lee, Jeff, Michael, Kelly, Steve, Catherine, Bub, Ramzi, Jill, Jeska, Don, Kona, Callum, Charity, Jack, Shawn, babbage, James, Lauren, Blue, Brent, Reuben, Pathfinder, Jesse, Patsy, Torley, Bo, Cyn, Jonathan, Gia, Annette, Ginsu, Harry, Lex, Runitai, Guy, Cornelius, Beth, Swiss, Thumper, Wendy, Teeple, Seth, Dee, Mia, Sally, Liana, Aura, Beez, Milo, Red, Gulliver, Marius, Joe, Jose, Dore, Justin, Nora, Morpheus, Lexie, Amber, Chris, Xan, Leyla, Walker, Sabin, Joshua, Hiromi, Tofu, Fritz, June, Jean, Ivy, Dez, Ken, Betsy, Which, Spike, Rob, Zee, Dustin, George, Claudia, del, Matthew, jane, jay, Adrian, Yool, Rika, Yoz, siobhan, Qarl, Benjamin, Beast, Everett, madhavi, Christopher, Izzy, stephany, Jeremy, sean, adreanne, Pramod, Tobin, sejong, Iridium, maurice, kj, Meta, kari, JP, bert, kyle, Jon, Socrates, Bridie, Ivan, maria, Aric, Coco, Periapse, sandy, Storrs, Lotte, Colossus, Brad, Pastrami, Zen, BigPapi, Banzai, Sardonyx, Mani, Garry, Jaime, Neuro, Samuel, Niko, CeeLo, Austin, Soft, Poppy, emma, tessa, angelo, kurz, alexa, Sue, CG, Blake, Erica, Brett, Bevis, kristen, Q, simon, Enus, MJ, laurap, Kip, Scouse, Ron, Ram, kend, Marty, Prospero, melissa, kraft, Nat, Seraph, Hamilton, Lordan, Green, miz, Ashlei, Trinity, Ekim, Echo, Charlie, Rowan, Rome, Jt, Doris, benoc, Christy, Bao, Kate, Tj, Patch, Cheah, Johan, Brandy, Angela, Oreh, Cogsworth, Lan, Mitchell, Space, Bambers, Einstein, Bender, Malbers, Matias, Maggie, Rothman, Milton, Niall, Marin, Allison, Mango, Andrea, Katt, Yi, Ambroff, Rico, Raymond, Gail, Christa, William, Dawn, Usi, Dynamike, M, Corr, Dante, Molly, kaylee, Danica, Kelv, Lil, jacob, Nya, Rodney, elsie, Blondin, Grant, Nyx, Devin, Monty, Minerva, Keira, Katie, Jenn, Makai, Clare, Joy, Cody, Gayathri, FJ, spider, Oskar, Landon, Jarv, Noelle, Al, Doc, Gray, Vir, t, Maestro, Simone, Shannon, yang, Courtney, Scott, charlene, Quixote, Susan, Zed, Amanda, Katelin, Esbee, JoRoan, Enkidu, roxie, Scarlet, Merov, Kevin, Judy, Rand, Newell, Les, Dessie, Galen, Michon, Geo, Siz, Calyle, Pete, Praveen, Callen, Sheldon, Pink, Nelson, jenelle, Terrence, Nathan, Juan, Sascha, Huseby, Karina, Kaye, Kotler, Lis, Darv, Charrell, Dakota, Kimmora, Theeba, Taka, Mae, Perry, Ducot, dana, Esther, Dough, gisele, Doten, Viale, Fisher, jessieann, ashley, Torres, delby, rountree, kurt, Slaton, Madison, Rue, Gino, Wen, Casssandra, Brodesky, Squid, Gez, Rakesh, Gecko, Ladan, Tony, Tatem, Squire, Falcon, BK, Crimp, Tiggs, Bacon, Coyot, Carmilla, Webb, Sea, Arch, Jillian, Jason, Bernard, Vogt, Peggy, dragon, Pup, xandix, Wallace, Bewest, Inoshiro, Rhett, AG, Aimee, Ghengis, Itiaes, Eli, Steffan, Epic, Grapes, Stone, Prep, Scobu, Robert, Alain, Carla, Vicky, Tia, Alec, Taras, Lisa, Oz, Ariane, Log, House, Kazu, Kim, Drofnas, Tyler, Campbell, Michele, Madeline, Nelly, Baron, Thor, Lori, Hele, Fredrik, Teddy, Pixie, Berry, Gabrielle, Alfonso, Brooke, Wolf, Ringo, Cru, Charlar, Rodvik, Gibson, Elise, Bagman, Greger, Leonidas, Jerm, Leslie, CB, Brenda, Durian, Carlo, mm, Zeeshan, Caleb, Max, Elikak, Mercille, Steph, Chase +Philip, Andrew, Doug, Richard, Phoenix, Ian, Mark, Robin, Dan, Char, Ryan, Eric, Jim, Lee, Jeff, Michael, Kelly, Steve, Catherine, Bub, Ramzi, Jill, Jeska, Don, Kona, Callum, Charity, Jack, Shawn, babbage, James, Lauren, Blue, Brent, Reuben, Pathfinder, Jesse, Patsy, Torley, Bo, Cyn, Jonathan, Gia, Annette, Ginsu, Harry, Lex, Runitai, Guy, Cornelius, Beth, Swiss, Thumper, Wendy, Teeple, Seth, Dee, Mia, Sally, Liana, Aura, Beez, Milo, Red, Gulliver, Marius, Joe, Jose, Dore, Justin, Nora, Morpheus, Lexie, Amber, Chris, Xan, Leyla, Walker, Sabin, Joshua, Hiromi, Tofu, Fritz, June, Jean, Ivy, Dez, Ken, Betsy, Which, Spike, Rob, Zee, Dustin, George, Claudia, del, Matthew, jane, jay, Adrian, Yool, Rika, Yoz, siobhan, Qarl, Benjamin, Beast, Everett, madhavi, Christopher, Izzy, stephany, Jeremy, sean, adreanne, Pramod, Tobin, sejong, Iridium, maurice, kj, Meta, kari, JP, bert, kyle, Jon, Socrates, Bridie, Ivan, maria, Aric, Coco, Periapse, sandy, Storrs, Lotte, Colossus, Brad, Pastrami, Zen, BigPapi, Banzai, Sardonyx, Mani, Garry, Jaime, Neuro, Samuel, Niko, CeeLo, Austin, Soft, Poppy, emma, tessa, angelo, kurz, alexa, Sue, CG, Blake, Erica, Brett, Bevis, kristen, Q, simon, Enus, MJ, laurap, Kip, Scouse, Ron, Ram, kend, Marty, Prospero, melissa, kraft, Nat, Seraph, Hamilton, Lordan, Green, miz, Ashlei, Trinity, Ekim, Echo, Charlie, Rowan, Rome, Jt, Doris, benoc, Christy, Bao, Kate, Tj, Patch, Cheah, Johan, Brandy, Angela, Oreh, Cogsworth, Lan, Mitchell, Space, Bambers, Einstein, Bender, Malbers, Matias, Maggie, Rothman, Milton, Niall, Marin, Allison, Mango, Andrea, Katt, Yi, Ambroff, Rico, Raymond, Gail, Christa, William, Dawn, Usi, Dynamike, M, Corr, Dante, Molly, kaylee, Danica, Kelv, Lil, jacob, Nya, Rodney, elsie, Blondin, Grant, Nyx, Devin, Monty, Minerva, Keira, Katie, Jenn, Makai, Clare, Joy, Cody, Gayathri, FJ, spider, Oskar, Landon, Jarv, Noelle, Al, Doc, Gray, Vir, t, Maestro, Simone, Shannon, yang, Courtney, Scott, charlene, Quixote, Susan, Zed, Amanda, Katelin, Esbee, JoRoan, Enkidu, roxie, Scarlet, Merov, Kevin, Judy, Rand, Newell, Les, Dessie, Galen, Michon, Geo, Siz, Calyle, Pete, Praveen, Callen, Sheldon, Pink, Nelson, jenelle, Terrence, Nathan, Juan, Sascha, Huseby, Karina, Kaye, Kotler, Lis, Darv, Charrell, Dakota, Kimmora, Theeba, Taka, Mae, Perry, Ducot, dana, Esther, Dough, gisele, Doten, Viale, Fisher, jessieann, ashley, Torres, delby, rountree, kurt, Slaton, Madison, Rue, Gino, Wen, Casssandra, Brodesky, Squid, Gez, Rakesh, Gecko, Ladan, Tony, Tatem, Squire, Falcon, BK, Crimp, Tiggs, Bacon, Coyot, Carmilla, Webb, Sea, Arch, Jillian, Jason, Bernard, Vogt, Peggy, dragon, Pup, xandix, Wallace, Bewest, Inoshiro, Rhett, AG, Aimee, Ghengis, Itiaes, Eli, Steffan, Epic, Grapes, Stone, Prep, Scobu, Robert, Alain, Carla, Vicky, Tia, Alec, Taras, Lisa, Oz, Ariane, Log, House, Kazu, Kim, Drofnas, Tyler, Campbell, Michele, Madeline, Nelly, Baron, Thor, Lori, Hele, Fredrik, Teddy, Pixie, Berry, Gabrielle, Alfonso, Brooke, Wolf, Ringo, Cru, Charlar, Rodvik, Gibson, Elise, Bagman, Greger, Leonidas, Jerm, Leslie, CB, Brenda, Durian, Carlo, mm, Zeeshan, Caleb, Max, Elikak, Mercille, Steph, Chase, Baker </text_editor> <text follows="top|left" diff --git a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml index c86ed595a7..17bc818cc1 100755 --- a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml +++ b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml @@ -2,7 +2,7 @@ <floater legacy_header_height="18" can_minimize="false" - height="408" + height="440" layout="topleft" name="Inventory Finder" help_topic="inventory_finder" @@ -95,36 +95,36 @@ width="126" /> <icon height="16" - image_name="Inv_Mesh" + image_name="Inv_Notecard" layout="topleft" left="8" mouse_opaque="true" - name="icon_mesh" - top="142" + name="icon_notecard" + top="122" width="16" /> <check_box height="16" - label="Meshes" + label="Notecards" layout="topleft" left_pad="2" - name="check_mesh" + name="check_notecard" top_delta="0" width="126" /> <icon height="16" - image_name="Inv_Notecard" + image_name="Inv_Mesh" layout="topleft" left="8" mouse_opaque="true" - name="icon_notecard" - top="122" + name="icon_mesh" + top="142" width="16" /> <check_box height="16" - label="Notecards" + label="Meshes" layout="topleft" left_pad="2" - name="check_notecard" + name="check_mesh" top_delta="0" width="126" /> <icon @@ -223,25 +223,33 @@ top="262" width="100" /> <button - follows="left|top" height="20" label="None" label_selected="None" - layout="topleft" left_delta="0" name="None" - top_pad="4" + left_pad="10" width="100" /> <check_box height="16" label="Always show folders" layout="topleft" - left_delta="0" + left="8" name="check_show_empty" - top_pad="4" + top_pad="6" width="144" /> + <view_border + bevel_style="none" + follows="top|left" + height="0" + layout="topleft" + left="10" + name="horiz_separator" + top_pad="8" + width="260"/> <check_box height="16" + top="324" label="Since Logoff" layout="topleft" left_delta="0" @@ -257,36 +265,74 @@ layout="topleft" left_delta="0" name="- OR -" - top_delta="16" + top="342" width="144"> - OR - </text> + <radio_group + height="16" + layout="topleft" + name="date_search_direction" + top="360" + left="8" + width="270"> + <radio_item + label="Newer than" + layout="topleft" + name="newer" + top_pad="6" + left="0" /> + <radio_item + label="Older than" + layout="topleft" + name="older" + top_delta="0" + left="120" /> + </radio_group> <spinner follows="left|top" height="16" increment="1" initial_value="0" - label="Hours Ago" - label_width="64" layout="topleft" left_delta="0" max_val="240000" name="spin_hours_ago" top_pad="4" - width="144" /> + width="64" /> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left_pad="3" + top_delta="4" + width="80"> + Hours + </text> <spinner follows="left|top" height="16" increment="1" initial_value="0" - label="Days Ago" - label_width="64" layout="topleft" - left_delta="0" max_val="10000" name="spin_days_ago" top_pad="4" - width="144" /> + left="8" + width="64" /> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left_pad="3" + top_delta="4" + width="80"> + Days + </text> <button follows="top|right" height="20" @@ -295,6 +341,6 @@ layout="topleft" name="Close" right="-6" - top="382" + top="406" width="76" /> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_top_objects.xml b/indra/newview/skins/default/xui/en/floater_top_objects.xml index 0b71177345..36ceddd305 100755 --- a/indra/newview/skins/default/xui/en/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/en/floater_top_objects.xml @@ -38,6 +38,18 @@ name="none_descriptor"> None found. </floater.string> + <floater.string + name="URLs"> + URLs + </floater.string> + <floater.string + name="memory"> + Memory (KB) + </floater.string> + + + + <text type="string" length="1" @@ -82,7 +94,7 @@ name="parcel" width="120" /> <scroll_list.columns - label="Time" + label="Date" name="time" width="130" /> <scroll_list.columns diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml index 31b1d091ee..ed362b36e5 100755 --- a/indra/newview/skins/default/xui/en/menu_conversation.xml +++ b/indra/newview/skins/default/xui/en/menu_conversation.xml @@ -17,6 +17,7 @@ layout="topleft" name="open_voice_conversation"> <on_click function="Avatar.DoToSelected" parameter="open_voice_conversation"/> + <on_enable function="Avatar.EnableItem" parameter="can_open_voice_conversation"/> </menu_item_call> <menu_item_call label="Disconnect from voice" @@ -213,4 +214,12 @@ <on_enable function="Avatar.EnableItem" parameter="can_moderate_voice" /> </menu_item_call> </context_menu> + <menu_item_separator layout="topleft" name="Group Ban Separator"/> + <menu_item_call + label="Ban member" + layout="topleft" + name="BanMember"> + <on_click function="Avatar.DoToSelected" parameter="ban_member" /> + <on_enable function="Avatar.EnableItem" parameter="can_ban_member" /> + </menu_item_call> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml index d2519a5aa4..06d0b849a3 100755 --- a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml @@ -63,7 +63,7 @@ <menu_item_separator layout="topleft" /> <menu_item_call - label="Show Filters" + label="Show Filters..." layout="topleft" name="show_filters"> <on_click diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index f49f300868..2c7dbc3c18 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -169,6 +169,16 @@ No tutorial is currently available. <notification icon="alertmodal.tga" + name="GenericAlertOK" + type="alertmodal"> +[MESSAGE] + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" name="BadInstallation" type="alertmodal"> An error occurred while updating [APP_NAME]. Please [http://get.secondlife.com download the latest version] of the Viewer. @@ -506,7 +516,35 @@ Add this Ability to '[ROLE_NAME]'? notext="No" yestext="Yes"/> </notification> - + + <notification + icon="alertmodal.tga" + name="AssignBanAbilityWarning" + type="alertmodal"> +You are about to add the Ability '[ACTION_NAME]' to the Role '[ROLE_NAME]'. + + *WARNING* +Any Member in a Role with this Ability will also be granted the Abilities '[ACTION_NAME_2]' and '[ACTION_NAME_3]' + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="RemoveBanAbilityWarning" + type="alertmodal"> +You are removing the Ability '[ACTION_NAME]' to the Role '[ROLE_NAME]'. + + *WARNING* +Removing this ability will NOT remove the Abilities '[ACTION_NAME_2]' and '[ACTION_NAME_3]'. + +If you no longer wish to have these abilities granted to this role, disable them immediately! + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + <notification icon="alertmodal.tga" name="EjectGroupMemberWarning" @@ -3747,6 +3785,28 @@ Leave Group? </notification> <notification + icon="aler.tga" + name="GroupDepartError" + type="alert"> +Unable to leave group: [reason]. + <tag>reason</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alert.tga" + name="GroupDepart" + type="alert"> +You have left the group [group_name]. + <tag>group_name</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification icon="alert.tga" name="ConfirmKick" type="alert"> @@ -4581,6 +4641,17 @@ The region you're trying to visit contains [REGIONMATURITY] content, but your cu <notification icon="alertmodal.tga" + name="RegionTPSpecialUsageBlocked" + type="alertmodal"> + <tag>fail</tag> + Unable to enter region. '[REGION_NAME]' is a Skill Gaming Region, and you must meet certain criteria in order to enter. For details, please review the [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life Skill Gaming FAQ]. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" name="PreferredMaturityChanged" type="alertmodal"> You won't receive any more notifications that you're about to visit a region with [RATING] content. You may change your content preferences in the future by using Me > Preferences > General from the menu bar. diff --git a/indra/newview/skins/default/xui/en/panel_group_bulk_ban.xml b/indra/newview/skins/default/xui/en/panel_group_bulk_ban.xml new file mode 100644 index 0000000000..509dcf354e --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_group_bulk_ban.xml @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + height="330" + label="Ban Residents" + layout="topleft" + left="0" + name="bulk_ban_panel" + top="330" + width="210"> + <panel.string + name="loading"> + (loading...) + </panel.string> + <panel.string + name="ban_selection_too_large"> + Group bans not sent: too many Residents selected. Group bans are limited to 100 per request. + </panel.string> + <panel.string + name="ban_not_permitted"> + Group ban not sent: you do not have 'Manage ban list' ability. + </panel.string> + <panel.string + name="ban_limit_fail"> + Group ban not sent: your group have reached limit of allowed ban records. + </panel.string> + <panel.string + name="partial_ban"> + Some group bans were not sent: +[REASONS] + </panel.string> + <panel.string + name="ban_failed"> + Group bans were not sent: +[REASONS] + </panel.string> + <panel.string + name="residents_already_banned"> + - The following resident(s) are already banned: [RESIDENTS]. + </panel.string> + <panel.string + name="ban_limit_reached"> + - Ban limit reached, following agents not banned: [RESIDENTS]. + </panel.string> + <panel.string + name="cant_ban_yourself"> + - You cannot ban yourself from a group. + </panel.string> + <text + type="string" + length="1" + height="54" + layout="topleft" + left="7" + name="help_text" + top="28" + word_wrap="true" + width="200"> + You can select multiple Residents to ban from your group. Click 'Open Resident Chooser' to start. + </text> + <button + height="20" + label="Open Resident Chooser" + layout="topleft" + left_delta="-2" + name="add_button" + top_delta="44" + width="200" /> + <name_list + allow_calling_card_drop="true" + column_padding="0" + height="174" + layout="topleft" + left_delta="0" + multi_select="true" + name="banned_agent_list" + tool_tip="Hold the Ctrl key and click Resident names to multi-select" + top_pad="4" + width="200" /> + <button + height="20" + label="Remove Selected from List" + layout="topleft" + left_delta="0" + name="remove_button" + tool_tip="Removes the Residents selected above from the ban list" + top_pad="4" + width="200" /> + <button + height="20" + label="Ban Residents" + layout="topleft" + left="4" + name="ban_button" + top_delta="30" + width="135" /> + <button + height="20" + label="Cancel" + layout="topleft" + left_pad="2" + name="cancel_button" + top_delta="0" + width="65" /> + <string + name="GroupBulkBan"> + Group Ban + </string> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_group_invite.xml b/indra/newview/skins/default/xui/en/panel_group_invite.xml index 124c0596c3..ebb460deb0 100755 --- a/indra/newview/skins/default/xui/en/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/en/panel_group_invite.xml @@ -76,7 +76,7 @@ Choose what Role to assign them to: </text> <combo_box - height="16" + height="20" layout="topleft" left_delta="0" name="role_name" @@ -88,7 +88,7 @@ label="Send Invitations" layout="topleft" left="4" - name="ok_button" + name="invite_button" top="356" width="135" /> <button diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml index 9ac5b8800e..dac4371a38 100755 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -118,6 +118,13 @@ clicking on their names. left_pad="10" name="member_eject" width="100" /> + <button + height="23" + label="Ban Member(s)" + follows="top|left" + left_pad="10" + name="member_ban" + width="100" /> </panel> <panel border="false" @@ -138,454 +145,535 @@ clicking on their names. right="-5" name="show_all_button" width="100" />--> - <panel.string - name="help_text"> - Roles have a title and an allowed list of Abilities -that Members can perform. Members can belong to -one or more Roles. A group can have up to 10 Roles, -including the Everyone and Owner Roles. - </panel.string> - <panel.string - name="cant_delete_role"> - The 'Everyone' and 'Owners' Roles are special and can't be deleted. - </panel.string> - <panel.string - name="power_folder_icon" translate="false"> - Inv_FolderClosed - </panel.string> - <panel.string - name="power_all_have_icon" translate="false"> - Checkbox_On - </panel.string> - <panel.string - name="power_partial_icon" translate="false"> - Checkbox_Off - </panel.string> - <filter_editor - layout="topleft" - top="5" - left="5" - right="-5" - height="22" - search_button_visible="false" - follows="left|top|right" - label="Filter Roles" - name="filter_input" /> - <scroll_list - column_padding="0" - draw_heading="true" - draw_stripes="false" - heading_height="23" - height="132" - layout="topleft" - search_column="1" - left="0" - follows="left|top|right" - right="-1" - name="role_list" - top_pad="2" - width="310"> - <scroll_list.columns - label="Role" - name="name" - relative_width="0.45" /> - <scroll_list.columns - label="Title" - name="title" - relative_width="0.45" /> - <scroll_list.columns - label="#" - name="members" - relative_width="0.15" /> - </scroll_list> - <button - follows="top|left" - height="23" - label="New Role" - layout="topleft" - left="0" - name="role_create" - width="120" /> - <button - height="23" - follows="top|left" - label="Delete Role" - layout="topleft" - left_pad="10" - name="role_delete" - width="120" /> - </panel> - <panel - border="false" - height="303" - label="ABILITIES" - layout="topleft" - left="0" - right="-1" - help_topic="roles_actions_tab" - name="actions_sub_tab" - class="panel_group_actions_subtab" - tool_tip="You can view an Ability's Description and which Roles and Members can execute the Ability." - width="310"> - <panel.string - name="help_text"> - Abilities allow Members in Roles to do specific -things in this group. There's a broad variety of Abilities. - </panel.string> - <panel.string - name="power_folder_icon" translate="false"> - Inv_FolderClosed - </panel.string> - <panel.string - name="power_all_have_icon" translate="false"> - Checkbox_On - </panel.string> - <panel.string - name="power_partial_icon" translate="false"> - Checkbox_Off - </panel.string> - <filter_editor - layout="topleft" - top="5" - left="5" - right="-5" - height="22" - search_button_visible="false" - follows="left|top|right" - label="Filter Abilities" - name="filter_input" /> - <scroll_list - column_padding="0" - draw_stripes="true" - height="200" - follows="left|top|right" - layout="topleft" - left="0" - right="-1" - name="action_list" - search_column="2" - tool_tip="Select an Ability to view more details" - top_pad="5" - width="300"> - <scroll_list.columns - label="" - name="icon" - width="2" /> - <scroll_list.columns - label="" - name="checkbox" - width="20" /> - <scroll_list.columns - label="" - name="action" - width="270" /> - </scroll_list> - </panel> - </tab_container> + <panel.string + name="help_text"> + Roles have a title and an allowed list of Abilities + that Members can perform. Members can belong to + one or more Roles. A group can have up to 10 Roles, + including the Everyone and Owner Roles. + </panel.string> + <panel.string + name="cant_delete_role"> + The 'Everyone' and 'Owners' Roles are special and can't be deleted. + </panel.string> + <panel.string + name="power_folder_icon" translate="false"> + Inv_FolderClosed + </panel.string> + <panel.string + name="power_all_have_icon" translate="false"> + Checkbox_On + </panel.string> + <panel.string + name="power_partial_icon" translate="false"> + Checkbox_Off + </panel.string> + <filter_editor + layout="topleft" + top="5" + left="5" + right="-5" + height="22" + search_button_visible="false" + follows="left|top|right" + label="Filter Roles" + name="filter_input" /> + <scroll_list + column_padding="0" + draw_heading="true" + draw_stripes="false" + heading_height="23" + height="132" + layout="topleft" + search_column="1" + left="0" + follows="left|top|right" + right="-1" + name="role_list" + top_pad="2" + width="310"> + <scroll_list.columns + label="Role" + name="name" + relative_width="0.45" /> + <scroll_list.columns + label="Title" + name="title" + relative_width="0.45" /> + <scroll_list.columns + label="#" + name="members" + relative_width="0.15" /> + </scroll_list> + <button + follows="top|left" + height="23" + label="New Role" + layout="topleft" + left="0" + name="role_create" + width="120" /> + <button + height="23" + follows="top|left" + label="Delete Role" + layout="topleft" + left_pad="10" + name="role_delete" + width="120" /> + </panel> <panel - height="350" - background_visible="false" - bg_alpha_color="FloaterUnfocusBorderColor" + border="false" + height="303" + label="ABILITIES" layout="topleft" - follows="top|left|right" left="0" right="-1" - width="313" - mouse_opaque="false" - name="members_footer" - top="325" - visible="false"> - <text - type="string" - height="16" - layout="topleft" - follows="left|top" - left="5" - top="8" - text_color="EmphasisColor" - name="static" - width="300"> - Assigned Roles - </text> - <scroll_list - draw_stripes="true" - follows="left|top|right" - height="150" - layout="topleft" - left="0" - right="-1" - name="member_assigned_roles" - top_pad="0"> - <scroll_list.columns - label="" - name="checkbox" - width="20" /> - <scroll_list.columns - label="" - name="role" - width="270" /> - </scroll_list> - <text - type="string" - height="16" - layout="topleft" - follows="left|top" - left="5" - top_pad="5" - text_color="EmphasisColor" - name="static2" - width="285"> - Allowed Abilities - </text> - <scroll_list - draw_stripes="true" - follows="left|top|right" - height="150" - layout="topleft" - left="0" - right="-1" - name="member_allowed_actions" - search_column="2" - tool_tip="For details of each allowed ability see the abilities tab" - top_pad="0"> - <scroll_list.columns - label="" - name="icon" - width="2" /> - <scroll_list.columns - label="" - name="checkbox" - width="20" /> - <scroll_list.columns - label="" - name="action" - width="270" /> - </scroll_list> + help_topic="roles_actions_tab" + name="actions_sub_tab" + class="panel_group_actions_subtab" + tool_tip="You can view an Ability's Description and which Roles and Members can execute the Ability." + width="310"> + <panel.string + name="help_text"> + Abilities allow Members in Roles to do specific + things in this group. There's a broad variety of Abilities. + </panel.string> + <panel.string + name="power_folder_icon" translate="false"> + Inv_FolderClosed + </panel.string> + <panel.string + name="power_all_have_icon" translate="false"> + Checkbox_On + </panel.string> + <panel.string + name="power_partial_icon" translate="false"> + Checkbox_Off + </panel.string> + <filter_editor + layout="topleft" + top="5" + left="5" + right="-5" + height="22" + search_button_visible="false" + follows="left|top|right" + label="Filter Abilities" + name="filter_input" /> + <scroll_list + column_padding="0" + draw_stripes="true" + height="200" + follows="left|top|right" + layout="topleft" + left="0" + right="-1" + name="action_list" + search_column="2" + tool_tip="Select an Ability to view more details" + top_pad="5" + width="300"> + <scroll_list.columns + label="" + name="icon" + width="2" /> + <scroll_list.columns + label="" + name="checkbox" + width="20" /> + <scroll_list.columns + label="" + name="action" + width="270" /> + </scroll_list> </panel> <panel - height="550" - background_visible="false" - bg_alpha_color="FloaterUnfocusBorderColor" + border="false" + height="303" + label="BANNED RESIDENTS" layout="topleft" - follows="top|left|right" left="0" right="-1" - width="313" - mouse_opaque="false" - name="roles_footer" - top_delta="0" - top="209" - visible="false"> - <text - type="string" - height="16" - layout="topleft" - follows="left|top" - left="5" - top="5" - name="static" - width="300"> - Role Name - </text> - <line_editor - type="string" - height="20" - layout="topleft" - left="0" - follows="left|top|right" - right="-1" - max_length_bytes="20" - name="role_name" - top_pad="0" - width="300"> - </line_editor> - <text - type="string" - height="16" - layout="topleft" - follows="left|top" - left="5" - name="static3" - top_pad="5" - width="300"> - Role Title - </text> - <line_editor - type="string" - height="20" - layout="topleft" - left="0" - follows="left|top|right" - right="-1" - max_length_bytes="20" - name="role_title" - top_pad="0" - width="300"> - </line_editor> - <text - type="string" - height="16" - layout="topleft" - follows="left|top" - left="5" - name="static2" - top_pad="5" - width="200"> - Description - </text> - <text_editor - type="string" - layout="topleft" - left="0" - follows="left|top|right" - right="-1" - max_length="295" - height="35" - name="role_description" - top_pad="0" - width="300" - word_wrap="true"> - </text_editor> - <text - type="string" - height="16" - layout="topleft" - follows="left|top" - left="5" - text_color="EmphasisColor" - name="static4" - top_pad="5" - width="300"> - Assigned Members - </text> - <name_list - draw_stripes="true" - height="128" - layout="topleft" - left="0" - follows="left|top|right" - right="-1" - name="role_assigned_members" - top_pad="0" - width="300" /> - <check_box - height="15" - label="Reveal members" - left="5" - layout="topleft" - name="role_visible_in_list" - tool_tip="Sets whether members of this role are visible in the General tab to people outside of the group." - top_pad="4" - width="300" /> - <text - type="string" - height="16" - layout="topleft" - follows="left|top" - left="5" - text_color="EmphasisColor" - name="static5" - top_pad="2" - width="300"> - Allowed Abilities - </text> - <scroll_list - draw_stripes="true" - height="140" - layout="topleft" - left="0" - follows="left|top|right" - right="-1" - name="role_allowed_actions" - search_column="2" - tool_tip="For details of each allowed ability see the abilities tab" - top_pad="0" - width="300"> - <scroll_list.columns - label="" - name="icon" - width="2" /> - <scroll_list.columns - label="" - name="checkbox" - width="20" /> - <scroll_list.columns - label="" - name="action" - width="270" /> - </scroll_list> + help_topic="roles_banlist_tab" + name="banlist_sub_tab" + class="panel_group_banlist_subtab" + tool_tip="View the banned residents from this group." + width="310"> + <panel.string + name="help_text"> + Any resident on the ban list will be unable to join the group. + </panel.string> + <panel.string + name="ban_count_template"> + Ban count: [COUNT]/[LIMIT] + </panel.string> + <name_list + column_padding="0" + draw_heading="true" + height="400" + follows="left|top|right" + layout="topleft" + left="0" + right="-1" + multi_select="true" + name="ban_list" + short_names="false" + top_pad="5"> + <name_list.columns + label="Resident" + name="name" + font.name="SANSSERIF_SMALL" + font.style="NORMAL" + relative_width="0.7" /> + <name_list.columns + label="Date Banned" + name="ban_date" + relative_width="0.3" /> + </name_list> + <button + follows="top|left" + height="23" + label="Ban Resident(s)" + layout="topleft" + left="3" + name="ban_create" + tool_tip="Ban residents from your group" + width="120" /> + <button + follows="top|left" + height="23" + label="Remove Ban(s)" + layout="topleft" + left_pad="5" + name="ban_delete" + tool_tip="Unban selected residents from your group" + width="120" /> + <button + follows="top|left" + height="23" + width="23" + image_overlay="Refresh_Off" + layout="topleft" + left_pad="5" + name="ban_refresh" + tool_tip="Refresh the ban list" + /> + <text + type="string" + height="18" + left_pad="5" + follows="top|left" + layout="topleft" + name="ban_count" + width="100"> + </text> </panel> - <panel - height="424" - background_visible="false" - bg_alpha_color="FloaterUnfocusBorderColor" + </tab_container> + <panel + height="350" + background_visible="false" + bg_alpha_color="FloaterUnfocusBorderColor" + layout="topleft" + follows="top|left|right" + left="0" + right="-1" + width="313" + mouse_opaque="false" + name="members_footer" + top="325" + visible="false"> + <text + type="string" + height="16" + layout="topleft" + follows="left|top" + left="5" + top="8" + text_color="EmphasisColor" + name="static" + width="300"> + Assigned Roles + </text> + <scroll_list + draw_stripes="true" + follows="left|top|right" + height="150" layout="topleft" - follows="top|left|right" left="0" right="-1" - width="313" - mouse_opaque="false" - name="actions_footer" - top_delta="0" - top="255" - visible="false"> - <text_editor - bg_readonly_color="Transparent" - text_readonly_color="EmphasisColor" - font="SansSerifSmall" - type="string" - enabled="false" - halign="left" - layout="topleft" + name="member_assigned_roles" + top_pad="0"> + <scroll_list.columns + label="" + name="checkbox" + width="20" /> + <scroll_list.columns + label="" + name="role" + width="270" /> + </scroll_list> + <text + type="string" + height="16" + layout="topleft" + follows="left|top" + left="5" + top_pad="5" + text_color="EmphasisColor" + name="static2" + width="285"> + Allowed Abilities + </text> + <scroll_list + draw_stripes="true" follows="left|top|right" - left="0" - right="-1" - height="90" - max_length="512" - name="action_description" - top="0" - word_wrap="true"> - This Ability is 'Eject Members from this Group'. Only an Owner can eject another Owner. - </text_editor> - <text + height="150" + layout="topleft" + left="0" + right="-1" + name="member_allowed_actions" + search_column="2" + tool_tip="For details of each allowed ability see the abilities tab" + top_pad="0"> + <scroll_list.columns + label="" + name="icon" + width="2" /> + <scroll_list.columns + label="" + name="checkbox" + width="20" /> + <scroll_list.columns + label="" + name="action" + width="270" /> + </scroll_list> + </panel> + <panel + height="550" + background_visible="false" + bg_alpha_color="FloaterUnfocusBorderColor" + layout="topleft" + follows="top|left|right" + left="0" + right="-1" + width="313" + mouse_opaque="false" + name="roles_footer" + top_delta="0" + top="209" + visible="false"> + <text + type="string" + height="16" + layout="topleft" + follows="left|top" + left="5" + top="5" + name="static" + width="300"> + Role Name + </text> + <line_editor + type="string" + height="20" + layout="topleft" + left="0" + follows="left|top|right" + right="-1" + max_length_bytes="20" + name="role_name" + top_pad="0" + width="300"> + </line_editor> + <text + type="string" + height="16" + layout="topleft" + follows="left|top" + left="5" + name="static3" + top_pad="5" + width="300"> + Role Title + </text> + <line_editor + type="string" + height="20" + layout="topleft" + left="0" + follows="left|top|right" + right="-1" + max_length_bytes="20" + name="role_title" + top_pad="0" + width="300"> + </line_editor> + <text type="string" height="16" layout="topleft" follows="left|top" left="5" name="static2" - top_pad="1" - width="300"> - Roles with this ability - </text> - <scroll_list - height="172" - layout="topleft" - follows="left|top|right" - left="5" - right="-1" - name="action_roles" - top_pad="0" - width="300" /> - <text - type="string" - height="16" - layout="topleft" - follows="left|top" - left="5" - name="static3" top_pad="5" - width="300"> - Members with this ability - </text> - <name_list - height="122" - follows="left|top|right" - layout="topleft" - left="5" - right="-1" - name="action_members" - top_pad="0" - width="300" /> - </panel> + width="200"> + Description + </text> + <text_editor + type="string" + layout="topleft" + left="0" + follows="left|top|right" + right="-1" + max_length="295" + height="35" + name="role_description" + top_pad="0" + width="300" + word_wrap="true"> + </text_editor> + <text + type="string" + height="16" + layout="topleft" + follows="left|top" + left="5" + text_color="EmphasisColor" + name="static4" + top_pad="5" + width="300"> + Assigned Members + </text> + <name_list + draw_stripes="true" + height="128" + layout="topleft" + left="0" + follows="left|top|right" + right="-1" + name="role_assigned_members" + top_pad="0" + width="300" /> + <check_box + height="15" + label="Reveal members" + left="5" + layout="topleft" + name="role_visible_in_list" + tool_tip="Sets whether members of this role are visible in the General tab to people outside of the group." + top_pad="4" + width="300" /> + <text + type="string" + height="16" + layout="topleft" + follows="left|top" + left="5" + text_color="EmphasisColor" + name="static5" + top_pad="2" + width="300"> + Allowed Abilities + </text> + <scroll_list + draw_stripes="true" + height="140" + layout="topleft" + left="0" + follows="left|top|right" + right="-1" + name="role_allowed_actions" + search_column="2" + tool_tip="For details of each allowed ability see the abilities tab" + top_pad="0" + width="300"> + <scroll_list.columns + label="" + name="icon" + width="2" /> + <scroll_list.columns + label="" + name="checkbox" + width="20" /> + <scroll_list.columns + label="" + name="action" + width="270" /> + </scroll_list> + </panel> + <panel + height="424" + background_visible="false" + bg_alpha_color="FloaterUnfocusBorderColor" + layout="topleft" + follows="top|left|right" + left="0" + right="-1" + width="313" + mouse_opaque="false" + name="actions_footer" + top_delta="0" + top="255" + visible="false"> + <text_editor + bg_readonly_color="Transparent" + text_readonly_color="EmphasisColor" + font="SansSerifSmall" + type="string" + enabled="false" + halign="left" + layout="topleft" + follows="left|top|right" + left="0" + right="-1" + height="90" + max_length="512" + name="action_description" + top="0" + word_wrap="true"> + This Ability is 'Eject Members from this Group'. Only an Owner can eject another Owner. + </text_editor> + <text + type="string" + height="16" + layout="topleft" + follows="left|top" + left="5" + name="static2" + top_pad="1" + width="300"> + Roles with this ability + </text> + <scroll_list + height="172" + layout="topleft" + follows="left|top|right" + left="5" + right="-1" + name="action_roles" + top_pad="0" + width="300" /> + <text + type="string" + height="16" + layout="topleft" + follows="left|top" + left="5" + name="static3" + top_pad="5" + width="300"> + Members with this ability + </text> + <name_list + height="122" + follows="left|top|right" + layout="topleft" + left="5" + right="-1" + name="action_members" + top_pad="0" + width="300" /> + </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index 426c0c4915..cb6b2fafd8 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -36,8 +36,9 @@ <color_swatch can_apply_immediately="true" follows="left|top" - height="45" + height="22" label="" + label_height="0" layout="topleft" left="10" name="colorswatch" diff --git a/indra/newview/skins/default/xui/en/role_actions.xml b/indra/newview/skins/default/xui/en/role_actions.xml index 0eeccbeac5..1044cbfd2e 100755 --- a/indra/newview/skins/default/xui/en/role_actions.xml +++ b/indra/newview/skins/default/xui/en/role_actions.xml @@ -9,7 +9,10 @@ <action description="Eject Members from this Group" longdescription="Eject Members from this Group using the 'Eject' button in the Roles section > Members tab. An Owner can eject anyone except another Owner. If you're not an Owner, a Member can be ejected from a group if, and only if, they're only in the Everyone Role, and NO other Roles. To remove Members from Roles, you need to have the 'Remove Members from Roles' Ability." name="member eject" value="2" /> - <action + <action description="Manage ban list" + longdescription="Allows the group member to ban / un-ban Residents from this group." + name="allow ban" value="51" /> + <action description="Toggle 'Open Enrollment' and change 'Enrollment fee'" longdescription="Toggle 'Open Enrollment' to let new Members join without an invitation, and change the 'Enrollment fee' in the General section." name="member options" value="3" /> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index ba95d701ab..5fbc539a06 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3775,6 +3775,7 @@ Abuse Report</string> <string name="LocalEstimateUSD">US$ [AMOUNT]</string> <!-- Group Profile roles and powers --> + <string name="Group Ban">Group Ban</string> <string name="Membership">Membership</string> <string name="Roles">Roles</string> <string name="Group Identity">Group Identity</string> diff --git a/indra/newview/skins/default/xui/en/teleport_strings.xml b/indra/newview/skins/default/xui/en/teleport_strings.xml index fdf41991cd..5a9a16d344 100755 --- a/indra/newview/skins/default/xui/en/teleport_strings.xml +++ b/indra/newview/skins/default/xui/en/teleport_strings.xml @@ -48,7 +48,10 @@ Go to 'Welcome Island Public' to repeat the tutorial. <message name="MustGetAgeRegion"> You must be age 18 or over to enter this region. </message> - </message_set> + <message name="RegionTPSpecialUsageBlocked"> + Unable to enter region. '[REGION_NAME]' is a Skill Gaming Region, and you must meet certain criteria in order to enter. For details, please review the [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life Skill Gaming FAQ]. + </message> + </message_set> <message_set name="progress"> <message name="sending_dest"> Sending to destination. diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index f079f31c81..7544fe1c41 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -798,15 +798,42 @@ class Darwin_i386_Manifest(ViewerManifest): for libfile in dylibs: symlinkf(os.path.join(os.pardir, os.pardir, os.pardir, libfile), os.path.join(resource_path, libfile)) - - # plugins + # SLPlugin.app/Contents/Resources gets those Qt4 libraries it needs. + if self.prefix(src="", dst="SLPlugin.app/Contents/Resources"): + for libfile in ('libQtCore.4.dylib', + 'libQtCore.4.7.1.dylib', + 'libQtGui.4.dylib', + 'libQtGui.4.7.1.dylib', + 'libQtNetwork.4.dylib', + 'libQtNetwork.4.7.1.dylib', + 'libQtOpenGL.4.dylib', + 'libQtOpenGL.4.7.1.dylib', + 'libQtSvg.4.dylib', + 'libQtSvg.4.7.1.dylib', + 'libQtWebKit.4.dylib', + 'libQtWebKit.4.7.1.dylib', + 'libQtXml.4.dylib', + 'libQtXml.4.7.1.dylib'): + self.path2basename("../packages/lib/release", libfile) + self.end_prefix("SLPlugin.app/Contents/Resources") + + # Qt4 codecs go to llplugin. Not certain why but this is the first + # location probed according to dtruss so we'll go with that. + if self.prefix(src="../packages/plugins/codecs/", dst="llplugin/codecs"): + self.path("libq*.dylib") + self.end_prefix("llplugin/codecs") + + # Similarly for imageformats. + if self.prefix(src="../packages/plugins/imageformats/", dst="llplugin/imageformats"): + self.path("libq*.dylib") + self.end_prefix("llplugin/imageformats") + + # SLPlugin plugins proper if self.prefix(src="", dst="llplugin"): self.path2basename("../media_plugins/quicktime/" + self.args['configuration'], "media_plugin_quicktime.dylib") self.path2basename("../media_plugins/webkit/" + self.args['configuration'], "media_plugin_webkit.dylib") - self.path2basename("../packages/lib/release", "libllqtwebkit.dylib") - self.end_prefix("llplugin") self.end_prefix("Resources") @@ -1011,6 +1038,7 @@ class LinuxManifest(ViewerManifest): self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so") self.end_prefix("bin/llplugin") + # llcommon if not self.path("../llcommon/libllcommon.so", "lib/libllcommon.so"): print "Skipping llcommon.so (assuming llcommon was linked statically)" @@ -1076,20 +1104,9 @@ class Linux_i686_Manifest(LinuxManifest): self.path("libaprutil-1.so") self.path("libaprutil-1.so.0") self.path("libaprutil-1.so.0.4.1") - self.path("libboost_context-mt.so.*") - self.path("libboost_filesystem-mt.so.*") - self.path("libboost_program_options-mt.so.*") - self.path("libboost_regex-mt.so.*") - self.path("libboost_signals-mt.so.*") - self.path("libboost_system-mt.so.*") - self.path("libboost_thread-mt.so.*") - self.path("libcollada14dom.so") self.path("libdb*.so") - self.path("libcrypto.so.*") self.path("libexpat.so.*") - self.path("libssl.so.1.0.0") self.path("libGLOD.so") - self.path("libminizip.so") self.path("libuuid.so*") self.path("libSDL-1.2.so.*") self.path("libdirectfb-1.*.so.*") @@ -1121,6 +1138,10 @@ class Linux_i686_Manifest(LinuxManifest): # previous call did, without having to explicitly state the # version number. self.path("libfontconfig.so.*.*") + + # Include libfreetype.so. but have it work as libfontconfig does. + self.path("libfreetype.so.*.*") + try: self.path("libtcmalloc.so*") #formerly called google perf tools pass @@ -1129,26 +1150,55 @@ class Linux_i686_Manifest(LinuxManifest): pass try: - self.path("libfmodex-*.so") - self.path("libfmodex.so") - pass + self.path("libfmodex-*.so") + self.path("libfmodex.so") + pass except: - print "Skipping libfmodex.so - not found" - pass + print "Skipping libfmodex.so - not found" + pass self.end_prefix("lib") # Vivox runtimes if self.prefix(src="../packages/lib/release", dst="bin"): - self.path("SLVoice") - self.end_prefix() + self.path("SLVoice") + self.end_prefix() + if self.prefix(src="../packages/lib/release", dst="lib"): + self.path("libortp.so") + self.path("libsndfile.so.1") + #self.path("libvivoxoal.so.1") # no - we'll re-use the viewer's own OpenAL lib + self.path("libvivoxsdk.so") + self.path("libvivoxplatform.so") + self.end_prefix("lib") + + # plugin runtime if self.prefix(src="../packages/lib/release", dst="lib"): - self.path("libortp.so") - self.path("libsndfile.so.1") - #self.path("libvivoxoal.so.1") # no - we'll re-use the viewer's own OpenAL lib - self.path("libvivoxsdk.so") - self.path("libvivoxplatform.so") - self.end_prefix("lib") + self.path("libQtCore.so*") + self.path("libQtGui.so*") + self.path("libQtNetwork.so*") + self.path("libQtOpenGL.so*") + self.path("libQtSvg.so*") + self.path("libQtWebKit.so*") + self.path("libQtXml.so*") + self.end_prefix("lib") + + # For WebKit/Qt plugin runtimes (image format plugins) + if self.prefix(src="../packages/plugins/imageformats", dst="bin/llplugin/imageformats"): + self.path("libqgif.so") + self.path("libqico.so") + self.path("libqjpeg.so") + self.path("libqmng.so") + self.path("libqsvg.so") + self.path("libqtiff.so") + self.end_prefix("bin/llplugin/imageformats") + + # For WebKit/Qt plugin runtimes (codec/character encoding plugins) + if self.prefix(src="../packages/plugins/codecs", dst="bin/llplugin/codecs"): + self.path("libqcncodecs.so") + self.path("libqjpcodecs.so") + self.path("libqkrcodecs.so") + self.path("libqtwcodecs.so") + self.end_prefix("bin/llplugin/codecs") self.strip_binaries() diff --git a/indra/test_apps/llfbconnecttest/CMakeLists.txt b/indra/test_apps/llfbconnecttest/CMakeLists.txt index f56329a010..512bf202ae 100644 --- a/indra/test_apps/llfbconnecttest/CMakeLists.txt +++ b/indra/test_apps/llfbconnecttest/CMakeLists.txt @@ -122,32 +122,24 @@ add_custom_command(TARGET llfbconnecttest POST_BUILD ) -if (DARWIN OR WINDOWS) - get_target_property(BUILT_WEBKIT_PLUGIN media_plugin_webkit LOCATION) - add_custom_command(TARGET llfbconnecttest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_WEBKIT_PLUGIN} ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_WEBKIT_PLUGIN} - ) - - # copy over bookmarks file if llfbconnecttest gets built - get_target_property(BUILT_LLFBCONNECTTEST llfbconnecttest LOCATION) - add_custom_command(TARGET llfbconnecttest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${CMAKE_CURRENT_BINARY_DIR}/ - DEPENDS ${BUILT_LLFBCONNECTTEST} - ) - # also copy it to the same place as SLPlugin, which is what the mac wants... - add_custom_command(TARGET llfbconnecttest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_LLFBCONNECTTEST} - ) -endif (DARWIN OR WINDOWS) +get_target_property(BUILT_WEBKIT_PLUGIN media_plugin_webkit LOCATION) +add_custom_command(TARGET llfbconnecttest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_WEBKIT_PLUGIN} ${PLUGINS_DESTINATION_DIR} + DEPENDS ${BUILT_WEBKIT_PLUGIN} +) -if (DARWIN) - add_custom_command(TARGET llfbconnecttest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib ${PLUGINS_DESTINATION_DIR} - DEPENDS ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib - ) -endif (DARWIN) +# copy over bookmarks file if llfbconnecttest gets built +get_target_property(BUILT_LLFBCONNECTTEST llfbconnecttest LOCATION) +add_custom_command(TARGET llfbconnecttest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${CMAKE_CURRENT_BINARY_DIR}/ + DEPENDS ${BUILT_LLFBCONNECTTEST} +) + +# also copy it to the same place as SLPlugin, which is what the mac wants... +add_custom_command(TARGET llfbconnecttest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${PLUGINS_DESTINATION_DIR} + DEPENDS ${BUILT_LLFBCONNECTTEST} +) if(WINDOWS) #******************** @@ -301,4 +293,80 @@ if(WINDOWS) endif(WINDOWS) +if (DARWIN) + set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}") + set(fbconnecttest_release_files + libexception_handler.dylib + libaprutil-1.0.dylib + libapr-1.0.dylib + libexpat.1.5.2.dylib + libQtCore.4.7.1.dylib + libQtCore.4.dylib + libQtGui.4.7.1.dylib + libQtGui.4.dylib + libQtNetwork.4.7.1.dylib + libQtNetwork.4.dylib + libQtOpenGL.4.7.1.dylib + libQtOpenGL.4.dylib + libQtWebKit.4.7.1.dylib + libQtWebKit.4.dylib + libQtSvg.4.7.1.dylib + libQtSvg.4.dylib + libQtXml.4.7.1.dylib + libQtXml.4.dylib + ) + copy_if_different( + ${fbconnecttest_release_src_dir} + "${PLUGINS_DESTINATION_DIR}" + out_targets + ${fbconnecttest_release_files} + ) + set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets}) + + # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt image format plugins) + set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_PLUGINS}/imageformats") + set(fbconnecttest_release_files + libqgif.dylib + libqico.dylib + libqjpeg.dylib + libqmng.dylib + libqsvg.dylib + libqtiff.dylib + ) + copy_if_different( + ${fbconnecttest_release_src_dir} + "${PLUGINS_DESTINATION_DIR}/imageformats" + out_targets + ${fbconnecttest_release_files} + ) + set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets}) + + # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt codec plugins) + set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_PLUGINS}/codecs") + set(fbconnecttest_release_files + libqcncodecs.dylib + libqjpcodecs.dylib + libqkrcodecs.dylib + libqtwcodecs.dylib + ) + copy_if_different( + ${fbconnecttest_release_src_dir} + "${PLUGINS_DESTINATION_DIR}/codecs" + out_targets + ${fbconnecttest_release_files} + ) + set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets}) + + add_custom_target(copy_fbconnecttest_libs ALL + DEPENDS + ${fbconnect_test_targets} + ) + + add_dependencies(llfbconnecttest copy_fbconnecttest_libs) +endif (DARWIN) + +if (LINUX) + +endif (LINUX) + ll_deploy_sharedlibs_command(llfbconnecttest) diff --git a/indra/test_apps/llfbconnecttest/README.Linden b/indra/test_apps/llfbconnecttest/README.Linden new file mode 100644 index 0000000000..7488ce680a --- /dev/null +++ b/indra/test_apps/llfbconnecttest/README.Linden @@ -0,0 +1,20 @@ + +1. Description + + Exercises SLPlugin. Specific functions and goals aren't clear + from the source. + +2. Running + + 2.1 Mac + + Make certain '.' is included in PATH. E.g.: + + PATH=.:"$PATH" open build-darwin-i386/test_apps/llfbconnecttest/RelWithDebInfo/llfbconnecttest.app + + Otherwise the program won't find SLPlugin and will timeout and + fail after 30 seconds and give you little information as to why. + + Running 'dtruss' on plugin test applications will give you a great + deal of insight into why they aren't activating. + diff --git a/indra/test_apps/llplugintest/CMakeLists.txt b/indra/test_apps/llplugintest/CMakeLists.txt index 8179be66f5..9d44563e26 100755 --- a/indra/test_apps/llplugintest/CMakeLists.txt +++ b/indra/test_apps/llplugintest/CMakeLists.txt @@ -346,44 +346,44 @@ add_custom_command(TARGET llmediaplugintest POST_BUILD DEPENDS ${BUILT_LLCOMMON} ) +get_target_property(BUILT_WEBKIT_PLUGIN media_plugin_webkit LOCATION) +add_custom_command(TARGET llmediaplugintest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_WEBKIT_PLUGIN} ${PLUGINS_DESTINATION_DIR} + DEPENDS ${BUILT_WEBKIT_PLUGIN} +) if (DARWIN OR WINDOWS) - get_target_property(BUILT_WEBKIT_PLUGIN media_plugin_webkit LOCATION) - add_custom_command(TARGET llmediaplugintest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_WEBKIT_PLUGIN} ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_WEBKIT_PLUGIN} - ) - get_target_property(BUILT_QUICKTIME_PLUGIN media_plugin_quicktime LOCATION) add_custom_command(TARGET llmediaplugintest POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_QUICKTIME_PLUGIN} ${PLUGINS_DESTINATION_DIR} DEPENDS ${BUILT_QUICKTIME_PLUGIN} ) - - get_target_property(BUILT_EXAMPLE_PLUGIN media_plugin_example LOCATION) - add_custom_command(TARGET llmediaplugintest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_EXAMPLE_PLUGIN} ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_EXAMPLE_PLUGIN} - ) - - # copy over bookmarks file if llmediaplugintest gets built - get_target_property(BUILT_LLMEDIAPLUGINTEST llmediaplugintest LOCATION) - add_custom_command(TARGET llmediaplugintest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${CMAKE_CURRENT_BINARY_DIR}/ - DEPENDS ${BUILT_LLMEDIAPLUGINTEST} - ) - # also copy it to the same place as SLPlugin, which is what the mac wants... - add_custom_command(TARGET llmediaplugintest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_LLMEDIAPLUGINTEST} - ) endif (DARWIN OR WINDOWS) +get_target_property(BUILT_EXAMPLE_PLUGIN media_plugin_example LOCATION) +add_custom_command(TARGET llmediaplugintest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_EXAMPLE_PLUGIN} ${PLUGINS_DESTINATION_DIR} + DEPENDS ${BUILT_EXAMPLE_PLUGIN} +) + +# copy over bookmarks file if llmediaplugintest gets built +get_target_property(BUILT_LLMEDIAPLUGINTEST llmediaplugintest LOCATION) +add_custom_command(TARGET llmediaplugintest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${CMAKE_CURRENT_BINARY_DIR}/ + DEPENDS ${BUILT_LLMEDIAPLUGINTEST} +) + +# also copy it to the same place as SLPlugin, which is what the mac wants... +add_custom_command(TARGET llmediaplugintest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${PLUGINS_DESTINATION_DIR} + DEPENDS ${BUILT_LLMEDIAPLUGINTEST} +) + if (DARWIN) - add_custom_command(TARGET llmediaplugintest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib ${PLUGINS_DESTINATION_DIR} - DEPENDS ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib - ) +# add_custom_command(TARGET llmediaplugintest POST_BUILD +# COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib ${PLUGINS_DESTINATION_DIR} +# DEPENDS ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib +# ) endif (DARWIN) if(WINDOWS) @@ -538,4 +538,76 @@ if(WINDOWS) endif(WINDOWS) +if (DARWIN) + set(plugintest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}") + set(plugintest_release_files + libexception_handler.dylib + libaprutil-1.0.dylib + libapr-1.0.dylib + libexpat.1.5.2.dylib + libQtCore.4.7.1.dylib + libQtCore.4.dylib + libQtGui.4.7.1.dylib + libQtGui.4.dylib + libQtNetwork.4.7.1.dylib + libQtNetwork.4.dylib + libQtOpenGL.4.7.1.dylib + libQtOpenGL.4.dylib + libQtWebKit.4.7.1.dylib + libQtWebKit.4.dylib + libQtSvg.4.7.1.dylib + libQtSvg.4.dylib + libQtXml.4.7.1.dylib + libQtXml.4.dylib + ) + copy_if_different( + ${plugintest_release_src_dir} + "${PLUGINS_DESTINATION_DIR}" + out_targets + ${plugintest_release_files} + ) + set(plugin_test_targets ${plugin_test_targets} ${out_targets}) + + # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt image format plugins) + set(plugintest_release_src_dir "${ARCH_PREBUILT_DIRS_PLUGINS}/imageformats") + set(plugintest_release_files + libqgif.dylib + libqico.dylib + libqjpeg.dylib + libqmng.dylib + libqsvg.dylib + libqtiff.dylib + ) + copy_if_different( + ${plugintest_release_src_dir} + "${PLUGINS_DESTINATION_DIR}/imageformats" + out_targets + ${plugintest_release_files} + ) + set(plugin_test_targets ${plugin_test_targets} ${out_targets}) + + # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt codec plugins) + set(plugintest_release_src_dir "${ARCH_PREBUILT_DIRS_PLUGINS}/codecs") + set(plugintest_release_files + libqcncodecs.dylib + libqjpcodecs.dylib + libqkrcodecs.dylib + libqtwcodecs.dylib + ) + copy_if_different( + ${plugintest_release_src_dir} + "${PLUGINS_DESTINATION_DIR}/codecs" + out_targets + ${plugintest_release_files} + ) + set(plugin_test_targets ${plugin_test_targets} ${out_targets}) + + add_custom_target(copy_plugintest_libs ALL + DEPENDS + ${plugin_test_targets} + ) + + add_dependencies(llmediaplugintest copy_plugintest_libs) +endif (DARWIN) + ll_deploy_sharedlibs_command(llmediaplugintest) diff --git a/indra/test_apps/llplugintest/README.Linden b/indra/test_apps/llplugintest/README.Linden new file mode 100644 index 0000000000..4a9f223c21 --- /dev/null +++ b/indra/test_apps/llplugintest/README.Linden @@ -0,0 +1,21 @@ + +1. Description + + Exercises SLPlugin. Demonstrates mediakit plugin reuse and + switchover as MIME type changes (web, quicktime, flash). + + +2. Running + + 2.1 Mac + + Make certain '.' is included in PATH. E.g.: + + PATH=.:"$PATH" open build-darwin-i386/test_apps/llmediaplugintest/RelWithDebInfo/llmediaplugintest.app + + Otherwise the program won't find SLPlugin and will timeout and + fail after 30 seconds and give you little information as to why. + + Running 'dtruss' on plugin test applications will give you a great + deal of insight into why they aren't activating. + diff --git a/indra/viewer_components/login/CMakeLists.txt b/indra/viewer_components/login/CMakeLists.txt index 6f366677c9..ce80d55829 100755 --- a/indra/viewer_components/login/CMakeLists.txt +++ b/indra/viewer_components/login/CMakeLists.txt @@ -46,6 +46,8 @@ target_link_libraries(lllogin ${LLMATH_LIBRARIES} ${LLXML_LIBRARIES} ${BOOST_CONTEXT_LIBRARY} + ${BOOST_COROUTINE_LIBRARY} + ${BOOST_SYSTEM_LIBRARY} ) if(LL_TESTS) @@ -55,7 +57,7 @@ if(LL_TESTS) set_source_files_properties( lllogin.cpp PROPERTIES - LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_CONTEXT_LIBRARY}" + LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_CONTEXT_LIBRARY};${BOOST_COROUTINE_LIBRARY};${BOOST_SYSTEM_LIBRARY}" ) LL_ADD_PROJECT_UNIT_TESTS(lllogin "${lllogin_TEST_SOURCE_FILES}") diff --git a/indra/win_updater/CMakeLists.txt b/indra/win_updater/CMakeLists.txt deleted file mode 100755 index 210486c668..0000000000 --- a/indra/win_updater/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -# -*- cmake -*- - -project(win_updater) - -include(00-Common) -include(LLCommon) -include(Linking) - -# *HACK - override msvcrt implementation (intialized on 00-Common) to be -# statically linked for the installer this relies on vc taking the last flag on -# the command line -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MT") -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ) - -set(win_updater_SOURCE_FILES updater.cpp) - -set(win_updater_HEADER_FILES CMakeLists.txt) - -set_source_files_properties(${win_updater_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -list(APPEND win_updater_SOURCE_FILES ${win_updater_HEADER_FILES}) - -add_executable(windows-updater WIN32 ${win_updater_SOURCE_FILES}) - -target_link_libraries(windows-updater - wininet - user32 - gdi32 - shell32 - ) - -set_target_properties(windows-updater - PROPERTIES - LINK_FLAGS "/NODEFAULTLIB:MSVCRT" - LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;MSVCRT\"" - ) - -# The windows-updater doesn't link against anything non-system, apparently -#ll_deploy_sharedlibs_command(windows-updater) diff --git a/indra/win_updater/updater.cpp b/indra/win_updater/updater.cpp deleted file mode 100755 index aeab5a3b13..0000000000 --- a/indra/win_updater/updater.cpp +++ /dev/null @@ -1,516 +0,0 @@ -/** - * @file updater.cpp - * @brief Windows auto-updater - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -// -// Usage: updater -url <url> -// - -// We use dangerous fopen, strtok, mbstowcs, sprintf -// which generates warnings on VC2005. -// *TODO: Switch to fopen_s, strtok_s, etc. -#define _CRT_SECURE_NO_DEPRECATE - -#include <windows.h> -#include <wininet.h> -#include <stdio.h> -#include <string> -#include <iostream> -#include <stdexcept> -#include <sstream> -#include <fstream> - -#define BUFSIZE 8192 - -int gTotalBytesRead = 0; -DWORD gTotalBytes = -1; -HWND gWindow = NULL; -WCHAR gProgress[256]; -char* gUpdateURL = NULL; - -#if _DEBUG -std::ofstream logfile; -#define DEBUG(expr) logfile << expr << std::endl -#else -#define DEBUG(expr) /**/ -#endif - -char* wchars_to_utf8chars(const WCHAR* in_chars) -{ - int tlen = 0; - const WCHAR* twc = in_chars; - while (*twc++ != 0) - { - tlen++; - } - char* outchars = new char[tlen]; - char* res = outchars; - for (int i=0; i<tlen; i++) - { - int cur_char = (int)(*in_chars++); - if (cur_char < 0x80) - { - *outchars++ = (char)cur_char; - } - else - { - *outchars++ = '?'; - } - } - *outchars = 0; - return res; -} - -class Fetcher -{ -public: - Fetcher(const std::wstring& uri) - { - // These actions are broken out as separate methods not because it - // makes the code clearer, but to avoid triggering AntiVir and - // McAfee-GW-Edition virus scanners (DEV-31680). - mInet = openInet(); - mDownload = openUrl(uri); - } - - ~Fetcher() - { - DEBUG("Calling InternetCloseHandle"); - InternetCloseHandle(mDownload); - InternetCloseHandle(mInet); - } - - unsigned long read(char* buffer, size_t bufflen) const; - - DWORD getTotalBytes() const - { - DWORD totalBytes; - DWORD sizeof_total_bytes = sizeof(totalBytes); - HttpQueryInfo(mDownload, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, - &totalBytes, &sizeof_total_bytes, NULL); - return totalBytes; - } - - struct InetError: public std::runtime_error - { - InetError(const std::string& what): std::runtime_error(what) {} - }; - -private: - // We test results from a number of different MS functions with different - // return types -- but the common characteristic is that 0 (i.e. (! result)) - // means an error of some kind. - template <typename RESULT> - static RESULT check(const std::string& desc, RESULT result) - { - if (result) - { - // success, show caller - return result; - } - DWORD err = GetLastError(); - std::ostringstream out; - out << desc << " Failed: " << err; - DEBUG(out.str()); - throw InetError(out.str()); - } - - HINTERNET openUrl(const std::wstring& uri) const; - HINTERNET openInet() const; - - HINTERNET mInet, mDownload; -}; - -HINTERNET Fetcher::openInet() const -{ - DEBUG("Calling InternetOpen"); - // Init wininet subsystem - return check("InternetOpen", - InternetOpen(L"LindenUpdater", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0)); -} - -HINTERNET Fetcher::openUrl(const std::wstring& uri) const -{ - DEBUG("Calling InternetOpenUrl: " << wchars_to_utf8chars(uri.c_str())); - return check("InternetOpenUrl", - InternetOpenUrl(mInet, uri.c_str(), NULL, 0, INTERNET_FLAG_NEED_FILE, NULL)); -} - -unsigned long Fetcher::read(char* buffer, size_t bufflen) const -{ - unsigned long bytes_read = 0; - DEBUG("Calling InternetReadFile"); - check("InternetReadFile", - InternetReadFile(mDownload, buffer, bufflen, &bytes_read)); - return bytes_read; -} - -int WINAPI get_url_into_file(const std::wstring& uri, const std::string& path, int *cancelled) -{ - int success = FALSE; - *cancelled = FALSE; - - DEBUG("Opening '" << path << "'"); - - FILE* fp = fopen(path.c_str(), "wb"); /* Flawfinder: ignore */ - - if (!fp) - { - DEBUG("Failed to open '" << path << "'"); - return success; - } - - // Note, ctor can throw, since it uses check() function. - Fetcher fetcher(uri); - gTotalBytes = fetcher.getTotalBytes(); - -/*==========================================================================*| - // nobody uses total_bytes?!? What's this doing here? - DWORD total_bytes = 0; - success = check("InternetQueryDataAvailable", - InternetQueryDataAvailable(hdownload, &total_bytes, 0, 0)); -|*==========================================================================*/ - - success = FALSE; - while(!success && !(*cancelled)) - { - char data[BUFSIZE]; /* Flawfinder: ignore */ - unsigned long bytes_read = fetcher.read(data, sizeof(data)); - - if (!bytes_read) - { - DEBUG("InternetReadFile Read " << bytes_read << " bytes."); - } - - DEBUG("Reading Data, bytes_read = " << bytes_read); - - if (bytes_read == 0) - { - // If InternetFileRead returns TRUE AND bytes_read == 0 - // we've successfully downloaded the entire file - wsprintf(gProgress, L"Download complete."); - success = TRUE; - } - else - { - // write what we've got, then continue - fwrite(data, sizeof(char), bytes_read, fp); - - gTotalBytesRead += int(bytes_read); - - if (gTotalBytes != -1) - wsprintf(gProgress, L"Downloaded: %d%%", 100 * gTotalBytesRead / gTotalBytes); - else - wsprintf(gProgress, L"Downloaded: %dK", gTotalBytesRead / 1024); - - } - - DEBUG("Calling InvalidateRect"); - - // Mark the window as needing redraw (of the whole thing) - InvalidateRect(gWindow, NULL, TRUE); - - // Do the redraw - DEBUG("Calling UpdateWindow"); - UpdateWindow(gWindow); - - DEBUG("Calling PeekMessage"); - MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - { - // bail out, user cancelled - *cancelled = TRUE; - } - } - } - - fclose(fp); - return success; -} - -LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) -{ - HDC hdc; // Drawing context - PAINTSTRUCT ps; - - switch(message) - { - case WM_PAINT: - { - hdc = BeginPaint(hwnd, &ps); - - RECT rect; - GetClientRect(hwnd, &rect); - DrawText(hdc, gProgress, -1, &rect, - DT_SINGLELINE | DT_CENTER | DT_VCENTER); - - EndPaint(hwnd, &ps); - return 0; - } - case WM_CLOSE: - case WM_DESTROY: - // Get out of full screen - // full_screen_mode(false); - PostQuitMessage(0); - return 0; - } - return DefWindowProc(hwnd, message, wparam, lparam); -} - -#define win_class_name L"FullScreen" - -int parse_args(int argc, char **argv) -{ - int j; - - for (j = 1; j < argc; j++) - { - if ((!strcmp(argv[j], "-url")) && (++j < argc)) - { - gUpdateURL = argv[j]; - } - } - - // If nothing was set, let the caller know. - if (!gUpdateURL) - { - return 1; - } - return 0; -} - -int WINAPI -WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) -{ - // Parse the command line. - LPSTR cmd_line_including_exe_name = GetCommandLineA(); - - const int MAX_ARGS = 100; - int argc = 0; - char* argv[MAX_ARGS]; /* Flawfinder: ignore */ - -#if _DEBUG - logfile.open("updater.log", std::ios_base::out); - DEBUG("Parsing command arguments"); -#endif - - char *token = NULL; - if( cmd_line_including_exe_name[0] == '\"' ) - { - // Exe name is enclosed in quotes - token = strtok( cmd_line_including_exe_name, "\"" ); - argv[argc++] = token; - token = strtok( NULL, " \t," ); - } - else - { - // Exe name is not enclosed in quotes - token = strtok( cmd_line_including_exe_name, " \t," ); - } - - while( (token != NULL) && (argc < MAX_ARGS) ) - { - argv[argc++] = token; - /* Get next token: */ - if (*(token + strlen(token) + 1) == '\"') /* Flawfinder: ignore */ - { - token = strtok( NULL, "\""); - } - else - { - token = strtok( NULL, " \t," ); - } - } - - gUpdateURL = NULL; - - ///////////////////////////////////////// - // - // Process command line arguments - // - - DEBUG("Processing command arguments"); - - // - // Parse the command line arguments - // - int parse_args_result = parse_args(argc, argv); - - WNDCLASSEX wndclassex = { 0 }; - //DEVMODE dev_mode = { 0 }; - - const int WINDOW_WIDTH = 250; - const int WINDOW_HEIGHT = 100; - - wsprintf(gProgress, L"Connecting..."); - - /* Init the WNDCLASSEX */ - wndclassex.cbSize = sizeof(WNDCLASSEX); - wndclassex.style = CS_HREDRAW | CS_VREDRAW; - wndclassex.hInstance = hInstance; - wndclassex.lpfnWndProc = WinProc; - wndclassex.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); - wndclassex.lpszClassName = win_class_name; - - RegisterClassEx(&wndclassex); - - // Get the size of the screen - //EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode); - - gWindow = CreateWindowEx(NULL, win_class_name, - L"Second Life Updater", - WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, - CW_USEDEFAULT, - WINDOW_WIDTH, - WINDOW_HEIGHT, - NULL, NULL, hInstance, NULL); - - ShowWindow(gWindow, nShowCmd); - UpdateWindow(gWindow); - - if (parse_args_result) - { - MessageBox(gWindow, - L"Usage: updater -url <url> [-name <window_title>] [-program <program_name>] [-silent]", - L"Usage", MB_OK); - return parse_args_result; - } - - // Did we get a userserver to work with? - if (!gUpdateURL) - { - MessageBox(gWindow, L"Please specify the download url from the command line", - L"Error", MB_OK); - return 1; - } - - // Can't feed GetTempPath into GetTempFile directly - char temp_path[MAX_PATH]; /* Flawfinder: ignore */ - if (0 == GetTempPathA(sizeof(temp_path), temp_path)) - { - MessageBox(gWindow, L"Problem with GetTempPath()", - L"Error", MB_OK); - return 1; - } - std::string update_exec_path(temp_path); - update_exec_path.append("Second_Life_Updater.exe"); - - WCHAR update_uri[4096]; - mbstowcs(update_uri, gUpdateURL, sizeof(update_uri)); - - int success = 0; - int cancelled = 0; - - // Actually do the download - try - { - DEBUG("Calling get_url_into_file"); - success = get_url_into_file(update_uri, update_exec_path, &cancelled); - } - catch (const Fetcher::InetError& e) - { - (void)e; - success = FALSE; - DEBUG("Caught: " << e.what()); - } - - // WinInet can't tell us if we got a 404 or not. Therefor, we check - // for the size of the downloaded file, and assume that our installer - // will always be greater than 1MB. - if (gTotalBytesRead < (1024 * 1024) && ! cancelled) - { - MessageBox(gWindow, - L"The Second Life auto-update has failed.\n" - L"The problem may be caused by other software installed \n" - L"on your computer, such as a firewall.\n" - L"Please visit http://secondlife.com/download/ \n" - L"to download the latest version of Second Life.\n", - NULL, MB_OK); - return 1; - } - - if (cancelled) - { - // silently exit - return 0; - } - - if (!success) - { - MessageBox(gWindow, - L"Second Life download failed.\n" - L"Please try again later.", - NULL, MB_OK); - return 1; - } - - // TODO: Make updates silent (with /S to NSIS) - //char params[256]; /* Flawfinder: ignore */ - //sprintf(params, "/S"); /* Flawfinder: ignore */ - //MessageBox(gWindow, - // L"Updating Second Life.\n\nSecond Life will automatically start once the update is complete. This may take a minute...", - // L"Download Complete", - // MB_OK); - -/*==========================================================================*| - // DEV-31680: ShellExecuteA() causes McAfee-GW-Edition and AntiVir - // scanners to flag this executable as a probable virus vector. - // Less than or equal to 32 means failure - if (32 >= (int) ShellExecuteA(gWindow, "open", update_exec_path.c_str(), NULL, - "C:\\", SW_SHOWDEFAULT)) -|*==========================================================================*/ - // from http://msdn.microsoft.com/en-us/library/ms682512(VS.85).aspx - STARTUPINFOA si; - PROCESS_INFORMATION pi; - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - ZeroMemory(&pi, sizeof(pi)); - - if (! CreateProcessA(update_exec_path.c_str(), // executable file - NULL, // command line - NULL, // process cannot be inherited - NULL, // thread cannot be inherited - FALSE, // do not inherit existing handles - 0, // process creation flags - NULL, // inherit parent's environment - NULL, // inherit parent's current dir - &si, // STARTUPINFO - &pi)) // PROCESS_INFORMATION - { - MessageBox(gWindow, L"Update failed. Please try again later.", NULL, MB_OK); - return 1; - } - - // Give installer some time to open a window - Sleep(1000); - - return 0; -} |