master
Anchor Linden 2018-09-17 10:50:08 -07:00
commit e5aeaa659a
140 changed files with 2457 additions and 762 deletions

View File

@ -538,3 +538,5 @@ ad0e15543836d64d6399d28b32852510435e344a 5.1.0-release
7b6b020fd5ad9a8dc3670c5c92d1ca92e55fc485 5.1.4-release
2ea47f358b171178eb9a95503a1670d519c2886f 5.1.5-release
04538b8157c1f5cdacd9403f0a395452d4a93689 5.1.6-release
ac3b1332ad4f55b7182a8cbcc1254535a0069f75 5.1.7-release
23ea0fe36fadf009a60c080392ce80e4bf8af8d9 5.1.8-release

View File

@ -1692,7 +1692,7 @@
<key>darwin</key>
<map>
<key>archive</key>
<map>
<map>
<key>hash</key>
<string>3855bd40f950e3c22739ae8f3ee2afc9</string>
<key>url</key>
@ -1705,10 +1705,10 @@
<map>
<key>archive</key>
<map>
<key>hash</key>
<key>hash</key>
<string>d1521becaf21bf7233173722af63f57d</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15257/98440/kdu-7.10.4.513518-darwin64-513518.tar.bz2</string>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15257/98440/kdu-7.10.4.513518-darwin64-513518.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -1717,10 +1717,10 @@
<map>
<key>archive</key>
<map>
<key>hash</key>
<key>hash</key>
<string>43d7a6a69a54534a736f132e9c81795b</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15255/98451/kdu-7.10.4.513518-linux-513518.tar.bz2</string>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15255/98451/kdu-7.10.4.513518-linux-513518.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1752,11 +1752,11 @@
<key>windows64</key>
<map>
<key>archive</key>
<map>
<map>
<key>hash</key>
<string>da3b1ea90797b189d80ab5d50fdf05d4</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15260/98469/kdu-7.10.4.513518-windows64-513518.tar.bz2</string>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15260/98469/kdu-7.10.4.513518-windows64-513518.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
@ -3032,9 +3032,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>b1b0134bc55f55a7c1a04ee78d70c64d</string>
<string>a605ec940768c878527d3b8f2ff61288</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12438/73598/slvoice-4.9.0002.27586.511884-darwin64-511884.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/21421/157284/slvoice-4.9.0002.30313.517593-darwin64-517593.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -3068,9 +3068,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>ec50c31efce74bdedee470b5388aeeec</string>
<string>5a78539626b5f23522d0b466247f48b4</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12434/73576/slvoice-4.9.0002.27586.511884-windows-511884.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/21422/157291/slvoice-4.9.0002.30313.517593-windows-517593.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -3080,16 +3080,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>4bf45d641bf5b2bd6b2cc39edcb01a6e</string>
<string>1f8e09c053c00d9dc44ea74568e63dc1</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12433/73570/slvoice-4.9.0002.27586.511884-windows64-511884.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/21423/157298/slvoice-4.9.0002.30313.517593-windows64-517593.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>4.9.0002.27586.511884</string>
<string>4.9.0002.30313.517593</string>
</map>
<key>tut</key>
<map>
@ -3260,9 +3260,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>86f6708f393c162cd4f92426b0a3cde7</string>
<string>f45c0a5e7b4601b355e163bf62f5718e</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15341/99062/viewer_manager-1.0.513570-darwin64-513570.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/20587/147509/viewer_manager-1.0.517052-darwin64-517052.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -3284,9 +3284,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>c4dec51062ad78c09b11f7432aff4d1d</string>
<string>d2443caf062697430071d458a965f611</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/17857/121832/viewer_manager-1.0.515286-windows-515286.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/20588/147516/viewer_manager-1.0.517052-windows-517052.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -3297,7 +3297,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>source_type</key>
<string>hg</string>
<key>version</key>
<string>1.0.515286</string>
<string>1.0.517052</string>
</map>
<key>vlc-bin</key>
<map>
@ -3548,6 +3548,8 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
</map>
<key>package_description</key>
<map>
<key>canonical_repo</key>
<string>https://bitbucket.org/lindenlab/viewer-release</string>
<key>copyright</key>
<string>Copyright (c) 2014, Linden Research, Inc.</string>
<key>description</key>
@ -3662,10 +3664,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<map>
<key>command</key>
<string>xcodebuild</string>
<key>filters</key>
<array>
<string>setenv</string>
</array>
<key>options</key>
<array>
<string>-configuration</string>
@ -3722,10 +3720,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<map>
<key>command</key>
<string>xcodebuild</string>
<key>filters</key>
<array>
<string>setenv</string>
</array>
<key>options</key>
<array>
<string>-configuration</string>

View File

@ -114,7 +114,6 @@ pre_build()
-DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \
-DVIEWER_CHANNEL:STRING="${viewer_channel}" \
-DGRID:STRING="\"$viewer_grid\"" \
-DLL_TESTS:BOOL="$run_tests" \
-DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url \
"${SIGNING[@]}" \
|| fatal "$variant configuration failed"

View File

@ -220,7 +220,6 @@ Ansariel Hiller
STORM-2151
MAINT-6917
MAINT-8085
STORM-2122
Aralara Rajal
Arare Chantilly
CHUIBUG-191

View File

@ -1,2 +1,3 @@

View File

@ -335,6 +335,7 @@ const U8 CLICK_ACTION_OPEN = 4;
const U8 CLICK_ACTION_PLAY = 5;
const U8 CLICK_ACTION_OPEN_MEDIA = 6;
const U8 CLICK_ACTION_ZOOM = 7;
const U8 CLICK_ACTION_DISABLED = 8;
// DO NOT CHANGE THE SEQUENCE OF THIS LIST!!

View File

@ -35,6 +35,7 @@
// external library headers
#include <boost/bind.hpp>
// other Linden headers
#include "lltimer.h"
#include "llevents.h"
#include "llerror.h"
#include "stringize.h"
@ -280,6 +281,25 @@ void LLCoros::setStackSize(S32 stacksize)
mStackSize = stacksize;
}
void LLCoros::printActiveCoroutines()
{
LL_INFOS("LLCoros") << "Number of active coroutines: " << (S32)mCoros.size() << LL_ENDL;
if (mCoros.size() > 0)
{
LL_INFOS("LLCoros") << "-------------- List of active coroutines ------------";
CoroMap::iterator iter;
CoroMap::iterator end = mCoros.end();
F64 time = LLTimer::getTotalSeconds();
for (iter = mCoros.begin(); iter != end; iter++)
{
F64 life_time = time - iter->second->mCreationTime;
LL_CONT << LL_NEWLINE << "Name: " << iter->first << " life: " << life_time;
}
LL_CONT << LL_ENDL;
LL_INFOS("LLCoros") << "-----------------------------------------------------" << LL_ENDL;
}
}
#if LL_WINDOWS
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
@ -375,7 +395,8 @@ LLCoros::CoroData::CoroData(CoroData* prev, const std::string& name,
mCoro(boost::bind(toplevel, _1, this, callable), stacksize),
// don't consume events unless specifically directed
mConsuming(false),
mSelf(0)
mSelf(0),
mCreationTime(LLTimer::getTotalSeconds())
{
}
@ -384,7 +405,13 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
std::string name(generateDistinctName(prefix));
Current current;
// pass the current value of Current as previous context
CoroData* newCoro = new CoroData(current, name, callable, mStackSize);
CoroData* newCoro = new(std::nothrow) CoroData(current, name, callable, mStackSize);
if (newCoro == NULL)
{
// Out of memory?
printActiveCoroutines();
LL_ERRS("LLCoros") << "Failed to start coroutine: " << name << " Stacksize: " << mStackSize << " Total coroutines: " << mCoros.size() << LL_ENDL;
}
// Store it in our pointer map
mCoros.insert(name, newCoro);
// also set it as current

View File

@ -151,6 +151,9 @@ public:
/// for delayed initialization
void setStackSize(S32 stacksize);
/// for delayed initialization
void printActiveCoroutines();
/// get the current coro::self& for those who really really care
static coro::self& get_self();
@ -223,6 +226,7 @@ private:
// function signature down to that point -- and of course through every
// other caller of every such function.
LLCoros::coro::self* mSelf;
F64 mCreationTime; // since epoch
};
typedef boost::ptr_map<std::string, CoroData> CoroMap;
CoroMap mCoros;

View File

@ -249,23 +249,13 @@ namespace LLError
{
#ifdef __GNUC__
// GCC: type_info::name() returns a mangled class name,st demangle
static size_t abi_name_len = 100;
static char* abi_name_buf = (char*)malloc(abi_name_len);
// warning: above is voodoo inferred from the GCC manual,
// do NOT change
int status;
// We don't use status, and shouldn't have to pass apointer to it
// but gcc 3.3 libstc++'s implementation of demangling is broken
// and fails without.
char* name = abi::__cxa_demangle(mangled,
abi_name_buf, &abi_name_len, &status);
// this call can realloc the abi_name_buf pointer (!)
return name ? name : mangled;
// passing nullptr, 0 forces allocation of a unique buffer we can free
// fixing MAINT-8724 on OSX 10.14
int status = -1;
char* name = abi::__cxa_demangle(mangled, nullptr, 0, &status);
std::string result(name ? name : mangled);
free(name);
return result;
#elif LL_WINDOWS
// DevStudio: type_info::name() includes the text "class " at the start

View File

@ -95,10 +95,12 @@ HttpService::~HttpService()
if (! mThread->timedJoin(250))
{
// Failed to join, expect problems ahead so do a hard termination.
mThread->cancel();
LL_WARNS(LOG_CORE) << "Destroying HttpService with running thread. Expect problems." << LL_NEWLINE
<< "State: " << S32(sState)
<< " Last policy: " << U32(mLastPolicy)
<< LL_ENDL;
LL_WARNS(LOG_CORE) << "Destroying HttpService with running thread. Expect problems."
<< LL_ENDL;
mThread->cancel();
}
}
}

View File

@ -192,7 +192,13 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
ret = (U8*) ll_aligned_malloc<64>(size);
if (!ret)
{
LL_ERRS() << "Failed to allocate for LLVBOPool buffer" << LL_ENDL;
LL_ERRS() << "Failed to allocate "<< size << " bytes for LLVBOPool buffer " << name <<"." << LL_NEWLINE
<< "Free list size: " << mFreeList.size() // this happens if we are out of memory so a solution might be to clear some from freelist
<< " Allocated Bytes: " << LLVertexBuffer::sAllocatedBytes
<< " Allocated Index Bytes: " << LLVertexBuffer::sAllocatedIndexBytes
<< " Pooled Bytes: " << sBytesPooled
<< " Pooled Index Bytes: " << sIndexBytesPooled
<< LL_ENDL;
}
}
}

View File

@ -2784,7 +2784,6 @@ void LLScrollListCtrl::onClickColumn(void *userdata)
}
// if this column is the primary sort key, reverse the direction
sort_column_t cur_sort_column;
if (!parent->mSortColumns.empty() && parent->mSortColumns.back().first == column_index)
{
ascending = !parent->mSortColumns.back().second;

View File

@ -201,6 +201,7 @@ set(viewer_SOURCE_FILES
llflickrconnect.cpp
llfloaterabout.cpp
llfloaterbvhpreview.cpp
llfloaterauction.cpp
llfloaterautoreplacesettings.cpp
llfloateravatar.cpp
llfloateravatarpicker.cpp
@ -822,6 +823,7 @@ set(viewer_HEADER_FILES
llflickrconnect.h
llfloaterabout.h
llfloaterbvhpreview.h
llfloaterauction.h
llfloaterautoreplacesettings.h
llfloateravatar.h
llfloateravatarpicker.h
@ -2055,7 +2057,12 @@ if (DARWIN)
# These all get set with PROPERTIES
set(product "Second Life")
# this is the setting for the Python wrapper, see SL-322 and WRAPPER line in Info-SecondLife.plist
set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
if (PACKAGE)
set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
else (PACKAGE)
# force the name of the actual executable to allow running it within Xcode for debugging
set(MACOSX_WRAPPER_EXECUTABLE_NAME "../Resources/Second Life Viewer.app/Contents/MacOS/Second Life")
endif (PACKAGE)
set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer")
set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")

View File

@ -1 +1 @@
5.1.7
5.1.9

View File

@ -3703,13 +3703,13 @@
<key>FeatureManagerHTTPTable</key>
<map>
<key>Comment</key>
<string>Base directory for HTTP feature/gpu table fetches</string>
<string>Deprecated</string>
<key>Persist</key>
<integer>1</integer>
<integer>0</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>http://viewer-settings.secondlife.com</string>
<string></string>
</map>
<key>FPSLogFrequency</key>
<map>
@ -12280,7 +12280,7 @@
<key>Comment</key>
<string>If TRUE, always load textures at full resolution (discard = 0)</string>
<key>Persist</key>
<integer>1</integer>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>

View File

@ -76,6 +76,8 @@ const F32 AVATAR_ZOOM_MIN_Y_FACTOR = 0.7f;
const F32 AVATAR_ZOOM_MIN_Z_FACTOR = 1.15f;
const F32 MAX_CAMERA_DISTANCE_FROM_AGENT = 50.f;
const F32 MAX_CAMERA_DISTANCE_FROM_OBJECT = 496.f;
const F32 CAMERA_FUDGE_FROM_OBJECT = 16.f;
const F32 MAX_CAMERA_SMOOTH_DISTANCE = 50.0f;
@ -738,10 +740,7 @@ F32 LLAgentCamera::getCameraZoomFraction()
else
{
F32 min_zoom;
const F32 DIST_FUDGE = 16.f; // meters
F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE,
LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE,
MAX_CAMERA_DISTANCE_FROM_AGENT);
F32 max_zoom = getCameraMaxZoomDistance();
F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
if (mFocusObject.notNull())
@ -787,23 +786,17 @@ void LLAgentCamera::setCameraZoomFraction(F32 fraction)
else
{
F32 min_zoom = LAND_MIN_ZOOM;
const F32 DIST_FUDGE = 16.f; // meters
F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE,
LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE,
MAX_CAMERA_DISTANCE_FROM_AGENT);
F32 max_zoom = getCameraMaxZoomDistance();
if (mFocusObject.notNull())
{
if (mFocusObject.notNull())
if (mFocusObject->isAvatar())
{
if (mFocusObject->isAvatar())
{
min_zoom = AVATAR_MIN_ZOOM;
}
else
{
min_zoom = OBJECT_MIN_ZOOM;
}
min_zoom = AVATAR_MIN_ZOOM;
}
else
{
min_zoom = OBJECT_MIN_ZOOM;
}
}
@ -909,10 +902,7 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction)
new_distance = llmax(new_distance, min_zoom);
// Don't zoom too far back
const F32 DIST_FUDGE = 16.f; // meters
F32 max_distance = llmin(mDrawDistance - DIST_FUDGE,
LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
F32 max_distance = getCameraMaxZoomDistance();
max_distance = llmin(max_distance, current_distance * 4.f); //Scaled max relative to current distance. MAINT-3154
@ -978,10 +968,7 @@ void LLAgentCamera::cameraOrbitIn(const F32 meters)
new_distance = llmax(new_distance, min_zoom);
// Don't zoom too far back
const F32 DIST_FUDGE = 16.f; // meters
F32 max_distance = llmin(mDrawDistance - DIST_FUDGE,
LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
F32 max_distance = getCameraMaxZoomDistance();
if (new_distance > max_distance)
{
@ -1946,6 +1933,13 @@ LLVector3 LLAgentCamera::getCameraOffsetInitial()
return convert_from_llsd<LLVector3>(mCameraOffsetInitial[mCameraPreset]->get(), TYPE_VEC3, "");
}
F32 LLAgentCamera::getCameraMaxZoomDistance()
{
// Ignore "DisableCameraConstraints", we don't want to be out of draw range when we focus onto objects or avatars
return llmin(MAX_CAMERA_DISTANCE_FROM_OBJECT,
mDrawDistance - 1, // convenience, don't hit draw limit when focusing on something
LLWorld::getInstance()->getRegionWidthInMeters() - CAMERA_FUDGE_FROM_OBJECT);
}
//-----------------------------------------------------------------------------
// handleScrollWheel()

View File

@ -112,6 +112,8 @@ public:
private:
/** Determines default camera offset depending on the current camera preset */
LLVector3 getCameraOffsetInitial();
/** Determines maximum camera distance from target for mouselook, opposite to LAND_MIN_ZOOM */
F32 getCameraMaxZoomDistance();
/** Camera preset in Third Person Mode */
ECameraPreset mCameraPreset;

View File

@ -42,6 +42,7 @@
#include "llagentlanguage.h"
#include "llagentui.h"
#include "llagentwearables.h"
#include "lldirpicker.h"
#include "llfloaterimcontainer.h"
#include "llimprocessing.h"
#include "llwindow.h"
@ -1082,6 +1083,8 @@ bool LLAppViewer::init()
}
}
// don't nag developers who need to run the executable directly
#if LL_RELEASE_FOR_DOWNLOAD
// MAINT-8305: If we're processing a SLURL, skip the launcher check.
if (gSavedSettings.getString("CmdLineLoginLocation").empty())
{
@ -1098,6 +1101,7 @@ bool LLAppViewer::init()
LLNotificationsUtil::add("RunLauncher");
}
}
#endif
#if LL_WINDOWS
if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())
@ -1577,6 +1581,11 @@ bool LLAppViewer::doFrame()
saveFinalSnapshot();
}
if (LLVoiceClient::instanceExists())
{
LLVoiceClient::getInstance()->terminate();
}
delete gServicePump;
destroyMainloopTimeout();
@ -1676,11 +1685,6 @@ bool LLAppViewer::cleanup()
// Give any remaining SLPlugin instances a chance to exit cleanly.
LLPluginProcessParent::shutdown();
if (LLVoiceClient::instanceExists())
{
LLVoiceClient::getInstance()->terminate();
}
disconnectViewer();
LL_INFOS() << "Viewer disconnected" << LL_ENDL;
@ -1794,6 +1798,8 @@ bool LLAppViewer::cleanup()
// (Deleted observers should have already removed themselves)
gInventory.cleanupInventory();
LLCoros::getInstance()->printActiveCoroutines();
LL_INFOS() << "Cleaning up Selections" << LL_ENDL;
// Clean up selection managers after UI is destroyed, as UI may be observing them.
@ -1980,6 +1986,7 @@ bool LLAppViewer::cleanup()
mAppCoreHttp.cleanup();
SUBSYSTEM_CLEANUP(LLFilePickerThread);
SUBSYSTEM_CLEANUP(LLDirPickerThread);
//MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl)
delete sTextureCache;
@ -2150,6 +2157,7 @@ bool LLAppViewer::initThreads()
gMeshRepo.init();
LLFilePickerThread::initClass();
LLDirPickerThread::initClass();
// *FIX: no error handling here!
return true;
@ -4584,7 +4592,7 @@ void LLAppViewer::idle()
LLSmoothInterpolation::updateInterpolants();
LLMortician::updateClass();
LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify()
LLDirPickerThread::clearDead();
F32 dt_raw = idle_timer.getElapsedTimeAndResetF32();
// Cap out-of-control frame times

View File

@ -528,10 +528,24 @@ public:
registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2));
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mPopupMenuHandleAvatar = menu->getHandle();
if (menu)
{
mPopupMenuHandleAvatar = menu->getHandle();
}
else
{
LL_WARNS() << " Failed to create menu_avatar_icon.xml" << LL_ENDL;
}
menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_object_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mPopupMenuHandleObject = menu->getHandle();
if (menu)
{
mPopupMenuHandleObject = menu->getHandle();
}
else
{
LL_WARNS() << " Failed to create menu_object_icon.xml" << LL_ENDL;
}
setDoubleClickCallback(boost::bind(&LLChatHistoryHeader::showInspector, this));
@ -619,7 +633,12 @@ public:
}
mUserNameFont = style_params.font();
LLTextBox* user_name = getChild<LLTextBox>("user_name");
if (!mUserNameTextBox)
{
mUserNameTextBox = getChild<LLTextBox>("user_name");
mTimeBoxTextBox = getChild<LLTextBox>("time_box");
}
LLTextBox* user_name = mUserNameTextBox;
user_name->setReadOnlyColor(style_params.readonly_color());
user_name->setColor(style_params.color());

View File

@ -77,6 +77,14 @@ LLDirPicker::LLDirPicker() :
mFileName(NULL),
mLocked(false)
{
bi.hwndOwner = NULL;
bi.pidlRoot = NULL;
bi.pszDisplayName = NULL;
bi.lpszTitle = NULL;
bi.ulFlags = BIF_USENEWUI;
bi.lpfn = NULL;
bi.lParam = NULL;
bi.iImage = 0;
}
LLDirPicker::~LLDirPicker()
@ -84,7 +92,7 @@ LLDirPicker::~LLDirPicker()
// nothing
}
BOOL LLDirPicker::getDir(std::string* filename)
BOOL LLDirPicker::getDir(std::string* filename, bool blocking)
{
if( mLocked )
{
@ -99,39 +107,39 @@ BOOL LLDirPicker::getDir(std::string* filename)
BOOL success = FALSE;
// Modal, so pause agent
send_agent_pause();
if (blocking)
{
// Modal, so pause agent
send_agent_pause();
}
BROWSEINFO bi;
memset(&bi, 0, sizeof(bi));
bi.hwndOwner = (HWND)gViewerWindow->getPlatformWindow();
bi.ulFlags = BIF_USENEWUI;
bi.hwndOwner = (HWND)gViewerWindow->getPlatformWindow();
bi.lpszTitle = NULL;
::OleInitialize(NULL);
LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);
::OleInitialize(NULL);
if(pIDL != NULL)
{
WCHAR buffer[_MAX_PATH] = {'\0'};
LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);
if(::SHGetPathFromIDList(pIDL, buffer) != 0)
{
// Set the string value.
if(pIDL != NULL)
{
WCHAR buffer[_MAX_PATH] = {'\0'};
mDir = utf16str_to_utf8str(llutf16string(buffer));
success = TRUE;
}
// free the item id list
CoTaskMemFree(pIDL);
}
if(::SHGetPathFromIDList(pIDL, buffer) != 0)
{
// Set the string value.
::OleUninitialize();
mDir = utf16str_to_utf8str(llutf16string(buffer));
success = TRUE;
}
// free the item id list
CoTaskMemFree(pIDL);
}
::OleUninitialize();
send_agent_resume();
if (blocking)
{
send_agent_resume();
}
// Account for the fact that the app has been stalled.
LLFrameTimer::updateFrameTime();
@ -167,7 +175,7 @@ void LLDirPicker::reset()
//static
BOOL LLDirPicker::getDir(std::string* filename)
BOOL LLDirPicker::getDir(std::string* filename, bool blocking)
{
LLFilePicker::ELoadFilter filter=LLFilePicker::FFLOAD_DIRECTORY;
@ -201,7 +209,7 @@ void LLDirPicker::reset()
mFilePicker->reset();
}
BOOL LLDirPicker::getDir(std::string* filename)
BOOL LLDirPicker::getDir(std::string* filename, bool blocking)
{
reset();
@ -256,7 +264,7 @@ void LLDirPicker::reset()
{
}
BOOL LLDirPicker::getDir(std::string* filename)
BOOL LLDirPicker::getDir(std::string* filename, bool blocking)
{
return FALSE;
}
@ -267,3 +275,94 @@ std::string LLDirPicker::getDirName()
}
#endif
LLMutex* LLDirPickerThread::sMutex = NULL;
std::queue<LLDirPickerThread*> LLDirPickerThread::sDeadQ;
void LLDirPickerThread::getFile()
{
#if LL_WINDOWS
start();
#else
run();
#endif
}
//virtual
void LLDirPickerThread::run()
{
#if LL_WINDOWS
bool blocking = false;
#else
bool blocking = true; // modal
#endif
LLDirPicker picker;
if (picker.getDir(&mProposedName, blocking))
{
mResponses.push_back(picker.getDirName());
}
{
LLMutexLock lock(sMutex);
sDeadQ.push(this);
}
}
//static
void LLDirPickerThread::initClass()
{
sMutex = new LLMutex(NULL);
}
//static
void LLDirPickerThread::cleanupClass()
{
clearDead();
delete sMutex;
sMutex = NULL;
}
//static
void LLDirPickerThread::clearDead()
{
if (!sDeadQ.empty())
{
LLMutexLock lock(sMutex);
while (!sDeadQ.empty())
{
LLDirPickerThread* thread = sDeadQ.front();
thread->notify(thread->mResponses);
delete thread;
sDeadQ.pop();
}
}
}
LLDirPickerThread::LLDirPickerThread(const dir_picked_signal_t::slot_type& cb, const std::string &proposed_name)
: LLThread("dir picker"),
mFilePickedSignal(NULL)
{
mFilePickedSignal = new dir_picked_signal_t();
mFilePickedSignal->connect(cb);
}
LLDirPickerThread::~LLDirPickerThread()
{
delete mFilePickedSignal;
}
void LLDirPickerThread::notify(const std::vector<std::string>& filenames)
{
if (!filenames.empty())
{
if (mFilePickedSignal)
{
(*mFilePickedSignal)(filenames, mProposedName);
}
}
}

