summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/indra_constants.h1
-rw-r--r--indra/llcommon/llcoros.cpp28
-rw-r--r--indra/llcommon/llcoros.h4
-rw-r--r--indra/llcommon/llerror.cpp24
-rw-r--r--indra/llcorehttp/_httpservice.cpp8
-rw-r--r--indra/llrender/llvertexbuffer.cpp8
-rw-r--r--indra/llui/llscrolllistctrl.cpp1
-rw-r--r--indra/newview/CMakeLists.txt9
-rw-r--r--indra/newview/app_settings/settings.xml6
-rw-r--r--indra/newview/llagentcamera.cpp44
-rw-r--r--indra/newview/llagentcamera.h2
-rw-r--r--indra/newview/llappviewer.cpp10
-rw-r--r--indra/newview/llchathistory.cpp25
-rw-r--r--indra/newview/lldirpicker.cpp159
-rw-r--r--indra/newview/lldirpicker.h42
-rw-r--r--indra/newview/lldrawpoolalpha.cpp3
-rw-r--r--indra/newview/llfeaturemanager.cpp102
-rw-r--r--indra/newview/llfeaturemanager.h5
-rw-r--r--indra/newview/llfloaterauction.cpp552
-rw-r--r--indra/newview/llfloaterauction.h86
-rw-r--r--indra/newview/llfloaterland.cpp25
-rw-r--r--indra/newview/llfloaterpreference.cpp39
-rw-r--r--indra/newview/llfloaterpreference.h2
-rw-r--r--indra/newview/llfloatersnapshot.cpp10
-rw-r--r--indra/newview/llfloatersnapshot.h4
-rw-r--r--indra/newview/llglsandbox.cpp9
-rw-r--r--indra/newview/lloutfitgallery.cpp114
-rw-r--r--indra/newview/lloutfitgallery.h1
-rw-r--r--indra/newview/llpanellogin.cpp13
-rw-r--r--indra/newview/llpanellogin.h1
-rw-r--r--indra/newview/llpanelpermissions.cpp7
-rw-r--r--indra/newview/llpanelsnapshotlocal.cpp28
-rw-r--r--indra/newview/llpreviewscript.cpp16
-rw-r--r--indra/newview/llsidepaneltaskinfo.cpp2
-rw-r--r--indra/newview/llsnapshotlivepreview.cpp46
-rw-r--r--indra/newview/llsnapshotlivepreview.h9
-rw-r--r--indra/newview/lltexturecache.cpp4
-rw-r--r--indra/newview/lltooldraganddrop.cpp17
-rw-r--r--indra/newview/lltooldraganddrop.h2
-rw-r--r--indra/newview/lltoolpie.cpp6
-rw-r--r--indra/newview/llviewerfloaterreg.cpp2
-rw-r--r--indra/newview/llviewermenufile.cpp34
-rw-r--r--indra/newview/llviewermenufile.h5
-rw-r--r--indra/newview/llviewermessage.cpp334
-rw-r--r--indra/newview/llviewernetwork.cpp2
-rw-r--r--indra/newview/llviewerregion.cpp4
-rw-r--r--indra/newview/llviewerwindow.cpp128
-rw-r--r--indra/newview/llviewerwindow.h8
-rw-r--r--indra/newview/llvoicevivox.cpp1
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_auction.xml96
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml4
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml11
-rw-r--r--indra/newview/skins/default/xui/en/panel_login.xml17
-rw-r--r--indra/newview/skins/default/xui/en/panel_login_first.xml15
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_task_info.xml12
-rw-r--r--indra/newview/tests/llviewernetwork_test.cpp10
57 files changed, 1699 insertions, 460 deletions
diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h
index fda84aa5a8..a00a82aff0 100644
--- a/indra/llcommon/indra_constants.h
+++ b/indra/llcommon/indra_constants.h
@@ -323,6 +323,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!!
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index c5ba23f68c..3165ce0743 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -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,22 @@ void LLCoros::setStackSize(S32 stacksize)
mStackSize = stacksize;
}
+void LLCoros::printActiveCoroutines()
+{
+ LL_INFOS("LLCoros") << "Number of active coroutines: " << (S32)mCoros.size() << LL_ENDL;
+ 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 +392,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 +402,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
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index 884d6b159c..8fb27af6a4 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -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;
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index f31a054139..29de79dc64 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -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
diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp
index 49d865cbfa..0b72b53186 100644
--- a/indra/llcorehttp/_httpservice.cpp
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -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();
}
}
}
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index e3e605d040..1312f6afda 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -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;
}
}
}
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 212e27477b..ed65b1e45f 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -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;
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index b7a860aae0..2fc722d4c3 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -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")
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f0782e0bf7..a01435626f 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -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>
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 5b9f1b9d4f..92a3026096 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -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()
diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h
index ab793ff316..d087de1e2f 100644
--- a/indra/newview/llagentcamera.h
+++ b/indra/newview/llagentcamera.h
@@ -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;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f705084bdb..acec68f393 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -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())
@@ -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
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 97a71a8802..1099d4bc09 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -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());
diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp
index 5c4f0f4d5d..5443afe60c 100644
--- a/indra/newview/lldirpicker.cpp
+++ b/indra/newview/lldirpicker.cpp
@@ -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();
-
- BROWSEINFO bi;
- memset(&bi, 0, sizeof(bi));
-
- bi.ulFlags = BIF_USENEWUI;
- bi.hwndOwner = (HWND)gViewerWindow->getPlatformWindow();
- bi.lpszTitle = NULL;
-
- ::OleInitialize(NULL);
+
+ if (blocking)
+ {
+ // Modal, so pause agent
+ send_agent_pause();
+ }
- LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);
+ bi.hwndOwner = (HWND)gViewerWindow->getPlatformWindow();
- if(pIDL != NULL)
- {
- WCHAR buffer[_MAX_PATH] = {'\0'};
+ ::OleInitialize(NULL);
+ 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;
- }
+ if(::SHGetPathFromIDList(pIDL, buffer) != 0)
+ {
+ // Set the string value.
- // free the item id list
- CoTaskMemFree(pIDL);
- }
+ mDir = utf16str_to_utf8str(llutf16string(buffer));
+ success = TRUE;
+ }
+ // free the item id list
+ CoTaskMemFree(pIDL);
+ }
- ::OleUninitialize();
+ ::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);
+ }
+ }
+}
diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h
index 8656b23afd..c7dba12130 100644
--- a/indra/newview/lldirpicker.h
+++ b/indra/newview/lldirpicker.h
@@ -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
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index b0d48abb14..0873300cd2 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -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();
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index bc96ee00f7..487496df9a 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -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());
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index 54bd07329a..f77861a1a7 100644
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -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;
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
new file mode 100644
index 0000000000..56619e818a
--- /dev/null
+++ b/indra/newview/llfloaterauction.cpp
@@ -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);
+ }
+}
diff --git a/indra/newview/llfloaterauction.h b/indra/newview/llfloaterauction.h
new file mode 100644
index 0000000000..c83a11ba8b
--- /dev/null
+++ b/indra/newview/llfloaterauction.h
@@ -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
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 596b04c31c..88b3fb7b96 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -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
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 9d723bdd9d..4ce35643b1 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -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();
+ (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 != dir_name)
+ if (proposed_name != filenames[0])
{
- gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
+ gSavedPerAccountSettings.setString("InstantMessageLogPath", filenames[0]);
mPriorInstantMessageLogPath = proposed_name;
-
- // enable/disable 'Delete transcripts button
- updateDeleteTranscriptsButton();
-}
+
+ // enable/disable 'Delete transcripts button
+ updateDeleteTranscriptsButton();
+ }
}
bool LLFloaterPreference::moveTranscriptsAndLog()
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 0cd7bac20f..8339a18296 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -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);
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 156b2ba7b1..c08aaf3f50 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -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()
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 698273ac90..bcba14d63d 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -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();
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 4b0b10dd5a..a9b15fc8b6 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -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
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index dc3b153da2..a90a29a731 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -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);
+ image_load_error = image_info.getLastError();
+ }
- 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;
- 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);
- 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);
+ }
- 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;
+ }
- 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;
- 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;
- }
+ 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)
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index 383924a7d6..6dd8a6298f 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -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();
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index ef5ce155b1..142dea83e2 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -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)
{
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index 852195b304..c633582d89 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -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();
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index a7c53a7050..fc44ce340c 100644
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -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;
}
}
diff --git a/indra/newview/llpanelsnapshotlocal.cpp b/indra/newview/llpanelsnapshotlocal.cpp
index 77378f8092..e7fced92a7 100644
--- a/indra/newview/llpanelsnapshotlocal.cpp
+++ b/indra/newview/llpanelsnapshotlocal.cpp
@@ -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;
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index d4eecaffce..9431914ba3 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -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;
}
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index f73722521a..f03c7abc4d 100644
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -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;
}
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index ee8b2d79c0..d0cff1464b 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -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);
}
diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h
index 4ea8d25a5a..683cd016d8 100644
--- a/indra/newview/llsnapshotlivepreview.h
+++ b/indra/newview/llsnapshotlivepreview.h
@@ -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;
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 2a0d961952..dd5dce3279 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -2027,13 +2027,15 @@ 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);
+ raw = raw->duplicate();
if (raw->isBufferInvalid())
{
LL_WARNS() << "Invalid image duplicate buffer" << LL_ENDL;
return false;
}
+ raw->scale(w, h);
+
discardlevel += i ;
}
}
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 9fb53dc9ab..0f38cca56f 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -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)
{
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 2d99de2244..24a712029c 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -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,
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index f473000657..6a8843cb44 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -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;
}
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 55317bdaf5..0ebacddd9b 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -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>);
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index dc05d98228..cf1c442ce9 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -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())
+ {
+ if (mFailureSignal)
+ {
+ (*mFailureSignal)(filenames, mLoadFilter, mSaveFilter);
+ }
+ }
+ else
{
- (*mFilePickedSignal)(filenames, mLoadFilter, mSaveFilter);
+ 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)
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index 15bbdd1e2d..35f86f606b 100644
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -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;
};
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 0f326efe09..6cba7dd70c 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -153,6 +153,96 @@ 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() << "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() << "HTTP status, " << status.toTerseString() <<
+ ". friendship offer accept failed." << LL_ENDL;
+ }
+ else
+ {
+ if (!result.has("success") || result["success"].asBoolean() == false)
+ {
+ LL_WARNS() << "Server failed to process accepted friendship. " << httpResults << LL_ENDL;
+ }
+ else
+ {
+ // 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() << "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() << "HTTP status, " << status.toTerseString() <<
+ ". friendship offer decline failed." << LL_ENDL;
+ }
+ else
+ {
+ if (!result.has("success") || result["success"].asBoolean() == false)
+ {
+ LL_WARNS() << "Server failed to process declined friendship. " << httpResults << LL_ENDL;
+ }
+ else
+ {
+ 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 +253,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 +263,73 @@ 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()));
-
- LLSD payload = notification["payload"];
- LLNotificationsUtil::add("FriendshipAcceptedByMe",
- notification["substitutions"], payload);
+ std::string url = gAgent.getRegionCapability("AcceptFriendship");
+ if (!url.empty())
+ {
+ LLCoros::instance().launch("LLMessageSystem::acceptFriendshipOffer",
+ boost::bind(accept_friendship_coro, url, notification));
+ }
+ else if (payload.has("session_id") && payload["session_id"].asUUID().notNull())
+ {
+ 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()));
+
+ // add friend to recent people list
+ LLRecentPeople::instance().add(payload["from_id"]);
+ LLNotificationsUtil::add("FriendshipAcceptedByMe",
+ notification["substitutions"], payload);
+ }
+ else
+ {
+ LL_WARNS() << "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()));
-
- // start IM session
- if(2 == option)
- {
- LLAvatarActions::startIM(payload["from_id"].asUUID());
- }
+ // the rejection to the simulator to delete the pending userop.
+ std::string url = gAgent.getRegionCapability("DeclineFriendship");
+ if (!url.empty())
+ {
+ LLCoros::instance().launch("LLMessageSystem::declineFriendshipOffer",
+ boost::bind(decline_friendship_coro, url, notification, option));
+ }
+ else if (payload.has("session_id") && payload["session_id"].asUUID().notNull())
+ {
+ 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()));
+
+ 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() << "Failed to decline friendship offer, neither capability nor transaction id are accessible" << LL_ENDL;
+ }
}
default:
// close button probably, possibly timed out
@@ -3258,6 +3372,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 +3494,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 +3515,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 +3551,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 +3778,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;
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index 6937d064f9..9f6d606a22 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -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";
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index feaafad2e1..832dcc2dd8 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -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");
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index f394d6913f..cef19c9c2d 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -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;
+
+ 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;
- // pick a directory in which to save
- LLFilePicker& picker = LLFilePicker::instance();
- if (!picker.getSaveFile(pick_type, proposed_name))
- {
- // Clicked cancel
- return FALSE;
- }
+ (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();
+ }
+ else
+ {
+ 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];
- // Copy the directory + file name
- std::string filepath = picker.getFirstFile();
+ gSavedPerAccountSettings.setString("SnapshotBaseName", gDirUtilp->getBaseFileName(filepath, true));
+ gSavedPerAccountSettings.setString("SnapshotBaseDir", gDirUtilp->getDirName(filepath));
+ saveImageLocal(image, success_cb, failure_cb);
+}
- gSavedPerAccountSettings.setString("SnapshotBaseName", gDirUtilp->getBaseFileName(filepath, true));
- gSavedPerAccountSettings.setString("SnapshotBaseDir", gDirUtilp->getDirName(filepath));
- }
+void LLViewerWindow::onSelectionFailure(const snapshot_saved_signal_t::slot_type& failure_cb)
+{
+ failure_cb();
+}
- std::string snapshot_dir = sSnapshotDir;
- if(snapshot_dir.empty())
+
+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())
{
- return FALSE;
+ 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()
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index c01921641c..d8d420e6be 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -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.
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index da4b6a5008..6a3242b43f 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -6193,6 +6193,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)
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index cf843a07a6..535af317d9 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -502,7 +502,7 @@
name="Buy Land..."
width="130" />
<button
- enabled="true"
+ enabled="false"
follows="left|top"
height="23"
label="Linden Sale"
diff --git a/indra/newview/skins/default/xui/en/floater_auction.xml b/indra/newview/skins/default/xui/en/floater_auction.xml
new file mode 100644
index 0000000000..9c6d114c4c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_auction.xml
@@ -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>
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index ed3cc26851..bdcf3648fa 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -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"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 7f9dc0c41f..6b164c660a 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -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"
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index 3a34bcbe21..7759d4fdb2 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -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"
diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml
index 35b80c56ab..213f9a6b0c 100644
--- a/indra/newview/skins/default/xui/en/panel_login_first.xml
+++ b/indra/newview/skins/default/xui/en/panel_login_first.xml
@@ -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"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
index b84dce222f..efedb9559e 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
@@ -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"
diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp
index 3dd327591e..d1dddf8e7e 100644
--- a/indra/newview/tests/llviewernetwork_test.cpp
+++ b/indra/newview/tests/llviewernetwork_test.cpp
@@ -236,7 +236,7 @@ namespace tut
std::string("https://secondlife.com/helpers/"));
ensure_equals("Agni login page",
LLGridManager::getInstance()->getLoginPage("util.agni.lindenlab.com"),
- std::string("http://viewer-login.agni.lindenlab.com/"));
+ std::string("https://viewer-splash.secondlife.com/"));
ensure("Agni is a system grid",
LLGridManager::getInstance()->isSystemGrid("util.agni.lindenlab.com"));
@@ -261,7 +261,7 @@ namespace tut
std::string("http://aditi-secondlife.webdev.lindenlab.com/helpers/"));
ensure_equals("Aditi login page",
LLGridManager::getInstance()->getLoginPage("util.aditi.lindenlab.com"),
- std::string("http://viewer-login.agni.lindenlab.com/"));
+ std::string("https://viewer-splash.secondlife.com/"));
ensure("Aditi is a system grid",
LLGridManager::getInstance()->isSystemGrid("util.aditi.lindenlab.com"));
}
@@ -309,7 +309,7 @@ namespace tut
std::string("https://secondlife.com/helpers/"));
ensure_equals("Agni login page",
LLGridManager::getInstance()->getLoginPage("util.agni.lindenlab.com"),
- std::string("http://viewer-login.agni.lindenlab.com/"));
+ std::string("https://viewer-splash.secondlife.com/"));
ensure("Agni is a system grid",
LLGridManager::getInstance()->isSystemGrid("util.agni.lindenlab.com"));
@@ -333,7 +333,7 @@ namespace tut
std::string("http://aditi-secondlife.webdev.lindenlab.com/helpers/"));
ensure_equals("Aditi login page",
LLGridManager::getInstance()->getLoginPage("util.aditi.lindenlab.com"),
- std::string("http://viewer-login.agni.lindenlab.com/"));
+ std::string("https://viewer-splash.secondlife.com/"));
ensure("Aditi is a system grid",
LLGridManager::getInstance()->isSystemGrid("util.aditi.lindenlab.com"));
@@ -422,7 +422,7 @@ namespace tut
std::string("https://secondlife.com/helpers/"));
ensure_equals("getLoginPage",
LLGridManager::getInstance()->getLoginPage(),
- std::string("http://viewer-login.agni.lindenlab.com/"));
+ std::string("https://viewer-splash.secondlife.com/"));
ensure_equals("update url base for Agni", // relies on agni being the default
std::string("https://update.secondlife.com/update"),
LLGridManager::getInstance()->getUpdateServiceURL());