View File

@ -33,6 +33,13 @@
#include "stdtypes.h"
#include "llthread.h"
#include <queue>
#if LL_WINDOWS
#include <shlobj.h>
#endif
#if LL_DARWIN
// AssertMacros.h does bad things.
@ -53,7 +60,7 @@ public:
// calling this before main() is undefined
static LLDirPicker& instance( void ) { return sInstance; }
BOOL getDir(std::string* filename);
BOOL getDir(std::string* filename, bool blocking = true);
std::string getDirName();
// clear any lists of buffers or whatever, and make sure the dir
@ -76,11 +83,15 @@ private:
LLFilePicker *mFilePicker;
#endif
std::string* mFileName;
std::string mDir;
bool mLocked;
static LLDirPicker sInstance;
#if LL_WINDOWS
BROWSEINFO bi;
#endif
public:
// don't call these directly please.
@ -88,4 +99,33 @@ public:
~LLDirPicker();
};
class LLDirPickerThread : public LLThread
{
public:
static std::queue<LLDirPickerThread*> sDeadQ;
static LLMutex* sMutex;
static void initClass();
static void cleanupClass();
static void clearDead();
std::vector<std::string> mResponses;
std::string mProposedName;
typedef boost::signals2::signal<void(const std::vector<std::string>& filenames, std::string proposed_name)> dir_picked_signal_t;
LLDirPickerThread(const dir_picked_signal_t::slot_type& cb, const std::string &proposed_name);
~LLDirPickerThread();
void getFile();
virtual void run();
virtual void notify(const std::vector<std::string>& filenames);
private:
dir_picked_signal_t* mFilePickedSignal;
};
#endif

View File

@ -328,6 +328,9 @@ void LLDrawPoolAlpha::render(S32 pass)
gGL.diffuseColor4f(0, 0, 1, 1);
pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
gGL.diffuseColor4f(0, 1, 0, 1);
pushBatches(LLRenderPass::PASS_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
if(shaders)
{
gHighlightProgram.unbind();

View File

@ -62,13 +62,10 @@
#if LL_DARWIN
const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt";
const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_mac.%s.txt";
#elif LL_LINUX
const char FEATURE_TABLE_FILENAME[] = "featuretable_linux.txt";
const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_linux.%s.txt";
#else
const char FEATURE_TABLE_FILENAME[] = "featuretable.txt";
const char FEATURE_TABLE_VER_FILENAME[] = "featuretable.%s.txt";
#endif
#if 0 // consuming code in #if 0 below
@ -273,33 +270,11 @@ bool LLFeatureManager::loadFeatureTables()
app_path += gDirUtilp->getDirDelimiter();
std::string filename;
std::string http_filename;
filename = FEATURE_TABLE_FILENAME;
http_filename = llformat(FEATURE_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str());
app_path += filename;
// second table is downloaded with HTTP - note that this will only be used on the run _after_ it is downloaded
std::string http_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, http_filename);
// use HTTP table if it exists
std::string path;
bool parse_ok = false;
if (gDirUtilp->fileExists(http_path))
{
parse_ok = parseFeatureTable(http_path);
if (!parse_ok)
{
// the HTTP table failed to parse, so delete it
LLFile::remove(http_path);
LL_WARNS("RenderInit") << "Removed invalid feature table '" << http_path << "'" << LL_ENDL;
}
}
if (!parse_ok)
{
parse_ok = parseFeatureTable(app_path);
}
bool parse_ok = parseFeatureTable(app_path);
return parse_ok;
}
@ -407,7 +382,16 @@ bool LLFeatureManager::loadGPUClass()
if (!gSavedSettings.getBOOL("SkipBenchmark"))
{
//get memory bandwidth from benchmark
F32 gbps = gpu_benchmark();
F32 gbps;
try
{
gbps = gpu_benchmark();
}
catch (const std::exception& e)
{
gbps = -1.f;
LL_WARNS("RenderInit") << "GPU benchmark failed: " << e.what() << LL_ENDL;
}
if (gbps < 0.f)
{ //couldn't bench, use GLVersion
@ -486,70 +470,6 @@ bool LLFeatureManager::loadGPUClass()
return true; // indicates that a gpu value was established
}
void LLFeatureManager::fetchFeatureTableCoro(std::string tableName)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FeatureManagerHTTPTable", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
const std::string base = gSavedSettings.getString("FeatureManagerHTTPTable");
#if LL_WINDOWS
std::string os_string = LLOSInfo::instance().getOSStringSimple();
std::string filename;
if (os_string.find("Microsoft Windows XP") == 0)
{
filename = llformat(tableName.c_str(), "_xp", LLVersionInfo::getVersion().c_str());
}
else
{
filename = llformat(tableName.c_str(), "", LLVersionInfo::getVersion().c_str());
}
#else
const std::string filename = llformat(tableName.c_str(), LLVersionInfo::getVersion().c_str());
#endif
std::string url = base + "/" + filename;
// testing url below
//url = "http://viewer-settings.secondlife.com/featuretable.2.1.1.208406.txt";
const std::string path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
LL_INFOS() << "LLFeatureManager fetching " << url << " into " << path << LL_ENDL;
LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url);
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (status)
{ // There was a newer feature table on the server. We've grabbed it and now should write it.
// write to file
const LLSD::Binary &raw = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
LL_INFOS() << "writing feature table to " << path << LL_ENDL;
S32 size = raw.size();
if (size > 0)
{
// write to file
LLAPRFile out(path, LL_APR_WB);
out.write(raw.data(), size);
out.close();
}
}
}
// fetch table(s) from a website (S3)
void LLFeatureManager::fetchHTTPTables()
{
LLCoros::instance().launch("LLFeatureManager::fetchFeatureTableCoro",
boost::bind(&LLFeatureManager::fetchFeatureTableCoro, this, FEATURE_TABLE_VER_FILENAME));
}
void LLFeatureManager::cleanupFeatureTables()
{
std::for_each(mMaskList.begin(), mMaskList.end(), DeletePairedPointer());

View File

@ -145,9 +145,6 @@ public:
// in the skip list if true
void applyFeatures(bool skipFeatures);
// load the dynamic GPU/feature table from a website
void fetchHTTPTables();
LLSD getRecommendedSettingsMap();
protected:
@ -158,8 +155,6 @@ protected:
void initBaseMask();
void fetchFeatureTableCoro(std::string name);
std::map<std::string, LLFeatureList *> mMaskList;
std::set<std::string> mSkippedFeatures;
BOOL mInited;

View File

@ -0,0 +1,552 @@
/**
* @file llfloaterauction.cpp
* @author James Cook, Ian Wilkes
* @brief Implementation of the auction floater.
*
* $LicenseInfo:firstyear=2004&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 "llviewerprecompiledheaders.h"
#include "llfloaterauction.h"
#include "llgl.h"
#include "llimagej2c.h"
#include "llimagetga.h"
#include "llparcel.h"
#include "llvfile.h"
#include "llvfs.h"
#include "llwindow.h"
#include "message.h"
#include "llagent.h"
#include "llassetstorage.h"
#include "llcombobox.h"
#include "llestateinfomodel.h"
#include "llmimetypes.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llsavedsettingsglue.h"
#include "llviewertexturelist.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "lluictrlfactory.h"
#include "llviewerwindow.h"
#include "llviewerdisplay.h"
#include "llviewercontrol.h"
#include "llui.h"
#include "llrender.h"
#include "llsdutil.h"
#include "llsdutil_math.h"
#include "lltrans.h"
#include "llcorehttputil.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
///----------------------------------------------------------------------------
void auction_j2c_upload_done(const LLUUID& asset_id,
void* user_data, S32 status, LLExtStat ext_status);
void auction_tga_upload_done(const LLUUID& asset_id,
void* user_data, S32 status, LLExtStat ext_status);
///----------------------------------------------------------------------------
/// Class llfloaterauction
///----------------------------------------------------------------------------
// Default constructor
LLFloaterAuction::LLFloaterAuction(const LLSD& key)
: LLFloater(key),
mParcelID(-1)
{
mCommitCallbackRegistrar.add("ClickSnapshot", boost::bind(&LLFloaterAuction::onClickSnapshot, this));
mCommitCallbackRegistrar.add("ClickSellToAnyone", boost::bind(&LLFloaterAuction::onClickSellToAnyone, this));
mCommitCallbackRegistrar.add("ClickStartAuction", boost::bind(&LLFloaterAuction::onClickStartAuction, this));
mCommitCallbackRegistrar.add("ClickResetParcel", boost::bind(&LLFloaterAuction::onClickResetParcel, this));
}
// Destroys the object
LLFloaterAuction::~LLFloaterAuction()
{
}
BOOL LLFloaterAuction::postBuild()
{
return TRUE;
}
void LLFloaterAuction::onOpen(const LLSD& key)
{
initialize();
}
void LLFloaterAuction::initialize()
{
mParcelUpdateCapUrl.clear();
mParcelp = LLViewerParcelMgr::getInstance()->getParcelSelection();
LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
LLParcel* parcelp = mParcelp->getParcel();
if(parcelp && region && !parcelp->getForSale())
{
mParcelHost = region->getHost();
mParcelID = parcelp->getLocalID();
mParcelUpdateCapUrl = region->getCapability("ParcelPropertiesUpdate");
getChild<LLUICtrl>("parcel_text")->setValue(parcelp->getName());
getChildView("snapshot_btn")->setEnabled(TRUE);
getChildView("reset_parcel_btn")->setEnabled(TRUE);
getChildView("start_auction_btn")->setEnabled(TRUE);
U32 estate_id = LLEstateInfoModel::instance().getID();
// Only enable "Sell to Anyone" on Teen grid or if we don't know the ID yet
getChildView("sell_to_anyone_btn")->setEnabled(estate_id == ESTATE_TEEN || estate_id == 0);
}
else
{
mParcelHost.invalidate();
if(parcelp && parcelp->getForSale())
{
getChild<LLUICtrl>("parcel_text")->setValue(getString("already for sale"));
}
else
{
getChild<LLUICtrl>("parcel_text")->setValue(LLStringUtil::null);
}
mParcelID = -1;
getChildView("snapshot_btn")->setEnabled(false);
getChildView("reset_parcel_btn")->setEnabled(false);
getChildView("sell_to_anyone_btn")->setEnabled(false);
getChildView("start_auction_btn")->setEnabled(false);
}
mImageID.setNull();
mImage = NULL;
}
void LLFloaterAuction::draw()
{
LLFloater::draw();
if(!isMinimized() && mImage.notNull())
{
LLView* snapshot_icon = findChildView("snapshot_icon");
if (snapshot_icon)
{
LLRect rect = snapshot_icon->getRect();
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gl_rect_2d(rect, LLColor4(0.f, 0.f, 0.f, 1.f));
rect.stretch(-1);
}
{
LLGLSUIDefault gls_ui;
gGL.color3f(1.f, 1.f, 1.f);
gl_draw_scaled_image(rect.mLeft,
rect.mBottom,
rect.getWidth(),
rect.getHeight(),
mImage);
}
}
}
}
// static
void LLFloaterAuction::onClickSnapshot(void* data)
{
LLFloaterAuction* self = (LLFloaterAuction*)(data);
LLPointer<LLImageRaw> raw = new LLImageRaw;
gForceRenderLandFence = self->getChild<LLUICtrl>("fence_check")->getValue().asBoolean();
BOOL success = gViewerWindow->rawSnapshot(raw,
gViewerWindow->getWindowWidthScaled(),
gViewerWindow->getWindowHeightScaled(),
TRUE, FALSE,
FALSE, FALSE);
gForceRenderLandFence = FALSE;
if (success)
{
self->mTransactionID.generate();
self->mImageID = self->mTransactionID.makeAssetID(gAgent.getSecureSessionID());
if(!gSavedSettings.getBOOL("QuietSnapshotsToDisk"))
{
gViewerWindow->playSnapshotAnimAndSound();
}
LL_INFOS() << "Writing TGA..." << LL_ENDL;
LLPointer<LLImageTGA> tga = new LLImageTGA;
tga->encode(raw);
LLVFile::writeFile(tga->getData(), tga->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_IMAGE_TGA);
raw->biasedScaleToPowerOfTwo(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT);
LL_INFOS() << "Writing J2C..." << LL_ENDL;
LLPointer<LLImageJ2C> j2c = new LLImageJ2C;
j2c->encode(raw, 0.0f);
LLVFile::writeFile(j2c->getData(), j2c->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_TEXTURE);
self->mImage = LLViewerTextureManager::getLocalTexture((LLImageRaw*)raw, FALSE);
gGL.getTexUnit(0)->bind(self->mImage);
self->mImage->setAddressMode(LLTexUnit::TAM_CLAMP);
}
else
{
LL_WARNS() << "Unable to take snapshot" << LL_ENDL;
}
}
// static
void LLFloaterAuction::onClickStartAuction(void* data)
{
LLFloaterAuction* self = (LLFloaterAuction*)(data);
if(self->mImageID.notNull())
{
LLSD parcel_name = self->getChild<LLUICtrl>("parcel_text")->getValue();
// create the asset
std::string* name = new std::string(parcel_name.asString());
gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_IMAGE_TGA,
&auction_tga_upload_done,
(void*)name,
FALSE);
self->getWindow()->incBusyCount();
std::string* j2c_name = new std::string(parcel_name.asString());
gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_TEXTURE,
&auction_j2c_upload_done,
(void*)j2c_name,
FALSE);
self->getWindow()->incBusyCount();
LLNotificationsUtil::add("UploadingAuctionSnapshot");
}
LLMessageSystem* msg = gMessageSystem;
msg->newMessage("ViewerStartAuction");
msg->nextBlock("AgentData");
msg->addUUID("AgentID", gAgent.getID());
msg->addUUID("SessionID", gAgent.getSessionID());
msg->nextBlock("ParcelData");
msg->addS32("LocalID", self->mParcelID);
msg->addUUID("SnapshotID", self->mImageID);
msg->sendReliable(self->mParcelHost);
// clean up floater, and get out
self->cleanupAndClose();
}
void LLFloaterAuction::cleanupAndClose()
{
mImageID.setNull();
mImage = NULL;
mParcelID = -1;
mParcelHost.invalidate();
closeFloater();
}
// static glue
void LLFloaterAuction::onClickResetParcel(void* data)
{
LLFloaterAuction* self = (LLFloaterAuction*)(data);
if (self)
{
self->doResetParcel();
}
}
// Reset all the values for the parcel in preparation for a sale
void LLFloaterAuction::doResetParcel()
{
LLParcel* parcelp = mParcelp->getParcel();
LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
if (parcelp
&& region
&& !mParcelUpdateCapUrl.empty())
{
LLSD body;
std::string empty;
// request new properties update from simulator
U32 message_flags = 0x01;
body["flags"] = ll_sd_from_U32(message_flags);
// Set all the default parcel properties for auction
body["local_id"] = parcelp->getLocalID();
U32 parcel_flags = PF_ALLOW_LANDMARK |
PF_ALLOW_FLY |
PF_CREATE_GROUP_OBJECTS |
PF_ALLOW_ALL_OBJECT_ENTRY |
PF_ALLOW_GROUP_OBJECT_ENTRY |
PF_ALLOW_GROUP_SCRIPTS |
PF_RESTRICT_PUSHOBJECT |
PF_SOUND_LOCAL |
PF_ALLOW_VOICE_CHAT |
PF_USE_ESTATE_VOICE_CHAN;
body["parcel_flags"] = ll_sd_from_U32(parcel_flags);
// Build a parcel name like "Ahern (128,128) PG 4032m"
std::ostringstream parcel_name;
LLVector3 center_point( parcelp->getCenterpoint() );
center_point.snap(0); // Get rid of fractions
parcel_name << region->getName()
<< " ("
<< (S32) center_point.mV[VX]
<< ","
<< (S32) center_point.mV[VY]
<< ") "
<< region->getSimAccessString()
<< " "
<< parcelp->getArea()
<< "m";
std::string new_name(parcel_name.str().c_str());
body["name"] = new_name;
getChild<LLUICtrl>("parcel_text")->setValue(new_name); // Set name in dialog as well, since it won't get updated otherwise
body["sale_price"] = (S32) 0;
body["description"] = empty;
body["music_url"] = empty;
body["media_url"] = empty;
body["media_desc"] = empty;
body["media_type"] = LLMIMETypes::getDefaultMimeType();
body["media_width"] = (S32) 0;
body["media_height"] = (S32) 0;
body["auto_scale"] = (S32) 0;
body["media_loop"] = (S32) 0;
body["obscure_media"] = (S32) 0; // OBSOLETE - no longer used
body["obscure_music"] = (S32) 0; // OBSOLETE - no longer used
body["media_id"] = LLUUID::null;
body["group_id"] = MAINTENANCE_GROUP_ID; // Use maintenance group
body["pass_price"] = (S32) 10; // Defaults to $10
body["pass_hours"] = 0.0f;
body["category"] = (U8) LLParcel::C_NONE;
body["auth_buyer_id"] = LLUUID::null;
body["snapshot_id"] = LLUUID::null;
body["user_location"] = ll_sd_from_vector3( LLVector3::zero );
body["user_look_at"] = ll_sd_from_vector3( LLVector3::zero );
body["landing_type"] = (U8) LLParcel::L_DIRECT;
LL_INFOS() << "Sending parcel update to reset for auction via capability to: "
<< mParcelUpdateCapUrl << LL_ENDL;
LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(mParcelUpdateCapUrl, body,
"Parcel reset for auction",
"Parcel not set for auction.");
// Send a message to clear the object return time
LLMessageSystem *msg = gMessageSystem;
msg->newMessageFast(_PREHASH_ParcelSetOtherCleanTime);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_ParcelData);
msg->addS32Fast(_PREHASH_LocalID, parcelp->getLocalID());
msg->addS32Fast(_PREHASH_OtherCleanTime, 5); // 5 minute object auto-return
msg->sendReliable(region->getHost());
// Clear the access lists
clearParcelAccessList(parcelp, region, AL_ACCESS);
clearParcelAccessList(parcelp, region, AL_BAN);
clearParcelAccessList(parcelp, region, AL_ALLOW_EXPERIENCE);
clearParcelAccessList(parcelp, region, AL_BLOCK_EXPERIENCE);
}
}
void LLFloaterAuction::clearParcelAccessList(LLParcel* parcel, LLViewerRegion* region, U32 list)
{
if (!region || !parcel) return;
LLUUID transactionUUID;
transactionUUID.generate();
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_ParcelAccessListUpdate);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
msg->nextBlockFast(_PREHASH_Data);
msg->addU32Fast(_PREHASH_Flags, list);
msg->addS32(_PREHASH_LocalID, parcel->getLocalID() );
msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID);
msg->addS32Fast(_PREHASH_SequenceID, 1); // sequence_id
msg->addS32Fast(_PREHASH_Sections, 0); // num_sections
// pack an empty block since there will be no data
msg->nextBlockFast(_PREHASH_List);
msg->addUUIDFast(_PREHASH_ID, LLUUID::null );
msg->addS32Fast(_PREHASH_Time, 0 );
msg->addU32Fast(_PREHASH_Flags, 0 );
msg->sendReliable( region->getHost() );
}
// static - 'Sell to Anyone' clicked, throw up a confirmation dialog
void LLFloaterAuction::onClickSellToAnyone(void* data)
{
LLFloaterAuction* self = (LLFloaterAuction*)(data);
if (self)
{
LLParcel* parcelp = self->mParcelp->getParcel();
// Do a confirmation
S32 sale_price = parcelp->getArea(); // Selling for L$1 per meter
S32 area = parcelp->getArea();
LLSD args;
args["LAND_SIZE"] = llformat("%d", area);
args["SALE_PRICE"] = llformat("%d", sale_price);
args["NAME"] = LLTrans::getString("Anyone");
LLNotification::Params params("ConfirmLandSaleChange"); // Re-use existing dialog
params.substitutions(args)
.functor.function(boost::bind(&LLFloaterAuction::onSellToAnyoneConfirmed, self, _1, _2));
params.name("ConfirmLandSaleToAnyoneChange");
// ask away
LLNotifications::instance().add(params);
}
}
// Sell confirmation clicked
bool LLFloaterAuction::onSellToAnyoneConfirmed(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0)
{
doSellToAnyone();
}
return false;
}
// Reset all the values for the parcel in preparation for a sale
void LLFloaterAuction::doSellToAnyone()
{
LLParcel* parcelp = mParcelp->getParcel();
LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
if (parcelp
&& region
&& !mParcelUpdateCapUrl.empty())
{
LLSD body;
std::string empty;
// request new properties update from simulator
U32 message_flags = 0x01;
body["flags"] = ll_sd_from_U32(message_flags);
// Set all the default parcel properties for auction
body["local_id"] = parcelp->getLocalID();
// Set 'for sale' flag
U32 parcel_flags = parcelp->getParcelFlags() | PF_FOR_SALE;
// Ensure objects not included
parcel_flags &= ~PF_FOR_SALE_OBJECTS;
body["parcel_flags"] = ll_sd_from_U32(parcel_flags);
body["sale_price"] = parcelp->getArea(); // Sell for L$1 per square meter
body["auth_buyer_id"] = LLUUID::null; // To anyone
LL_INFOS() << "Sending parcel update to sell to anyone for L$1 via capability to: "
<< mParcelUpdateCapUrl << LL_ENDL;
LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(mParcelUpdateCapUrl, body,
"Parcel set as sell to everyone.",
"Parcel sell to everyone failed.");
// clean up floater, and get out
cleanupAndClose();
}
}
///----------------------------------------------------------------------------
/// Local function definitions
///----------------------------------------------------------------------------
void auction_tga_upload_done(const LLUUID& asset_id, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
{
std::string* name = (std::string*)(user_data);
LL_INFOS() << "Upload of asset '" << *name << "' " << asset_id
<< " returned " << status << LL_ENDL;
delete name;
gViewerWindow->getWindow()->decBusyCount();
if (0 == status)
{
LLNotificationsUtil::add("UploadWebSnapshotDone");
}
else
{
LLSD args;
args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
LLNotificationsUtil::add("UploadAuctionSnapshotFail", args);
}
}
void auction_j2c_upload_done(const LLUUID& asset_id, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
{
std::string* name = (std::string*)(user_data);
LL_INFOS() << "Upload of asset '" << *name << "' " << asset_id
<< " returned " << status << LL_ENDL;
delete name;
gViewerWindow->getWindow()->decBusyCount();
if (0 == status)
{
LLNotificationsUtil::add("UploadSnapshotDone");
}
else
{
LLSD args;
args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
LLNotificationsUtil::add("UploadAuctionSnapshotFail", args);
}
}

View File

@ -0,0 +1,86 @@
/**
* @file llfloaterauction.h
* @author James Cook, Ian Wilkes
* @brief llfloaterauction class header file
*
* $LicenseInfo:firstyear=2004&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$
*/
#ifndef LL_LLFLOATERAUCTION_H
#define LL_LLFLOATERAUCTION_H
#include "llfloater.h"
#include "lluuid.h"
#include "llpointer.h"
#include "llviewertexture.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFloaterAuction
//
// Class which holds the functionality to start auctions.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLParcelSelection;
class LLParcel;
class LLViewerRegion;
class LLFloaterAuction : public LLFloater
{
friend class LLFloaterReg;
public:
// LLFloater interface
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void draw();
private:
LLFloaterAuction(const LLSD& key);
~LLFloaterAuction();
void initialize();
static void onClickSnapshot(void* data);
static void onClickResetParcel(void* data);
static void onClickSellToAnyone(void* data); // Sell to anyone clicked
bool onSellToAnyoneConfirmed(const LLSD& notification, const LLSD& response); // Sell confirmation clicked
static void onClickStartAuction(void* data);
/*virtual*/ BOOL postBuild();
void doResetParcel();
void doSellToAnyone();
void clearParcelAccessList( LLParcel* parcel, LLViewerRegion* region, U32 list);
void cleanupAndClose();
private:
LLTransactionID mTransactionID;
LLAssetID mImageID;
LLPointer<LLViewerTexture> mImage;
LLSafeHandle<LLParcelSelection> mParcelp;
S32 mParcelID;
LLHost mParcelHost;
std::string mParcelUpdateCapUrl; // "ParcelPropertiesUpdate" capability
};
#endif // LL_LLFLOATERAUCTION_H

View File

@ -45,6 +45,7 @@
#include "llcombobox.h"
#include "llfloaterreg.h"
#include "llfloateravatarpicker.h"
#include "llfloaterauction.h"
#include "llfloatergroups.h"
#include "llfloaterscriptlimits.h"
#include "llavataractions.h"
@ -78,7 +79,6 @@
#include "llpanelexperiencelisteditor.h"
#include "llpanelexperiencepicker.h"
#include "llexperiencecache.h"
#include "llweb.h"
#include "llgroupactions.h"
@ -542,6 +542,7 @@ void LLPanelLandGeneral::refresh()
mBtnDeedToGroup->setEnabled(FALSE);
mBtnSetGroup->setEnabled(FALSE);
mBtnStartAuction->setEnabled(FALSE);
mCheckDeedToGroup ->set(FALSE);
mCheckDeedToGroup ->setEnabled(FALSE);
@ -639,6 +640,7 @@ void LLPanelLandGeneral::refresh()
mTextClaimDate->setEnabled(FALSE);
mTextGroup->setText(getString("none_text"));
mTextGroup->setEnabled(FALSE);
mBtnStartAuction->setEnabled(FALSE);
}
else
{
@ -690,6 +692,11 @@ void LLPanelLandGeneral::refresh()
LLStringUtil::format (claim_date_str, substitution);
mTextClaimDate->setText(claim_date_str);
mTextClaimDate->setEnabled(is_leased);
BOOL enable_auction = (gAgent.getGodLevel() >= GOD_LIAISON)
&& (owner_id == GOVERNOR_LINDEN_ID)
&& (parcel->getAuctionID() == 0);
mBtnStartAuction->setEnabled(enable_auction);
}
// Display options
@ -1017,8 +1024,20 @@ void LLPanelLandGeneral::onClickBuyPass(void* data)
// static
void LLPanelLandGeneral::onClickStartAuction(void* data)
{
std::string auction_url = "https://places.[GRID]/auctions/";
LLWeb::loadURLExternal(LLWeb::expandURLSubstitutions(auction_url, LLSD()));
LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data;
LLParcel* parcelp = panelp->mParcel->getParcel();
if(parcelp)
{
if(parcelp->getForSale())
{
LLNotificationsUtil::add("CannotStartAuctionAlreadyForSale");
}
else
{
//LLFloaterAuction::showInstance();
LLFloaterReg::showInstance("auction");
}
}
}
// static

View File

@ -1096,16 +1096,15 @@ void LLFloaterPreference::onClickSetCache()
std::string proposed_name(cur_name);
LLDirPicker& picker = LLDirPicker::instance();
if (! picker.getDir(&proposed_name ) )
{
return; //Canceled!
}
(new LLDirPickerThread(boost::bind(&LLFloaterPreference::changeCachePath, this, _1, _2), proposed_name))->getFile();
}
std::string dir_name = picker.getDirName();
if (!dir_name.empty() && dir_name != cur_name)
void LLFloaterPreference::changeCachePath(const std::vector<std::string>& filenames, std::string proposed_name)
{
std::string dir_name = filenames[0];
if (!dir_name.empty() && dir_name != proposed_name)
{
std::string new_top_folder(gDirUtilp->getBaseFileName(dir_name));
std::string new_top_folder(gDirUtilp->getBaseFileName(dir_name));
LLNotificationsUtil::add("CacheWillBeMoved");
gSavedSettings.setString("NewCacheLocation", dir_name);
gSavedSettings.setString("NewCacheLocationTopFolder", new_top_folder);
@ -1744,25 +1743,21 @@ void LLFloaterPreference::onClickLogPath()
std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
mPriorInstantMessageLogPath.clear();
LLDirPicker& picker = LLDirPicker::instance();
//Launches a directory picker and waits for feedback
if (!picker.getDir(&proposed_name ) )
{
return; //Canceled!
}
//Gets the path from the directory picker
std::string dir_name = picker.getDirName();
//Path changed
if(proposed_name != dir_name)
{
gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
mPriorInstantMessageLogPath = proposed_name;
// enable/disable 'Delete transcripts button
updateDeleteTranscriptsButton();
(new LLDirPickerThread(boost::bind(&LLFloaterPreference::changeLogPath, this, _1, _2), proposed_name))->getFile();
}
void LLFloaterPreference::changeLogPath(const std::vector<std::string>& filenames, std::string proposed_name)
{
//Path changed
if (proposed_name != filenames[0])
{
gSavedPerAccountSettings.setString("InstantMessageLogPath", filenames[0]);
mPriorInstantMessageLogPath = proposed_name;
// enable/disable 'Delete transcripts button
updateDeleteTranscriptsButton();
}
}
bool LLFloaterPreference::moveTranscriptsAndLog()

View File

@ -133,6 +133,7 @@ public:
void setCacheLocation(const LLStringExplicit& location);
void onClickSetCache();
void changeCachePath(const std::vector<std::string>& filenames, std::string proposed_name);
void onClickResetCache();
void onClickSkin(LLUICtrl* ctrl,const LLSD& userdata);
void onSelectSkin();
@ -145,6 +146,7 @@ public:
void resetAllIgnored();
void setAllIgnored();
void onClickLogPath();
void changeLogPath(const std::vector<std::string>& filenames, std::string proposed_name);
bool moveTranscriptsAndLog();
void enableHistory();
void setPersonalInfo(const std::string& visibility, bool im_via_email, bool is_verified_email);

View File

@ -1309,17 +1309,15 @@ void LLFloaterSnapshot::saveTexture()
previewp->saveTexture();
}
BOOL LLFloaterSnapshot::saveLocal()
void LLFloaterSnapshot::saveLocal(const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
{
LL_DEBUGS() << "saveLocal" << LL_ENDL;
LLSnapshotLivePreview* previewp = getPreviewView();
if (!previewp)
llassert(previewp != NULL);
if (previewp)
{
llassert(previewp != NULL);
return FALSE;
previewp->saveLocal(success_cb, failure_cb);
}
return previewp->saveLocal();
}
void LLFloaterSnapshotBase::postSave()

View File

@ -156,7 +156,9 @@ public:
static LLFloaterSnapshot* getInstance();
static LLFloaterSnapshot* findInstance();
/*virtual*/ void saveTexture();
BOOL saveLocal();
typedef boost::signals2::signal<void(void)> snapshot_saved_signal_t;
void saveLocal(const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
static void setAgentEmail(const std::string& email);
BOOL isWaitingState();

View File

@ -966,15 +966,6 @@ private:
//-----------------------------------------------------------------------------
F32 gpu_benchmark()
{
#if LL_WINDOWS
if (gGLManager.mIsIntel
&& std::string::npos != LLOSInfo::instance().getOSStringSimple().find("Microsoft Windows 8")) // or 8.1
{ // don't run benchmark on Windows 8/8.1 based PCs with Intel GPU (MAINT-8197)
LL_WARNS() << "Skipping gpu_benchmark() for Intel graphics on Windows 8." << LL_ENDL;
return -1.f;
}
#endif
if (!gGLManager.mHasShaderObjects || !gGLManager.mHasTimerQuery)
{ // don't bother benchmarking the fixed function
// or venerable drivers which don't support accurate timing anyway

View File

@ -1166,72 +1166,72 @@ void LLOutfitGallery::refreshTextures(const LLUUID& category_id)
void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
{
outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
if (outfit_it == mOutfitMap.end() || outfit_it->first.isNull())
{
return;
}
outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
if (outfit_it == mOutfitMap.end() || outfit_it->first.isNull())
{
return;
}
(new LLFilePickerReplyThread(boost::bind(&LLOutfitGallery::uploadOutfitImage, this, _1, outfit_id), LLFilePicker::FFLOAD_IMAGE, false))->getFile();
}
LLFilePicker& picker = LLFilePicker::instance();
if (picker.getOpenFile(LLFilePicker::FFLOAD_IMAGE))
void LLOutfitGallery::uploadOutfitImage(const std::vector<std::string>& filenames, LLUUID outfit_id)
{
std::string filename = filenames[0];
LLLocalBitmap* unit = new LLLocalBitmap(filename);
if (unit->getValid())
{
std::string filename = picker.getFirstFile();
LLLocalBitmap* unit = new LLLocalBitmap(filename);
if (unit->getValid())
std::string exten = gDirUtilp->getExtension(filename);
U32 codec = LLImageBase::getCodecFromExtension(exten);
LLImageDimensionsInfo image_info;
std::string image_load_error;
if (!image_info.load(filename, codec))
{
std::string exten = gDirUtilp->getExtension(filename);
U32 codec = LLImageBase::getCodecFromExtension(exten);
LLImageDimensionsInfo image_info;
std::string image_load_error;
if (!image_info.load(filename, codec))
{
image_load_error = image_info.getLastError();
}
S32 max_width = MAX_OUTFIT_PHOTO_WIDTH;
S32 max_height = MAX_OUTFIT_PHOTO_HEIGHT;
if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
{
LLStringUtil::format_map_t args;
args["WIDTH"] = llformat("%d", max_width);
args["HEIGHT"] = llformat("%d", max_height);
image_load_error = LLTrans::getString("outfit_photo_load_dimensions_error", args);
}
if (!image_load_error.empty())
{
LLSD subst;
subst["REASON"] = image_load_error;
LLNotificationsUtil::add("OutfitPhotoLoadError", subst);
return;
}
S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
void *nruserdata = NULL;
nruserdata = (void *)&outfit_id;
LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(outfit_id);
if (!outfit_cat) return;
updateSnapshotFolderObserver();
checkRemovePhoto(outfit_id);
std::string upload_pending_name = outfit_id.asString();
std::string upload_pending_desc = "";
LLAssetStorage::LLStoreAssetCallback callback = NULL;
LLUUID photo_id = upload_new_resource(filename, // file
upload_pending_name,
upload_pending_desc,
0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
LLFloaterPerms::getNextOwnerPerms("Uploads"),
LLFloaterPerms::getGroupPerms("Uploads"),
LLFloaterPerms::getEveryonePerms("Uploads"),
upload_pending_name, callback, expected_upload_cost, nruserdata);
mOutfitLinkPending = outfit_id;
image_load_error = image_info.getLastError();
}
delete unit;
S32 max_width = MAX_OUTFIT_PHOTO_WIDTH;
S32 max_height = MAX_OUTFIT_PHOTO_HEIGHT;
if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
{
LLStringUtil::format_map_t args;
args["WIDTH"] = llformat("%d", max_width);
args["HEIGHT"] = llformat("%d", max_height);
image_load_error = LLTrans::getString("outfit_photo_load_dimensions_error", args);
}
if (!image_load_error.empty())
{
LLSD subst;
subst["REASON"] = image_load_error;
LLNotificationsUtil::add("OutfitPhotoLoadError", subst);
return;
}
S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
void *nruserdata = NULL;
nruserdata = (void *)&outfit_id;
LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(outfit_id);
if (!outfit_cat) return;
updateSnapshotFolderObserver();
checkRemovePhoto(outfit_id);
std::string upload_pending_name = outfit_id.asString();
std::string upload_pending_desc = "";
LLAssetStorage::LLStoreAssetCallback callback = NULL;
LLUUID photo_id = upload_new_resource(filename, // file
upload_pending_name,
upload_pending_desc,
0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
LLFloaterPerms::getNextOwnerPerms("Uploads"),
LLFloaterPerms::getGroupPerms("Uploads"),
LLFloaterPerms::getEveryonePerms("Uploads"),
upload_pending_name, callback, expected_upload_cost, nruserdata);
mOutfitLinkPending = outfit_id;
}
delete unit;
}
void LLOutfitGallery::linkPhotoToOutfit(LLUUID photo_id, LLUUID outfit_id)

View File

@ -130,6 +130,7 @@ protected:
private:
void loadPhotos();
void uploadPhoto(LLUUID outfit_id);
void uploadOutfitImage(const std::vector<std::string>& filenames, LLUUID outfit_id);
void updateSnapshotFolderObserver();
LLUUID getPhotoAssetId(const LLUUID& outfit_id);
LLUUID getDefaultPhoto();

View File

@ -204,6 +204,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
// change z sort of clickable text to be behind buttons
sendChildToBack(getChildView("forgot_password_text"));
sendChildToBack(getChildView("sign_up_text"));
LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo");
updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
@ -271,6 +272,9 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
LLTextBox* forgot_password_text = getChild<LLTextBox>("forgot_password_text");
forgot_password_text->setClickedCallback(onClickForgotPassword, NULL);
LLTextBox* sign_up_text = getChild<LLTextBox>("sign_up_text");
sign_up_text->setClickedCallback(onClickSignUp, NULL);
// get the web browser control
LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html");
web_browser->addObserver(this);
@ -921,6 +925,15 @@ void LLPanelLogin::onClickForgotPassword(void*)
}
}
//static
void LLPanelLogin::onClickSignUp(void*)
{
if (sInstance)
{
LLWeb::loadURLExternal(sInstance->getString("sign_up_url"));
}
}
// static
void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
{

View File

@ -99,6 +99,7 @@ private:
static void onClickNewAccount(void*);
static void onClickVersion(void*);
static void onClickForgotPassword(void*);
static void onClickSignUp(void*);
static void onPassKey(LLLineEditor* caller, void* user_data);
static void updateServerCombo();

View File

@ -1168,12 +1168,12 @@ void LLPanelNearByMedia::onClickSelectedMediaMute()
F32 volume = impl->getVolume();
if(volume > 0.0)
{
impl->setVolume(0.0);
impl->setMute(true);
}
else if (mVolumeSlider->getValueF32() == 0.0)
{
impl->setVolume(1.0);
mVolumeSlider->setValue(1.0);
impl->setMute(false);
mVolumeSlider->setValue(impl->getVolume());
}
else
{

View File

@ -100,6 +100,10 @@ U8 string_value_to_click_action(std::string p_value)
{
return CLICK_ACTION_ZOOM;
}
if (p_value == "None")
{
return CLICK_ACTION_DISABLED;
}
return CLICK_ACTION_TOUCH;
}
@ -126,6 +130,9 @@ std::string click_action_to_string_value( U8 action)
case CLICK_ACTION_ZOOM:
return "Zoom";
break;
case CLICK_ACTION_DISABLED:
return "None";
break;
}
}
@ -1203,23 +1210,34 @@ void LLPanelPermissions::setAllSaleInfo()
LLSaleInfo new_sale_info(sale_type, price);
LLSelectMgr::getInstance()->selectionSetObjectSaleInfo(new_sale_info);
struct f : public LLSelectedObjectFunctor
// Note: won't work right if a root and non-root are both single-selected (here and other places).
BOOL is_perm_modify = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
&& LLSelectMgr::getInstance()->selectGetRootsModify())
|| LLSelectMgr::getInstance()->selectGetModify();
BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
&& LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
|| LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
if (is_perm_modify && is_nonpermanent_enforced)
{
virtual bool apply(LLViewerObject* object)
struct f : public LLSelectedObjectFunctor
{
return object->getClickAction() == CLICK_ACTION_BUY
|| object->getClickAction() == CLICK_ACTION_TOUCH;
virtual bool apply(LLViewerObject* object)
{
return object->getClickAction() == CLICK_ACTION_BUY
|| object->getClickAction() == CLICK_ACTION_TOUCH;
}
} check_actions;
// Selection should only contain objects that are of target
// action already or of action we are aiming to remove.
bool default_actions = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&check_actions);
if (default_actions && old_sale_info.isForSale() != new_sale_info.isForSale())
{
U8 new_click_action = new_sale_info.isForSale() ? CLICK_ACTION_BUY : CLICK_ACTION_TOUCH;
LLSelectMgr::getInstance()->selectionSetClickAction(new_click_action);
}
} check_actions;
// Selection should only contain objects that are of target
// action already or of action we are aiming to remove.
bool default_actions = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&check_actions);
if (default_actions && old_sale_info.isForSale() != new_sale_info.isForSale())
{
U8 new_click_action = new_sale_info.isForSale() ? CLICK_ACTION_BUY : CLICK_ACTION_TOUCH;
LLSelectMgr::getInstance()->selectionSetClickAction(new_click_action);
}
}

View File

@ -65,6 +65,9 @@ private:
void onFormatComboCommit(LLUICtrl* ctrl);
void onQualitySliderCommit(LLUICtrl* ctrl);
void onSaveFlyoutCommit(LLUICtrl* ctrl);
void onLocalSaved();
void onLocalCanceled();
};
static LLPanelInjector<LLPanelSnapshotLocal> panel_class("llpanelsnapshotlocal");
@ -164,19 +167,22 @@ void LLPanelSnapshotLocal::onSaveFlyoutCommit(LLUICtrl* ctrl)
LLFloaterSnapshot* floater = LLFloaterSnapshot::getInstance();
floater->notify(LLSD().with("set-working", true));
BOOL saved = floater->saveLocal();
if (saved)
{
mSnapshotFloater->postSave();
floater->notify(LLSD().with("set-finished", LLSD().with("ok", true).with("msg", "local")));
}
else
{
cancel();
floater->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "local")));
}
floater->saveLocal((boost::bind(&LLPanelSnapshotLocal::onLocalSaved, this)), (boost::bind(&LLPanelSnapshotLocal::onLocalCanceled, this)));
}
void LLPanelSnapshotLocal::onLocalSaved()
{
mSnapshotFloater->postSave();
LLFloaterSnapshot::getInstance()->notify(LLSD().with("set-finished", LLSD().with("ok", true).with("msg", "local")));
}
void LLPanelSnapshotLocal::onLocalCanceled()
{
cancel();
LLFloaterSnapshot::getInstance()->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "local")));
}
LLSnapshotModel::ESnapshotType LLPanelSnapshotLocal::getSnapshotType()
{
return LLSnapshotModel::SNAPSHOT_LOCAL;

View File

@ -39,7 +39,6 @@
// Library includes (after viewer)
#include "lluictrlfactory.h"
static LLPanelInjector<LLPanelVoiceDeviceSettings> t_panel_group_general("panel_voice_device_settings");
static const std::string DEFAULT_DEVICE("Default");
@ -233,18 +232,18 @@ void LLPanelVoiceDeviceSettings::refresh()
}
else if (LLVoiceClient::getInstance()->deviceSettingsUpdated())
{
LLVoiceDeviceList::const_iterator iter;
LLVoiceDeviceList::const_iterator device;
if(mCtrlInputDevices)
{
mCtrlInputDevices->removeall();
mCtrlInputDevices->add(getLocalizedDeviceName(DEFAULT_DEVICE), DEFAULT_DEVICE, ADD_BOTTOM);
for(iter=LLVoiceClient::getInstance()->getCaptureDevices().begin();
iter != LLVoiceClient::getInstance()->getCaptureDevices().end();
iter++)
for(device=LLVoiceClient::getInstance()->getCaptureDevices().begin();
device != LLVoiceClient::getInstance()->getCaptureDevices().end();
device++)
{
mCtrlInputDevices->add(getLocalizedDeviceName(*iter), *iter, ADD_BOTTOM);
mCtrlInputDevices->add(getLocalizedDeviceName(device->display_name), device->full_name, ADD_BOTTOM);
}
// Fix invalid input audio device preference.
@ -261,10 +260,11 @@ void LLPanelVoiceDeviceSettings::refresh()
mCtrlOutputDevices->removeall();
mCtrlOutputDevices->add(getLocalizedDeviceName(DEFAULT_DEVICE), DEFAULT_DEVICE, ADD_BOTTOM);
for(iter= LLVoiceClient::getInstance()->getRenderDevices().begin();
iter != LLVoiceClient::getInstance()->getRenderDevices().end(); iter++)
for(device = LLVoiceClient::getInstance()->getRenderDevices().begin();
device != LLVoiceClient::getInstance()->getRenderDevices().end();
device++)
{
mCtrlOutputDevices->add(getLocalizedDeviceName(*iter), *iter, ADD_BOTTOM);
mCtrlOutputDevices->add(getLocalizedDeviceName(device->display_name), device->full_name, ADD_BOTTOM);
}
// Fix invalid output audio device preference.

View File

@ -1741,14 +1741,22 @@ void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAsset
buffer[file_length] = 0;
preview->mScriptEd->setScriptText(LLStringExplicit(&buffer[0]), TRUE);
preview->mScriptEd->mEditor->makePristine();
std::string script_name = DEFAULT_SCRIPT_NAME;
LLInventoryItem* item = gInventory.getItem(*item_uuid);
BOOL is_modifiable = FALSE;
if(item
&& gAgent.allowOperation(PERM_MODIFY, item->getPermissions(),
GP_OBJECT_MANIPULATE))
if (item)
{
is_modifiable = TRUE;
if (!item->getName().empty())
{
script_name = item->getName();
}
if (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE))
{
is_modifiable = TRUE;
}
}
preview->mScriptEd->setScriptName(script_name);
preview->mScriptEd->setEnableEditing(is_modifiable);
preview->mAssetStatus = PREVIEW_ASSET_LOADED;
}

View File

@ -1130,6 +1130,8 @@ static U8 string_value_to_click_action(std::string p_value)
return CLICK_ACTION_OPEN;
if (p_value == "Zoom")
return CLICK_ACTION_ZOOM;
if (p_value == "None")
return CLICK_ACTION_DISABLED;
return CLICK_ACTION_TOUCH;
}

View File

@ -70,6 +70,7 @@ S32 BORDER_WIDTH = 6;
const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
std::set<LLSnapshotLivePreview*> LLSnapshotLivePreview::sList;
LLPointer<LLImageFormatted> LLSnapshotLivePreview::sSaveLocalImage = NULL;
LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Params& p)
: LLView(p),
@ -131,6 +132,7 @@ LLSnapshotLivePreview::~LLSnapshotLivePreview()
// gIdleCallbacks.deleteFunction( &LLSnapshotLivePreview::onIdle, (void*)this );
sList.erase(this);
sSaveLocalImage = NULL;
}
void LLSnapshotLivePreview::setMaxImageSize(S32 size)
@ -1065,53 +1067,19 @@ void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)
mDataSize = 0;
}
BOOL LLSnapshotLivePreview::saveLocal()
void LLSnapshotLivePreview::saveLocal(const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
{
// Update mFormattedImage if necessary
getFormattedImage();
// Save the formatted image
BOOL success = saveLocal(mFormattedImage);
if(success)
{
gViewerWindow->playSnapshotAnimAndSound();
}
return success;
saveLocal(mFormattedImage, success_cb, failure_cb);
}
//Check if failed due to insufficient memory
BOOL LLSnapshotLivePreview::saveLocal(LLPointer<LLImageFormatted> mFormattedImage)
void LLSnapshotLivePreview::saveLocal(LLPointer<LLImageFormatted> image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
{
BOOL insufficient_memory;
BOOL success = gViewerWindow->saveImageNumbered(mFormattedImage, FALSE, insufficient_memory);
sSaveLocalImage = image;
if (insufficient_memory)
{
std::string lastSnapshotDir = LLViewerWindow::getLastSnapshotDir();
#ifdef LL_WINDOWS
boost::filesystem::path b_path(utf8str_to_utf16str(lastSnapshotDir));
#else
boost::filesystem::path b_path(lastSnapshotDir);
#endif
boost::filesystem::space_info b_space = boost::filesystem::space(b_path);
if (b_space.free < mFormattedImage->getDataSize())
{
LLSD args;
args["PATH"] = lastSnapshotDir;
std::string needM_bytes_string;
LLResMgr::getInstance()->getIntegerString(needM_bytes_string, (mFormattedImage->getDataSize()) >> 10);
args["NEED_MEMORY"] = needM_bytes_string;
std::string freeM_bytes_string;
LLResMgr::getInstance()->getIntegerString(freeM_bytes_string, (b_space.free) >> 10);
args["FREE_MEMORY"] = freeM_bytes_string;
LLNotificationsUtil::add("SnapshotToComputerFailed", args);
return false;
}
}
return success;
gViewerWindow->saveImageNumbered(sSaveLocalImage, FALSE, success_cb, failure_cb);
}

View File

@ -40,8 +40,9 @@ class LLSnapshotLivePreview : public LLView
{
LOG_CLASS(LLSnapshotLivePreview);
public:
typedef boost::signals2::signal<void(void)> snapshot_saved_signal_t;
static BOOL saveLocal(LLPointer<LLImageFormatted>);
static void saveLocal(LLPointer<LLImageFormatted> image, const snapshot_saved_signal_t::slot_type& success_cb = snapshot_saved_signal_t(), const snapshot_saved_signal_t::slot_type& failure_cb = snapshot_saved_signal_t());
struct Params : public LLInitParam::Block<Params, LLView::Params>
{
Params()
@ -101,7 +102,7 @@ public:
std::string getFilter() const { return mFilterName; }
void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f);
void saveTexture(BOOL outfit_snapshot = FALSE, std::string name = "");
BOOL saveLocal();
void saveLocal(const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
LLPointer<LLImageFormatted> getFormattedImage();
LLPointer<LLImageRaw> getEncodedImage();
@ -170,7 +171,9 @@ private:
LLQuaternion mCameraRot;
BOOL mSnapshotActive;
LLSnapshotModel::ESnapshotLayerType mSnapshotBufferType;
std::string mFilterName;
std::string mFilterName;
static LLPointer<LLImageFormatted> sSaveLocalImage;
public:
static std::set<LLSnapshotLivePreview*> sList;

View File

@ -615,7 +615,7 @@ bool LLTextureCacheRemoteWorker::doWrite()
if(idx >= 0)
{
// write to the fast cache.
if(!mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel))
if(!mCache->writeToFastCache(mID, idx, mRawImage, mRawDiscardLevel))
{
LL_WARNS() << "writeToFastCache failed" << LL_ENDL;
mDataSize = -1; // failed
@ -1998,8 +1998,48 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
return raw;
}
#if LL_WINDOWS
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
U32 exception_dupe_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
{
if (code == STATUS_MSC_EXCEPTION)
{
// C++ exception, go on
return EXCEPTION_CONTINUE_SEARCH;
}
else
{
// handle it
return EXCEPTION_EXECUTE_HANDLER;
}
}
//due to unwinding
void dupe(LLPointer<LLImageRaw> &raw)
{
raw = raw->duplicate();
}
void logExceptionDupplicate(LLPointer<LLImageRaw> &raw)
{
__try
{
dupe(raw);
}
__except (exception_dupe_filter(GetExceptionCode(), GetExceptionInformation()))
{
// convert to C++ styled exception
char integer_string[32];
sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
throw std::exception(integer_string);
}
}
#endif
//return the fast cache location
bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
{
//rescale image if needed
if (raw.isNull() || raw->isBufferInvalid() || !raw->getData())
@ -2027,13 +2067,39 @@ bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 dis
if(w * h *c > 0) //valid
{
//make a duplicate to keep the original raw image untouched.
raw = raw->scaled(w, h);
try
{
#if LL_WINDOWS
// Temporary diagnostics for scale/duplicate crash
logExceptionDupplicate(raw);
#else
raw = raw->duplicate();
#endif
}
catch (...)
{
removeFromCache(image_id);
LL_ERRS() << "Failed to cache image: " << image_id
<< " local id: " << id
<< " Exception: " << boost::current_exception_diagnostic_information()
<< " Image new width: " << w
<< " Image new height: " << h
<< " Image new components: " << c
<< " Image discard difference: " << i
<< LL_ENDL;
return false;
}
if (raw->isBufferInvalid())
{
LL_WARNS() << "Invalid image duplicate buffer" << LL_ENDL;
return false;
}
raw->scale(w, h);
discardlevel += i ;
}
}

View File

@ -179,7 +179,7 @@ private:
void openFastCache(bool first_time = false);
void closeFastCache(bool forced = false);
bool writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel);
bool writeToFastCache(LLUUID image_id, S32 cache_id, LLPointer<LLImageRaw> raw, S32 discardlevel);
private:
// Internal

View File

@ -263,7 +263,7 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()
addEntry(DAD_CLOTHING, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_OBJECT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dRezAttachmentFromInv, &LLToolDragAndDrop::dad3dGiveInventoryObject, &LLToolDragAndDrop::dad3dRezObjectOnObject, &LLToolDragAndDrop::dad3dRezObjectOnLand));
addEntry(DAD_NOTECARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearCategory, &LLToolDragAndDrop::dad3dGiveInventoryCategory, &LLToolDragAndDrop::dad3dUpdateInventoryCategory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearCategory, &LLToolDragAndDrop::dad3dGiveInventoryCategory, &LLToolDragAndDrop::dad3dRezCategoryOnObject, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_ROOT_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_BODYPART, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_ANIMATION, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
@ -2335,6 +2335,21 @@ EAcceptance LLToolDragAndDrop::dad3dUpdateInventoryCategory(
return rv;
}
EAcceptance LLToolDragAndDrop::dad3dRezCategoryOnObject(
LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
{
if ((mask & MASK_CONTROL))
{
return dad3dUpdateInventoryCategory(obj, face, mask, drop);
}
else
{
return ACCEPT_NO;
}
}
BOOL LLToolDragAndDrop::dadUpdateInventoryCategory(LLViewerObject* obj,
BOOL drop)
{

View File

@ -162,6 +162,8 @@ protected:
MASK mask, BOOL drop);
EAcceptance dad3dRezObjectOnObject(LLViewerObject* obj, S32 face,
MASK mask, BOOL drop);
EAcceptance dad3dRezCategoryOnObject(LLViewerObject* obj, S32 face,
MASK mask, BOOL drop);
EAcceptance dad3dRezScript(LLViewerObject* obj, S32 face,
MASK mask, BOOL drop);
EAcceptance dad3dTextureObject(LLViewerObject* obj, S32 face,

View File

@ -300,6 +300,8 @@ BOOL LLToolPie::handleLeftClickPick()
}
}
return TRUE;
case CLICK_ACTION_DISABLED:
return TRUE;
default:
// nothing
break;
@ -463,6 +465,8 @@ ECursorType LLToolPie::cursorFromObject(LLViewerObject* object)
case CLICK_ACTION_OPEN_MEDIA:
cursor = cursor_from_parcel_media(click_action);
break;
case CLICK_ACTION_DISABLED:
break;
default:
break;
}
@ -528,6 +532,8 @@ void LLToolPie::selectionPropertiesReceived()
case CLICK_ACTION_OPEN:
LLFloaterReg::showInstance("openobject");
break;
case CLICK_ACTION_DISABLED:
break;
default:
break;
}

View File

@ -34,6 +34,7 @@
#include "llcompilequeue.h"
#include "llfasttimerview.h"
#include "llfloaterabout.h"
#include "llfloaterauction.h"
#include "llfloaterautoreplacesettings.h"
#include "llfloateravatar.h"
#include "llfloateravatarpicker.h"
@ -193,6 +194,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLand>);
LLFloaterReg::add("appearance", "floater_my_appearance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("associate_listing", "floater_associate_listing.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAssociateListing>);
LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>);
LLFloaterReg::add("avatar", "floater_avatar.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatar>);
LLFloaterReg::add("avatar_picker", "floater_avatar_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarPicker>);
LLFloaterReg::add("avatar_render_settings", "floater_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarRenderSettings>);

View File

@ -1555,6 +1555,7 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
mNavigateServerRequest(false),
mMediaSourceFailed(false),
mRequestedVolume(1.0f),
mPreviousVolume(1.0f),
mIsMuted(false),
mNeedsMuteCheck(false),
mPreviousMediaState(MEDIA_NONE),
@ -2081,6 +2082,20 @@ void LLViewerMediaImpl::setVolume(F32 volume)
updateVolume();
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::setMute(bool mute)
{
if (mute)
{
mPreviousVolume = mRequestedVolume;
setVolume(0.0);
}
else
{
setVolume(mPreviousVolume);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::updateVolume()
{

View File

@ -216,6 +216,7 @@ public:
void skipBack(F32 step_scale);
void skipForward(F32 step_scale);
void setVolume(F32 volume);
void setMute(bool mute);
void updateVolume();
F32 getVolume();
void focus(bool focus);
@ -448,6 +449,7 @@ private:
bool mNavigateServerRequest;
bool mMediaSourceFailed;
F32 mRequestedVolume;
F32 mPreviousVolume;
bool mIsMuted;
bool mNeedsMuteCheck;
int mPreviousMediaState;

View File

@ -3649,9 +3649,16 @@ class LLSelfSitDown : public view_listener_t
}
};
bool show_sitdown_self()
{
return isAgentAvatarValid() && !gAgentAvatarp->isSitting();
}
bool enable_sitdown_self()
{
return isAgentAvatarValid() && !gAgentAvatarp->isSitting() && !gAgentAvatarp->isEditingAppearance() && !gAgent.getFlying();
return show_sitdown_self() && !gAgentAvatarp->isEditingAppearance() && !gAgent.getFlying();
}
class LLCheckPanelPeopleTab : public view_listener_t
@ -9068,7 +9075,8 @@ void initialize_menus()
view_listener_t::addMenu(new LLSelfStandUp(), "Self.StandUp");
enable.add("Self.EnableStandUp", boost::bind(&enable_standup_self));
view_listener_t::addMenu(new LLSelfSitDown(), "Self.SitDown");
enable.add("Self.EnableSitDown", boost::bind(&enable_sitdown_self));
enable.add("Self.EnableSitDown", boost::bind(&enable_sitdown_self));
enable.add("Self.ShowSitDown", boost::bind(&show_sitdown_self));
view_listener_t::addMenu(new LLSelfRemoveAllAttachments(), "Self.RemoveAllAttachments");
view_listener_t::addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments");

View File

@ -203,38 +203,55 @@ void LLFilePickerThread::clearDead()
}
}
LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple)
LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb)
: LLFilePickerThread(filter, get_multiple),
mLoadFilter(filter),
mSaveFilter(LLFilePicker::FFSAVE_ALL),
mFilePickedSignal(NULL)
mFilePickedSignal(NULL),
mFailureSignal(NULL)
{
mFilePickedSignal = new file_picked_signal_t();
mFilePickedSignal->connect(cb);
mFailureSignal = new file_picked_signal_t();
mFailureSignal->connect(failure_cb);
}
LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name)
LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb)
: LLFilePickerThread(filter, proposed_name),
mLoadFilter(LLFilePicker::FFLOAD_ALL),
mSaveFilter(filter),
mFilePickedSignal(NULL)
mFilePickedSignal(NULL),
mFailureSignal(NULL)
{
mFilePickedSignal = new file_picked_signal_t();
mFilePickedSignal->connect(cb);
mFailureSignal = new file_picked_signal_t();
mFailureSignal->connect(failure_cb);
}
LLFilePickerReplyThread::~LLFilePickerReplyThread()
{
delete mFilePickedSignal;
delete mFailureSignal;
}
void LLFilePickerReplyThread::notify(const std::vector<std::string>& filenames)
{
if (filenames.empty()) return;
if (mFilePickedSignal)
if (filenames.empty())
{
(*mFilePickedSignal)(filenames, mLoadFilter, mSaveFilter);
if (mFailureSignal)
{
(*mFailureSignal)(filenames, mLoadFilter, mSaveFilter);
}
}
else
{
if (mFilePickedSignal)
{
(*mFilePickedSignal)(filenames, mLoadFilter, mSaveFilter);
}
}
}
@ -592,7 +609,6 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
gSavedSettings.getBOOL("RenderUIInSnapshot"),
FALSE))
{
gViewerWindow->playSnapshotAnimAndSound();
LLPointer<LLImageFormatted> formatted;
LLSnapshotModel::ESnapshotFormat fmt = (LLSnapshotModel::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
switch (fmt)

View File

@ -113,8 +113,8 @@ public:
typedef boost::signals2::signal<void(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter)> file_picked_signal_t;
LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple);
LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name);
LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
~LLFilePickerReplyThread();
virtual void notify(const std::vector<std::string>& filenames);
@ -123,6 +123,7 @@ private:
LLFilePicker::ELoadFilter mLoadFilter;
LLFilePicker::ESaveFilter mSaveFilter;
file_picked_signal_t* mFilePickedSignal;
file_picked_signal_t* mFailureSignal;
};

View File

@ -153,6 +153,98 @@ const U8 AU_FLAGS_NONE = 0x00;
const U8 AU_FLAGS_HIDETITLE = 0x01;
const U8 AU_FLAGS_CLIENT_AUTOPILOT = 0x02;
void accept_friendship_coro(std::string url, LLSD notification)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("friendshipResponceErrorProcessing", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
if (url.empty())
{
LL_WARNS("Friendship") << "Empty capability!" << LL_ENDL;
return;
}
LLSD payload = notification["payload"];
url += "?from=" + payload["from_id"].asString();
url += "&agent_name=\"" + LLURI::escape(gAgentAvatarp->getFullname()) + "\"";
LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (!status)
{
LL_WARNS("Friendship") << "HTTP status, " << status.toTerseString() <<
". friendship offer accept failed." << LL_ENDL;
}
else
{
if (!result.has("success") || result["success"].asBoolean() == false)
{
LL_WARNS("Friendship") << "Server failed to process accepted friendship. " << httpResults << LL_ENDL;
}
else
{
LL_DEBUGS("Friendship") << "Adding friend to list" << httpResults << LL_ENDL;
// add friend to recent people list
LLRecentPeople::instance().add(payload["from_id"]);
LLNotificationsUtil::add("FriendshipAcceptedByMe",
notification["substitutions"], payload);
}
}
}
void decline_friendship_coro(std::string url, LLSD notification, S32 option)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("friendshipResponceErrorProcessing", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
if (url.empty())
{
LL_WARNS("Friendship") << "Empty capability!" << LL_ENDL;
return;
}
LLSD payload = notification["payload"];
url += "?from=" + payload["from_id"].asString();
LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (!status)
{
LL_WARNS("Friendship") << "HTTP status, " << status.toTerseString() <<
". friendship offer decline failed." << LL_ENDL;
}
else
{
if (!result.has("success") || result["success"].asBoolean() == false)
{
LL_WARNS("Friendship") << "Server failed to process declined friendship. " << httpResults << LL_ENDL;
}
else
{
LL_DEBUGS("Friendship") << "Friendship declined" << httpResults << LL_ENDL;
if (option == 1)
{
LLNotificationsUtil::add("FriendshipDeclinedByMe",
notification["substitutions"], payload);
}
else if (option == 2)
{
// start IM session
LLAvatarActions::startIM(payload["from_id"].asUUID());
}
}
}
}
bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
@ -163,9 +255,6 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
// this will be skipped if the user offering friendship is blocked
if (notification_ptr)
{
// add friend to recent people list
LLRecentPeople::instance().add(payload["from_id"]);
switch(option)
{
case 0:
@ -176,46 +265,79 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
const LLUUID fid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
// This will also trigger an onlinenotification if the user is online
msg->newMessageFast(_PREHASH_AcceptFriendship);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_TransactionBlock);
msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
msg->nextBlockFast(_PREHASH_FolderData);
msg->addUUIDFast(_PREHASH_FolderID, fid);
msg->sendReliable(LLHost(payload["sender"].asString()));
std::string url = gAgent.getRegionCapability("AcceptFriendship");
LL_DEBUGS("Friendship") << "Cap string: " << url << LL_ENDL;
if (!url.empty() && payload.has("online") && payload["online"].asBoolean() == false)
{
LL_DEBUGS("Friendship") << "Accepting friendship via capability" << LL_ENDL;
LLCoros::instance().launch("LLMessageSystem::acceptFriendshipOffer",
boost::bind(accept_friendship_coro, url, notification));
}
else if (payload.has("session_id") && payload["session_id"].asUUID().notNull())
{
LL_DEBUGS("Friendship") << "Accepting friendship via viewer message" << LL_ENDL;
msg->newMessageFast(_PREHASH_AcceptFriendship);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_TransactionBlock);
msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
msg->nextBlockFast(_PREHASH_FolderData);
msg->addUUIDFast(_PREHASH_FolderID, fid);
msg->sendReliable(LLHost(payload["sender"].asString()));
LLSD payload = notification["payload"];
LLNotificationsUtil::add("FriendshipAcceptedByMe",
notification["substitutions"], payload);
// add friend to recent people list
LLRecentPeople::instance().add(payload["from_id"]);
LLNotificationsUtil::add("FriendshipAcceptedByMe",
notification["substitutions"], payload);
}
else
{
LL_WARNS("Friendship") << "Failed to accept friendship offer, neither capability nor transaction id are accessible" << LL_ENDL;
}
break;
}
case 1: // Decline
{
LLSD payload = notification["payload"];
LLNotificationsUtil::add("FriendshipDeclinedByMe",
notification["substitutions"], payload);
}
// fall-through
case 2: // Send IM - decline and start IM session
{
// decline
// We no longer notify other viewers, but we DO still send
// the rejection to the simulator to delete the pending userop.
msg->newMessageFast(_PREHASH_DeclineFriendship);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_TransactionBlock);
msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
msg->sendReliable(LLHost(payload["sender"].asString()));
// the rejection to the simulator to delete the pending userop.
std::string url = gAgent.getRegionCapability("DeclineFriendship");
LL_DEBUGS("Friendship") << "Cap string: " << url << LL_ENDL;
if (!url.empty() && payload.has("online") && payload["online"].asBoolean() == false)
{
LL_DEBUGS("Friendship") << "Declining friendship via capability" << LL_ENDL;
LLCoros::instance().launch("LLMessageSystem::declineFriendshipOffer",
boost::bind(decline_friendship_coro, url, notification, option));
}
else if (payload.has("session_id") && payload["session_id"].asUUID().notNull())
{
LL_DEBUGS("Friendship") << "Declining friendship via viewer message" << LL_ENDL;
msg->newMessageFast(_PREHASH_DeclineFriendship);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_TransactionBlock);
msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
msg->sendReliable(LLHost(payload["sender"].asString()));
// start IM session
if(2 == option)
{
LLAvatarActions::startIM(payload["from_id"].asUUID());
}
if (option == 1) // due to fall-through
{
LLNotificationsUtil::add("FriendshipDeclinedByMe",
notification["substitutions"], payload);
}
else if (option == 2)
{
// start IM session
LLAvatarActions::startIM(payload["from_id"].asUUID());
}
}
else
{
LL_WARNS("Friendship") << "Failed to decline friendship offer, neither capability nor transaction id are accessible" << LL_ENDL;
}
}
default:
// close button probably, possibly timed out
@ -3258,6 +3380,110 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
}
// sounds can arrive before objects, store them for a short time
// Note: this is a workaround for MAINT-4743, real fix would be to make
// server send sound along with object update that creates (rezes) the object
class PostponedSoundData
{
public:
PostponedSoundData() :
mExpirationTime(0)
{}
PostponedSoundData(const LLUUID &object_id, const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, const U8 flags);
bool hasExpired() { return LLFrameTimer::getTotalSeconds() > mExpirationTime; }
LLUUID mObjectId;
LLUUID mSoundId;
LLUUID mOwnerId;
F32 mGain;
U8 mFlags;
static const F64 MAXIMUM_PLAY_DELAY;
private:
F64 mExpirationTime; //seconds since epoch
};
const F64 PostponedSoundData::MAXIMUM_PLAY_DELAY = 15.0;
static F64 postponed_sounds_update_expiration = 0.0;
static std::map<LLUUID, PostponedSoundData> postponed_sounds;
void set_attached_sound(LLViewerObject *objectp, const LLUUID &object_id, const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, const U8 flags)
{
if (LLMuteList::getInstance()->isMuted(object_id)) return;
if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
// Don't play sounds from a region with maturity above current agent maturity
LLVector3d pos = objectp->getPositionGlobal();
if (!gAgent.canAccessMaturityAtGlobal(pos))
{
return;
}
objectp->setAttachedSound(sound_id, owner_id, gain, flags);
}
PostponedSoundData::PostponedSoundData(const LLUUID &object_id, const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, const U8 flags)
:
mObjectId(object_id),
mSoundId(sound_id),
mOwnerId(owner_id),
mGain(gain),
mFlags(flags),
mExpirationTime(LLFrameTimer::getTotalSeconds() + MAXIMUM_PLAY_DELAY)
{
}
// static
void update_attached_sounds()
{
if (postponed_sounds.empty())
{
return;
}
std::map<LLUUID, PostponedSoundData>::iterator iter = postponed_sounds.begin();
std::map<LLUUID, PostponedSoundData>::iterator end = postponed_sounds.end();
while (iter != end)
{
std::map<LLUUID, PostponedSoundData>::iterator cur_iter = iter++;
PostponedSoundData* data = &cur_iter->second;
if (data->hasExpired())
{
postponed_sounds.erase(cur_iter);
}
else
{
LLViewerObject *objectp = gObjectList.findObject(data->mObjectId);
if (objectp)
{
set_attached_sound(objectp, data->mObjectId, data->mSoundId, data->mOwnerId, data->mGain, data->mFlags);
postponed_sounds.erase(cur_iter);
}
}
}
postponed_sounds_update_expiration = LLFrameTimer::getTotalSeconds() + 2 * PostponedSoundData::MAXIMUM_PLAY_DELAY;
}
//static
void clear_expired_postponed_sounds()
{
if (postponed_sounds_update_expiration > LLFrameTimer::getTotalSeconds())
{
return;
}
std::map<LLUUID, PostponedSoundData>::iterator iter = postponed_sounds.begin();
std::map<LLUUID, PostponedSoundData>::iterator end = postponed_sounds.end();
while (iter != end)
{
std::map<LLUUID, PostponedSoundData>::iterator cur_iter = iter++;
PostponedSoundData* data = &cur_iter->second;
if (data->hasExpired())
{
postponed_sounds.erase(cur_iter);
}
}
postponed_sounds_update_expiration = LLFrameTimer::getTotalSeconds() + 2 * PostponedSoundData::MAXIMUM_PLAY_DELAY;
}
// *TODO: Remove this dependency, or figure out a better way to handle
// this hack.
@ -3276,7 +3502,12 @@ void process_object_update(LLMessageSystem *mesgsys, void **user_data)
}
// Update the object...
S32 old_num_objects = gObjectList.mNumNewObjects;
gObjectList.processObjectUpdate(mesgsys, user_data, OUT_FULL);
if (old_num_objects != gObjectList.mNumNewObjects)
{
update_attached_sounds();
}
}
void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data)
@ -3292,7 +3523,12 @@ void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data
}
// Update the object...
S32 old_num_objects = gObjectList.mNumNewObjects;
gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_FULL_COMPRESSED);
if (old_num_objects != gObjectList.mNumNewObjects)
{
update_attached_sounds();
}
}
void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data)
@ -3323,7 +3559,12 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_
gObjectData += (U32Bytes)mesgsys->getReceiveSize();
}
S32 old_num_objects = gObjectList.mNumNewObjects;
gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED);
if (old_num_objects != gObjectList.mNumNewObjects)
{
update_attached_sounds();
}
}
static LLTrace::BlockTimerStatHandle FTM_PROCESS_OBJECTS("Process Kill Objects");
@ -3545,28 +3786,27 @@ void process_attached_sound(LLMessageSystem *msg, void **user_data)
msg->getU8Fast(_PREHASH_DataBlock, _PREHASH_Flags, flags);
LLViewerObject *objectp = gObjectList.findObject(object_id);
if (!objectp)
if (objectp)
{
// we don't know about this object, just bail
return;
set_attached_sound(objectp, object_id, sound_id, owner_id, gain, flags);
}
if (LLMuteList::getInstance()->isMuted(object_id)) return;
if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
// Don't play sounds from a region with maturity above current agent maturity
LLVector3d pos = objectp->getPositionGlobal();
if( !gAgent.canAccessMaturityAtGlobal(pos) )
else if (sound_id.notNull())
{
return;
// we don't know about this object yet, probably it has yet to arrive
// std::map for dupplicate prevention.
postponed_sounds[object_id] = (PostponedSoundData(object_id, sound_id, owner_id, gain, flags));
clear_expired_postponed_sounds();
}
else
{
std::map<LLUUID, PostponedSoundData>::iterator iter = postponed_sounds.find(object_id);
if (iter != postponed_sounds.end())
{
postponed_sounds.erase(iter);
}
}
objectp->setAttachedSound(sound_id, owner_id, gain, flags);
}
void process_attached_sound_gain_change(LLMessageSystem *mesgsys, void **user_data)
{
F32 gain = 0;

View File

@ -63,7 +63,7 @@ const std::string GRID_LOGIN_IDENTIFIER_TYPES = "login_identifier_types";
const std::string GRID_SLURL_BASE = "slurl_base";
const std::string GRID_APP_SLURL_BASE = "app_slurl_base";
const std::string DEFAULT_LOGIN_PAGE = "http://viewer-login.agni.lindenlab.com/";
const std::string DEFAULT_LOGIN_PAGE = "https://viewer-splash.secondlife.com/";
const std::string MAIN_GRID_LOGIN_URI = "https://login.agni.lindenlab.com/cgi-bin/login.cgi";

View File

@ -1877,7 +1877,7 @@ void LLViewerRegion::updateNetStats()
mLastPacketsLost = mPacketsLost;
mPacketsIn = cdp->getPacketsIn();
mBitsIn = cdp->getBytesIn();
mBitsIn = 8 * cdp->getBytesIn();
mPacketsOut = cdp->getPacketsOut();
mPacketsLost = cdp->getPacketsLost();
mPingDelay = cdp->getPingDelay();
@ -2817,6 +2817,7 @@ void LLViewerRegion::unpackRegionHandshake()
void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
{
capabilityNames.append("AbuseCategories");
//capabilityNames.append("AcceptFriendship");
capabilityNames.append("AgentPreferences");
capabilityNames.append("AgentState");
capabilityNames.append("AttachmentResources");
@ -2826,6 +2827,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("ChatSessionRequest");
capabilityNames.append("CopyInventoryFromNotecard");
capabilityNames.append("CreateInventoryCategory");
//capabilityNames.append("DeclineFriendship");
capabilityNames.append("DispatchRegionInfo");
capabilityNames.append("DirectDelivery");
capabilityNames.append("EnvironmentSettings");

View File

@ -193,6 +193,7 @@
#include "llviewerdisplay.h"
#include "llspatialpartition.h"
#include "llviewerjoystick.h"
#include "llviewermenufile.h" // LLFilePickerReplyThread
#include "llviewernetwork.h"
#include "llpostprocess.h"
#include "llfloaterimnearbychat.h"
@ -4365,77 +4366,110 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d
}
// Saves an image to the harddrive as "SnapshotX" where X >= 1.
BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picker, BOOL& insufficient_memory)
void LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picker, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
{
insufficient_memory = FALSE;
if (!image)
{
LL_WARNS() << "No image to save" << LL_ENDL;
return FALSE;
return;
}
LLFilePicker::ESaveFilter pick_type;
std::string extension("." + image->getExtension());
if (extension == ".j2c")
pick_type = LLFilePicker::FFSAVE_J2C;
else if (extension == ".bmp")
pick_type = LLFilePicker::FFSAVE_BMP;
else if (extension == ".jpg")
pick_type = LLFilePicker::FFSAVE_JPEG;
else if (extension == ".png")
pick_type = LLFilePicker::FFSAVE_PNG;
else if (extension == ".tga")
pick_type = LLFilePicker::FFSAVE_TGA;
else
pick_type = LLFilePicker::FFSAVE_ALL; // ???
BOOL is_snapshot_name_loc_set = isSnapshotLocSet();
LLImageFormatted* formatted_image = image;
// Get a base file location if needed.
if (force_picker || !isSnapshotLocSet())
{
std::string proposed_name( sSnapshotBaseName );
std::string proposed_name(sSnapshotBaseName);
// getSaveFile will append an appropriate extension to the proposed name, based on the ESaveFilter constant passed in.
LLFilePicker::ESaveFilter pick_type;
// pick a directory in which to save
LLFilePicker& picker = LLFilePicker::instance();
if (!picker.getSaveFile(pick_type, proposed_name))
{
// Clicked cancel
return FALSE;
}
if (extension == ".j2c")
pick_type = LLFilePicker::FFSAVE_J2C;
else if (extension == ".bmp")
pick_type = LLFilePicker::FFSAVE_BMP;
else if (extension == ".jpg")
pick_type = LLFilePicker::FFSAVE_JPEG;
else if (extension == ".png")
pick_type = LLFilePicker::FFSAVE_PNG;
else if (extension == ".tga")
pick_type = LLFilePicker::FFSAVE_TGA;
else
pick_type = LLFilePicker::FFSAVE_ALL;
// Copy the directory + file name
std::string filepath = picker.getFirstFile();
gSavedPerAccountSettings.setString("SnapshotBaseName", gDirUtilp->getBaseFileName(filepath, true));
gSavedPerAccountSettings.setString("SnapshotBaseDir", gDirUtilp->getDirName(filepath));
(new LLFilePickerReplyThread(boost::bind(&LLViewerWindow::onDirectorySelected, this, _1, formatted_image, success_cb, failure_cb), pick_type, proposed_name,
boost::bind(&LLViewerWindow::onSelectionFailure, this, failure_cb)))->getFile();
}
std::string snapshot_dir = sSnapshotDir;
if(snapshot_dir.empty())
else
{
return FALSE;
saveImageLocal(formatted_image, success_cb, failure_cb);
}
}
void LLViewerWindow::onDirectorySelected(const std::vector<std::string>& filenames, LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
{
// Copy the directory + file name
std::string filepath = filenames[0];
gSavedPerAccountSettings.setString("SnapshotBaseName", gDirUtilp->getBaseFileName(filepath, true));
gSavedPerAccountSettings.setString("SnapshotBaseDir", gDirUtilp->getDirName(filepath));
saveImageLocal(image, success_cb, failure_cb);
}
void LLViewerWindow::onSelectionFailure(const snapshot_saved_signal_t::slot_type& failure_cb)
{
failure_cb();
}
void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
{
std::string lastSnapshotDir = LLViewerWindow::getLastSnapshotDir();
if (lastSnapshotDir.empty())
{
failure_cb();
return;
}
// Check if there is enough free space to save snapshot
#ifdef LL_WINDOWS
boost::filesystem::space_info b_space = boost::filesystem::space(utf8str_to_utf16str(snapshot_dir));
boost::filesystem::path b_path(utf8str_to_utf16str(lastSnapshotDir));
#else
boost::filesystem::space_info b_space = boost::filesystem::space(snapshot_dir);
boost::filesystem::path b_path(lastSnapshotDir);
#endif
if (!boost::filesystem::is_directory(b_path))
{
LLSD args;
args["PATH"] = lastSnapshotDir;
LLNotificationsUtil::add("SnapshotToLocalDirNotExist", args);
resetSnapshotLoc();
failure_cb();
return;
}
boost::filesystem::space_info b_space = boost::filesystem::space(b_path);
if (b_space.free < image->getDataSize())
{
insufficient_memory = TRUE;
return FALSE;
LLSD args;
args["PATH"] = lastSnapshotDir;
std::string needM_bytes_string;
LLResMgr::getInstance()->getIntegerString(needM_bytes_string, (image->getDataSize()) >> 10);
args["NEED_MEMORY"] = needM_bytes_string;
std::string freeM_bytes_string;
LLResMgr::getInstance()->getIntegerString(freeM_bytes_string, (b_space.free) >> 10);
args["FREE_MEMORY"] = freeM_bytes_string;
LLNotificationsUtil::add("SnapshotToComputerFailed", args);
failure_cb();
}
// Look for an unused file name
BOOL is_snapshot_name_loc_set = isSnapshotLocSet();
std::string filepath;
S32 i = 1;
S32 err = 0;
std::string extension("." + image->getExtension());
do
{
filepath = sSnapshotDir;
@ -4457,7 +4491,15 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picke
&& is_snapshot_name_loc_set); // Or stop if we are rewriting.
LL_INFOS() << "Saving snapshot to " << filepath << LL_ENDL;
return image->save(filepath);
if (image->save(filepath))
{
playSnapshotAnimAndSound();
success_cb();
}
else
{
failure_cb();
}
}
void LLViewerWindow::resetSnapshotLoc()

View File

@ -352,7 +352,13 @@ public:
BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type);
BOOL isSnapshotLocSet() const;
void resetSnapshotLoc() const;
BOOL saveImageNumbered(LLImageFormatted *image, BOOL force_picker, BOOL& insufficient_memory);
typedef boost::signals2::signal<void(void)> snapshot_saved_signal_t;
void saveImageNumbered(LLImageFormatted *image, BOOL force_picker, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
void onDirectorySelected(const std::vector<std::string>& filenames, LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
void saveImageLocal(LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
void onSelectionFailure(const snapshot_saved_signal_t::slot_type& failure_cb);
// Reset the directory where snapshots are saved.
// Client will open directory picker on next snapshot save.

View File

@ -79,7 +79,7 @@ LLVoiceHandler gVoiceHandler;
std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserver::EStatusType inStatus)
{
std::string result = "UNKNOWN";
std::string result = "UNTRANSLATED";
// Prevent copy-paste errors when updating this list...
#define CASE(x) case x: result = #x; break
@ -92,12 +92,18 @@ std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserv
CASE(STATUS_JOINED);
CASE(STATUS_LEFT_CHANNEL);
CASE(STATUS_VOICE_DISABLED);
CASE(STATUS_VOICE_ENABLED);
CASE(BEGIN_ERROR_STATUS);
CASE(ERROR_CHANNEL_FULL);
CASE(ERROR_CHANNEL_LOCKED);
CASE(ERROR_NOT_AVAILABLE);
CASE(ERROR_UNKNOWN);
default:
{
std::ostringstream stream;
stream << "UNKNOWN(" << (int)inStatus << ")";
result = stream.str();
}
break;
}

View File

@ -40,8 +40,19 @@ class LLVOAvatar;
// devices
typedef std::vector<std::string> LLVoiceDeviceList;
class LLVoiceDevice
{
public:
std::string display_name; // friendly value for the user
std::string full_name; // internal value for selection
LLVoiceDevice(const std::string& display_name, const std::string& full_name)
:display_name(display_name)
,full_name(full_name)
{
};
};
typedef std::vector<LLVoiceDevice> LLVoiceDeviceList;
class LLVoiceClientParticipantObserver
{

View File

@ -99,6 +99,7 @@ namespace {
const int CONNECT_RETRY_MAX = 3;
const F32 LOGIN_ATTEMPT_TIMEOUT = 30.0f;
const F32 LOGOUT_ATTEMPT_TIMEOUT = 5.0f;
const int LOGIN_RETRY_MAX = 3;
const F32 PROVISION_RETRY_TIMEOUT = 2.0;
@ -259,9 +260,16 @@ static void killGateway()
{
if (sGatewayPtr)
{
LL_DEBUGS("Voice") << "SLVoice " << sGatewayPtr->getStatusString() << LL_ENDL;
sGatewayPump.stopListening("VivoxDaemonPump");
sGatewayPtr->kill();
sGatewayPtr->kill(__FUNCTION__);
sGatewayPtr=NULL;
}
else
{
LL_DEBUGS("Voice") << "no gateway" << LL_ENDL;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
@ -283,7 +291,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
mDevicesListUpdated(false),
mAreaVoiceDisabled(false),
mAudioSession(),
mAudioSession(), // TBD - should be NULL
mAudioSessionChanged(false),
mNextAudioSession(),
@ -416,6 +424,7 @@ void LLVivoxVoiceClient::cleanUp()
deleteAllSessions();
deleteAllVoiceFonts();
deleteVoiceFontTemplates();
LL_DEBUGS("Voice") << "exiting" << LL_ENDL;
}
//---------------------------------------------------
@ -542,6 +551,10 @@ void LLVivoxVoiceClient::connectorShutdown()
writeString(stream.str());
}
else
{
mShutdownComplete = true;
}
}
void LLVivoxVoiceClient::userAuthorized(const std::string& user_id, const LLUUID &agentID)
@ -641,18 +654,18 @@ void LLVivoxVoiceClient::idle(void* user_data)
//
void LLVivoxVoiceClient::voiceControlCoro()
{
LL_DEBUGS("Voice") << "starting" << LL_ENDL;
mIsCoroutineActive = true;
LLCoros::set_consuming(true);
while (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
{
LL_INFOS("Voice") << "Suspending voiceControlCoro() due to teleport. Tuning: " << mTuningMode << ". Relog: " << mRelogRequested << LL_ENDL;
LL_DEBUGS("Voice") << "Suspending voiceControlCoro() momentarily for teleport. Tuning: " << mTuningMode << ". Relog: " << mRelogRequested << LL_ENDL;
llcoro::suspendUntilTimeout(1.0);
}
do
{
if (startAndConnectSession())
{
if (mTuningMode)
@ -662,6 +675,7 @@ void LLVivoxVoiceClient::voiceControlCoro()
waitForChannel(); // this doesn't normally return unless relog is needed or shutting down
LL_DEBUGS("Voice") << "lost channel RelogRequested=" << mRelogRequested << LL_ENDL;
endAndDisconnectSession();
}
@ -669,16 +683,23 @@ void LLVivoxVoiceClient::voiceControlCoro()
// that we attempted to relog into Vivox and were rejected.
// Rather than just quit out of voice, we will tear it down (above)
// and then reconstruct the voice connecion from scratch.
LL_DEBUGS("Voice")
<< "disconnected"
<< " RelogRequested=" << mRelogRequested
<< LL_ENDL;
if (mRelogRequested)
{
LL_INFOS("Voice") << "will attempt to reconnect to voice" << LL_ENDL;
while (isGatewayRunning() || gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
{
LL_INFOS("Voice") << "waiting for SLVoice to exit" << LL_ENDL;
llcoro::suspendUntilTimeout(1.0);
}
}
}
while (mRelogRequested);
while (mVoiceEnabled && mRelogRequested);
mIsCoroutineActive = false;
LL_INFOS("Voice") << "exiting" << LL_ENDL;
}
@ -710,6 +731,8 @@ bool LLVivoxVoiceClient::startAndConnectSession()
bool LLVivoxVoiceClient::endAndDisconnectSession()
{
LL_DEBUGS("Voice") << LL_ENDL;
breakVoiceConnection(true);
killGateway();
@ -719,13 +742,15 @@ bool LLVivoxVoiceClient::endAndDisconnectSession()
bool LLVivoxVoiceClient::callbackEndDaemon(const LLSD& data)
{
if (!LLAppViewer::isExiting())
if (!LLAppViewer::isExiting() && mVoiceEnabled)
{
LL_WARNS("Voice") << "SLVoice terminated " << ll_stream_notation_sd(data) << LL_ENDL;
terminateAudioSession(false);
closeSocket();
cleanUp();
LLVoiceClient::getInstance()->setUserPTTState(false);
gAgent.setVoiceConnected(false);
mRelogRequested = true;
}
sGatewayPump.stopListening("VivoxDaemonPump");
return false;
@ -737,6 +762,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
if (!voiceEnabled())
{
// Voice is locked out, we must not launch the vivox daemon.
LL_WARNS("Voice") << "voice disabled; not starting daemon" << LL_ENDL;
return false;
}
@ -744,11 +770,6 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
{
#ifndef VIVOXDAEMON_REMOTEHOST
// Launch the voice daemon
// *FIX:Mani - Using the executable dir instead
// of mAppRODataDir, the working directory from which the app
// is launched.
//std::string exe_path = gDirUtilp->getAppRODataDir();
std::string exe_path = gDirUtilp->getExecutableDir();
exe_path += gDirUtilp->getDirDelimiter();
#if LL_WINDOWS
@ -803,13 +824,16 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
params.postend = sGatewayPump.getName();
sGatewayPump.listen("VivoxDaemonPump", boost::bind(&LLVivoxVoiceClient::callbackEndDaemon, this, _1));
LL_INFOS("Voice") << "Launching SLVoice" << LL_ENDL;
LL_DEBUGS("Voice") << "SLVoice params " << params << LL_ENDL;
sGatewayPtr = LLProcess::create(params);
mDaemonHost = LLHost(gSavedSettings.getString("VivoxVoiceHost").c_str(), gSavedSettings.getU32("VivoxVoicePort"));
}
else
{
LL_INFOS("Voice") << exe_path << " not found." << LL_ENDL;
LL_WARNS("Voice") << exe_path << " not found." << LL_ENDL;
return false;
}
#else
@ -832,6 +856,10 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
mMainSessionGroupHandle.clear();
}
else
{
LL_DEBUGS("Voice") << " gateway running; not attempting to start" << LL_ENDL;
}
//---------------------------------------------------------------------
llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
@ -896,12 +924,15 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
while (!gAgent.getRegion() || !gAgent.getRegion()->capabilitiesReceived())
{
LL_DEBUGS("Voice") << "no capabilities for voice provisioning; waiting " << LL_ENDL;
// *TODO* Pump a message for wake up.
llcoro::suspend();
}
std::string url = gAgent.getRegionCapability("ProvisionVoiceAccountRequest");
LL_DEBUGS("Voice") << "region ready for voice provisioning; url=" << url << LL_ENDL;
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("voiceAccountProvision", httpPolicy));
@ -949,14 +980,23 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
std::string voiceUserName = result["username"].asString();
std::string voicePassword = result["password"].asString();
//LL_DEBUGS("Voice") << "ProvisionVoiceAccountRequest response:" << dumpResponse() << LL_ENDL;
if (result.has("voice_sip_uri_hostname"))
{
voiceSipUriHostname = result["voice_sip_uri_hostname"].asString();
}
// this key is actually misnamed -- it will be an entire URI, not just a hostname.
if (result.has("voice_account_server_name"))
{
voiceAccountServerUri = result["voice_account_server_name"].asString();
}
LL_DEBUGS("Voice") << "ProvisionVoiceAccountRequest response"
<< " user " << (voiceUserName.empty() ? "not set" : "set")
<< " password " << (voicePassword.empty() ? "not set" : "set")
<< " sip uri " << voiceSipUriHostname
<< " account uri " << voiceAccountServerUri
<< LL_ENDL;
setLoginInfo(voiceUserName, voicePassword, voiceSipUriHostname, voiceAccountServerUri);
@ -968,8 +1008,11 @@ bool LLVivoxVoiceClient::establishVoiceConnection()
LLEventPump &voiceConnectPump = LLEventPumps::instance().obtain("vivoxClientPump");
if (!mVoiceEnabled && mIsInitialized)
{
LL_WARNS("Voice") << "cannot establish connection; enabled "<<mVoiceEnabled<<" initialized "<<mIsInitialized<<LL_ENDL;
return false;
}
LLSD result;
bool connected(false);
bool giving_up(false);
@ -1031,7 +1074,7 @@ bool LLVivoxVoiceClient::establishVoiceConnection()
bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
{
LL_DEBUGS("Voice") << LL_ENDL;
LL_DEBUGS("Voice") << "( wait=" << corowait << ")" << LL_ENDL;
LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
bool retval(true);
@ -1040,26 +1083,38 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
if (corowait)
{
LLSD result = llcoro::suspendUntilEventOn(voicePump);
LLSD timeoutResult(LLSDMap("connector", "timeout"));
LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
retval = result.has("connector");
}
else
{ // If we are not doing a corowait then we must sleep until the connector has responded
{
mRelogRequested = false; //stop the control coro
// If we are not doing a corowait then we must sleep until the connector has responded
// otherwise we may very well close the socket too early.
#if LL_WINDOWS
int count = 0;
while (!mShutdownComplete && 10 > count++)
{ // Rider: This comes out to a max wait time of 10 seconds.
// The situation that brings us here is a call from ::terminate()
// and so the viewer is attempting to go away. Don't slow it down
// longer than this.
if (!mShutdownComplete)
{
// The situation that brings us here is a call from ::terminate()
// At this point message system is already down so we can't wait for
// the message, yet we need to receive "connector shutdown response".
// Either wait a bit and emulate it or check gMessageSystem for specific message
_sleep(1000);
if (mConnected)
{
mConnected = false;
LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false)));
LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
}
mShutdownComplete = true;
}
#endif
}
LL_DEBUGS("Voice") << "closing SLVoice socket" << LL_ENDL;
closeSocket(); // Need to do this now -- bad things happen if the destructor does it later.
cleanUp();
mConnected = false;
@ -1161,31 +1216,35 @@ bool LLVivoxVoiceClient::loginToVivox()
void LLVivoxVoiceClient::logoutOfVivox(bool wait)
{
if (!mIsLoggedIn)
return;
// Ensure that we'll re-request provisioning before logging in again
mAccountPassword.clear();
mVoiceAccountServerURI.clear();
logoutSendMessage();
if (wait)
if (mIsLoggedIn)
{
LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
LLSD timeoutResult(LLSDMap("lougout", "timeout"));
// Ensure that we'll re-request provisioning before logging in again
mAccountPassword.clear();
mVoiceAccountServerURI.clear();
LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult);
logoutSendMessage();
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("logout"))
if (wait)
{
}
}
LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
LLSD timeoutResult(LLSDMap("logout", "timeout"));
mIsLoggedIn = false;
LL_DEBUGS("Voice")
<< "waiting for logout response on "
<< voicePump.getName()
<< LL_ENDL;
LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
}
else
{
LL_DEBUGS("Voice") << "not waiting for logout" << LL_ENDL;
}
mIsLoggedIn = false;
}
}
@ -1256,6 +1315,10 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo()
// state. If the cap request is still pending,
// the responder will check to see if we've moved
// to a new session and won't change any state.
LL_DEBUGS("Voice") << "terminate requested " << mSessionTerminateRequested
<< " enabled " << mVoiceEnabled
<< " initialized " << mIsInitialized
<< LL_ENDL;
terminateAudioSession(true);
return false;
}
@ -1280,17 +1343,30 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo()
LLSD voice_credentials = result["voice_credentials"];
if (voice_credentials.has("channel_uri"))
{
LL_DEBUGS("Voice") << "got voice channel uri" << LL_ENDL;
uri = voice_credentials["channel_uri"].asString();
}
else
{
LL_WARNS("Voice") << "No voice channel uri" << LL_ENDL;
}
if (voice_credentials.has("channel_credentials"))
{
LL_DEBUGS("Voice") << "got voice channel credentials" << LL_ENDL;
credentials =
voice_credentials["channel_credentials"].asString();
}
}
else
{
LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL;
if (!uri.empty())
LL_INFOS("Voice") << "Voice URI is " << uri << LL_ENDL;
}
}
else
{
LL_WARNS("Voice") << "No voice credentials" << LL_ENDL;
}
// set the spatial channel. If no voice credentials or uri are
// available, then we simply drop out of voice spatially.
@ -1353,7 +1429,10 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
if (!mVoiceEnabled && mIsInitialized)
{
LL_DEBUGS("Voice") << "Voice no longer enabled. Exiting." << LL_ENDL;
LL_DEBUGS("Voice") << "Voice no longer enabled. Exiting"
<< " enabled " << mVoiceEnabled
<< " initialized " << mIsInitialized
<< LL_ENDL;
mIsJoiningSession = false;
// User bailed out during connect -- jump straight to teardown.
terminateAudioSession(true);
@ -1476,7 +1555,7 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
if (mAudioSession)
{
LL_INFOS("Voice") << "Terminating current voice session " << mAudioSession->mHandle << LL_ENDL;
LL_INFOS("Voice") << "terminateAudioSession(" << wait << ") Terminating current voice session " << mAudioSession->mHandle << LL_ENDL;
if (mIsLoggedIn)
{
@ -1506,7 +1585,9 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
LLSD result;
do
{
result = llcoro::suspendUntilEventOn(voicePump);
LLSD timeoutResult(LLSDMap("session", "timeout"));
result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("session"))
@ -1521,7 +1602,7 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
}
std::string message = result["session"].asString();
if (message == "removed")
if (message == "removed" || message == "timeout")
break;
}
} while (true);
@ -1546,11 +1627,10 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
// The old session may now need to be deleted.
reapSession(oldSession);
}
else
{
LL_WARNS("Voice") << "stateSessionTerminated with NULL mAudioSession" << LL_ENDL;
LL_WARNS("Voice") << "terminateAudioSession(" << wait << ") with NULL mAudioSession" << LL_ENDL;
}
notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL);
@ -1560,13 +1640,15 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
// the region chat.
mSessionTerminateRequested = false;
if ((mVoiceEnabled || !mIsInitialized) && !mRelogRequested && !LLApp::isExiting())
{
// Just leaving a channel, go back to stateNoChannel (the "logged in but have no channel" state).
return true;
}
return false;
bool status=((mVoiceEnabled || !mIsInitialized) && !mRelogRequested && !LLApp::isExiting());
LL_DEBUGS("Voice") << "exiting"
<< " VoiceEnabled " << mVoiceEnabled
<< " IsInitialized " << mIsInitialized
<< " RelogRequested " << mRelogRequested
<< " AppExiting " << LLApp::isExiting()
<< " returning " << status
<< LL_ENDL;
return status;
}
bool LLVivoxVoiceClient::waitForChannel()
@ -1627,7 +1709,18 @@ bool LLVivoxVoiceClient::waitForChannel()
sessionStatePtr_t joinSession = mNextAudioSession;
mNextAudioSession.reset();
if (!runSession(joinSession))
{
LL_DEBUGS("Voice") << "runSession returned false; leaving inner loop" << LL_ENDL;
break;
}
else
{
LL_DEBUGS("Voice")
<< "runSession returned true to inner loop"
<< " RelogRequested=" << mRelogRequested
<< " VoiceEnabled=" << mVoiceEnabled
<< LL_ENDL;
}
}
if (!mNextAudioSession)
@ -1636,20 +1729,33 @@ bool LLVivoxVoiceClient::waitForChannel()
}
} while (mVoiceEnabled && !mRelogRequested);
LL_DEBUGS("Voice")
<< "leaving inner waitForChannel loop"
<< " RelogRequested=" << mRelogRequested
<< " VoiceEnabled=" << mVoiceEnabled
<< LL_ENDL;
mIsProcessingChannels = false;
logoutOfVivox(true);
if (mRelogRequested)
{
LL_DEBUGS("Voice") << "Relog Requested, restarting provisioning" << LL_ENDL;
if (!provisionVoiceAccount())
{
LL_WARNS("Voice") << "provisioning voice failed; giving up" << LL_ENDL;
giveUp();
return false;
}
}
} while (mVoiceEnabled && mRelogRequested);
} while (mVoiceEnabled && mRelogRequested && isGatewayRunning());
LL_DEBUGS("Voice")
<< "exiting"
<< " RelogRequested=" << mRelogRequested
<< " VoiceEnabled=" << mVoiceEnabled
<< LL_ENDL;
return true;
}
@ -1663,6 +1769,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
if (mSessionTerminateRequested)
{
LL_DEBUGS("Voice") << "runSession terminate requested " << LL_ENDL;
terminateAudioSession(true);
}
// if a relog has been requested then addAndJoineSession
@ -1681,7 +1788,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
mIsInChannel = true;
mMuteMicDirty = true;
while (mVoiceEnabled && !mSessionTerminateRequested && !mTuningMode)
while (mVoiceEnabled && isGatewayRunning() && !mSessionTerminateRequested && !mTuningMode)
{
sendCaptureAndRenderDevices();
if (mAudioSession && mAudioSession->mParticipantsChanged)
@ -1731,7 +1838,9 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
mIsInitialized = true;
LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, UPDATE_THROTTLE_SECONDS, timeoutEvent);
if (!result.has("timeout")) // logging the timeout event spams the log
{
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
}
if (result.has("session"))
{
if (result.has("handle"))
@ -1752,6 +1861,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
if (message == "removed")
{
LL_DEBUGS("Voice") << "session removed" << LL_ENDL;
notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL);
break;
}
@ -1761,15 +1871,16 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
std::string message = result["login"];
if (message == "account_logout")
{
LL_DEBUGS("Voice") << "logged out" << LL_ENDL;
mIsLoggedIn = false;
mRelogRequested = true;
break;
}
}
}
mIsInChannel = false;
LL_DEBUGS("Voice") << "terminating at end of runSession" << LL_ENDL;
terminateAudioSession(true);
return true;
@ -1965,6 +2076,7 @@ bool LLVivoxVoiceClient::performMicTuning()
if (mTuningSpeakerVolumeDirty)
{
LL_INFOS("Voice") << "setting tuning speaker level to " << mTuningSpeakerVolume << LL_ENDL;
stream
<< "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetSpeakerLevel.1\">"
<< "<Level>" << mTuningSpeakerVolume << "</Level>"
@ -2322,11 +2434,10 @@ void LLVivoxVoiceClient::clearCaptureDevices()
mCaptureDevices.clear();
}
void LLVivoxVoiceClient::addCaptureDevice(const std::string& name)
void LLVivoxVoiceClient::addCaptureDevice(const LLVoiceDevice& device)
{
LL_DEBUGS("Voice") << name << LL_ENDL;
mCaptureDevices.push_back(name);
LL_DEBUGS("Voice") << "display: '" << device.display_name << "' device: '" << device.full_name << "'" << LL_ENDL;
mCaptureDevices.push_back(device);
}
LLVoiceDeviceList& LLVivoxVoiceClient::getCaptureDevices()
@ -2364,10 +2475,10 @@ void LLVivoxVoiceClient::clearRenderDevices()
mRenderDevices.clear();
}
void LLVivoxVoiceClient::addRenderDevice(const std::string& name)
void LLVivoxVoiceClient::addRenderDevice(const LLVoiceDevice& device)
{
LL_DEBUGS("Voice") << name << LL_ENDL;
mRenderDevices.push_back(name);
LL_DEBUGS("Voice") << "display: '" << device.display_name << "' device: '" << device.full_name << "'" << LL_ENDL;
mRenderDevices.push_back(device);
}
LLVoiceDeviceList& LLVivoxVoiceClient::getRenderDevices()
@ -2515,13 +2626,13 @@ bool LLVivoxVoiceClient::deviceSettingsAvailable()
}
bool LLVivoxVoiceClient::deviceSettingsUpdated()
{
bool updated = mDevicesListUpdated;
if (mDevicesListUpdated)
{
// a hot swap event or a polling of the audio devices has been parsed since the last redraw of the input and output device panel.
mDevicesListUpdated = !mDevicesListUpdated; // toggle the setting
return true;
mDevicesListUpdated = false; // toggle the setting
}
return false;
return updated;
}
void LLVivoxVoiceClient::refreshDeviceLists(bool clearCurrentList)
@ -2540,8 +2651,7 @@ void LLVivoxVoiceClient::daemonDied()
// The daemon died, so the connection is gone. Reset everything and start over.
LL_WARNS("Voice") << "Connection to vivox daemon lost. Resetting state."<< LL_ENDL;
// Try to relaunch the daemon
/*TODO:*/
//TODO: Try to relaunch the daemon
}
void LLVivoxVoiceClient::giveUp()
@ -2902,7 +3012,6 @@ void LLVivoxVoiceClient::sendPositionAndVolumeUpdate(void)
}
}
//sendLocalAudioUpdates(); obsolete, used to send volume setting on position updates
std::string update(stream.str());
if(!update.empty())
{
@ -2947,7 +3056,6 @@ void LLVivoxVoiceClient::sendLocalAudioUpdates()
{
// Check all of the dirty states and then send messages to those needing to be changed.
// Tuningmode hands its own mute settings.
std::ostringstream stream;
if (mMuteMicDirty && !mTuningMode)
@ -2956,7 +3064,7 @@ void LLVivoxVoiceClient::sendLocalAudioUpdates()
// Send a local mute command.
LL_DEBUGS("Voice") << "Sending MuteLocalMic command with parameter " << (mMuteMic ? "true" : "false") << LL_ENDL;
LL_INFOS("Voice") << "Sending MuteLocalMic command with parameter " << (mMuteMic ? "true" : "false") << LL_ENDL;
stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.MuteLocalMic.1\">"
<< "<ConnectorHandle>" << LLVivoxSecurity::getInstance()->connectorHandle() << "</ConnectorHandle>"
@ -3218,8 +3326,6 @@ void LLVivoxVoiceClient::sessionConnectResponse(std::string &requestId, int stat
{
LL_DEBUGS("Voice") << "Session.Connect response received (success)" << LL_ENDL;
}
/*TODO: Post response?*/
}
void LLVivoxVoiceClient::logoutResponse(int statusCode, std::string &statusString)
@ -3243,6 +3349,7 @@ void LLVivoxVoiceClient::connectorShutdownResponse(int statusCode, std::string &
}
mConnected = false;
mShutdownComplete = true;
LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false)));
@ -4023,7 +4130,7 @@ void LLVivoxVoiceClient::sessionNotificationEvent(std::string &sessionHandle, st
void LLVivoxVoiceClient::auxAudioPropertiesEvent(F32 energy)
{
LL_DEBUGS("Voice") << "got energy " << energy << LL_ENDL;
LL_DEBUGS("VoiceEnergy") << "got energy " << energy << LL_ENDL;
mTuningEnergy = energy;
}
@ -4975,6 +5082,12 @@ void LLVivoxVoiceClient::setMuteMic(bool muted)
void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)
{
LL_DEBUGS("Voice")
<< "( " << (enabled ? "enabled" : "disabled") << " )"
<< " was "<< (mVoiceEnabled ? "enabled" : "disabled")
<< " coro "<< (mIsCoroutineActive ? "active" : "inactive")
<< LL_ENDL;
if (enabled != mVoiceEnabled)
{
// TODO: Refactor this so we don't call into LLVoiceChannel, but simply
@ -4984,6 +5097,7 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)
if (enabled)
{
LL_DEBUGS("Voice") << "enabling" << LL_ENDL;
LLVoiceChannel::getCurrentVoiceChannel()->activate();
status = LLVoiceClientStatusObserver::STATUS_VOICE_ENABLED;
@ -4991,6 +5105,10 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)
{
LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro();",
boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance()));
}
else
{
LL_DEBUGS("Voice") << "coro should be active.. not launching" << LL_ENDL;
}
}
else
@ -4999,8 +5117,13 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)
LLVoiceChannel::getCurrentVoiceChannel()->deactivate();
status = LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED;
}
notifyStatusObservers(status);
notifyStatusObservers(status);
}
else
{
LL_DEBUGS("Voice") << " no-op" << LL_ENDL;
}
}
bool LLVivoxVoiceClient::voiceEnabled()
@ -5704,7 +5827,7 @@ void LLVivoxVoiceClient::deleteSession(const sessionStatePtr_t &session)
void LLVivoxVoiceClient::deleteAllSessions()
{
LL_DEBUGS("Voice") << "called" << LL_ENDL;
LL_DEBUGS("Voice") << LL_ENDL;
while (!mSessionsByHandle.empty())
{
@ -5755,6 +5878,10 @@ void LLVivoxVoiceClient::removeObserver(LLVoiceClientStatusObserver* observer)
void LLVivoxVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::EStatusType status)
{
LL_DEBUGS("Voice") << "( " << LLVoiceClientStatusObserver::status2string(status) << " )"
<< " mAudioSession=" << mAudioSession
<< LL_ENDL;
if(mAudioSession)
{
if(status == LLVoiceClientStatusObserver::ERROR_UNKNOWN)
@ -5799,8 +5926,8 @@ void LLVivoxVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESta
LL_DEBUGS("Voice")
<< " " << LLVoiceClientStatusObserver::status2string(status)
<< ", session URI " << getAudioSessionURI()
<< (inSpatialChannel()?", proximal is true":", proximal is false")
<< LL_ENDL;
<< ", proximal is " << inSpatialChannel()
<< LL_ENDL;
for (status_observer_set_t::iterator it = mStatusObservers.begin();
it != mStatusObservers.end();
@ -6193,6 +6320,7 @@ void LLVivoxVoiceClient::expireVoiceFonts()
LLSD args;
args["URL"] = LLTrans::getString("voice_morphing_url");
args["PREMIUM_URL"] = LLTrans::getString("premium_voice_morphing_url");
// Give a notification if any voice fonts have expired.
if (have_expired)
@ -7007,16 +7135,20 @@ void LLVivoxProtocolParser::EndTag(const char *tag)
else if (!stricmp("Presence", tag))
statusString = string;
else if (!stricmp("CaptureDevices", tag))
{
LLVivoxVoiceClient::getInstance()->setDevicesListUpdated(true);
}
else if (!stricmp("RenderDevices", tag))
{
LLVivoxVoiceClient::getInstance()->setDevicesListUpdated(true);
}
else if (!stricmp("CaptureDevice", tag))
{
LLVivoxVoiceClient::getInstance()->addCaptureDevice(deviceString);
LLVivoxVoiceClient::getInstance()->addCaptureDevice(LLVoiceDevice(displayNameString, deviceString));
}
else if (!stricmp("RenderDevice", tag))
{
LLVivoxVoiceClient::getInstance()->addRenderDevice(deviceString);
LLVivoxVoiceClient::getInstance()->addRenderDevice(LLVoiceDevice(displayNameString, deviceString));
}
else if (!stricmp("BlockMask", tag))
blockMask = string;

View File

@ -432,10 +432,10 @@ protected:
//----------------------------------
// devices
void clearCaptureDevices();
void addCaptureDevice(const std::string& name);
void addCaptureDevice(const LLVoiceDevice& device);
void clearRenderDevices();
void setDevicesListUpdated(bool state);
void addRenderDevice(const std::string& name);
void addRenderDevice(const LLVoiceDevice& device);
void buildSetAudioDevices(std::ostringstream &stream);
void getCaptureDevicesSendMessage();

View File

@ -31,7 +31,7 @@
<text name="AvatarPhysicsDetailText">
Niedrig
</text>
<text name="ShadersText">
<text name="HardwareText">
Hardware
</text>
<slider label="Texturen-Cache (MB):" name="GraphicsCardTextureMemory" tool_tip="Speicherplatz, der für Texturen zur Verfügung steht. In der Regel handelt es sich um Grafikkartenspeicher. Ein kleinerer Wert kann die Geschwindigkeit erhöhen, aber auch zu Texturunschärfen führen."/>
@ -56,6 +56,9 @@
<text name="antialiasing restart">
(Neustart erforderlich)
</text>
<text name="MeshText">
Netz
</text>
<slider label="Gitterdetails Terrain:" name="TerrainMeshDetail"/>
<text name="TerrainMeshDetailText">
Niedrig
@ -72,6 +75,9 @@
<text name="FlexibleMeshDetailText">
Niedrig
</text>
<text name="ShadersText">
Shader
</text>
<check_box initial_value="true" label="Transparentes Wasser" name="TransparentWater"/>
<check_box initial_value="true" label="Bumpmapping und Glanz" name="BumpShiny"/>
<check_box initial_value="true" label="Lokale Lichtquellen" name="LocalLights"/>
@ -111,5 +117,6 @@
<button label="Auf empfohlene Einstellungen zurücksetzen" name="Defaults"/>
<button label="OK" label_selected="OK" name="OK"/>
<button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/>
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxNonImpostors"/>
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxComplexity"/>
<check_box label="RenderAvatarMaxNonImpostors" name="RenderAvatarMaxNonImpostors"/>
</floater>

View File

@ -3,6 +3,7 @@
<menu_item_call label="Nicht mehr ignorieren" name="unblock"/>
<menu_item_check label="Voice ignorieren" name="BlockVoice"/>
<menu_item_check label="Text ignorieren" name="MuteText"/>
<menu_item_check label="Partikel blockieren" name="MuteParticles"/>
<menu_item_check label="Objektsounds ignorieren" name="BlockObjectSounds"/>
<menu_item_call label="Profil..." name="profile"/>
</toggleable_menu>

View File

@ -4317,7 +4317,7 @@ Wählen Sie eine kleinere Landfläche aus.
Aufgrund eines internen Fehlers konnte Ihr Viewer nicht ordnungsgemäß aktualisiert werden. Der in Ihrem Viewer angezeigte L$-Kontostand oder Parzellenbesitz stimmt möglicherweise nicht mit dem aktuellen Stand auf den Servern überein.
</notification>
<notification name="LargePrimAgentIntersect">
Große Prims, die sich mit anderen Spielern überschneiden, können nicht erstellt werden. Bitte erneut versuchen, wenn sich die anderen Spieler bewegt haben.
Große Prims, die sich mit anderen Einwohnern überschneiden, können nicht erstellt werden. Bitte erneut versuchen, wenn sich die anderen Einwohner fort bewegt haben.
</notification>
<notification name="PreferenceChatClearLog">
Dadurch werden die Protokolle vorheriger Unterhaltungen und alle Backups dieser Datei gelöscht.

View File

@ -96,6 +96,11 @@ um mehrere Mitglieder auszuwählen.
<scroll_list.columns label="" name="action"/>
</scroll_list>
</panel>
<panel name="members_header">
<text_editor name="member_action_description">
Diese Fähigkeit wird als „Mitglieder dieser Gruppe verweisen“ bezeichnet. Eigentümer können nur von anderen Eigentümern verwiesen werden.
</text_editor>
</panel>
<panel name="roles_footer">
<text name="static">
Rolle:
@ -121,6 +126,11 @@ um mehrere Mitglieder auszuwählen.
<scroll_list.columns label="" name="action"/>
</scroll_list>
</panel>
<panel name="roles_header">
<text_editor name="role_action_description">
Diese Fähigkeit wird als „Mitglieder dieser Gruppe verweisen“ bezeichnet. Eigentümer können nur von anderen Eigentümern verwiesen werden.
</text_editor>
</panel>
<panel name="actions_footer">
<text_editor name="action_description">
Diese Fähigkeit heißt „Mitglieder aus dieser Gruppe werfen“. Eigentümer können nur von anderen Eigentümern hinausgeworfen werden.

View File

@ -3,7 +3,7 @@
<panel.string name="log_in_to_change">
Anmelden, um Änderungen vorzunehmen
</panel.string>
<button label="Cache leeren" name="clear_cache" tool_tip="Bild bei Anmeldung, letzter Standort, Teleport-Liste, Internet- und Texturen-Cache löschen"/>
<button label="Cache leeren" name="clear_cache" tool_tip="Anmeldungsbild, letzten Standort, Teleport-Liste, Internet- und Texturen-Cache löschen"/>
<text name="cache_size_label_l">
(Standorte, Bilder, Web, Suchverlauf)
</text>

View File

@ -15,8 +15,8 @@
Web:
</text>
<radio_group name="preferred_browser_behavior">
<radio_item label="Meinen Browser (Chrome, Firefox, IE) für alle Links verwenden" name="internal" tool_tip="Standard-Browser für Hilfe, Weblinks usw. verwenden. Im Vollbildmodus nicht empfohlen." value="0"/>
<radio_item label="Integrierten Browser nur für Linden Lab-/Second Life-Links verwenden" name="external" tool_tip="Verwenden Sie den Standard-Webbrowser Ihres Systems für Hilfe, Weblinks usw. Der integrierte Browser wird nur für Linden Lab-/Second Life-Links verwendet." value="1"/>
<radio_item label="Standard-Systembrowser für alle Links verwenden" name="internal" tool_tip="Standard-Browser für Hilfe, Weblinks usw. verwenden. Im Vollbildmodus nicht empfohlen." value="0"/>
<radio_item label="Integrierten Browser nur für Second Life-Links verwenden" name="external" tool_tip="Standard-Systembrowser für Hilfe, Weblinks usw. verwenden. Der integrierte Browser wird nur für LindenLab-/Second Life-Links verwendet." value="1"/>
<radio_item label="Integrierten Browser für alle Links verwenden" name="external_all" tool_tip="Integrierten Browser für Hilfe, Internetlinks, usw. verwenden. Der Browser wird als eigenständiges Fenster in [APP_NAME] geöffnet." value="2"/>
</radio_group>
<check_box initial_value="true" label="Plugins aktivieren" name="browser_plugins_enabled"/>

View File

@ -12,6 +12,9 @@
<text name="title_animation">
Animationen
</text>
<text name="title_model">
Modelle
</text>
<text name="upload_help">
Um einen Zielordner zu ändern, klicken Sie im Inventar mit der rechten Maustaste auf den Ordner und wählen Sie „Als Standard verwenden für“.
</text>

View File

@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<role_actions>
<action_set description="Diese Fähigkeiten ermöglichen das Hinzufügen und Entfernen von Mitgliedern sowie den Beitritt ohne Einladung." name="Membership">
<action description="Personen in diese Gruppe einladen" longdescription="Leute in diese Gruppe mit der Schaltfläche „Einladen“ im Abschnitt „Rollen“ &gt; Registerkarte „Mitglieder“ in die Gruppe einladen." name="member invite" value="1"/>
<action description="Mitglieder aus dieser Gruppe werfen" longdescription="Leute aus dieser Gruppe mit der Schaltfläche „Hinauswerfen“ im Abschnitt „Rollen“ &gt; Registerkarte „Mitglieder“ aus der Gruppe werfen. Ein Eigentümer kann jeden, außer einen anderen Eigentümer, ausschließen. Wenn Sie kein Eigentümer sind, können Sie ein Mitglied nur dann aus der Gruppe werfen, wenn es die Rolle Jeder inne hat, jedoch KEINE andere Rolle. Um Mitgliedern Rollen entziehen zu können, müssen Sie über die Fähigkeit „Mitgliedern Rollen entziehen“ verfügen." name="member eject" value="2"/>
<action description="Personen in diese Gruppe einladen" longdescription="Andere Personen über die Schaltfläche &quot;Einladen&quot; im Bereich &quot;Rollen und Mitglieder&quot; &gt; Registerkarte &quot;Mitglieder&quot; in diese Gruppe einladen." name="member invite" value="1"/>
<action description="Mitglieder mit der Rolle &quot;Jeder&quot; dieser Gruppe verweisen" longdescription="Mitglieder mithilfe der Schaltfläche „Hinauswerfen“ im Abschnitt „Rollen und Mitglieder“ &gt; Registerkarte „Mitglieder“ der Gruppe verweisen. Ein Eigentümer kann, mit Ausnahme eines anderen Eigentümers, jedes Mitglied ausschließen. Wenn Sie kein Eigentümer sind, können Sie ein Mitglied nur dann aus der Gruppe ausschließen, wenn es über die Rolle &quot;Jeder&quot;, ansonsten jedoch über KEINE weitere Rolle verfügt. Um Mitgliedern Rollen entziehen zu können, müssen Sie über die Fähigkeit „Mitgliedern Rollen entziehen“ verfügen." name="member eject" value="2"/>
<action description="Bannliste verwalten" longdescription="Gruppenmitglied das Verbannen/Zulassen von Einwohnern aus dieser Gruppe gestatten." name="allow ban" value="51"/>
<action description="„Registrierung offen“ aktivieren/deaktivieren und „Beitrittsgebühr“ ändern." longdescription="„Registrierung offen“ aktivieren, um damit neue Mitglieder ohne Einladung beitreten können, und die „Beitrittsgebühr“ im Abschnitt „Allgemein“ ändern." name="member options" value="3"/>
</action_set>
<action_set description="Diese Fähigkeiten ermöglichen das Hinzufügen, Entfernen und Ändern von Gruppenrollen, das Zuweisen und Entfernen von Rollen und das Zuweisen von Fähigkeiten zu Rollen." name="Roles">
<action description="Neue Rollen erstellen" longdescription="Neue Rollen im Abschnitt „Rollen“ &gt; Registerkarte „Rollen“ erstellen." name="role create" value="4"/>
<action description="Rollen löschen" longdescription="Neue Rollen im Abschnitt „Rollen“ &gt; Registerkarte „Rollen“ löschen." name="role delete" value="5"/>
<action description="Rollennamen, Titel, Beschreibungen und ob die Rolleninhaber öffentlich bekannt sein sollen, ändern." longdescription="Rollennamen, Titel, Beschreibungen und ob die Rolleninhaber öffentlich bekannt sein sollen, ändern. Dies wird im unteren Bereich des Abschnitts „Rollen“ &gt; Registerkarte „Rollen“ eingestellt, nachdem eine Rolle ausgewählt wurde." name="role properties" value="6"/>
<action description="Mitgliedern nur eigene Rollen zuweisen" longdescription="In der Liste „Rollen“ (Abschnitt „Rollen“ &gt; Registerkarte „Mitglieder“) können Mitgliedern Rollen zugewiesen werden. Ein Mitglied mit dieser Fähigkeit kann anderen Mitgliedern nur die eigenen Rollen zuweisen." name="role assign member limited" value="7"/>
<action description="Mitgliedern beliebige Rolle zuweisen" longdescription="Sie können Mitglieder jede beliebige Rolle der Liste „Rollen“ (Abschnitt „Rollen“ &gt; Registerkarte „Mitglieder“) zuweisen. *WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann sich selbst und jedem anderen Mitglied (außer dem Eigentümer) Rollen mit weitreichenden Fähigkeiten zuweisen und damit fast Eigentümerrechte erreichen. Überlegen Sie sich gut, wem Sie diese Fähigkeit verleihen." name="role assign member" value="8"/>
<action description="Mitgliedern Rollen entziehen" longdescription="In der Liste „Rollen“ (Abschnitt „Rollen“ &gt; Registerkarte „Mitglieder“) können Mitgliedern Rollen abgenommen werden. Eigentümer können nicht entfernt werden." name="role remove member" value="9"/>
<action description="Rollenfähigkeiten zuweisen und entfernen" longdescription="Fähigkeiten für jede Rolle können in der Liste „Zulässige Fähigkeiten&quot; (Abschnitt „Rollen&quot; &gt; Registerkarte „Rollen“) zugewiesen und auch entzogen werden. *WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann sich selbst und jedem anderen Mitglied (außer dem Eigentümer) alle Fähigkeiten zuweisen und damit fast Eigentümerrechte erreichen. Überlegen Sie sich gut, wem Sie diese Fähigkeit verleihen." name="role change actions" value="10"/>
<action description="Neue Rollen erstellen" longdescription="Erstellen neuer Rollen im Abschnitt „Rollen und Mitglieder“ &gt; Registerkarte „Rollen“." name="role create" value="4"/>
<action description="Rollen löschen" longdescription="Löschen von Rollen im Abschnitt „Rollen und Mitglieder“ &gt; Registerkarte „Rollen“." name="role delete" value="5"/>
<action description="Rollennamen, Titel, Beschreibungen und ob die Rolleninhaber öffentlich bekannt sein sollen, ändern." longdescription="Ändern von Rollennamen, Titeln, Beschreibungen und öffentlicher Bekanntgabe der Rolleninhaber. Dies wird im unteren Bereich des Abschnitts „Rollen und Mitglieder“ &gt; Registerkarte „Rollen“ eingestellt, nachdem eine Rolle ausgewählt wurde." name="role properties" value="6"/>
<action description="Mitgliedern nur eigene Rollen zuweisen" longdescription="In der Liste „Zugewiesene Rollen“ (Abschnitt „Rollen und Mitglieder“ &gt; Registerkarte „Mitglieder“) können Mitgliedern Rollen zugewiesen werden. Ein Mitglied mit dieser Fähigkeit kann anderen Mitgliedern nur die eigene Rolle zuweisen." name="role assign member limited" value="7"/>
<action description="Mitgliedern beliebige Rolle zuweisen" longdescription="Sie können Mitgliedern in der Liste „Zugewiesene Rollen“ (Abschnitt „Rollen und Mitglieder“ &gt; Registerkarte „Mitglieder“) jede beliebige Rolle zuweisen.*WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann sich selbst und jedem anderen Mitglied (außer dem Eigentümer) Rollen mit weitreichenden Berechtigungen zuweisen und damit nahezu Eigentümerrechte erreichen. Überlegen Sie also genau, wem Sie diese Berechtigung erteilen." name="role assign member" value="8"/>
<action description="Mitgliedern Rollen entziehen" longdescription="In der Liste „Zugewiesene Rollen“ (Abschnitt „Rollen und Mitglieder“ &gt; Registerkarte „Mitglieder“) können Mitglieder aus Rollenzuweisungen entfernt werden. Eigentümer können nicht entfernt werden." name="role remove member" value="9"/>
<action description="Rollenfähigkeiten zuweisen und entfernen" longdescription="In der Liste &quot;Zulässige Fähigkeiten&quot; (Bereich &quot;Rollen und Mitglieder&quot; &gt; Registerkarte &quot;Rollen&quot;) können für jede Rolle Fähigkeiten hinzugefügt und entfernt werden. *WARNUNG* Jedes Mitglied in einer Rolle mit dieser Fähigkeit kann sich selbst und jedem anderen Mitglied (außer dem Eigentümer) alle Fähigkeiten zuweisen und damit nahezu Eigentümerrechte erreichen. Überlegen Sie also genau, wem Sie diese Fähigkeit zuweisen." name="role change actions" value="10"/>
</action_set>
<action_set description="Diese Fähigkeiten ermöglichen es, die Gruppenidentität zu ändern, z. B. öffentliche Sichtbarkeit, Charta und Insignien." name="Group Identity">
<action description="Charta, Insignien und „Im Web veröffentlichen“ ändern und festlegen, welche Mitglieder in der Gruppeninfo öffentlich sichtbar sind." longdescription="Charta, Insignien und „In Suche anzeigen&quot; ändern. Diese Einstellungen werden im Abschnitt „Allgemein&quot; vorgenommen." name="group change identity" value="11"/>

View File

@ -502,7 +502,7 @@
name="Buy Land..."
width="130" />
<button
enabled="true"
enabled="false"
follows="left|top"
height="23"
label="Linden Sale"

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
can_resize="true"
height="412"
layout="topleft"
min_height="412"
min_width="420"
name="floater_auction"
help_topic="floater_auction"
title="START LINDEN LAND SALE"
width="420">
<floater.string
name="already for sale">
You cannot auction parcels which are already for sale.
</floater.string>
<icon
bottom="280"
follows="left|right|top|bottom"
layout="topleft"
left="4"
name="snapshot_icon"
right="-4"
top="24" />
<text
follows="left|right|bottom"
height="16"
layout="topleft"
left_delta="0"
name="parcel_text"
top_pad="12"
width="400" />
<check_box
control_name="AuctionShowFence"
follows="left|bottom"
height="16"
initial_value="true"
label="Include yellow selection fence"
layout="topleft"
left_delta="0"
name="fence_check"
top_pad="12"
width="199" />
<button
follows="left|bottom"
height="20"
label="Snapshot"
label_selected="Snapshot"
layout="topleft"
left_delta="0"
name="snapshot_btn"
top_pad="4"
width="150">
<button.commit_callback
function="ClickSnapshot" />
</button>
<button
follows="left|bottom"
height="20"
label="Sell to Anyone"
label_selected="Sell to Anyone"
layout="topleft"
left_delta="0"
name="sell_to_anyone_btn"
top_pad="4"
width="150">
<button.commit_callback
function="ClickSellToAnyone" />
</button>
<button
follows="left|bottom"
height="20"
label="Clear Settings"
label_selected="Clear Settings"
layout="topleft"
left_delta="0"
name="reset_parcel_btn"
top_pad="4"
width="150">
<button.commit_callback
function="ClickResetParcel" />
</button>
<button
follows="left|bottom"
height="20"
label="Start Auction"
label_selected="Start Auction"
layout="topleft"
left_pad="4"
name="start_auction_btn"
top_delta="0"
width="150">
<button.commit_callback
function="ClickStartAuction" />
</button>
</floater>

View File

@ -1115,6 +1115,10 @@
label="Zoom"
name="Zoom"
value="Zoom" />
<combo_box.item
label="None"
name="None"
value="None" />
</combo_box>
<check_box
height="23"

View File

@ -92,11 +92,24 @@
shortcut="alt|shift|S"
name="Sit Down Here">
<menu_item_call.on_click
function="Self.SitDown"
parameter="" />
function="Self.SitDown"/>
<menu_item_call.on_visible
function="Self.ShowSitDown"/>
<menu_item_call.on_enable
function="Self.EnableSitDown" />
</menu_item_call>
<menu_item_call
label="Stand Up"
layout="topleft"
shortcut="alt|shift|S"
name="Stand up">
<menu_item_call.on_click
function="Self.StandUp"/>
<menu_item_call.on_visible
function="Self.EnableStandUp"/>
<menu_item_call.on_enable
function="Self.EnableStandUp" />
</menu_item_call>
<menu_item_check
label="Fly"
name="Fly"

View File

@ -8102,6 +8102,8 @@ Failed to connect to [VOICE_CHANNEL_NAME], please try again later. You will now
<unique/>
One or more of your subscribed Voice Morphs has expired.
[[URL] Click here] to renew your subscription.
If you are a Premium Member, [[PREMIUM_URL] click here] to receive your voice morphing perk.
<tag>fail</tag>
<tag>voice</tag>
</notification>
@ -8115,6 +8117,8 @@ One or more of your subscribed Voice Morphs has expired.
<unique/>
The active Voice Morph has expired, your normal voice settings have been applied.
[[URL] Click here] to renew your subscription.
If you are a Premium Member, [[PREMIUM_URL] click here] to receive your voice morphing perk.
<tag>fail</tag>
<tag>voice</tag>
</notification>
@ -8128,6 +8132,8 @@ The active Voice Morph has expired, your normal voice settings have been applied
<unique/>
One or more of your Voice Morphs will expire in less than [INTERVAL] days.
[[URL] Click here] to renew your subscription.
If you are a Premium Member, [[PREMIUM_URL] click here] to receive your voice morphing perk.
<tag>fail</tag>
<tag>voice</tag>
</notification>
@ -8260,6 +8266,11 @@ Failed to save appearance to XML.
Failed to save snapshot to [PATH]: Disk is full. [NEED_MEMORY]KB is required but only [FREE_MEMORY]KB is free.
</notification>
<notification icon="notifytip.tga"
name="SnapshotToLocalDirNotExist" type="notifytip">
Failed to save snapshot to [PATH]: Directory does not exist.
</notification>
<notification
icon="notifytip.tga"
name="PresetNotSaved"

View File

@ -12,6 +12,10 @@
name="forgot_password_url">
http://secondlife.com/account/request.php
</panel.string>
<panel.string
name="sign_up_url">
https://join.secondlife.com/
</panel.string>
<layout_stack
follows="left|right|top"
height="172"
@ -149,7 +153,18 @@
label="Select grid"
layout="topleft"
name="server_combo"
width="149" />
width="149" />
<text
follows="left|top"
font="SansSerifMedium"
text_color="EmphasisColor"
height="16"
name="sign_up_text"
left="778"
bottom_delta="-10"
width="200">
Sign up
</text>
</layout_panel>
<layout_panel
height="172"

View File

@ -12,6 +12,10 @@
name="forgot_password_url">
http://secondlife.com/account/request.php
</panel.string>
<panel.string
name="sign_up_url">
https://join.secondlife.com/
</panel.string>
<layout_stack
follows="left|right|top|bottom"
width="1024"
@ -168,6 +172,17 @@
width="200">
Forgotten password
</text>
<text
follows="left|top"
font="SansSerifLarge"
text_color="EmphasisColor"
height="16"
name="sign_up_text"
left="432"
top="34"
width="200">
Sign up
</text>
</layout_panel>
<layout_panel
height="100"

View File

@ -292,10 +292,14 @@
label="Open"
name="Open"
value="Open" />
<combo_box.item
label="Zoom"
name="Zoom"
value="Zoom" />
<combo_box.item
label="Zoom"
name="Zoom"
value="Zoom" />
<combo_box.item
label="None"
name="None"
value="None" />
</combo_box>
<panel
border="false"

View File

@ -31,7 +31,7 @@
<text name="AvatarPhysicsDetailText">
Bajo
</text>
<text name="ShadersText">
<text name="HardwareText">
Hardware
</text>
<slider label="Memoria para texturas (MB):" name="GraphicsCardTextureMemory" tool_tip="Cantidad de memoria asignada a las texturas. Por defecto es la memoria de la tarjeta de vídeo. Reducir esta cantidad puede mejorar el rendimiento, pero también hacer que las texturas se vean borrosas."/>
@ -56,6 +56,9 @@
<text name="antialiasing restart">
(requiere reiniciar)
</text>
<text name="MeshText">
Malla
</text>
<slider label="Detalle de la malla del terreno:" name="TerrainMeshDetail"/>
<text name="TerrainMeshDetailText">
Bajo
@ -72,6 +75,9 @@
<text name="FlexibleMeshDetailText">
Bajo
</text>
<text name="ShadersText">
Shaders
</text>
<check_box initial_value="true" label="Agua transparente" name="TransparentWater"/>
<check_box initial_value="true" label="Efecto de relieve y brillo" name="BumpShiny"/>
<check_box initial_value="true" label="Puntos de luz locales" name="LocalLights"/>
@ -111,5 +117,6 @@
<button label="Restablecer la configuración recomendada" name="Defaults"/>
<button label="OK" label_selected="OK" name="OK"/>
<button label="Cancelar" label_selected="Cancelar" name="Cancel"/>
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxNonImpostors"/>
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxComplexity"/>
<check_box label="RenderAvatarMaxNonImpostors" name="RenderAvatarMaxNonImpostors"/>
</floater>

View File

@ -3,6 +3,7 @@
<menu_item_call label="No ignorar" name="unblock"/>
<menu_item_check label="Bloquear la voz" name="BlockVoice"/>
<menu_item_check label="Bloquear el texto" name="MuteText"/>
<menu_item_check label="Bloquear partículas" name="MuteParticles"/>
<menu_item_check label="Bloquear los sonidos de objeto" name="BlockObjectSounds"/>
<menu_item_call label="Perfil..." name="profile"/>
</toggleable_menu>

View File

@ -4299,7 +4299,7 @@ Prueba a seleccionar un terreno más pequeño.
Un error interno nos ha impedido actualizar tu visor correctamente. El saldo en L$ o las parcelas en propiedad presentadas en el visor podrían no coincidir con tu saldo real en los servidores.
</notification>
<notification name="LargePrimAgentIntersect">
No se pueden crear prims grandes que intersectan a otros jugadores. Reinténtalo cuando se hayan movido otros jugadores.
No se pudo crear primitivas grandes que se crucen con otros residentes. Por favor, vuelve a intentar cuando otros residentes se hayan desplazado.
</notification>
<notification name="PreferenceChatClearLog">
Esto eliminará los registros de conversaciones anteriores y las copias de seguridad de ese archivo.

View File

@ -91,6 +91,11 @@ Seleccione varios nombres manteniendo pulsada la tecla Ctrl y pulsando en cada u
<scroll_list.columns label="" name="action"/>
</scroll_list>
</panel>
<panel name="members_header">
<text_editor name="member_action_description">
Esta habilidad es &apos;Expulsar miembros de este grupo&apos;. Sólo un propietario puede expulsar a otro propietario.
</text_editor>
</panel>
<panel name="roles_footer">
<text name="static">
Nombre del rol
@ -117,6 +122,11 @@ Seleccione varios nombres manteniendo pulsada la tecla Ctrl y pulsando en cada u
<scroll_list.columns label="" name="action"/>
</scroll_list>
</panel>
<panel name="roles_header">
<text_editor name="role_action_description">
Esta habilidad es &apos;Expulsar miembros de este grupo&apos;. Sólo un propietario puede expulsar a otro propietario.
</text_editor>
</panel>
<panel name="actions_footer">
<text_editor name="action_description">
Esta capacidad es la de &apos;Expulsar miembros de este grupo&apos;. Sólo un propietario puede expulsar a otro.

View File

@ -15,8 +15,8 @@
Web:
</text>
<radio_group name="preferred_browser_behavior">
<radio_item label="Usar mi navegador (Chrome, Firefox, IE) para todos los enlaces" name="internal" tool_tip="Usa el navegador predeterminado para obtener ayuda, visitar enlaces web, etc. No es aconsejable si estás a pantalla completa." value="0"/>
<radio_item label="Usar el navegador integrado solo para los enlaces de Second Life" name="external" tool_tip="Usa el navegador predeterminado del sistema para obtener ayuda, visitar enlaces web, etc. El navegador integrado solo se utilizará para los enlaces de LindenLab/SecondLife." value="1"/>
<radio_item label="Usar el navegador incorporado para todos los enlaces" name="internal" tool_tip="Usa el navegador predeterminado para obtener ayuda, visitar enlaces web, etc. No es aconsejable si estás a pantalla completa." value="0"/>
<radio_item label="Usar el navegador integrado solo para los enlaces de Second Life" name="external" tool_tip="Usa el navegador predeterminado para obtener ayuda, visitar enlaces web, etc. Se utilizará el navegador incorporado sólo para los enlaces LindenLab/Second Life." value="1"/>
<radio_item label="Usar el navegador incorporado para todos los vínculos" name="external_all" tool_tip="Usa el navegador incorporado para ayuda, enlaces web, etc. Este navegador se abre en una nueva ventana dentro de [APP_NAME]." value="2"/>
</radio_group>
<check_box initial_value="true" label="Activar plugins" name="browser_plugins_enabled"/>

View File

@ -12,6 +12,9 @@
<text name="title_animation">
Animaciones
</text>
<text name="title_model">
Modelos
</text>
<text name="upload_help">
Para cambiar una carpeta de destino, pulsa con el botón derecho en ella en el inventario y elige
&quot;Usar como valor predeterminado para&quot;

View File

@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<role_actions>
<action_set description="Estas capacidades incluyen poderes para añadir o quitar miembros del grupo, y para pemitir que se sumen nuevos miembros sin necesidad de invitación." name="Membership">
<action description="Invitar personas al grupo" longdescription="Invitar a gente a este grupo usando el botón &apos;Invitar&apos; en la sección Roles &gt; pestaña Miembros." name="member invite" value="1"/>
<action description="Expulsar a miembros del grupo" longdescription="Expulsar a miembros de este grupo usando el botón &apos;Expulsar&apos; en la sección Roles &gt; pestaña Miembros. Un propietario puede expulsar a cualquiera, excepto a otro propietario. Si no eres un propietario, un miembro puede ser expulsado única y exclusivamente si está en el rol de Cualquiera y NO en otros roles. Para quitar roles a los miembros, tienes que tener la capacidad de &apos;Quitar roles a los miembros&apos;." name="member eject" value="2"/>
<action description="Invitar personas al grupo" longdescription="Invitar a gente a este grupo usando el botón &apos;Invitar&apos; en la sección Roles y Miembros &gt; pestaña Miembros." name="member invite" value="1"/>
<action description="Expulsar miembros que pertenecen al rol &apos;Todos&apos; en este grupo." longdescription="Expulsar a miembros de este grupo usando el botón &apos;Expulsar&apos; en la sección Roles y Miembros &gt; pestaña Miembros. Un propietario puede expulsar a cualquiera, excepto a otro propietario. Si no eres un propietario, un miembro puede ser expulsado única y exclusivamente si está en el rol de Todos y NO en otros roles. Para quitar roles a los miembros, tienes que tener la capacidad de &apos;Quitar roles a los miembros&apos;." name="member eject" value="2"/>
<action description="Administra la lista de expulsados" longdescription="Permite que el miembro del grupo expulse a residentes de este grupo o los readmita." name="allow ban" value="51"/>
<action description="Cambiar &apos;Inscripción abierta&apos; y &apos;Cuota de inscripción&apos;" longdescription="En la sección General, cambiar la &apos;Inscripción abierta&apos; -que permite entrar al grupo sin invitación- y la &apos;Cuota de inscripción&apos;." name="member options" value="3"/>
</action_set>
<action_set description="Estas habilidades incluyen el poder añadir, quitar y cambiar roles, asignarlos a miembros, y darles capacidades." name="Roles">
<action description="Crear nuevos roles" longdescription="Crear roles nuevos en la sección Roles &gt; pestaña Roles." name="role create" value="4"/>
<action description="Borrar roles" longdescription="Borrar roles en la sección Roles &gt; pestaña Roles." name="role delete" value="5"/>
<action description="Cambiar el nombre, la etiqueta y la descripción de los roles, así como qué miembros se muestran públicamente en ese rol" longdescription="Cambiar el nombre, la etiqueta y la descripción de los roles, así como qué miembros se muestran públicamente en ese rol. Se hace seleccionando el rol, dentro de la sección Roles &gt; pestaña Roles." name="role properties" value="6"/>
<action description="Designar miembros para el rol del asignador" longdescription="Añadir miembros a los roles en la lista de Roles asignados (sección Roles &gt; pestaña Miembros). Un miembro con esta capacidad sólo puede añadir miembros a los roles que tenga él mismo." name="role assign member limited" value="7"/>
<action description="Designar miembros para cualquier rol" longdescription="Designar miembros para cualquier rol en la lista de Roles asignados (sección Roles &gt; pestaña Miembros). *AVISO* Todos los miembros que tengan un rol con esta capacidad podrán asignarse a sí mismos -y a otros miembros que no sean los propietarios- roles con mayores poderes de los que actualmente tienen. Potencialmente, podrían elevarse hasta poderes cercanos a los del propietario. Asegúrate de lo que estás haciendo antes de otorgar esta capacidad." name="role assign member" value="8"/>
<action description="Quitar capacidades a los miembros" longdescription="Quitar miembros de los roles en la lista de roles asignados (sección Roles &gt; pestaña Miembros). No se puede quitar a los Propietarios." name="role remove member" value="9"/>
<action description="Añadir o quitar capacidades a los roles" longdescription="Asignar y quitar capacidades a cada rol en la lista de capacidades permitidas (sección Roles &gt; pestaña Roles). *AVISO* Todos los miembros que tengan un rol con esta capacidad podrán asignarse a sí mismos -y a otros miembros que no sean los propietarios- todas las capacidades. Potencialmente, podrían elevarse hasta poderes cercanos a los del propietario. Asegúrate de lo que estás haciendo antes de otorgar esta capacidad." name="role change actions" value="10"/>
<action description="Crear nuevos roles" longdescription="Crear roles nuevos en la sección Roles y Miembros &gt; pestaña Roles." name="role create" value="4"/>
<action description="Borrar roles" longdescription="Borrar roles en la sección Roles y Miembros &gt; pestaña Roles." name="role delete" value="5"/>
<action description="Cambiar el nombre, la etiqueta y la descripción de los roles, así como qué miembros se muestran públicamente en ese rol" longdescription="Cambiar el nombre, la etiqueta y la descripción de los roles, y si los miembros se muestran públicamente en ese rol. Esto se hace al final de la sección Roles y Miembros &gt; pestaña Roles, luego de seleccionar un Rol." name="role properties" value="6"/>
<action description="Designar miembros para el rol del asignador" longdescription="Añadir miembros a los roles en la lista de Roles asignados (sección Roles y Miembros &gt; pestaña Miembros). Un miembro con esta capacidad sólo puede añadir miembros a los roles que tenga él mismo." name="role assign member limited" value="7"/>
<action description="Designar miembros para cualquier rol" longdescription="Asignar miembros a cualquier rol en la lista de roles asignados (Sección Roles y miembros &gt; pestaña Miembros) *AVISO* Todos los miembros que tengan un rol con esta capacidad podrán asignarse a sí mismos -y a otros miembros que no sean los propietarios- roles con mayores poderes de los que actualmente tienen. Potencialmente, podrían elevarse hasta poderes cercanos a los del propietario. Asegúrate de lo que estás haciendo antes de otorgar esta capacidad." name="role assign member" value="8"/>
<action description="Quitar capacidades a los miembros" longdescription="Quitar miembros de los roles en la lista de roles asignados (sección Roles y Miembros &gt; pestaña Miembros). No se puede quitar a los Propietarios." name="role remove member" value="9"/>
<action description="Añadir o quitar capacidades a los roles" longdescription="Asignar y quitar habilidades para cada Rol en la lista de capacidades permitidas (Sección Roles y Miembros &gt; pestaña Roles). *AVISO* Todos los miembros que tengan un rol con esta capacidad podrán asignarse a sí mismos -y a otros miembros que no sean los propietarios- todas las capacidades. Potencialmente, podrían elevarse hasta poderes cercanos a los del propietario. Asegúrate de lo que estás haciendo antes de otorgar esta capacidad." name="role change actions" value="10"/>
</action_set>
<action_set description="Estas capacidades incluyen poderes para modificar la identidad del grupo, como su visibilidad pública, su carta o su emblema." name="Group Identity">
<action description="Cambiar la carta, emblema, &apos;Mostrar en la búsqueda&apos;, y qué miembros serán visibles en la información del grupo" longdescription="Cambia la carta, emblema y &apos;Mostrar en la búsqueda&apos;. Se hace en la sección General." name="group change identity" value="11"/>

View File

@ -31,7 +31,7 @@
<text name="AvatarPhysicsDetailText">
Faible
</text>
<text name="ShadersText">
<text name="HardwareText">
Matériel
</text>
<slider label="Mémoire textures (Mo) :" name="GraphicsCardTextureMemory" tool_tip="Quantité de mémoire à affecter aux textures. Utilise la mémoire de la carte vidéo par défaut. Si vous réduisez ce paramètre, cela peut améliorer les performances, mais les textures risquent dêtre floues."/>
@ -56,6 +56,9 @@
<text name="antialiasing restart">
(redémarrage requis)
</text>
<text name="MeshText">
Maillage
</text>
<slider label="Détails des rendus des terrains :" name="TerrainMeshDetail"/>
<text name="TerrainMeshDetailText">
Faible
@ -72,6 +75,9 @@
<text name="FlexibleMeshDetailText">
Faible
</text>
<text name="ShadersText">
Effets
</text>
<check_box initial_value="true" label="Eau transparente" name="TransparentWater"/>
<check_box initial_value="true" label="Placage de relief et brillance" name="BumpShiny"/>
<check_box initial_value="true" label="Lumières locales" name="LocalLights"/>
@ -111,5 +117,6 @@
<button label="Réinitialiser les paramètres recommandés" name="Defaults"/>
<button label="OK" label_selected="OK" name="OK"/>
<button label="Annuler" label_selected="Annuler" name="Cancel"/>
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxNonImpostors"/>
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxComplexity"/>
<check_box label="RenderAvatarMaxNonImpostors" name="RenderAvatarMaxNonImpostors"/>
</floater>

View File

@ -3,6 +3,7 @@
<menu_item_call label="Ne plus ignorer" name="unblock"/>
<menu_item_check label="Bloquer le chat vocal" name="BlockVoice"/>
<menu_item_check label="Ignorer le texte" name="MuteText"/>
<menu_item_check label="Ignorez les particules" name="MuteParticles"/>
<menu_item_check label="Bloquer les sons des objets" name="BlockObjectSounds"/>
<menu_item_call label="Profil..." name="profile"/>
</toggleable_menu>

View File

@ -4302,7 +4302,7 @@ Veuillez sélectionner un terrain plus petit.
Une erreur interne nous a empêchés de mettre votre client à jour correctement. Le solde de L$ et le patrimoine affichés dans votre client peuvent ne pas correspondre à votre solde réel sur les serveurs.
</notification>
<notification name="LargePrimAgentIntersect">
Impossible de créer de grandes prims qui coupent d&apos;autres joueurs. Réessayez une fois que les autres joueurs se seront déplacés.
Impossible de créer de grands prims qui rejoignent d&apos;autres résidents. Veuillez essayer à nouveau lorsque les autres résidents seront partis.
</notification>
<notification name="PreferenceChatClearLog">
Cela supprimera les journaux des conversations précédentes, ainsi que toute copie de sauvegarde de ce fichier.

View File

@ -95,6 +95,11 @@ Pour sélectionner plusieurs membres, cliquez sur leurs noms en maintenant la to
<scroll_list.columns label="" name="action"/>
</scroll_list>
</panel>
<panel name="members_header">
<text_editor name="member_action_description">
Ce pouvoir permet « d&apos;expulser des membres de ce groupe ». Seul un propriétaire peut expulser un autre propriétaire.
</text_editor>
</panel>
<panel name="roles_footer">
<text name="static">
Nom du rôle
@ -120,6 +125,11 @@ Pour sélectionner plusieurs membres, cliquez sur leurs noms en maintenant la to
<scroll_list.columns label="" name="action"/>
</scroll_list>
</panel>
<panel name="roles_header">
<text_editor name="role_action_description">
Ce pouvoir permet « d&apos;expulser des membres de ce groupe ». Seul un propriétaire peut expulser un autre propriétaire.
</text_editor>
</panel>
<panel name="actions_footer">
<text_editor name="action_description">
Ce pouvoir permet d&apos;expulser des membres du groupe. Seul un propriétaire peut expulser un autre propriétaire.

View File

@ -3,7 +3,7 @@
<panel.string name="log_in_to_change">
se connecter pour changer
</panel.string>
<button label="Vider l&apos;historique" name="clear_cache" tool_tip="Effacer le cache de l&apos;image de connexion, du dernier lieu, de l&apos;historique des téléportations, Web et de texture."/>
<button label="Vider l&apos;historique" name="clear_cache" tool_tip="Effacez le cache de l&apos;image de connexion, du dernier lieu, de l&apos;historique des téléportations, du Web et des textures."/>
<text name="cache_size_label_l">
(endroits, images, web, historique des recherches)
</text>

View File

@ -15,9 +15,9 @@
Web :
</text>
<radio_group name="preferred_browser_behavior">
<radio_item label="Utiliser mon navigateur (Chrome, Firefox, IE) pour tous les liens" name="internal" tool_tip="Utiliser le navigateur web système par défaut pour l&apos;aide, les liens, etc. Non recommandé en mode plein écran." value="0"/>
<radio_item label="Utiliser le navigateur intégré pour les liens Second Life uniquement" name="external" tool_tip="Utilisez le navigateur web système par défaut pour l&apos;aide, les liens Web, etc. Le navigateur intégré sera uniquement utilisé pour les liens LindenLab/SecondLife." value="1"/>
<radio_item label="Utiliser le navigateur intégré pour tous les liens" name="external_all" tool_tip="Utilisez le navigateur intégré pour obtenir de laide, ouvrir des liens etc. Ce navigateur souvre dans [APP_NAME]." value="2"/>
<radio_item label="Utilisez le navigateur intégré par défaut pour tous les liens" name="internal" tool_tip="Utiliser le navigateur web système par défaut pour l&apos;aide, les liens, etc. Non recommandé en mode plein écran." value="0"/>
<radio_item label="Utilisez le navigateur intégré pour les liens Second Life uniquement" name="external" tool_tip="Utilisez le navigateur web système par défaut pour trouver de l&apos;aide, les liens web, etc. Le navigateur intégré ne sera utilisé que pour les liens LindenLab / SeconLife." value="1"/>
<radio_item label="Utilisez le navigateur intégré pour tous les liens" name="external_all" tool_tip="Utilisez le navigateur intégré pour obtenir de laide, ouvrir des liens etc. Ce navigateur souvre dans [APP_NAME]." value="2"/>
</radio_group>
<check_box initial_value="true" label="Activer les plugins" name="browser_plugins_enabled"/>
<check_box initial_value="true" label="Accepter les cookies" name="cookies_enabled"/>

View File

@ -12,6 +12,9 @@
<text name="title_animation">
Animations
</text>
<text name="title_model">
Modèles
</text>
<text name="upload_help">
Pour modifier un dossier de destination, cliquez-droit sur ce dossier dans linventaire et faites votre choix
&quot;Utiliser comme défaut pour&quot;

View File

@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<role_actions>
<action_set description="Ces pouvoirs permettent d&apos;ajouter et de supprimer des membres du groupe et permettent aux nouveaux membres de rejoindre le groupe sans recevoir d&apos;invitation." name="Membership">
<action description="Inviter des membres dans ce groupe" longdescription="Invitez des personnes à rejoindre ce groupe en utilisant le bouton Inviter dans l&apos;onglet Membres de la section Rôles." name="member invite" value="1"/>
<action description="Expulser des membres du groupe" longdescription="Expulsez des personnes de ce groupe en utilisant le bouton Expulser dans l&apos;onglet Membres de la section Rôles. Un propriétaire peut expulser tout le monde à l&apos;exception des autres propriétaires. Si vous n&apos;êtes pas propriétaire, vous pouvez expulser un membre d&apos;un groupe uniquement si il n&apos;a que le rôle Tous et AUCUN autre rôle. Pour supprimer des membres des rôles, vous devez disposer du pouvoir correspondant." name="member eject" value="2"/>
<action description="Inviter des membres dans ce groupe" longdescription="Invitez des personnes à rejoindre ce groupe en utilisant le bouton « Inviter » dans la section Rôles et membres &gt; onglet Membres" name="member invite" value="1"/>
<action description="Expulser les Membres appartenant du rôle « Tous » de ce groupe" longdescription="Expulsez des personnes de ce groupe en utilisant le bouton « Expulser » dans la section Rôles et membres &gt; onglet Membres Un propriétaire peut expulser tout le monde à lexception des autres propriétaires. Si vous nêtes pas propriétaire, vous pouvez expulser un membre dun groupe si, et uniquement s&apos;il na que le rôle Tous et AUCUN autre rôle. Pour supprimer des membres des rôles, vous devez disposer du pouvoir « Supprimer des membres des rôles »" name="member eject" value="2"/>
<action description="Gérer la liste des résidents bannis" longdescription="Permet au membre du groupe de bannir / d&apos;annuler le bannissement des résidents de ce groupe." name="allow ban" value="51"/>
<action description="Activer Inscription libre et modifier les frais d&apos;inscription" longdescription="Activez Inscription libre pour permettre aux nouveaux membres de s&apos;inscrire sans invitation, et changez les frais d&apos;inscription dans la section Général." name="member options" value="3"/>
</action_set>
<action_set description="Ces pouvoirs permettent d&apos;ajouter, de supprimer et de modifier les rôles dans le groupe et d&apos;y assigner des membres et des pouvoirs." name="Roles">
<action description="Créer des rôles" longdescription="Créez de nouveaux rôles dans l&apos;onglet Rôles de la section Rôles." name="role create" value="4"/>
<action description="Supprimer des rôles" longdescription="Supprimez des rôles dans l&apos;onglet Rôles de la section Rôles." name="role delete" value="5"/>
<action description="Changer les noms, les titres et les descriptions des rôles et indiquer si les membres des rôles sont rendus publics" longdescription="Changez les noms, les titres et les descriptions des rôles, et indiquez si les membres des rôles sont rendus publics. Vous pouvez le faire au bas de l&apos;onglet Rôles dans la section Rôles, après avoir sélectionné un rôle." name="role properties" value="6"/>
<action description="Attribuer des rôles limités" longdescription="Assignez des membres aux rôles dans la liste Rôles assignés (section Rôles &gt; onglet Membres). Un membre avec ce pouvoir peut uniquement ajouter des membres à un rôle dans lequel le responsable de l&apos;assignation est déjà présent." name="role assign member limited" value="7"/>
<action description="Attribuer tous les rôles" longdescription="Assignez des membres à n&apos;importe quel rôle dans la liste Rôles assignés (section Rôles &gt; onglet Membres). *AVERTISSEMENT* Tout membre disposant de ce pouvoir peut s&apos;assigner lui-même, ainsi que tout autre membre non-propriétaire, à des rôles disposant de pouvoirs plus importants, et accéder potentiellement à des pouvoirs proches de ceux d&apos;un propriétaire. Assurez-vous de bien comprendre ce que vous faites avant d&apos;attribuer ce pouvoir." name="role assign member" value="8"/>
<action description="Destituer des membres de leurs rôles" longdescription="Supprimez des membres des rôles dans la liste Rôles assignés (section Rôles &gt; onglet Membres). Les propriétaires ne peuvent pas être supprimés." name="role remove member" value="9"/>
<action description="Modifier les pouvoirs d&apos;un rôle" longdescription="Attribuez et supprimez des pouvoirs pour chaque rôle dans la liste Pouvoirs attribués (section Rôles &gt; onglet Rôles). *AVERTISSEMENT* Tout membre dans un rôle avec ce pouvoir peut s&apos;attribuer à lui-même, ainsi qu&apos;à tout autre membre non-propriétaire, tous les pouvoirs, et accéder potentiellement à des pouvoirs proches de ceux d&apos;un propriétaire. Assurez-vous de bien comprendre ce que vous faites avant d&apos;attribuer ce pouvoir." name="role change actions" value="10"/>
<action description="Créer des rôles" longdescription="Créez de nouveaux rôles dans la section Rôles et membres &gt; onglet Rôles" name="role create" value="4"/>
<action description="Supprimer des rôles" longdescription="Supprimez des rôles dans la section Rôles et membres &gt; onglet Rôles" name="role delete" value="5"/>
<action description="Changer les noms, les titres et les descriptions des rôles et indiquer si les membres des rôles sont rendus publics" longdescription="Changez les noms, les titres et les descriptions des rôles, et indiquez si les membres des rôles sont rendus publics. Vous pouvez le faire au bas de la section Rôles et membres &gt; onglet Rôles après avoir sélectionné un rôle." name="role properties" value="6"/>
<action description="Attribuer des rôles limités" longdescription="Assignez des membres aux rôles dans la liste Rôles assignés (section Rôles et membres &gt; onglet Membres). Un membre avec ce pouvoir peut uniquement ajouter des membres à un rôle dans lequel le responsable de lassignation est déjà présent." name="role assign member limited" value="7"/>
<action description="Attribuer tous les rôles" longdescription="Attribuez aux membres tout rôle dans la liste des Rôles assignés (Section Rôles et membres &gt; onglet Membres). AVERTISSEMENT* Tout membre disposant de ce pouvoir peut sassigner lui-même, ainsi que tout autre membre non-propriétaire, à des rôles disposant de pouvoirs plus importants que ceux dont ils disposent actuellement, et accéder potentiellement à des pouvoirs proches de ceux d&apos;un propriétaire. Assurez-vous de bien comprendre ce que vous faites avant d&apos;attribuer ce pouvoir." name="role assign member" value="8"/>
<action description="Destituer des membres de leurs rôles" longdescription="Supprimez des membres des rôles dans la liste Rôles assignés (section Rôles et membres &gt; onglet Membres). Les propriétaires ne peuvent pas être supprimés." name="role remove member" value="9"/>
<action description="Modifier les pouvoirs d&apos;un rôle" longdescription="Attribuez et Supprimez des pouvoirs pour chaque rôle figurant dans la liste Pouvoirs assignés (Section Rôles et membres &gt; onglet Rôles). *AVERTISSEMENT* Tout membre dans un rôle avec ce pouvoir peut s&apos;attribuer à lui-même, ainsi qu&apos;à tout autre membre non-propriétaire, tous les pouvoirs, et accéder potentiellement à des pouvoirs proches de ceux d&apos;un propriétaire. Assurez-vous de bien comprendre ce que vous faites avant d&apos;attribuer ce pouvoir." name="role change actions" value="10"/>
</action_set>
<action_set description="Ces pouvoirs permettent de modifier le profil public du groupe, sa charte et son logo." name="Group Identity">
<action description="Modifier le profil public du groupe" longdescription="Modifiez la charte, le logo et l&apos;affichage dans les résultats de recherche. Vous pouvez faire cela dans la section Général." name="group change identity" value="11"/>

View File

@ -31,7 +31,7 @@
<text name="AvatarPhysicsDetailText">
Basso
</text>
<text name="ShadersText">
<text name="HardwareText">
Hardware
</text>
<slider label="Memoria texture (MB):" name="GraphicsCardTextureMemory" tool_tip="Spazio di memoria da assegnare alle texture. Utilizza la memoria della scheda video come impostazione predefinita. La riduzione di questa impostazione potrebbe migliorare il rendimento ma potrebbe anche rendere le texture poco definite."/>
@ -56,6 +56,9 @@
<text name="antialiasing restart">
(richiede il riavvio)
</text>
<text name="MeshText">
Mesh
</text>
<slider label="Dettagli mesh terreno:" name="TerrainMeshDetail"/>
<text name="TerrainMeshDetailText">
Basso
@ -72,6 +75,9 @@
<text name="FlexibleMeshDetailText">
Basso
</text>
<text name="ShadersText">
Shader
</text>
<check_box initial_value="true" label="Acqua trasparente" name="TransparentWater"/>
<check_box initial_value="true" label="Mappatura urti e brillantezza" name="BumpShiny"/>
<check_box initial_value="true" label="Luci locali" name="LocalLights"/>
@ -111,5 +117,6 @@
<button label="Ripristina impostazioni consigliate" name="Defaults"/>
<button label="OK" label_selected="OK" name="OK"/>
<button label="Annulla" label_selected="Annulla" name="Cancel"/>
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxNonImpostors"/>
<check_box label="RenderAvatarMaxComplexity" name="RenderAvatarMaxComplexity"/>
<check_box label="RenderAvatarMaxNonImpostors" name="RenderAvatarMaxNonImpostors"/>
</floater>

View File

@ -3,6 +3,7 @@
<menu_item_call label="Sblocca" name="unblock"/>
<menu_item_check label="Blocca voce" name="BlockVoice"/>
<menu_item_check label="Blocca testo" name="MuteText"/>
<menu_item_check label="Blocca Particelle" name="MuteParticles"/>
<menu_item_check label="Blocca suoni oggetto" name="BlockObjectSounds"/>
<menu_item_call label="Profilo..." name="profile"/>
</toggleable_menu>

View File

@ -4301,7 +4301,7 @@ Prova a selezionare un pezzo di terreno più piccolo.
Un errore interno ha impedito l&apos;aggiornamento del Viewer. Il saldo in L$ o i lotti posseduti mostrati nel Viewer potrebbero non corrispondere ai valori correnti sui server.
</notification>
<notification name="LargePrimAgentIntersect">
Non puoi creare prim grandi che intersecano altri giocatori. Riprova quando gli altri giocatori si sono spostati.
Impossibile creare prim larghi che si intersechino con altri residenti. Si prega di riprovare quando gli altri residenti si saranno mossi.
</notification>
<notification name="PreferenceChatClearLog">
Verranno cancellati i registri delle conversazioni precedenti e tutti gli eventuali backup di quel file.

View File

@ -82,6 +82,11 @@ cliccando sui loro nomi.
</text>
<scroll_list name="member_allowed_actions" tool_tip="Per i dettagli di ogni abilità consentita vedi la scheda abilità."/>
</panel>
<panel name="members_header">
<text_editor name="member_action_description">
Questa abilità è “Espelli membri da questo gruppo”. Solo un proprietario può espellere un altro proprietario.
</text_editor>
</panel>
<panel name="roles_footer">
<text name="static">
Nome del ruolo
@ -104,6 +109,11 @@ cliccando sui loro nomi.
</text>
<scroll_list name="role_allowed_actions" tool_tip="Per i dettagli di ogni abilità consentita vedi la scheda abilità."/>
</panel>
<panel name="roles_header">
<text_editor name="role_action_description">
Questa abilità è “Espelli membri da questo gruppo”. Solo un proprietario può espellere un altro proprietario.
</text_editor>
</panel>
<panel name="actions_footer">
<text_editor name="action_description">
Questa abilità è &apos;Espelli i membri dal gruppo&apos;. Solo un Capogruppo puo espellere un&apos;altro Capogruppo.

View File

@ -3,7 +3,7 @@
<panel.string name="log_in_to_change">
accedi per cambiare
</panel.string>
<button label="Pulisci la cronologia" name="clear_cache" tool_tip="Elimina immagine login, ultimo luogo, cronologia teleport, web e texture cache"/>
<button label="Pulisci la cronologia" name="clear_cache" tool_tip="Elimina immagine login, ultimo luogo, cronologia teletrasporto, cache web e texture"/>
<text name="cache_size_label_l">
(Luoghi, immagini, web, cronologia ricerche)
</text>

Some files were not shown because too many files have changed in this diff Show More