summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt8
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/commands.xml20
-rw-r--r--indra/newview/app_settings/settings.xml24
-rw-r--r--indra/newview/llagentcamera.cpp8
-rw-r--r--indra/newview/llagentcamera.h1
-rw-r--r--indra/newview/llagentwearables.cpp4
-rw-r--r--indra/newview/llappearancemgr.cpp2
-rw-r--r--indra/newview/llappviewer.cpp3
-rw-r--r--indra/newview/llflickrconnect.cpp538
-rw-r--r--indra/newview/llflickrconnect.h108
-rw-r--r--indra/newview/llfloaterbigpreview.h2
-rw-r--r--indra/newview/llfloaterexperiences.cpp8
-rw-r--r--indra/newview/llfloaterflickr.cpp787
-rw-r--r--indra/newview/llfloaterflickr.h134
-rw-r--r--indra/newview/llfloatergesture.cpp53
-rw-r--r--indra/newview/llfloatergesture.h3
-rw-r--r--indra/newview/llfloatergridstatus.cpp2
-rw-r--r--indra/newview/llfloatermodelpreview.cpp9
-rw-r--r--indra/newview/llfloateroutfitsnapshot.cpp2
-rw-r--r--indra/newview/llfloaterpreference.cpp70
-rw-r--r--indra/newview/llfloaterpreference.h1
-rw-r--r--indra/newview/llfloaterproperties.cpp2
-rw-r--r--indra/newview/llfloatersnapshot.cpp7
-rw-r--r--indra/newview/llfloatertwitter.cpp810
-rw-r--r--indra/newview/llfloatertwitter.h138
-rw-r--r--indra/newview/llfloaterwebcontent.cpp22
-rw-r--r--indra/newview/llhudeffectbeam.cpp12
-rw-r--r--indra/newview/llhudeffectlookat.cpp20
-rw-r--r--indra/newview/llhudeffectpointat.cpp20
-rw-r--r--indra/newview/llhudeffecttrail.cpp12
-rw-r--r--indra/newview/llimagefiltersmanager.cpp2
-rw-r--r--indra/newview/llimagefiltersmanager.h2
-rw-r--r--indra/newview/llimprocessing.cpp20
-rw-r--r--indra/newview/llinventorybridge.cpp2
-rw-r--r--indra/newview/llinventoryfilter.cpp74
-rw-r--r--indra/newview/llinventoryfilter.h3
-rw-r--r--indra/newview/llnotificationlistitem.cpp1
-rw-r--r--indra/newview/llpanelsnapshotoptions.cpp30
-rw-r--r--indra/newview/llselectmgr.cpp107
-rw-r--r--indra/newview/llselectmgr.h19
-rw-r--r--indra/newview/llsidepanelappearance.cpp2
-rw-r--r--indra/newview/llsidepaneliteminfo.cpp142
-rw-r--r--indra/newview/llsidepaneliteminfo.h15
-rw-r--r--indra/newview/llsidepaneltaskinfo.cpp63
-rw-r--r--indra/newview/llsidepaneltaskinfo.h1
-rw-r--r--indra/newview/llsnapshotlivepreview.cpp2
-rw-r--r--indra/newview/llstartup.cpp18
-rw-r--r--indra/newview/llstatusbar.cpp35
-rw-r--r--indra/newview/llstatusbar.h3
-rw-r--r--indra/newview/lltexturecache.cpp126
-rw-r--r--indra/newview/lltexturecache.h10
-rw-r--r--indra/newview/lltoolgrab.cpp11
-rw-r--r--indra/newview/lltoolpie.cpp32
-rw-r--r--indra/newview/lltwitterconnect.cpp576
-rw-r--r--indra/newview/lltwitterconnect.h107
-rw-r--r--indra/newview/llviewerdisplay.cpp2
-rw-r--r--indra/newview/llviewerfloaterreg.cpp7
-rw-r--r--indra/newview/llviewerjointattachment.cpp16
-rw-r--r--indra/newview/llviewerjointattachment.h2
-rw-r--r--indra/newview/llviewermenu.cpp18
-rw-r--r--indra/newview/llviewermessage.cpp237
-rw-r--r--indra/newview/llviewermessage.h3
-rw-r--r--indra/newview/llviewerobject.cpp261
-rw-r--r--indra/newview/llviewerobject.h14
-rw-r--r--indra/newview/llviewerobjectlist.cpp2
-rw-r--r--indra/newview/llviewerregion.cpp2
-rw-r--r--indra/newview/llviewerwindow.cpp45
-rw-r--r--indra/newview/llviewerwindow.h5
-rw-r--r--indra/newview/llvoavatar.cpp92
-rw-r--r--indra/newview/llvoiceclient.cpp23
-rw-r--r--indra/newview/llvoiceclient.h6
-rw-r--r--indra/newview/pipeline.cpp2
-rw-r--r--indra/newview/skins/default/textures/textures.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_flickr.xml90
-rw-r--r--indra/newview/skins/default/xui/en/floater_twitter.xml75
-rw-r--r--indra/newview/skins/default/xui/en/menu_gesture_gear.xml10
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml21
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml68
-rw-r--r--indra/newview/skins/default/xui/en/panel_flickr_account.xml79
-rw-r--r--indra/newview/skins/default/xui/en/panel_flickr_photo.xml259
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_advanced.xml26
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_sound.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_options.xml34
-rw-r--r--indra/newview/skins/default/xui/en/panel_twitter_account.xml81
-rw-r--r--indra/newview/skins/default/xui/en/panel_twitter_photo.xml196
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml28
-rw-r--r--indra/newview/skins/default/xui/en/teleport_strings.xml3
-rw-r--r--indra/newview/skins/default/xui/ru/notifications.xml4
-rwxr-xr-xindra/newview/viewer_manifest.py1
90 files changed, 1286 insertions, 4671 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 6b77aa6070..763722470d 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -208,7 +208,6 @@ set(viewer_SOURCE_FILES
llfilteredwearablelist.cpp
llfirstuse.cpp
llflexibleobject.cpp
- llflickrconnect.cpp
llfloaterabout.cpp
llfloaterbvhpreview.cpp
llfloaterauction.cpp
@@ -245,7 +244,6 @@ set(viewer_SOURCE_FILES
llfloaterexperiencepicker.cpp
llfloaterexperienceprofile.cpp
llfloaterexperiences.cpp
- llfloaterflickr.cpp
llfloaterfonttest.cpp
llfloatergesture.cpp
llfloatergodtools.cpp
@@ -319,7 +317,6 @@ set(viewer_SOURCE_FILES
llfloatertos.cpp
llfloatertoybox.cpp
llfloatertranslationsettings.cpp
- llfloatertwitter.cpp
llfloateruipreview.cpp
llfloaterurlentry.cpp
llfloatervoiceeffect.cpp
@@ -616,7 +613,6 @@ set(viewer_SOURCE_FILES
lltransientdockablefloater.cpp
lltransientfloatermgr.cpp
lltranslate.cpp
- lltwitterconnect.cpp
lluiavatar.cpp
lluilistener.cpp
lluploaddialog.cpp
@@ -835,7 +831,6 @@ set(viewer_HEADER_FILES
llfilteredwearablelist.h
llfirstuse.h
llflexibleobject.h
- llflickrconnect.h
llfloaterabout.h
llfloaterbvhpreview.h
llfloaterauction.h
@@ -872,7 +867,6 @@ set(viewer_HEADER_FILES
llfloaterexperiencepicker.h
llfloaterexperienceprofile.h
llfloaterexperiences.h
- llfloaterflickr.h
llfloaterfonttest.h
llfloatergesture.h
llfloatergodtools.h
@@ -949,7 +943,6 @@ set(viewer_HEADER_FILES
llfloatertos.h
llfloatertoybox.h
llfloatertranslationsettings.h
- llfloatertwitter.h
llfloateruipreview.h
llfloaterurlentry.h
llfloatervoiceeffect.h
@@ -1236,7 +1229,6 @@ set(viewer_HEADER_FILES
lltransientdockablefloater.h
lltransientfloatermgr.h
lltranslate.h
- lltwitterconnect.h
lluiconstants.h
lluiavatar.h
lluilistener.h
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index b98d1d3fa7..c8320dd521 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.3.5
+6.3.6
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index a41e7171f2..717deebab2 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -226,26 +226,6 @@
is_running_function="Floater.IsOpen"
is_running_parameters="snapshot"
/>
- <command name="flickr"
- available_in_toybox="true"
- icon="Command_Flickr_Icon"
- label_ref="Command_Flickr_Label"
- tooltip_ref="Command_Flickr_Tooltip"
- execute_function="Floater.ToggleOrBringToFront"
- execute_parameters="flickr"
- is_running_function="Floater.IsOpen"
- is_running_parameters="flickr"
- />
- <command name="twitter"
- available_in_toybox="true"
- icon="Command_Twitter_Icon"
- label_ref="Command_Twitter_Label"
- tooltip_ref="Command_Twitter_Tooltip"
- execute_function="Floater.ToggleOrBringToFront"
- execute_parameters="twitter"
- is_running_function="Floater.IsOpen"
- is_running_parameters="twitter"
- />
<command name="speak"
available_in_toybox="true"
icon="Command_Speak_Icon"
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 49601ae98f..f73f925635 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -5304,7 +5304,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>https://secondlife-status.statuspage.io/history.atom</string>
+ <string>https://status.secondlifegrid.net/history.atom</string>
</map>
<key>GridStatusUpdateDelay</key>
<map>
@@ -11219,6 +11219,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>BasicUITooltips</key>
+ <map>
+ <key>Comment</key>
+ <string>Show tooltips for various 2D UI elements like buttons or checkboxes, won't supress tooltips like drag'n'drop, inworld, links or media</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>ShowHoverTips</key>
<map>
<key>Comment</key>
@@ -13133,6 +13144,17 @@
<key>Value</key>
<real>3</real>
</map>
+ <key>HUDScaleFactor</key>
+ <map>
+ <key>Comment</key>
+ <string>Scale of HUD attachments</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
<key>UIScaleFactor</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 0b4b848014..8edb1a5f0b 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -807,6 +807,12 @@ void LLAgentCamera::setCameraZoomFraction(F32 fraction)
startCameraAnimation();
}
+F32 LLAgentCamera::getAgentHUDTargetZoom()
+{
+ static LLCachedControl<F32> hud_scale_factor(gSavedSettings, "HUDScaleFactor");
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ return (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) ? hud_scale_factor*gAgentCamera.mHUDTargetZoom : hud_scale_factor;
+}
//-----------------------------------------------------------------------------
// cameraOrbitAround()
@@ -1449,7 +1455,7 @@ void LLAgentCamera::updateCamera()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject *attached_object = (*attachment_iter);
+ LLViewerObject *attached_object = attachment_iter->get();
if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull())
{
// clear any existing "early" movements of attachment
diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h
index d087de1e2f..a4bc8434b0 100644
--- a/indra/newview/llagentcamera.h
+++ b/indra/newview/llagentcamera.h
@@ -266,6 +266,7 @@ public:
F32 getCameraZoomFraction(); // Get camera zoom as fraction of minimum and maximum zoom
void setCameraZoomFraction(F32 fraction); // Set camera zoom as fraction of minimum and maximum zoom
F32 calcCameraFOVZoomFactor();
+ F32 getAgentHUDTargetZoom();
//--------------------------------------------------------------------
// Pan
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 15e4de8f69..013c40f557 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1323,7 +1323,7 @@ void LLAgentWearables::findAttachmentsAddRemoveInfo(LLInventoryModel::item_array
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject *objectp = (*attachment_iter);
+ LLViewerObject *objectp = attachment_iter->get();
if (objectp)
{
LLUUID object_item_id = objectp->getAttachmentItemID();
@@ -1387,7 +1387,7 @@ std::vector<LLViewerObject*> LLAgentWearables::getTempAttachments()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject *objectp = (*attachment_iter);
+ LLViewerObject *objectp = attachment_iter->get();
if (objectp && objectp->isTempAttachment())
{
temp_attachs.push_back(objectp);
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 7325ec598a..3ac1c91cea 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -2911,7 +2911,7 @@ void LLAppearanceMgr::removeAllAttachmentsFromAvatar()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject *attached_object = (*attachment_iter);
+ LLViewerObject *attached_object = attachment_iter->get();
if (attached_object)
{
objects_to_remove.push_back(attached_object);
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index ff897ef962..a33e978c0a 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2125,6 +2125,9 @@ void watchdog_llerrs_callback(const std::string &error_string)
{
gLLErrorActivated = true;
+ gDebugInfo["FatalMessage"] = error_string;
+ LLAppViewer::instance()->writeDebugInfo();
+
#ifdef LL_WINDOWS
RaiseException(0,0,0,0);
#else
diff --git a/indra/newview/llflickrconnect.cpp b/indra/newview/llflickrconnect.cpp
deleted file mode 100644
index d7d161f239..0000000000
--- a/indra/newview/llflickrconnect.cpp
+++ /dev/null
@@ -1,538 +0,0 @@
-/**
- * @file llflickrconnect.h
- * @author Merov, Cho
- * @brief Connection to Flickr Service
- *
- * $LicenseInfo:firstyear=2013&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2013, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llflickrconnect.h"
-
-#include "llagent.h"
-#include "llcallingcard.h" // for LLAvatarTracker
-#include "llcommandhandler.h"
-#include "llnotificationsutil.h"
-#include "llurlaction.h"
-#include "llimagepng.h"
-#include "llimagejpeg.h"
-#include "lltrans.h"
-#include "llevents.h"
-#include "llviewerregion.h"
-
-#include "llfloaterwebcontent.h"
-#include "llfloaterreg.h"
-#include "llcorehttputil.h"
-
-boost::scoped_ptr<LLEventPump> LLFlickrConnect::sStateWatcher(new LLEventStream("FlickrConnectState"));
-boost::scoped_ptr<LLEventPump> LLFlickrConnect::sInfoWatcher(new LLEventStream("FlickrConnectInfo"));
-boost::scoped_ptr<LLEventPump> LLFlickrConnect::sContentWatcher(new LLEventStream("FlickrConnectContent"));
-
-// Local functions
-void log_flickr_connect_error(const std::string& request, U32 status, const std::string& reason, const std::string& code, const std::string& description)
-{
- // Note: 302 (redirect) is *not* an error that warrants logging
- if (status != 302)
- {
- LL_WARNS("FlickrConnect") << request << " request failed with a " << status << " " << reason << ". Reason: " << code << " (" << description << ")" << LL_ENDL;
- }
-}
-
-void toast_user_for_flickr_success()
-{
- LLSD args;
- args["MESSAGE"] = LLTrans::getString("flickr_post_success");
- LLNotificationsUtil::add("FlickrConnect", args);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFlickrConnect::flickrConnectCoro(std::string requestToken, std::string oauthVerifier)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- LLSD body;
- if (!requestToken.empty())
- body["request_token"] = requestToken;
- if (!oauthVerifier.empty())
- body["oauth_verifier"] = oauthVerifier;
-
- setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS);
-
- LLSD result = httpAdapter->putAndSuspend(httpRequest, getFlickrConnectURL("/connection"), body, httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- if ( status == LLCore::HttpStatus(HTTP_FOUND) )
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openFlickrWeb(location);
- }
- }
- else
- {
- LL_WARNS("FlickrConnect") << "Connection failed " << status.toString() << LL_ENDL;
- setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
- log_flickr_connect_error("Connect", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- }
- else
- {
- LL_DEBUGS("FlickrConnect") << "Connect successful. " << LL_ENDL;
- setConnectionState(LLFlickrConnect::FLICKR_CONNECTED);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-bool LLFlickrConnect::testShareStatus(LLSD &result)
-{
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (status)
- return true;
-
- if (status == LLCore::HttpStatus(HTTP_FOUND))
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openFlickrWeb(location);
- }
- }
- if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
- {
- LL_DEBUGS("FlickrConnect") << "Not connected. " << LL_ENDL;
- connectToFlickr();
- }
- else
- {
- LL_WARNS("FlickrConnect") << "HTTP Status error " << status.toString() << LL_ENDL;
- setConnectionState(LLFlickrConnect::FLICKR_POST_FAILED);
- log_flickr_connect_error("Share", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- return false;
-}
-
-void LLFlickrConnect::flickrShareCoro(LLSD share)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->postAndSuspend(httpRequest, getFlickrConnectURL("/share/photo", true), share, httpOpts);
-
- if (testShareStatus(result))
- {
- toast_user_for_flickr_success();
- LL_DEBUGS("FlickrConnect") << "Post successful. " << LL_ENDL;
- setConnectionState(LLFlickrConnect::FLICKR_POSTED);
- }
-
-}
-
-void LLFlickrConnect::flickrShareImageCoro(LLPointer<LLImageFormatted> image, std::string title, std::string description, std::string tags, int safetyLevel)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- std::string imageFormat;
- if (dynamic_cast<LLImagePNG*>(image.get()))
- {
- imageFormat = "png";
- }
- else if (dynamic_cast<LLImageJPEG*>(image.get()))
- {
- imageFormat = "jpg";
- }
- else
- {
- LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
- return;
- }
-
- // All this code is mostly copied from LLWebProfile::post()
- const std::string boundary = "----------------------------0123abcdefab";
-
- std::string contentType = "multipart/form-data; boundary=" + boundary;
- httpHeaders->append("Content-Type", contentType.c_str());
-
- LLCore::BufferArray::ptr_t raw = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); //
- LLCore::BufferArrayStream body(raw.get());
-
- // *NOTE: The order seems to matter.
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"title\"\r\n\r\n"
- << title << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"description\"\r\n\r\n"
- << description << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"tags\"\r\n\r\n"
- << tags << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"safety_level\"\r\n\r\n"
- << safetyLevel << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
- << "Content-Type: image/" << imageFormat << "\r\n\r\n";
-
- // Insert the image data.
- // *FIX: Treating this as a string will probably screw it up ...
- U8* image_data = image->getData();
- for (S32 i = 0; i < image->getDataSize(); ++i)
- {
- body << image_data[i];
- }
-
- body << "\r\n--" << boundary << "--\r\n";
-
- LLSD result = httpAdapter->postAndSuspend(httpRequest, getFlickrConnectURL("/share/photo", true), raw, httpOpts, httpHeaders);
-
- if (testShareStatus(result))
- {
- toast_user_for_flickr_success();
- LL_DEBUGS("FlickrConnect") << "Post successful. " << LL_ENDL;
- setConnectionState(LLFlickrConnect::FLICKR_POSTED);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFlickrConnect::flickrDisconnectCoro()
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- setConnectionState(LLFlickrConnect::FLICKR_DISCONNECTING);
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->deleteAndSuspend(httpRequest, getFlickrConnectURL("/connection"), httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status && (status != LLCore::HttpStatus(HTTP_NOT_FOUND)))
- {
- LL_WARNS("FlickrConnect") << "Disconnect failed!" << LL_ENDL;
- setConnectionState(LLFlickrConnect::FLICKR_DISCONNECT_FAILED);
-
- log_flickr_connect_error("Disconnect", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- else
- {
- LL_DEBUGS("FlickrConnect") << "Disconnect successful. " << LL_ENDL;
- clearInfo();
- setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFlickrConnect::flickrConnectedCoro(bool autoConnect)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS);
-
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, getFlickrConnectURL("/connection", true), httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
- {
- LL_DEBUGS("FlickrConnect") << "Not connected. " << LL_ENDL;
- if (autoConnect)
- {
- connectToFlickr();
- }
- else
- {
- setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED);
- }
- }
- else
- {
- LL_WARNS("FlickrConnect") << "Failed to test connection:" << status.toTerseString() << LL_ENDL;
-
- setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
- log_flickr_connect_error("Connected", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- }
- else
- {
- LL_DEBUGS("FlickrConnect") << "Connect successful. " << LL_ENDL;
- setConnectionState(LLFlickrConnect::FLICKR_CONNECTED);
- }
-
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFlickrConnect::flickrInfoCoro()
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, getFlickrConnectURL("/info", true), httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (status == LLCore::HttpStatus(HTTP_FOUND))
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openFlickrWeb(location);
- }
- }
- else if (!status)
- {
- LL_WARNS("FlickrConnect") << "Flickr Info failed: " << status.toString() << LL_ENDL;
- log_flickr_connect_error("Info", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- else
- {
- LL_INFOS("FlickrConnect") << "Flickr: Info received" << LL_ENDL;
- result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
- storeInfo(result);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-LLFlickrConnect::LLFlickrConnect()
-: mConnectionState(FLICKR_NOT_CONNECTED),
- mConnected(false),
- mInfo(),
- mRefreshInfo(false),
- mReadFromMaster(false)
-{
-}
-
-void LLFlickrConnect::openFlickrWeb(std::string url)
-{
- LLFloaterWebContent::Params p;
- p.url(url);
- p.show_chrome(true);
- p.allow_back_forward_navigation(false);
- p.clean_browser(true);
- LLFloater *floater = LLFloaterReg::showInstance("flickr_web", p);
- //the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems).
- //So when showing the internal web browser, set focus to it's containing floater "flickr_web". When a mouse event
- //occurs on the "webbrowser" panel part of the floater, a mouse cursor will properly show and the "webbrowser" will gain focus.
- //flickr_web floater contains the "webbrowser" panel. JIRA: ACME-744
- gFocusMgr.setKeyboardFocus( floater );
-
- //LLUrlAction::openURLExternal(url);
-}
-
-std::string LLFlickrConnect::getFlickrConnectURL(const std::string& route, bool include_read_from_master)
-{
- std::string url("");
- LLViewerRegion *regionp = gAgent.getRegion();
- if (regionp)
- {
- //url = "http://pdp15.lindenlab.com/flickr/agent/" + gAgentID.asString(); // TEMPORARY FOR TESTING - CHO
- url = regionp->getCapability("FlickrConnect");
- url += route;
-
- if (include_read_from_master && mReadFromMaster)
- {
- url += "?read_from_master=true";
- }
- }
- return url;
-}
-
-void LLFlickrConnect::connectToFlickr(const std::string& request_token, const std::string& oauth_verifier)
-{
- LLCoros::instance().launch("LLFlickrConnect::flickrConnectCoro",
- boost::bind(&LLFlickrConnect::flickrConnectCoro, this, request_token, oauth_verifier));
-}
-
-void LLFlickrConnect::disconnectFromFlickr()
-{
- LLCoros::instance().launch("LLFlickrConnect::flickrDisconnectCoro",
- boost::bind(&LLFlickrConnect::flickrDisconnectCoro, this));
-}
-
-void LLFlickrConnect::checkConnectionToFlickr(bool auto_connect)
-{
- LLCoros::instance().launch("LLFlickrConnect::flickrConnectedCoro",
- boost::bind(&LLFlickrConnect::flickrConnectedCoro, this, auto_connect));
-}
-
-void LLFlickrConnect::loadFlickrInfo()
-{
- if(mRefreshInfo)
- {
- LLCoros::instance().launch("LLFlickrConnect::flickrInfoCoro",
- boost::bind(&LLFlickrConnect::flickrInfoCoro, this));
- }
-}
-
-void LLFlickrConnect::uploadPhoto(const std::string& image_url, const std::string& title, const std::string& description, const std::string& tags, int safety_level)
-{
- LLSD body;
- body["image"] = image_url;
- body["title"] = title;
- body["description"] = description;
- body["tags"] = tags;
- body["safety_level"] = safety_level;
-
- setConnectionState(LLFlickrConnect::FLICKR_POSTING);
-
- LLCoros::instance().launch("LLFlickrConnect::flickrShareCoro",
- boost::bind(&LLFlickrConnect::flickrShareCoro, this, body));
-}
-
-void LLFlickrConnect::uploadPhoto(LLPointer<LLImageFormatted> image, const std::string& title, const std::string& description, const std::string& tags, int safety_level)
-{
- setConnectionState(LLFlickrConnect::FLICKR_POSTING);
-
- LLCoros::instance().launch("LLFlickrConnect::flickrShareImageCoro",
- boost::bind(&LLFlickrConnect::flickrShareImageCoro, this, image,
- title, description, tags, safety_level));
-}
-
-void LLFlickrConnect::storeInfo(const LLSD& info)
-{
- mInfo = info;
- mRefreshInfo = false;
-
- sInfoWatcher->post(info);
-}
-
-const LLSD& LLFlickrConnect::getInfo() const
-{
- return mInfo;
-}
-
-void LLFlickrConnect::clearInfo()
-{
- mInfo = LLSD();
-}
-
-void LLFlickrConnect::setDataDirty()
-{
- mRefreshInfo = true;
-}
-
-void LLFlickrConnect::setConnectionState(LLFlickrConnect::EConnectionState connection_state)
-{
- if(connection_state == FLICKR_CONNECTED)
- {
- mReadFromMaster = true;
- setConnected(true);
- setDataDirty();
- }
- else if(connection_state == FLICKR_NOT_CONNECTED)
- {
- setConnected(false);
- }
- else if(connection_state == FLICKR_POSTED)
- {
- mReadFromMaster = false;
- }
-
- if (mConnectionState != connection_state)
- {
- // set the connection state before notifying watchers
- mConnectionState = connection_state;
-
- LLSD state_info;
- state_info["enum"] = connection_state;
- sStateWatcher->post(state_info);
- }
-}
-
-void LLFlickrConnect::setConnected(bool connected)
-{
- mConnected = connected;
-}
diff --git a/indra/newview/llflickrconnect.h b/indra/newview/llflickrconnect.h
deleted file mode 100644
index 43cadca708..0000000000
--- a/indra/newview/llflickrconnect.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * @file llflickrconnect.h
- * @author Merov, Cho
- * @brief Connection to Flickr Service
- *
- * $LicenseInfo:firstyear=2013&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2013, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLFLICKRCONNECT_H
-#define LL_LLFLICKRCONNECT_H
-
-#include "llsingleton.h"
-#include "llimage.h"
-#include "llcoros.h"
-#include "lleventcoro.h"
-
-class LLEventPump;
-
-/**
- * @class LLFlickrConnect
- *
- * Manages authentication to, and interaction with, a web service allowing the
- * the viewer to upload photos to Flickr.
- */
-class LLFlickrConnect : public LLSingleton<LLFlickrConnect>
-{
- LLSINGLETON(LLFlickrConnect);
- ~LLFlickrConnect() {};
- LOG_CLASS(LLFlickrConnect);
-public:
- enum EConnectionState
- {
- FLICKR_NOT_CONNECTED = 0,
- FLICKR_CONNECTION_IN_PROGRESS = 1,
- FLICKR_CONNECTED = 2,
- FLICKR_CONNECTION_FAILED = 3,
- FLICKR_POSTING = 4,
- FLICKR_POSTED = 5,
- FLICKR_POST_FAILED = 6,
- FLICKR_DISCONNECTING = 7,
- FLICKR_DISCONNECT_FAILED = 8
- };
-
- void connectToFlickr(const std::string& request_token = "", const std::string& oauth_verifier = ""); // Initiate the complete Flickr connection. Please use checkConnectionToFlickr() in normal use.
- void disconnectFromFlickr(); // Disconnect from the Flickr service.
- void checkConnectionToFlickr(bool auto_connect = false); // Check if an access token is available on the Flickr service. If not, call connectToFlickr().
-
- void loadFlickrInfo();
- void uploadPhoto(const std::string& image_url, const std::string& title, const std::string& description, const std::string& tags, int safety_level);
- void uploadPhoto(LLPointer<LLImageFormatted> image, const std::string& title, const std::string& description, const std::string& tags, int safety_level);
-
- void storeInfo(const LLSD& info);
- const LLSD& getInfo() const;
- void clearInfo();
- void setDataDirty();
-
- void setConnectionState(EConnectionState connection_state);
- void setConnected(bool connected);
- bool isConnected() { return mConnected; }
- bool isTransactionOngoing() { return ((mConnectionState == FLICKR_CONNECTION_IN_PROGRESS) || (mConnectionState == FLICKR_POSTING) || (mConnectionState == FLICKR_DISCONNECTING)); }
- EConnectionState getConnectionState() { return mConnectionState; }
-
- void openFlickrWeb(std::string url);
-
-private:
-
- std::string getFlickrConnectURL(const std::string& route = "", bool include_read_from_master = false);
-
- EConnectionState mConnectionState;
- BOOL mConnected;
- LLSD mInfo;
- bool mRefreshInfo;
- bool mReadFromMaster;
-
- static boost::scoped_ptr<LLEventPump> sStateWatcher;
- static boost::scoped_ptr<LLEventPump> sInfoWatcher;
- static boost::scoped_ptr<LLEventPump> sContentWatcher;
-
- bool testShareStatus(LLSD &result);
- void flickrConnectCoro(std::string requestToken, std::string oauthVerifier);
- void flickrShareCoro(LLSD share);
- void flickrShareImageCoro(LLPointer<LLImageFormatted> image, std::string title, std::string description, std::string tags, int safetyLevel);
- void flickrDisconnectCoro();
- void flickrConnectedCoro(bool autoConnect);
- void flickrInfoCoro();
-
-};
-
-#endif // LL_LLFLICKRCONNECT_H
diff --git a/indra/newview/llfloaterbigpreview.h b/indra/newview/llfloaterbigpreview.h
index 63c6784d36..513ed8da6e 100644
--- a/indra/newview/llfloaterbigpreview.h
+++ b/indra/newview/llfloaterbigpreview.h
@@ -1,6 +1,6 @@
/**
* @file llfloaterbigpreview.h
-* @brief Display of extended (big) preview for snapshots and SL Share
+* @brief Display of extended (big) preview for snapshots
* @author merov@lindenlab.com
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
diff --git a/indra/newview/llfloaterexperiences.cpp b/indra/newview/llfloaterexperiences.cpp
index fdc1b47334..184e39402a 100644
--- a/indra/newview/llfloaterexperiences.cpp
+++ b/indra/newview/llfloaterexperiences.cpp
@@ -74,10 +74,6 @@ BOOL LLFloaterExperiences::postBuild()
getChild<LLTabContainer>("xp_tabs")->addTabPanel(new LLPanelExperienceLog());
resizeToTabs();
-
- LLEventPumps::instance().obtain("experience_permission").listen("LLFloaterExperiences",
- boost::bind(&LLFloaterExperiences::updatePermissions, this, _1));
-
return TRUE;
}
@@ -163,6 +159,10 @@ void LLFloaterExperiences::refreshContents()
void LLFloaterExperiences::onOpen( const LLSD& key )
{
+ LLEventPumps::instance().obtain("experience_permission").stopListening("LLFloaterExperiences");
+ LLEventPumps::instance().obtain("experience_permission").listen("LLFloaterExperiences",
+ boost::bind(&LLFloaterExperiences::updatePermissions, this, _1));
+
LLViewerRegion* region = gAgent.getRegion();
if(region)
{
diff --git a/indra/newview/llfloaterflickr.cpp b/indra/newview/llfloaterflickr.cpp
deleted file mode 100644
index 69a92b2b54..0000000000
--- a/indra/newview/llfloaterflickr.cpp
+++ /dev/null
@@ -1,787 +0,0 @@
-/**
-* @file llfloaterflickr.cpp
-* @brief Implementation of llfloaterflickr
-* @author cho@lindenlab.com
-*
-* $LicenseInfo:firstyear=2013&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2013, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
-* $/LicenseInfo$
-*/
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterflickr.h"
-
-#include "llagent.h"
-#include "llagentui.h"
-#include "llcheckboxctrl.h"
-#include "llcombobox.h"
-#include "llflickrconnect.h"
-#include "llfloaterreg.h"
-#include "lliconctrl.h"
-#include "llimagefiltersmanager.h"
-#include "llresmgr.h" // LLLocale
-#include "llsdserialize.h"
-#include "llloadingindicator.h"
-#include "llslurl.h"
-#include "lltrans.h"
-#include "llsnapshotlivepreview.h"
-#include "llfloaterbigpreview.h"
-#include "llviewerregion.h"
-#include "llviewercontrol.h"
-#include "llviewermedia.h"
-#include "lltabcontainer.h"
-#include "llviewerparcelmgr.h"
-#include "llviewerregion.h"
-#include <boost/regex.hpp>
-static LLPanelInjector<LLFlickrPhotoPanel> t_panel_photo("llflickrphotopanel");
-static LLPanelInjector<LLFlickrAccountPanel> t_panel_account("llflickraccountpanel");
-
-const std::string DEFAULT_PHOTO_QUERY_PARAMETERS = "?sourceid=slshare_photo&utm_source=flickr&utm_medium=photo&utm_campaign=slshare";
-const std::string DEFAULT_TAG_TEXT = "secondlife ";
-const std::string FLICKR_MACHINE_TAGS_NAMESPACE = "secondlife";
-
-///////////////////////////
-//LLFlickrPhotoPanel///////
-///////////////////////////
-
-LLFlickrPhotoPanel::LLFlickrPhotoPanel() :
-mResolutionComboBox(NULL),
-mRefreshBtn(NULL),
-mBtnPreview(NULL),
-mWorkingLabel(NULL),
-mThumbnailPlaceholder(NULL),
-mTitleTextBox(NULL),
-mDescriptionTextBox(NULL),
-mLocationCheckbox(NULL),
-mTagsTextBox(NULL),
-mRatingComboBox(NULL),
-mBigPreviewFloater(NULL),
-mPostButton(NULL)
-{
- mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLFlickrPhotoPanel::onSend, this));
- mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", boost::bind(&LLFlickrPhotoPanel::onClickNewSnapshot, this));
- mCommitCallbackRegistrar.add("SocialSharing.BigPreview", boost::bind(&LLFlickrPhotoPanel::onClickBigPreview, this));
-}
-
-LLFlickrPhotoPanel::~LLFlickrPhotoPanel()
-{
- if(mPreviewHandle.get())
- {
- mPreviewHandle.get()->die();
- }
-}
-
-BOOL LLFlickrPhotoPanel::postBuild()
-{
- setVisibleCallback(boost::bind(&LLFlickrPhotoPanel::onVisibilityChange, this, _2));
-
- mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox");
- mResolutionComboBox->setCommitCallback(boost::bind(&LLFlickrPhotoPanel::updateResolution, this, TRUE));
- mFilterComboBox = getChild<LLUICtrl>("filters_combobox");
- mFilterComboBox->setCommitCallback(boost::bind(&LLFlickrPhotoPanel::updateResolution, this, TRUE));
- mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
- mBtnPreview = getChild<LLButton>("big_preview_btn");
- mWorkingLabel = getChild<LLUICtrl>("working_lbl");
- mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
- mTitleTextBox = getChild<LLUICtrl>("photo_title");
- mDescriptionTextBox = getChild<LLUICtrl>("photo_description");
- mLocationCheckbox = getChild<LLUICtrl>("add_location_cb");
- mTagsTextBox = getChild<LLUICtrl>("photo_tags");
- mTagsTextBox->setValue(DEFAULT_TAG_TEXT);
- mRatingComboBox = getChild<LLUICtrl>("rating_combobox");
- mPostButton = getChild<LLUICtrl>("post_photo_btn");
- mCancelButton = getChild<LLUICtrl>("cancel_photo_btn");
- mBigPreviewFloater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
-
- // Update filter list
- std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
- LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
- for (U32 i = 0; i < filter_list.size(); i++)
- {
- filterbox->add(filter_list[i]);
- }
-
- return LLPanel::postBuild();
-}
-
-// virtual
-S32 LLFlickrPhotoPanel::notify(const LLSD& info)
-{
- if (info.has("snapshot-updating"))
- {
- // Disable the Post button and whatever else while the snapshot is not updated
- // updateControls();
- return 1;
- }
-
- if (info.has("snapshot-updated"))
- {
- // Enable the send/post/save buttons.
- updateControls();
-
- // The refresh button is initially hidden. We show it after the first update,
- // i.e. after snapshot is taken
- LLUICtrl * refresh_button = getRefreshBtn();
- if (!refresh_button->getVisible())
- {
- refresh_button->setVisible(true);
- }
- return 1;
- }
-
- return 0;
-}
-
-void LLFlickrPhotoPanel::draw()
-{
- LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
-
- // Enable interaction only if no transaction with the service is on-going (prevent duplicated posts)
- bool no_ongoing_connection = !(LLFlickrConnect::instance().isTransactionOngoing());
- mCancelButton->setEnabled(no_ongoing_connection);
- mTitleTextBox->setEnabled(no_ongoing_connection);
- mDescriptionTextBox->setEnabled(no_ongoing_connection);
- mTagsTextBox->setEnabled(no_ongoing_connection);
- mRatingComboBox->setEnabled(no_ongoing_connection);
- mResolutionComboBox->setEnabled(no_ongoing_connection);
- mFilterComboBox->setEnabled(no_ongoing_connection);
- mRefreshBtn->setEnabled(no_ongoing_connection);
- mBtnPreview->setEnabled(no_ongoing_connection);
- mLocationCheckbox->setEnabled(no_ongoing_connection);
-
- // Reassign the preview floater if we have the focus and the preview exists
- if (hasFocus() && isPreviewVisible())
- {
- attachPreview();
- }
-
- // Toggle the button state as appropriate
- bool preview_active = (isPreviewVisible() && mBigPreviewFloater->isFloaterOwner(getParentByType<LLFloater>()));
- mBtnPreview->setToggleState(preview_active);
-
- // Display the preview if one is available
- if (previewp && previewp->getThumbnailImage())
- {
- const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect();
- const S32 thumbnail_w = previewp->getThumbnailWidth();
- const S32 thumbnail_h = previewp->getThumbnailHeight();
-
- // calc preview offset within the preview rect
- const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2 ;
- const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2 ;
- S32 offset_x = thumbnail_rect.mLeft + local_offset_x;
- S32 offset_y = thumbnail_rect.mBottom + local_offset_y;
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- // Apply floater transparency to the texture unless the floater is focused.
- F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
- LLColor4 color = LLColor4::white;
- gl_draw_scaled_image(offset_x, offset_y,
- thumbnail_w, thumbnail_h,
- previewp->getThumbnailImage(), color % alpha);
- }
-
- // Update the visibility of the working (computing preview) label
- mWorkingLabel->setVisible(!(previewp && previewp->getSnapshotUpToDate()));
-
- // Enable Post if we have a preview to send and no on going connection being processed
- mPostButton->setEnabled(no_ongoing_connection && (previewp && previewp->getSnapshotUpToDate()));
-
- // Draw the rest of the panel on top of it
- LLPanel::draw();
-}
-
-LLSnapshotLivePreview* LLFlickrPhotoPanel::getPreviewView()
-{
- LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
- return previewp;
-}
-
-void LLFlickrPhotoPanel::onVisibilityChange(BOOL visible)
-{
- if (visible)
- {
- if (mPreviewHandle.get())
- {
- LLSnapshotLivePreview* preview = getPreviewView();
- if(preview)
- {
- LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
- preview->updateSnapshot(TRUE);
- }
- }
- else
- {
- LLRect full_screen_rect = getRootView()->getRect();
- LLSnapshotLivePreview::Params p;
- p.rect(full_screen_rect);
- LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
- mPreviewHandle = previewp->getHandle();
-
- previewp->setContainer(this);
- previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB);
- previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_PNG);
- previewp->setThumbnailSubsampled(TRUE); // We want the preview to reflect the *saved* image
- previewp->setAllowRenderUI(FALSE); // We do not want the rendered UI in our snapshots
- previewp->setAllowFullScreenPreview(FALSE); // No full screen preview in SL Share mode
- previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect());
-
- updateControls();
- }
- }
-}
-
-void LLFlickrPhotoPanel::onClickNewSnapshot()
-{
- LLSnapshotLivePreview* previewp = getPreviewView();
- if (previewp)
- {
- previewp->updateSnapshot(TRUE);
- }
-}
-
-void LLFlickrPhotoPanel::onClickBigPreview()
-{
- // Toggle the preview
- if (isPreviewVisible())
- {
- LLFloaterReg::hideInstance("big_preview");
- }
- else
- {
- attachPreview();
- LLFloaterReg::showInstance("big_preview");
- }
-}
-
-bool LLFlickrPhotoPanel::isPreviewVisible()
-{
- return (mBigPreviewFloater && mBigPreviewFloater->getVisible());
-}
-
-void LLFlickrPhotoPanel::attachPreview()
-{
- if (mBigPreviewFloater)
- {
- LLSnapshotLivePreview* previewp = getPreviewView();
- mBigPreviewFloater->setPreview(previewp);
- mBigPreviewFloater->setFloaterOwner(getParentByType<LLFloater>());
- }
-}
-
-void LLFlickrPhotoPanel::onSend()
-{
- LLEventPumps::instance().obtain("FlickrConnectState").stopListening("LLFlickrPhotoPanel"); // just in case it is already listening
- LLEventPumps::instance().obtain("FlickrConnectState").listen("LLFlickrPhotoPanel", boost::bind(&LLFlickrPhotoPanel::onFlickrConnectStateChange, this, _1));
-
- // Connect to Flickr if necessary and then post
- if (LLFlickrConnect::instance().isConnected())
- {
- sendPhoto();
- }
- else
- {
- LLFlickrConnect::instance().checkConnectionToFlickr(true);
- }
-}
-
-bool LLFlickrPhotoPanel::onFlickrConnectStateChange(const LLSD& data)
-{
- switch (data.get("enum").asInteger())
- {
- case LLFlickrConnect::FLICKR_CONNECTED:
- sendPhoto();
- break;
-
- case LLFlickrConnect::FLICKR_POSTED:
- LLEventPumps::instance().obtain("FlickrConnectState").stopListening("LLFlickrPhotoPanel");
- clearAndClose();
- break;
- }
-
- return false;
-}
-
-void LLFlickrPhotoPanel::sendPhoto()
-{
- // Get the title, description, and tags
- std::string title = mTitleTextBox->getValue().asString();
- std::string description = mDescriptionTextBox->getValue().asString();
- std::string tags = mTagsTextBox->getValue().asString();
-
- // Add the location if required
- bool add_location = mLocationCheckbox->getValue().asBoolean();
- if (add_location)
- {
- // Get the SLURL for the location
- LLSLURL slurl;
- LLAgentUI::buildSLURL(slurl);
- std::string slurl_string = slurl.getSLURLString();
-
- // Add query parameters so Google Analytics can track incoming clicks!
- slurl_string += DEFAULT_PHOTO_QUERY_PARAMETERS;
-
- std::string photo_link_text = "Visit this location";// at [] in Second Life";
- std::string parcel_name = LLViewerParcelMgr::getInstance()->getAgentParcelName();
- if (!parcel_name.empty())
- {
- boost::regex pattern = boost::regex("\\S\\.[a-zA-Z]{2,}");
- boost::match_results<std::string::const_iterator> matches;
- if(!boost::regex_search(parcel_name, matches, pattern))
- {
- photo_link_text += " at " + parcel_name;
- }
- }
- photo_link_text += " in Second Life";
-
- slurl_string = "<a href=\"" + slurl_string + "\">" + photo_link_text + "</a>";
-
- // Add it to the description (pretty crude, but we don't have a better option with photos)
- if (description.empty())
- description = slurl_string;
- else
- description = description + "\n\n" + slurl_string;
-
- // Also add special "machine tags" with location metadata
- const LLVector3& agent_pos_region = gAgent.getPositionAgent();
- LLViewerRegion* region = gAgent.getRegion();
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (region && parcel)
- {
- S32 pos_x = S32(agent_pos_region.mV[VX]);
- S32 pos_y = S32(agent_pos_region.mV[VY]);
- S32 pos_z = S32(agent_pos_region.mV[VZ]);
-
- std::string parcel_name = LLViewerParcelMgr::getInstance()->getAgentParcelName();
- std::string region_name = region->getName();
-
- if (!region_name.empty())
- {
- tags += llformat(" \"%s:region=%s\"", FLICKR_MACHINE_TAGS_NAMESPACE.c_str(), region_name.c_str());
- }
- if (!parcel_name.empty())
- {
- tags += llformat(" \"%s:parcel=%s\"", FLICKR_MACHINE_TAGS_NAMESPACE.c_str(), parcel_name.c_str());
- }
- tags += llformat(" \"%s:x=%d\"", FLICKR_MACHINE_TAGS_NAMESPACE.c_str(), pos_x);
- tags += llformat(" \"%s:y=%d\"", FLICKR_MACHINE_TAGS_NAMESPACE.c_str(), pos_y);
- tags += llformat(" \"%s:z=%d\"", FLICKR_MACHINE_TAGS_NAMESPACE.c_str(), pos_z);
- }
- }
-
- // Get the content rating
- int content_rating = mRatingComboBox->getValue().asInteger();
-
- // Get the image
- LLSnapshotLivePreview* previewp = getPreviewView();
-
- // Post to Flickr
- LLFlickrConnect::instance().uploadPhoto(previewp->getFormattedImage(), title, description, tags, content_rating);
-
- updateControls();
-}
-
-void LLFlickrPhotoPanel::clearAndClose()
-{
- mTitleTextBox->setValue("");
- mDescriptionTextBox->setValue("");
-
- LLFloater* floater = getParentByType<LLFloater>();
- if (floater)
- {
- floater->closeFloater();
- if (mBigPreviewFloater)
- {
- mBigPreviewFloater->closeOnFloaterOwnerClosing(floater);
- }
- }
-}
-
-void LLFlickrPhotoPanel::updateControls()
-{
- LLSnapshotLivePreview* previewp = getPreviewView();
- BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
-
- // *TODO: Separate maximum size for Web images from postcards
- LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL;
-
- updateResolution(FALSE);
-}
-
-void LLFlickrPhotoPanel::updateResolution(BOOL do_update)
-{
- LLComboBox* combobox = static_cast<LLComboBox *>(mResolutionComboBox);
- LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
-
- std::string sdstring = combobox->getSelectedValue();
- LLSD sdres;
- std::stringstream sstream(sdstring);
- LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
-
- S32 width = sdres[0];
- S32 height = sdres[1];
-
- // Note : index 0 of the filter drop down is assumed to be "No filter" in whichever locale
- std::string filter_name = (filterbox->getCurrentIndex() ? filterbox->getSimple() : "");
-
- LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
- if (previewp && combobox->getCurrentIndex() >= 0)
- {
- S32 original_width = 0 , original_height = 0 ;
- previewp->getSize(original_width, original_height) ;
-
- if (width == 0 || height == 0)
- {
- // take resolution from current window size
- LL_DEBUGS() << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << LL_ENDL;
- previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
- }
- else
- {
- // use the resolution from the selected pre-canned drop-down choice
- LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
- previewp->setSize(width, height);
- }
-
- checkAspectRatio(width);
-
- previewp->getSize(width, height);
- if ((original_width != width) || (original_height != height))
- {
- previewp->setSize(width, height);
- if (do_update)
- {
- previewp->updateSnapshot(TRUE);
- updateControls();
- }
- }
- // Get the old filter, compare to the current one "filter_name" and set if changed
- std::string original_filter = previewp->getFilter();
- if (original_filter != filter_name)
- {
- previewp->setFilter(filter_name);
- if (do_update)
- {
- previewp->updateSnapshot(FALSE, TRUE);
- updateControls();
- }
- }
- }
-}
-
-void LLFlickrPhotoPanel::checkAspectRatio(S32 index)
-{
- LLSnapshotLivePreview *previewp = getPreviewView() ;
-
- BOOL keep_aspect = FALSE;
-
- if (0 == index) // current window size
- {
- keep_aspect = TRUE;
- }
- else // predefined resolution
- {
- keep_aspect = FALSE;
- }
-
- if (previewp)
- {
- previewp->mKeepAspectRatio = keep_aspect;
- }
-}
-
-LLUICtrl* LLFlickrPhotoPanel::getRefreshBtn()
-{
- return mRefreshBtn;
-}
-
-///////////////////////////
-//LLFlickrAccountPanel//////
-///////////////////////////
-
-LLFlickrAccountPanel::LLFlickrAccountPanel() :
-mAccountCaptionLabel(NULL),
-mAccountNameLabel(NULL),
-mPanelButtons(NULL),
-mConnectButton(NULL),
-mDisconnectButton(NULL)
-{
- mCommitCallbackRegistrar.add("SocialSharing.Connect", boost::bind(&LLFlickrAccountPanel::onConnect, this));
- mCommitCallbackRegistrar.add("SocialSharing.Disconnect", boost::bind(&LLFlickrAccountPanel::onDisconnect, this));
-
- setVisibleCallback(boost::bind(&LLFlickrAccountPanel::onVisibilityChange, this, _2));
-}
-
-BOOL LLFlickrAccountPanel::postBuild()
-{
- mAccountCaptionLabel = getChild<LLTextBox>("account_caption_label");
- mAccountNameLabel = getChild<LLTextBox>("account_name_label");
- mPanelButtons = getChild<LLUICtrl>("panel_buttons");
- mConnectButton = getChild<LLUICtrl>("connect_btn");
- mDisconnectButton = getChild<LLUICtrl>("disconnect_btn");
-
- return LLPanel::postBuild();
-}
-
-void LLFlickrAccountPanel::draw()
-{
- LLFlickrConnect::EConnectionState connection_state = LLFlickrConnect::instance().getConnectionState();
-
- //Disable the 'disconnect' button and the 'use another account' button when disconnecting in progress
- bool disconnecting = connection_state == LLFlickrConnect::FLICKR_DISCONNECTING;
- mDisconnectButton->setEnabled(!disconnecting);
-
- //Disable the 'connect' button when a connection is in progress
- bool connecting = connection_state == LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS;
- mConnectButton->setEnabled(!connecting);
-
- LLPanel::draw();
-}
-
-void LLFlickrAccountPanel::onVisibilityChange(BOOL visible)
-{
- if(visible)
- {
- LLEventPumps::instance().obtain("FlickrConnectState").stopListening("LLFlickrAccountPanel");
- LLEventPumps::instance().obtain("FlickrConnectState").listen("LLFlickrAccountPanel", boost::bind(&LLFlickrAccountPanel::onFlickrConnectStateChange, this, _1));
-
- LLEventPumps::instance().obtain("FlickrConnectInfo").stopListening("LLFlickrAccountPanel");
- LLEventPumps::instance().obtain("FlickrConnectInfo").listen("LLFlickrAccountPanel", boost::bind(&LLFlickrAccountPanel::onFlickrConnectInfoChange, this));
-
- //Connected
- if(LLFlickrConnect::instance().isConnected())
- {
- showConnectedLayout();
- }
- //Check if connected (show disconnected layout in meantime)
- else
- {
- showDisconnectedLayout();
- }
- if ((LLFlickrConnect::instance().getConnectionState() == LLFlickrConnect::FLICKR_NOT_CONNECTED) ||
- (LLFlickrConnect::instance().getConnectionState() == LLFlickrConnect::FLICKR_CONNECTION_FAILED))
- {
- LLFlickrConnect::instance().checkConnectionToFlickr();
- }
- }
- else
- {
- LLEventPumps::instance().obtain("FlickrConnectState").stopListening("LLFlickrAccountPanel");
- LLEventPumps::instance().obtain("FlickrConnectInfo").stopListening("LLFlickrAccountPanel");
- }
-}
-
-bool LLFlickrAccountPanel::onFlickrConnectStateChange(const LLSD& data)
-{
- if(LLFlickrConnect::instance().isConnected())
- {
- //In process of disconnecting so leave the layout as is
- if(data.get("enum").asInteger() != LLFlickrConnect::FLICKR_DISCONNECTING)
- {
- showConnectedLayout();
- }
- }
- else
- {
- showDisconnectedLayout();
- }
-
- return false;
-}
-
-bool LLFlickrAccountPanel::onFlickrConnectInfoChange()
-{
- LLSD info = LLFlickrConnect::instance().getInfo();
- std::string clickable_name;
-
- //Strings of format [http://www.somewebsite.com Click Me] become clickable text
- if(info.has("link") && info.has("name"))
- {
- clickable_name = "[" + info["link"].asString() + " " + info["name"].asString() + "]";
- }
-
- mAccountNameLabel->setText(clickable_name);
-
- return false;
-}
-
-void LLFlickrAccountPanel::showConnectButton()
-{
- if(!mConnectButton->getVisible())
- {
- mConnectButton->setVisible(TRUE);
- mDisconnectButton->setVisible(FALSE);
- }
-}
-
-void LLFlickrAccountPanel::hideConnectButton()
-{
- if(mConnectButton->getVisible())
- {
- mConnectButton->setVisible(FALSE);
- mDisconnectButton->setVisible(TRUE);
- }
-}
-
-void LLFlickrAccountPanel::showDisconnectedLayout()
-{
- mAccountCaptionLabel->setText(getString("flickr_disconnected"));
- mAccountNameLabel->setText(std::string(""));
- showConnectButton();
-}
-
-void LLFlickrAccountPanel::showConnectedLayout()
-{
- LLFlickrConnect::instance().loadFlickrInfo();
-
- mAccountCaptionLabel->setText(getString("flickr_connected"));
- hideConnectButton();
-}
-
-void LLFlickrAccountPanel::onConnect()
-{
- LLFlickrConnect::instance().checkConnectionToFlickr(true);
-}
-
-void LLFlickrAccountPanel::onDisconnect()
-{
- LLFlickrConnect::instance().disconnectFromFlickr();
-}
-
-////////////////////////
-//LLFloaterFlickr///////
-////////////////////////
-
-LLFloaterFlickr::LLFloaterFlickr(const LLSD& key) : LLFloater(key),
- mFlickrPhotoPanel(NULL),
- mStatusErrorText(NULL),
- mStatusLoadingText(NULL),
- mStatusLoadingIndicator(NULL)
-{
- mCommitCallbackRegistrar.add("SocialSharing.Cancel", boost::bind(&LLFloaterFlickr::onCancel, this));
-}
-
-void LLFloaterFlickr::onClose(bool app_quitting)
-{
- LLFloaterBigPreview* big_preview_floater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
- if (big_preview_floater)
- {
- big_preview_floater->closeOnFloaterOwnerClosing(this);
- }
- LLFloater::onClose(app_quitting);
-}
-
-void LLFloaterFlickr::onCancel()
-{
- LLFloaterBigPreview* big_preview_floater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
- if (big_preview_floater)
- {
- big_preview_floater->closeOnFloaterOwnerClosing(this);
- }
- closeFloater();
-}
-
-BOOL LLFloaterFlickr::postBuild()
-{
- // Keep tab of the Photo Panel
- mFlickrPhotoPanel = static_cast<LLFlickrPhotoPanel*>(getChild<LLUICtrl>("panel_flickr_photo"));
- // Connection status widgets
- mStatusErrorText = getChild<LLTextBox>("connection_error_text");
- mStatusLoadingText = getChild<LLTextBox>("connection_loading_text");
- mStatusLoadingIndicator = getChild<LLUICtrl>("connection_loading_indicator");
- return LLFloater::postBuild();
-}
-
-void LLFloaterFlickr::showPhotoPanel()
-{
- LLTabContainer* parent = dynamic_cast<LLTabContainer*>(mFlickrPhotoPanel->getParent());
- if (!parent)
- {
- LL_WARNS() << "Cannot find panel container" << LL_ENDL;
- return;
- }
-
- parent->selectTabPanel(mFlickrPhotoPanel);
-}
-
-void LLFloaterFlickr::draw()
-{
- if (mStatusErrorText && mStatusLoadingText && mStatusLoadingIndicator)
- {
- mStatusErrorText->setVisible(false);
- mStatusLoadingText->setVisible(false);
- mStatusLoadingIndicator->setVisible(false);
- LLFlickrConnect::EConnectionState connection_state = LLFlickrConnect::instance().getConnectionState();
- std::string status_text;
-
- switch (connection_state)
- {
- case LLFlickrConnect::FLICKR_NOT_CONNECTED:
- // No status displayed when first opening the panel and no connection done
- case LLFlickrConnect::FLICKR_CONNECTED:
- // When successfully connected, no message is displayed
- case LLFlickrConnect::FLICKR_POSTED:
- // No success message to show since we actually close the floater after successful posting completion
- break;
- case LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS:
- // Connection loading indicator
- mStatusLoadingText->setVisible(true);
- status_text = LLTrans::getString("SocialFlickrConnecting");
- mStatusLoadingText->setValue(status_text);
- mStatusLoadingIndicator->setVisible(true);
- break;
- case LLFlickrConnect::FLICKR_POSTING:
- // Posting indicator
- mStatusLoadingText->setVisible(true);
- status_text = LLTrans::getString("SocialFlickrPosting");
- mStatusLoadingText->setValue(status_text);
- mStatusLoadingIndicator->setVisible(true);
- break;
- case LLFlickrConnect::FLICKR_CONNECTION_FAILED:
- // Error connecting to the service
- mStatusErrorText->setVisible(true);
- status_text = LLTrans::getString("SocialFlickrErrorConnecting");
- mStatusErrorText->setValue(status_text);
- break;
- case LLFlickrConnect::FLICKR_POST_FAILED:
- // Error posting to the service
- mStatusErrorText->setVisible(true);
- status_text = LLTrans::getString("SocialFlickrErrorPosting");
- mStatusErrorText->setValue(status_text);
- break;
- case LLFlickrConnect::FLICKR_DISCONNECTING:
- // Disconnecting loading indicator
- mStatusLoadingText->setVisible(true);
- status_text = LLTrans::getString("SocialFlickrDisconnecting");
- mStatusLoadingText->setValue(status_text);
- mStatusLoadingIndicator->setVisible(true);
- break;
- case LLFlickrConnect::FLICKR_DISCONNECT_FAILED:
- // Error disconnecting from the service
- mStatusErrorText->setVisible(true);
- status_text = LLTrans::getString("SocialFlickrErrorDisconnecting");
- mStatusErrorText->setValue(status_text);
- break;
- }
- }
- LLFloater::draw();
-}
-
diff --git a/indra/newview/llfloaterflickr.h b/indra/newview/llfloaterflickr.h
deleted file mode 100644
index 74da3bcea9..0000000000
--- a/indra/newview/llfloaterflickr.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/**
-* @file llfloaterflickr.h
-* @brief Header file for llfloaterflickr
-* @author cho@lindenlab.com
-*
-* $LicenseInfo:firstyear=2013&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2013, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
-* $/LicenseInfo$
-*/
-#ifndef LL_LLFLOATERFLICKR_H
-#define LL_LLFLOATERFLICKR_H
-
-#include "llfloater.h"
-#include "lltextbox.h"
-#include "llviewertexture.h"
-
-class LLIconCtrl;
-class LLCheckBoxCtrl;
-class LLSnapshotLivePreview;
-class LLFloaterBigPreview;
-
-class LLFlickrPhotoPanel : public LLPanel
-{
-public:
- LLFlickrPhotoPanel();
- ~LLFlickrPhotoPanel();
-
- BOOL postBuild();
- S32 notify(const LLSD& info);
- void draw();
-
- LLSnapshotLivePreview* getPreviewView();
- void onVisibilityChange(BOOL new_visibility);
- void onClickNewSnapshot();
- void onClickBigPreview();
- void onSend();
- bool onFlickrConnectStateChange(const LLSD& data);
-
- void sendPhoto();
- void clearAndClose();
-
- void updateControls();
- void updateResolution(BOOL do_update);
- void checkAspectRatio(S32 index);
- LLUICtrl* getRefreshBtn();
-
-private:
- bool isPreviewVisible();
- void attachPreview();
-
- LLHandle<LLView> mPreviewHandle;
-
- LLUICtrl * mResolutionComboBox;
- LLUICtrl * mFilterComboBox;
- LLUICtrl * mRefreshBtn;
- LLUICtrl * mWorkingLabel;
- LLUICtrl * mThumbnailPlaceholder;
- LLUICtrl * mTitleTextBox;
- LLUICtrl * mDescriptionTextBox;
- LLUICtrl * mLocationCheckbox;
- LLUICtrl * mTagsTextBox;
- LLUICtrl * mRatingComboBox;
- LLUICtrl * mPostButton;
- LLUICtrl * mCancelButton;
- LLButton * mBtnPreview;
-
- LLFloaterBigPreview * mBigPreviewFloater;
-};
-
-class LLFlickrAccountPanel : public LLPanel
-{
-public:
- LLFlickrAccountPanel();
- BOOL postBuild();
- void draw();
-
-private:
- void onVisibilityChange(BOOL new_visibility);
- bool onFlickrConnectStateChange(const LLSD& data);
- bool onFlickrConnectInfoChange();
- void onConnect();
- void onUseAnotherAccount();
- void onDisconnect();
-
- void showConnectButton();
- void hideConnectButton();
- void showDisconnectedLayout();
- void showConnectedLayout();
-
- LLTextBox * mAccountCaptionLabel;
- LLTextBox * mAccountNameLabel;
- LLUICtrl * mPanelButtons;
- LLUICtrl * mConnectButton;
- LLUICtrl * mDisconnectButton;
-};
-
-
-class LLFloaterFlickr : public LLFloater
-{
-public:
- LLFloaterFlickr(const LLSD& key);
- BOOL postBuild();
- void draw();
- void onClose(bool app_quitting);
- void onCancel();
-
- void showPhotoPanel();
-
-private:
- LLFlickrPhotoPanel* mFlickrPhotoPanel;
- LLTextBox* mStatusErrorText;
- LLTextBox* mStatusLoadingText;
- LLUICtrl* mStatusLoadingIndicator;
-};
-
-#endif // LL_LLFLOATERFLICKR_H
-
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index b840d37c4d..e778e8eb9e 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -41,6 +41,7 @@
#include "llkeyboard.h"
#include "llmenugl.h"
#include "llmultigesture.h"
+#include "llnotificationsutil.h"
#include "llpreviewgesture.h"
#include "llscrolllistctrl.h"
#include "lltrans.h"
@@ -125,6 +126,7 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key)
mCommitCallbackRegistrar.add("Gesture.Action.ShowPreview", boost::bind(&LLFloaterGesture::onClickEdit, this));
mCommitCallbackRegistrar.add("Gesture.Action.CopyPaste", boost::bind(&LLFloaterGesture::onCopyPasteAction, this, _2));
mCommitCallbackRegistrar.add("Gesture.Action.SaveToCOF", boost::bind(&LLFloaterGesture::addToCurrentOutFit, this));
+ mCommitCallbackRegistrar.add("Gesture.Action.Rename", boost::bind(&LLFloaterGesture::onRenameSelected, this));
mEnableCallbackRegistrar.add("Gesture.EnableAction", boost::bind(&LLFloaterGesture::isActionEnabled, this, _2));
}
@@ -430,6 +432,19 @@ bool LLFloaterGesture::isActionEnabled(const LLSD& command)
{
return mGestureList->getAllSelected().size() == 1;
}
+ else if ("rename_gesture" == command_name)
+ {
+ if (mGestureList->getAllSelected().size() == 1)
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(mGestureList->getCurrentID());
+
+ if (item && item->getPermissions().allowModifyBy(gAgentID))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
return true;
}
@@ -514,6 +529,44 @@ void LLFloaterGesture::onActivateBtnClick()
}
}
+void LLFloaterGesture::onRenameSelected()
+{
+ LLViewerInventoryItem* gesture = gInventory.getItem(mGestureList->getCurrentID());
+ if (!gesture)
+ {
+ return;
+ }
+
+ LLSD args;
+ args["NAME"] = gesture->getName();
+
+ LLSD payload;
+ payload["gesture_id"] = mGestureList->getCurrentID();
+
+ LLNotificationsUtil::add("RenameGesture", args, payload, boost::bind(onGestureRename, _1, _2));
+
+}
+
+void LLFloaterGesture::onGestureRename(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0) return; // canceled
+
+ std::string new_name = response["new_name"].asString();
+ LLInventoryObject::correctInventoryName(new_name);
+ if (!new_name.empty())
+ {
+ LLUUID item_id = notification["payload"]["gesture_id"].asUUID();
+ LLViewerInventoryItem* gesture = gInventory.getItem(item_id);
+ if (gesture && (gesture->getName() != new_name))
+ {
+ LLSD updates;
+ updates["name"] = new_name;
+ update_inventory_item(item_id, updates, NULL);
+ }
+ }
+}
+
void LLFloaterGesture::onCopyPasteAction(const LLSD& command)
{
std::string command_name = command.asString();
diff --git a/indra/newview/llfloatergesture.h b/indra/newview/llfloatergesture.h
index 8efb3e6461..1d702c6704 100644
--- a/indra/newview/llfloatergesture.h
+++ b/indra/newview/llfloatergesture.h
@@ -95,6 +95,9 @@ private:
void onCommitList();
void onCopyPasteAction(const LLSD& command);
void onDeleteSelected();
+ void onRenameSelected();
+
+ static void onGestureRename(const LLSD& notification, const LLSD& response);
LLUUID mSelectedID;
LLUUID mGestureFolderID;
diff --git a/indra/newview/llfloatergridstatus.cpp b/indra/newview/llfloatergridstatus.cpp
index c47ff1c1d9..faa7e9f3db 100644
--- a/indra/newview/llfloatergridstatus.cpp
+++ b/indra/newview/llfloatergridstatus.cpp
@@ -39,7 +39,7 @@
#include "llxmltree.h"
std::map<std::string, std::string> LLFloaterGridStatus::sItemsMap;
-const std::string DEFAULT_GRID_STATUS_URL = "http://secondlife-status.statuspage.io/";
+const std::string DEFAULT_GRID_STATUS_URL = "http://status.secondlifegrid.net/";
LLFloaterGridStatus::LLFloaterGridStatus(const Params& key) :
LLFloaterWebContent(key),
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index b6efc1590e..c4186132fe 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -3014,6 +3014,15 @@ void LLModelPreview::updateStatusMessages()
{
mFMP->childDisable("ok_btn");
}
+
+ if (mModelNoErrors && mLodsWithParsingError.empty())
+ {
+ mFMP->childEnable("calculate_btn");
+ }
+ else
+ {
+ mFMP->childDisable("calculate_btn");
+ }
//add up physics triangles etc
S32 phys_tris = 0;
diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index 97eab1fd9c..ad5e97e067 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -31,8 +31,6 @@
#include "llagent.h"
#include "llfloaterreg.h"
-#include "llfloaterflickr.h"
-#include "llfloatertwitter.h"
#include "llimagefiltersmanager.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index fe347a91a3..e0a3585c93 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -124,7 +124,9 @@ char const* const VISIBILITY_DEFAULT = "default";
char const* const VISIBILITY_HIDDEN = "hidden";
//control value for middle mouse as talk2push button
-const static std::string MIDDLE_MOUSE_CV = "MiddleMouse";
+const static std::string MIDDLE_MOUSE_CV = "MiddleMouse"; // for voice client and redability
+const static std::string MOUSE_BUTTON_4_CV = "MouseButton4";
+const static std::string MOUSE_BUTTON_5_CV = "MouseButton5";
/// This must equal the maximum value set for the IndirectMaxComplexity slider in panel_preferences_graphics1.xml
static const U32 INDIRECT_MAX_ARC_OFF = 101; // all the way to the right == disabled
@@ -168,6 +170,7 @@ public:
void setParent(LLFloaterPreference* parent) { mParent = parent; }
BOOL handleKeyHere(KEY key, MASK mask);
+ BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down);
static void onCancel(void* user_data);
private:
@@ -211,6 +214,25 @@ BOOL LLVoiceSetKeyDialog::handleKeyHere(KEY key, MASK mask)
return result;
}
+BOOL LLVoiceSetKeyDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
+{
+ BOOL result = FALSE;
+ if (down
+ && (clicktype == LLMouseHandler::CLICK_MIDDLE || clicktype == LLMouseHandler::CLICK_BUTTON4 || clicktype == LLMouseHandler::CLICK_BUTTON5)
+ && mask == 0)
+ {
+ mParent->setMouse(clicktype);
+ result = TRUE;
+ closeFloater();
+ }
+ else
+ {
+ result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
+ }
+
+ return result;
+}
+
//static
void LLVoiceSetKeyDialog::onCancel(void* user_data)
{
@@ -1694,6 +1716,41 @@ void LLFloaterPreference::setKey(KEY key)
getChild<LLUICtrl>("modifier_combo")->onCommit();
}
+void LLFloaterPreference::setMouse(LLMouseHandler::EClickType click)
+{
+ std::string bt_name;
+ std::string ctrl_value;
+ switch (click)
+ {
+ case LLMouseHandler::CLICK_MIDDLE:
+ bt_name = "middle_mouse";
+ ctrl_value = MIDDLE_MOUSE_CV;
+ break;
+ case LLMouseHandler::CLICK_BUTTON4:
+ bt_name = "button4_mouse";
+ ctrl_value = MOUSE_BUTTON_4_CV;
+ break;
+ case LLMouseHandler::CLICK_BUTTON5:
+ bt_name = "button5_mouse";
+ ctrl_value = MOUSE_BUTTON_5_CV;
+ break;
+ default:
+ break;
+ }
+
+ if (!ctrl_value.empty())
+ {
+ LLUICtrl* p2t_line_editor = getChild<LLUICtrl>("modifier_combo");
+ // We are using text control names for readability and compatibility with voice
+ p2t_line_editor->setControlValue(ctrl_value);
+ LLPanel* advanced_preferences = dynamic_cast<LLPanel*>(p2t_line_editor->getParent());
+ if (advanced_preferences)
+ {
+ p2t_line_editor->setValue(advanced_preferences->getString(bt_name));
+ }
+ }
+}
+
void LLFloaterPreference::onClickSetMiddleMouse()
{
LLUICtrl* p2t_line_editor = getChild<LLUICtrl>("modifier_combo");
@@ -2431,10 +2488,19 @@ BOOL LLPanelPreference::postBuild()
if (hasChild("modifier_combo", TRUE))
{
//localizing if push2talk button is set to middle mouse
- if (MIDDLE_MOUSE_CV == getChild<LLUICtrl>("modifier_combo")->getValue().asString())
+ std::string modifier_value = getChild<LLUICtrl>("modifier_combo")->getValue().asString();
+ if (MIDDLE_MOUSE_CV == modifier_value)
{
getChild<LLUICtrl>("modifier_combo")->setValue(getString("middle_mouse"));
}
+ else if (MOUSE_BUTTON_4_CV == modifier_value)
+ {
+ getChild<LLUICtrl>("modifier_combo")->setValue(getString("button4_mouse"));
+ }
+ else if (MOUSE_BUTTON_5_CV == modifier_value)
+ {
+ getChild<LLUICtrl>("modifier_combo")->setValue(getString("button5_mouse"));
+ }
}
//////////////////////PanelSetup ///////////////////
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 1b8229ada6..d46f0deb7a 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -148,6 +148,7 @@ public:
void onSelectSkin();
void onClickSetKey();
void setKey(KEY key);
+ void setMouse(LLMouseHandler::EClickType click);
void onClickSetMiddleMouse();
void onClickSetSounds();
void onClickEnablePopup();
diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp
index fbb7432f71..64ad40f419 100644
--- a/indra/newview/llfloaterproperties.cpp
+++ b/indra/newview/llfloaterproperties.cpp
@@ -85,7 +85,7 @@ public:
}
virtual void changed(U32 mask);
private:
- LLFloaterProperties* mFloater;
+ LLFloaterProperties* mFloater; // Not a handle because LLFloaterProperties is managing LLPropertiesObserver
};
void LLPropertiesObserver::changed(U32 mask)
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 2798e375c7..ef7a9fd536 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -29,8 +29,6 @@
#include "llfloatersnapshot.h"
#include "llfloaterreg.h"
-#include "llfloaterflickr.h"
-#include "llfloatertwitter.h"
#include "llimagefiltersmanager.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
@@ -1240,10 +1238,7 @@ BOOL LLFloaterSnapshot::isWaitingState()
BOOL LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized)
{
- LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr");
- LLFloaterTwitter* floater_twitter = LLFloaterReg::findTypedInstance<LLFloaterTwitter>("twitter");
-
- if (!initialized && !floater_flickr && !floater_twitter)
+ if (!initialized)
return FALSE;
BOOL changed = FALSE;
diff --git a/indra/newview/llfloatertwitter.cpp b/indra/newview/llfloatertwitter.cpp
deleted file mode 100644
index 2b33bc6935..0000000000
--- a/indra/newview/llfloatertwitter.cpp
+++ /dev/null
@@ -1,810 +0,0 @@
-/**
-* @file llfloatertwitter.cpp
-* @brief Implementation of llfloatertwitter
-* @author cho@lindenlab.com
-*
-* $LicenseInfo:firstyear=2013&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2013, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
-* $/LicenseInfo$
-*/
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloatertwitter.h"
-
-#include "llagent.h"
-#include "llagentui.h"
-#include "llcheckboxctrl.h"
-#include "llcombobox.h"
-#include "lltwitterconnect.h"
-#include "llfloaterbigpreview.h"
-#include "llfloaterreg.h"
-#include "lliconctrl.h"
-#include "llimagefiltersmanager.h"
-#include "llresmgr.h" // LLLocale
-#include "llsdserialize.h"
-#include "llloadingindicator.h"
-#include "llslurl.h"
-#include "lltrans.h"
-#include "llsnapshotlivepreview.h"
-#include "llviewerregion.h"
-#include "llviewercontrol.h"
-#include "llviewermedia.h"
-#include "lltabcontainer.h"
-#include "lltexteditor.h"
-
-static LLPanelInjector<LLTwitterPhotoPanel> t_panel_photo("lltwitterphotopanel");
-static LLPanelInjector<LLTwitterAccountPanel> t_panel_account("lltwitteraccountpanel");
-
-const std::string DEFAULT_PHOTO_LOCATION_URL = "http://maps.secondlife.com/";
-const std::string DEFAULT_PHOTO_QUERY_PARAMETERS = "?sourceid=slshare_photo&utm_source=twitter&utm_medium=photo&utm_campaign=slshare";
-const std::string DEFAULT_STATUS_TEXT = " #SecondLife";
-
-///////////////////////////
-//LLTwitterPhotoPanel///////
-///////////////////////////
-
-LLTwitterPhotoPanel::LLTwitterPhotoPanel() :
-mResolutionComboBox(NULL),
-mRefreshBtn(NULL),
-mBtnPreview(NULL),
-mWorkingLabel(NULL),
-mThumbnailPlaceholder(NULL),
-mStatusCounterLabel(NULL),
-mStatusTextBox(NULL),
-mLocationCheckbox(NULL),
-mPhotoCheckbox(NULL),
-mBigPreviewFloater(NULL),
-mPostButton(NULL)
-{
- mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLTwitterPhotoPanel::onSend, this));
- mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", boost::bind(&LLTwitterPhotoPanel::onClickNewSnapshot, this));
- mCommitCallbackRegistrar.add("SocialSharing.BigPreview", boost::bind(&LLTwitterPhotoPanel::onClickBigPreview, this));
-}
-
-LLTwitterPhotoPanel::~LLTwitterPhotoPanel()
-{
- if(mPreviewHandle.get())
- {
- mPreviewHandle.get()->die();
- }
-}
-
-BOOL LLTwitterPhotoPanel::postBuild()
-{
- setVisibleCallback(boost::bind(&LLTwitterPhotoPanel::onVisibilityChange, this, _2));
-
- mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox");
- mResolutionComboBox->setValue("[i800,i600]"); // hardcoded defaults ftw!
- mResolutionComboBox->setCommitCallback(boost::bind(&LLTwitterPhotoPanel::updateResolution, this, TRUE));
- mFilterComboBox = getChild<LLUICtrl>("filters_combobox");
- mFilterComboBox->setCommitCallback(boost::bind(&LLTwitterPhotoPanel::updateResolution, this, TRUE));
- mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
- mBtnPreview = getChild<LLButton>("big_preview_btn");
- mWorkingLabel = getChild<LLUICtrl>("working_lbl");
- mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
- mStatusCounterLabel = getChild<LLUICtrl>("status_counter_label");
- mStatusTextBox = getChild<LLUICtrl>("photo_status");
- mStatusTextBox->setValue(DEFAULT_STATUS_TEXT);
- mLocationCheckbox = getChild<LLUICtrl>("add_location_cb");
- mLocationCheckbox->setCommitCallback(boost::bind(&LLTwitterPhotoPanel::onAddLocationToggled, this));
- mPhotoCheckbox = getChild<LLUICtrl>("add_photo_cb");
- mPhotoCheckbox->setCommitCallback(boost::bind(&LLTwitterPhotoPanel::onAddPhotoToggled, this));
- mPostButton = getChild<LLUICtrl>("post_photo_btn");
- mCancelButton = getChild<LLUICtrl>("cancel_photo_btn");
- mBigPreviewFloater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
-
- // Update filter list
- std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
- LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
- for (U32 i = 0; i < filter_list.size(); i++)
- {
- filterbox->add(filter_list[i]);
- }
-
- return LLPanel::postBuild();
-}
-
-// virtual
-S32 LLTwitterPhotoPanel::notify(const LLSD& info)
-{
- if (info.has("snapshot-updating"))
- {
- // Disable the Post button and whatever else while the snapshot is not updated
- // updateControls();
- return 1;
- }
-
- if (info.has("snapshot-updated"))
- {
- // Enable the send/post/save buttons.
- updateControls();
-
- // The refresh button is initially hidden. We show it after the first update,
- // i.e. after snapshot is taken
- LLUICtrl * refresh_button = getRefreshBtn();
- if (!refresh_button->getVisible())
- {
- refresh_button->setVisible(true);
- }
- return 1;
- }
-
- return 0;
-}
-
-void LLTwitterPhotoPanel::draw()
-{
- LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
-
- // Enable interaction only if no transaction with the service is on-going (prevent duplicated posts)
- bool no_ongoing_connection = !(LLTwitterConnect::instance().isTransactionOngoing());
- bool photo_checked = mPhotoCheckbox->getValue().asBoolean();
- mCancelButton->setEnabled(no_ongoing_connection);
- mStatusTextBox->setEnabled(no_ongoing_connection);
- mResolutionComboBox->setEnabled(no_ongoing_connection && photo_checked);
- mFilterComboBox->setEnabled(no_ongoing_connection && photo_checked);
- mRefreshBtn->setEnabled(no_ongoing_connection && photo_checked);
- mBtnPreview->setEnabled(no_ongoing_connection);
- mLocationCheckbox->setEnabled(no_ongoing_connection);
- mPhotoCheckbox->setEnabled(no_ongoing_connection);
-
- bool add_location = mLocationCheckbox->getValue().asBoolean();
- bool add_photo = mPhotoCheckbox->getValue().asBoolean();
- updateStatusTextLength(false);
-
- // Reassign the preview floater if we have the focus and the preview exists
- if (hasFocus() && isPreviewVisible())
- {
- attachPreview();
- }
-
- // Toggle the button state as appropriate
- bool preview_active = (isPreviewVisible() && mBigPreviewFloater->isFloaterOwner(getParentByType<LLFloater>()));
- mBtnPreview->setToggleState(preview_active);
-
- // Display the preview if one is available
- if (previewp && previewp->getThumbnailImage())
- {
- const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect();
- const S32 thumbnail_w = previewp->getThumbnailWidth();
- const S32 thumbnail_h = previewp->getThumbnailHeight();
-
- // calc preview offset within the preview rect
- const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2 ;
- const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2 ;
- S32 offset_x = thumbnail_rect.mLeft + local_offset_x;
- S32 offset_y = thumbnail_rect.mBottom + local_offset_y;
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- // Apply floater transparency to the texture unless the floater is focused.
- F32 alpha = (add_photo ? (getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency()) : 0.5f);
- LLColor4 color = LLColor4::white;
- gl_draw_scaled_image(offset_x, offset_y,
- thumbnail_w, thumbnail_h,
- previewp->getThumbnailImage(), color % alpha);
- }
-
- // Update the visibility of the working (computing preview) label
- mWorkingLabel->setVisible(!(previewp && previewp->getSnapshotUpToDate()));
-
- // Enable Post if we have a preview to send and no on going connection being processed
- mPostButton->setEnabled(no_ongoing_connection && (previewp && previewp->getSnapshotUpToDate()) && (add_photo || add_location || !mStatusTextBox->getValue().asString().empty()));
-
- // Draw the rest of the panel on top of it
- LLPanel::draw();
-}
-
-LLSnapshotLivePreview* LLTwitterPhotoPanel::getPreviewView()
-{
- LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
- return previewp;
-}
-
-void LLTwitterPhotoPanel::onVisibilityChange(BOOL visible)
-{
- if (visible)
- {
- if (mPreviewHandle.get())
- {
- LLSnapshotLivePreview* preview = getPreviewView();
- if(preview)
- {
- LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
- preview->updateSnapshot(TRUE);
- }
- }
- else
- {
- LLRect full_screen_rect = getRootView()->getRect();
- LLSnapshotLivePreview::Params p;
- p.rect(full_screen_rect);
- LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
- mPreviewHandle = previewp->getHandle();
-
- previewp->setContainer(this);
- previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB);
- previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_JPEG);
- previewp->setThumbnailSubsampled(TRUE); // We want the preview to reflect the *saved* image
- previewp->setAllowRenderUI(FALSE); // We do not want the rendered UI in our snapshots
- previewp->setAllowFullScreenPreview(FALSE); // No full screen preview in SL Share mode
- previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect());
-
- updateControls();
- }
- }
-}
-
-void LLTwitterPhotoPanel::onAddLocationToggled()
-{
- bool add_location = mLocationCheckbox->getValue().asBoolean();
- updateStatusTextLength(!add_location);
-}
-
-void LLTwitterPhotoPanel::onAddPhotoToggled()
-{
- bool add_photo = mPhotoCheckbox->getValue().asBoolean();
- updateStatusTextLength(!add_photo);
-}
-
-void LLTwitterPhotoPanel::onClickNewSnapshot()
-{
- LLSnapshotLivePreview* previewp = getPreviewView();
- if (previewp)
- {
- previewp->updateSnapshot(TRUE);
- }
-}
-
-void LLTwitterPhotoPanel::onClickBigPreview()
-{
- // Toggle the preview
- if (isPreviewVisible())
- {
- LLFloaterReg::hideInstance("big_preview");
- }
- else
- {
- attachPreview();
- LLFloaterReg::showInstance("big_preview");
- }
-}
-
-bool LLTwitterPhotoPanel::isPreviewVisible()
-{
- return (mBigPreviewFloater && mBigPreviewFloater->getVisible());
-}
-
-void LLTwitterPhotoPanel::attachPreview()
-{
- if (mBigPreviewFloater)
- {
- LLSnapshotLivePreview* previewp = getPreviewView();
- mBigPreviewFloater->setPreview(previewp);
- mBigPreviewFloater->setFloaterOwner(getParentByType<LLFloater>());
- }
-}
-
-void LLTwitterPhotoPanel::onSend()
-{
- LLEventPumps::instance().obtain("TwitterConnectState").stopListening("LLTwitterPhotoPanel"); // just in case it is already listening
- LLEventPumps::instance().obtain("TwitterConnectState").listen("LLTwitterPhotoPanel", boost::bind(&LLTwitterPhotoPanel::onTwitterConnectStateChange, this, _1));
-
- // Connect to Twitter if necessary and then post
- if (LLTwitterConnect::instance().isConnected())
- {
- sendPhoto();
- }
- else
- {
- LLTwitterConnect::instance().checkConnectionToTwitter(true);
- }
-}
-
-bool LLTwitterPhotoPanel::onTwitterConnectStateChange(const LLSD& data)
-{
- switch (data.get("enum").asInteger())
- {
- case LLTwitterConnect::TWITTER_CONNECTED:
- sendPhoto();
- break;
-
- case LLTwitterConnect::TWITTER_POSTED:
- LLEventPumps::instance().obtain("TwitterConnectState").stopListening("LLTwitterPhotoPanel");
- clearAndClose();
- break;
- }
-
- return false;
-}
-
-void LLTwitterPhotoPanel::sendPhoto()
-{
- // Get the status text
- std::string status = mStatusTextBox->getValue().asString();
-
- // Add the location if required
- bool add_location = mLocationCheckbox->getValue().asBoolean();
- if (add_location)
- {
- // Get the SLURL for the location
- LLSLURL slurl;
- LLAgentUI::buildSLURL(slurl);
- std::string slurl_string = slurl.getSLURLString();
-
- // Use a valid http:// URL if the scheme is secondlife://
- LLURI slurl_uri(slurl_string);
- if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
- {
- slurl_string = DEFAULT_PHOTO_LOCATION_URL;
- }
-
- // Add query parameters so Google Analytics can track incoming clicks!
- slurl_string += DEFAULT_PHOTO_QUERY_PARAMETERS;
-
- // Add it to the status (pretty crude, but we don't have a better option with photos)
- if (status.empty())
- status = slurl_string;
- else
- status = status + " " + slurl_string;
- }
-
- // Add the photo if required
- bool add_photo = mPhotoCheckbox->getValue().asBoolean();
- if (add_photo)
- {
- // Get the image
- LLSnapshotLivePreview* previewp = getPreviewView();
-
- // Post to Twitter
- LLTwitterConnect::instance().uploadPhoto(previewp->getFormattedImage(), status);
- }
- else
- {
- // Just post the status to Twitter
- LLTwitterConnect::instance().updateStatus(status);
- }
-
- updateControls();
-}
-
-void LLTwitterPhotoPanel::clearAndClose()
-{
- mStatusTextBox->setValue(DEFAULT_STATUS_TEXT);
-
- LLFloater* floater = getParentByType<LLFloater>();
- if (floater)
- {
- floater->closeFloater();
- if (mBigPreviewFloater)
- {
- mBigPreviewFloater->closeOnFloaterOwnerClosing(floater);
- }
- }
-}
-
-void LLTwitterPhotoPanel::updateStatusTextLength(BOOL restore_old_status_text)
-{
- bool add_location = mLocationCheckbox->getValue().asBoolean();
-
- // Restrict the status text length to Twitter's character limit
- LLTextEditor* status_text_box = dynamic_cast<LLTextEditor*>(mStatusTextBox);
- if (status_text_box)
- {
- int max_status_length = 280 - (add_location ? 40 : 0);
- status_text_box->setMaxTextLength(max_status_length);
- if (restore_old_status_text)
- {
- if (mOldStatusText.length() > status_text_box->getText().length() && status_text_box->getText() == mOldStatusText.substr(0, status_text_box->getText().length()))
- {
- status_text_box->setText(mOldStatusText);
- }
- if (mOldStatusText.length() <= max_status_length)
- {
- mOldStatusText = "";
- }
- }
- if (status_text_box->getText().length() > max_status_length)
- {
- if (mOldStatusText.length() < status_text_box->getText().length() || status_text_box->getText() != mOldStatusText.substr(0, status_text_box->getText().length()))
- {
- mOldStatusText = status_text_box->getText();
- }
- status_text_box->setText(mOldStatusText.substr(0, max_status_length));
- }
-
- // Update the status character counter
- int characters_remaining = max_status_length - status_text_box->getText().length();
- mStatusCounterLabel->setValue(characters_remaining);
- }
-
-}
-
-void LLTwitterPhotoPanel::updateControls()
-{
- LLSnapshotLivePreview* previewp = getPreviewView();
- BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
-
- // *TODO: Separate maximum size for Web images from postcards
- LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL;
-
- updateResolution(FALSE);
-}
-
-void LLTwitterPhotoPanel::updateResolution(BOOL do_update)
-{
- LLComboBox* combobox = static_cast<LLComboBox *>(mResolutionComboBox);
- LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
-
- std::string sdstring = combobox->getSelectedValue();
- LLSD sdres;
- std::stringstream sstream(sdstring);
- LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
-
- S32 width = sdres[0];
- S32 height = sdres[1];
-
- // Note : index 0 of the filter drop down is assumed to be "No filter" in whichever locale
- std::string filter_name = (filterbox->getCurrentIndex() ? filterbox->getSimple() : "");
-
- LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
- if (previewp && combobox->getCurrentIndex() >= 0)
- {
- S32 original_width = 0 , original_height = 0 ;
- previewp->getSize(original_width, original_height) ;
-
- if (width == 0 || height == 0)
- {
- // take resolution from current window size
- LL_DEBUGS() << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << LL_ENDL;
- previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
- }
- else
- {
- // use the resolution from the selected pre-canned drop-down choice
- LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
- previewp->setSize(width, height);
- }
-
- checkAspectRatio(width);
-
- previewp->getSize(width, height);
-
- if (original_width != width || original_height != height)
- {
- previewp->setSize(width, height);
- if (do_update)
- {
- previewp->updateSnapshot(TRUE);
- updateControls();
- }
- }
- // Get the old filter, compare to the current one "filter_name" and set if changed
- std::string original_filter = previewp->getFilter();
- if (original_filter != filter_name)
- {
- previewp->setFilter(filter_name);
- if (do_update)
- {
- previewp->updateSnapshot(FALSE, TRUE);
- updateControls();
- }
- }
- }
-}
-
-void LLTwitterPhotoPanel::checkAspectRatio(S32 index)
-{
- LLSnapshotLivePreview *previewp = getPreviewView() ;
-
- BOOL keep_aspect = FALSE;
-
- if (0 == index) // current window size
- {
- keep_aspect = TRUE;
- }
- else // predefined resolution
- {
- keep_aspect = FALSE;
- }
-
- if (previewp)
- {
- previewp->mKeepAspectRatio = keep_aspect;
- }
-}
-
-LLUICtrl* LLTwitterPhotoPanel::getRefreshBtn()
-{
- return mRefreshBtn;
-}
-
-///////////////////////////
-//LLTwitterAccountPanel//////
-///////////////////////////
-
-LLTwitterAccountPanel::LLTwitterAccountPanel() :
-mAccountCaptionLabel(NULL),
-mAccountNameLabel(NULL),
-mPanelButtons(NULL),
-mConnectButton(NULL),
-mDisconnectButton(NULL)
-{
- mCommitCallbackRegistrar.add("SocialSharing.Connect", boost::bind(&LLTwitterAccountPanel::onConnect, this));
- mCommitCallbackRegistrar.add("SocialSharing.Disconnect", boost::bind(&LLTwitterAccountPanel::onDisconnect, this));
-
- setVisibleCallback(boost::bind(&LLTwitterAccountPanel::onVisibilityChange, this, _2));
-}
-
-BOOL LLTwitterAccountPanel::postBuild()
-{
- mAccountCaptionLabel = getChild<LLTextBox>("account_caption_label");
- mAccountNameLabel = getChild<LLTextBox>("account_name_label");
- mPanelButtons = getChild<LLUICtrl>("panel_buttons");
- mConnectButton = getChild<LLUICtrl>("connect_btn");
- mDisconnectButton = getChild<LLUICtrl>("disconnect_btn");
-
- return LLPanel::postBuild();
-}
-
-void LLTwitterAccountPanel::draw()
-{
- LLTwitterConnect::EConnectionState connection_state = LLTwitterConnect::instance().getConnectionState();
-
- //Disable the 'disconnect' button and the 'use another account' button when disconnecting in progress
- bool disconnecting = connection_state == LLTwitterConnect::TWITTER_DISCONNECTING;
- mDisconnectButton->setEnabled(!disconnecting);
-
- //Disable the 'connect' button when a connection is in progress
- bool connecting = connection_state == LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS;
- mConnectButton->setEnabled(!connecting);
-
- LLPanel::draw();
-}
-
-void LLTwitterAccountPanel::onVisibilityChange(BOOL visible)
-{
- if(visible)
- {
- LLEventPumps::instance().obtain("TwitterConnectState").stopListening("LLTwitterAccountPanel");
- LLEventPumps::instance().obtain("TwitterConnectState").listen("LLTwitterAccountPanel", boost::bind(&LLTwitterAccountPanel::onTwitterConnectStateChange, this, _1));
-
- LLEventPumps::instance().obtain("TwitterConnectInfo").stopListening("LLTwitterAccountPanel");
- LLEventPumps::instance().obtain("TwitterConnectInfo").listen("LLTwitterAccountPanel", boost::bind(&LLTwitterAccountPanel::onTwitterConnectInfoChange, this));
-
- //Connected
- if(LLTwitterConnect::instance().isConnected())
- {
- showConnectedLayout();
- }
- //Check if connected (show disconnected layout in meantime)
- else
- {
- showDisconnectedLayout();
- }
- if ((LLTwitterConnect::instance().getConnectionState() == LLTwitterConnect::TWITTER_NOT_CONNECTED) ||
- (LLTwitterConnect::instance().getConnectionState() == LLTwitterConnect::TWITTER_CONNECTION_FAILED))
- {
- LLTwitterConnect::instance().checkConnectionToTwitter();
- }
- }
- else
- {
- LLEventPumps::instance().obtain("TwitterConnectState").stopListening("LLTwitterAccountPanel");
- LLEventPumps::instance().obtain("TwitterConnectInfo").stopListening("LLTwitterAccountPanel");
- }
-}
-
-bool LLTwitterAccountPanel::onTwitterConnectStateChange(const LLSD& data)
-{
- if(LLTwitterConnect::instance().isConnected())
- {
- //In process of disconnecting so leave the layout as is
- if(data.get("enum").asInteger() != LLTwitterConnect::TWITTER_DISCONNECTING)
- {
- showConnectedLayout();
- }
- }
- else
- {
- showDisconnectedLayout();
- }
-
- return false;
-}
-
-bool LLTwitterAccountPanel::onTwitterConnectInfoChange()
-{
- LLSD info = LLTwitterConnect::instance().getInfo();
- std::string clickable_name;
-
- //Strings of format [http://www.somewebsite.com Click Me] become clickable text
- if(info.has("link") && info.has("name"))
- {
- clickable_name = "[" + info["link"].asString() + " " + info["name"].asString() + "]";
- }
-
- mAccountNameLabel->setText(clickable_name);
-
- return false;
-}
-
-void LLTwitterAccountPanel::showConnectButton()
-{
- if(!mConnectButton->getVisible())
- {
- mConnectButton->setVisible(TRUE);
- mDisconnectButton->setVisible(FALSE);
- }
-}
-
-void LLTwitterAccountPanel::hideConnectButton()
-{
- if(mConnectButton->getVisible())
- {
- mConnectButton->setVisible(FALSE);
- mDisconnectButton->setVisible(TRUE);
- }
-}
-
-void LLTwitterAccountPanel::showDisconnectedLayout()
-{
- mAccountCaptionLabel->setText(getString("twitter_disconnected"));
- mAccountNameLabel->setText(std::string(""));
- showConnectButton();
-}
-
-void LLTwitterAccountPanel::showConnectedLayout()
-{
- LLTwitterConnect::instance().loadTwitterInfo();
-
- mAccountCaptionLabel->setText(getString("twitter_connected"));
- hideConnectButton();
-}
-
-void LLTwitterAccountPanel::onConnect()
-{
- LLTwitterConnect::instance().checkConnectionToTwitter(true);
-}
-
-void LLTwitterAccountPanel::onDisconnect()
-{
- LLTwitterConnect::instance().disconnectFromTwitter();
-}
-
-////////////////////////
-//LLFloaterTwitter///////
-////////////////////////
-
-LLFloaterTwitter::LLFloaterTwitter(const LLSD& key) : LLFloater(key),
- mTwitterPhotoPanel(NULL),
- mStatusErrorText(NULL),
- mStatusLoadingText(NULL),
- mStatusLoadingIndicator(NULL)
-{
- mCommitCallbackRegistrar.add("SocialSharing.Cancel", boost::bind(&LLFloaterTwitter::onCancel, this));
-}
-
-void LLFloaterTwitter::onClose(bool app_quitting)
-{
- LLFloaterBigPreview* big_preview_floater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
- if (big_preview_floater)
- {
- big_preview_floater->closeOnFloaterOwnerClosing(this);
- }
- LLFloater::onClose(app_quitting);
-}
-
-void LLFloaterTwitter::onCancel()
-{
- LLFloaterBigPreview* big_preview_floater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
- if (big_preview_floater)
- {
- big_preview_floater->closeOnFloaterOwnerClosing(this);
- }
- closeFloater();
-}
-
-BOOL LLFloaterTwitter::postBuild()
-{
- // Keep tab of the Photo Panel
- mTwitterPhotoPanel = static_cast<LLTwitterPhotoPanel*>(getChild<LLUICtrl>("panel_twitter_photo"));
- // Connection status widgets
- mStatusErrorText = getChild<LLTextBox>("connection_error_text");
- mStatusLoadingText = getChild<LLTextBox>("connection_loading_text");
- mStatusLoadingIndicator = getChild<LLUICtrl>("connection_loading_indicator");
- return LLFloater::postBuild();
-}
-
-void LLFloaterTwitter::showPhotoPanel()
-{
- LLTabContainer* parent = dynamic_cast<LLTabContainer*>(mTwitterPhotoPanel->getParent());
- if (!parent)
- {
- LL_WARNS() << "Cannot find panel container" << LL_ENDL;
- return;
- }
-
- parent->selectTabPanel(mTwitterPhotoPanel);
-}
-
-void LLFloaterTwitter::draw()
-{
- if (mStatusErrorText && mStatusLoadingText && mStatusLoadingIndicator)
- {
- mStatusErrorText->setVisible(false);
- mStatusLoadingText->setVisible(false);
- mStatusLoadingIndicator->setVisible(false);
- LLTwitterConnect::EConnectionState connection_state = LLTwitterConnect::instance().getConnectionState();
- std::string status_text;
-
- switch (connection_state)
- {
- case LLTwitterConnect::TWITTER_NOT_CONNECTED:
- // No status displayed when first opening the panel and no connection done
- case LLTwitterConnect::TWITTER_CONNECTED:
- // When successfully connected, no message is displayed
- case LLTwitterConnect::TWITTER_POSTED:
- // No success message to show since we actually close the floater after successful posting completion
- break;
- case LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS:
- // Connection loading indicator
- mStatusLoadingText->setVisible(true);
- status_text = LLTrans::getString("SocialTwitterConnecting");
- mStatusLoadingText->setValue(status_text);
- mStatusLoadingIndicator->setVisible(true);
- break;
- case LLTwitterConnect::TWITTER_POSTING:
- // Posting indicator
- mStatusLoadingText->setVisible(true);
- status_text = LLTrans::getString("SocialTwitterPosting");
- mStatusLoadingText->setValue(status_text);
- mStatusLoadingIndicator->setVisible(true);
- break;
- case LLTwitterConnect::TWITTER_CONNECTION_FAILED:
- // Error connecting to the service
- mStatusErrorText->setVisible(true);
- status_text = LLTrans::getString("SocialTwitterErrorConnecting");
- mStatusErrorText->setValue(status_text);
- break;
- case LLTwitterConnect::TWITTER_POST_FAILED:
- // Error posting to the service
- mStatusErrorText->setVisible(true);
- status_text = LLTrans::getString("SocialTwitterErrorPosting");
- mStatusErrorText->setValue(status_text);
- break;
- case LLTwitterConnect::TWITTER_DISCONNECTING:
- // Disconnecting loading indicator
- mStatusLoadingText->setVisible(true);
- status_text = LLTrans::getString("SocialTwitterDisconnecting");
- mStatusLoadingText->setValue(status_text);
- mStatusLoadingIndicator->setVisible(true);
- break;
- case LLTwitterConnect::TWITTER_DISCONNECT_FAILED:
- // Error disconnecting from the service
- mStatusErrorText->setVisible(true);
- status_text = LLTrans::getString("SocialTwitterErrorDisconnecting");
- mStatusErrorText->setValue(status_text);
- break;
- }
- }
- LLFloater::draw();
-}
-
diff --git a/indra/newview/llfloatertwitter.h b/indra/newview/llfloatertwitter.h
deleted file mode 100644
index d586799d18..0000000000
--- a/indra/newview/llfloatertwitter.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
-* @file llfloatertwitter.h
-* @brief Header file for llfloatertwitter
-* @author cho@lindenlab.com
-*
-* $LicenseInfo:firstyear=2013&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2013, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
-* $/LicenseInfo$
-*/
-#ifndef LL_LLFLOATERTWITTER_H
-#define LL_LLFLOATERTWITTER_H
-
-#include "llfloater.h"
-#include "lltextbox.h"
-#include "llviewertexture.h"
-
-class LLIconCtrl;
-class LLCheckBoxCtrl;
-class LLSnapshotLivePreview;
-class LLFloaterBigPreview;
-
-class LLTwitterPhotoPanel : public LLPanel
-{
-public:
- LLTwitterPhotoPanel();
- ~LLTwitterPhotoPanel();
-
- BOOL postBuild();
- void draw();
-
- LLSnapshotLivePreview* getPreviewView();
- void onVisibilityChange(BOOL new_visibility);
- void onAddLocationToggled();
- void onAddPhotoToggled();
- void onClickBigPreview();
- void onClickNewSnapshot();
- void onSend();
- S32 notify(const LLSD& info);
- bool onTwitterConnectStateChange(const LLSD& data);
-
- void sendPhoto();
- void clearAndClose();
-
- void updateStatusTextLength(BOOL restore_old_status_text);
- void updateControls();
- void updateResolution(BOOL do_update);
- void checkAspectRatio(S32 index);
- LLUICtrl* getRefreshBtn();
-
-private:
- bool isPreviewVisible();
- void attachPreview();
-
- LLHandle<LLView> mPreviewHandle;
-
- LLUICtrl * mResolutionComboBox;
- LLUICtrl * mFilterComboBox;
- LLUICtrl * mRefreshBtn;
- LLUICtrl * mWorkingLabel;
- LLUICtrl * mThumbnailPlaceholder;
- LLUICtrl * mStatusCounterLabel;
- LLUICtrl * mStatusTextBox;
- LLUICtrl * mLocationCheckbox;
- LLUICtrl * mPhotoCheckbox;
- LLUICtrl * mPostButton;
- LLUICtrl * mCancelButton;
- LLButton * mBtnPreview;
-
- LLFloaterBigPreview * mBigPreviewFloater;
-
- std::string mOldStatusText;
-};
-
-class LLTwitterAccountPanel : public LLPanel
-{
-public:
- LLTwitterAccountPanel();
- BOOL postBuild();
- void draw();
-
-private:
- void onVisibilityChange(BOOL new_visibility);
- bool onTwitterConnectStateChange(const LLSD& data);
- bool onTwitterConnectInfoChange();
- void onConnect();
- void onUseAnotherAccount();
- void onDisconnect();
-
- void showConnectButton();
- void hideConnectButton();
- void showDisconnectedLayout();
- void showConnectedLayout();
-
- LLTextBox * mAccountCaptionLabel;
- LLTextBox * mAccountNameLabel;
- LLUICtrl * mPanelButtons;
- LLUICtrl * mConnectButton;
- LLUICtrl * mDisconnectButton;
-};
-
-
-class LLFloaterTwitter : public LLFloater
-{
-public:
- LLFloaterTwitter(const LLSD& key);
- BOOL postBuild();
- void draw();
- void onClose(bool app_quitting);
- void onCancel();
-
- void showPhotoPanel();
-
-private:
- LLTwitterPhotoPanel* mTwitterPhotoPanel;
- LLTextBox* mStatusErrorText;
- LLTextBox* mStatusLoadingText;
- LLUICtrl* mStatusLoadingIndicator;
-};
-
-#endif // LL_LLFLOATERTWITTER_H
-
diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp
index c591dfacaf..23fd6d9c8e 100644
--- a/indra/newview/llfloaterwebcontent.cpp
+++ b/indra/newview/llfloaterwebcontent.cpp
@@ -30,8 +30,6 @@
#include "lliconctrl.h"
#include "llfloaterreg.h"
#include "llhttpconstants.h"
-#include "llflickrconnect.h"
-#include "lltwitterconnect.h"
#include "lllayoutstack.h"
#include "llpluginclassmedia.h"
#include "llprogressbar.h"
@@ -288,26 +286,6 @@ void LLFloaterWebContent::onOpen(const LLSD& key)
//virtual
void LLFloaterWebContent::onClose(bool app_quitting)
{
- // If we close the web browsing window showing the Flickr login, we need to signal to this object that the connection will not happen
- // MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
- LLFloater* flickr_web = LLFloaterReg::findInstance("flickr_web");
- if (flickr_web == this)
- {
- if (!LLFlickrConnect::instance().isConnected())
- {
- LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
- }
- }
- // Same with Twitter
- // MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
- LLFloater* twitter_web = LLFloaterReg::findInstance("twitter_web");
- if (twitter_web == this)
- {
- if (!LLTwitterConnect::instance().isConnected())
- {
- LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
- }
- }
LLViewerMedia::getInstance()->proxyWindowClosed(mUUID);
destroy();
}
diff --git a/indra/newview/llhudeffectbeam.cpp b/indra/newview/llhudeffectbeam.cpp
index 54e683e048..d1d83e6e03 100644
--- a/indra/newview/llhudeffectbeam.cpp
+++ b/indra/newview/llhudeffectbeam.cpp
@@ -90,7 +90,7 @@ void LLHUDEffectBeam::packData(LLMessageSystem *mesgsys)
memset(packed_data, 0, 41);
if (mSourceObject)
{
- htonmemcpy(packed_data, mSourceObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(packed_data, mSourceObject->mID.mData, MVT_LLUUID, 16);
}
if (mTargetObject)
@@ -104,11 +104,11 @@ void LLHUDEffectBeam::packData(LLMessageSystem *mesgsys)
if (mTargetObject)
{
- htonmemcpy(&(packed_data[17]), mTargetObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[17]), mTargetObject->mID.mData, MVT_LLUUID, 16);
}
else
{
- htonmemcpy(&(packed_data[17]), mTargetPos.mdV, MVT_LLVector3d, 24);
+ htolememcpy(&(packed_data[17]), mTargetPos.mdV, MVT_LLVector3d, 24);
}
mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41);
}
@@ -131,7 +131,7 @@ void LLHUDEffectBeam::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
}
mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 41, blocknum);
- htonmemcpy(source_id.mData, packed_data, MVT_LLUUID, 16);
+ htolememcpy(source_id.mData, packed_data, MVT_LLUUID, 16);
LLViewerObject *objp = gObjectList.findObject(source_id);
if (objp)
@@ -143,7 +143,7 @@ void LLHUDEffectBeam::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
if (use_target_object)
{
- htonmemcpy(target_id.mData, &packed_data[17], MVT_LLUUID, 16);
+ htolememcpy(target_id.mData, &packed_data[17], MVT_LLUUID, 16);
LLViewerObject *objp = gObjectList.findObject(target_id);
if (objp)
@@ -153,7 +153,7 @@ void LLHUDEffectBeam::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
}
else
{
- htonmemcpy(new_target.mdV, &(packed_data[17]), MVT_LLVector3d, 24);
+ htolememcpy(new_target.mdV, &(packed_data[17]), MVT_LLVector3d, 24);
setTargetPos(new_target);
}
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index f46152dcec..6898dce7b1 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -269,29 +269,29 @@ void LLHUDEffectLookAt::packData(LLMessageSystem *mesgsys)
if (mSourceObject)
{
- htonmemcpy(&(packed_data[SOURCE_AVATAR]), mSourceObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[SOURCE_AVATAR]), mSourceObject->mID.mData, MVT_LLUUID, 16);
}
else
{
- htonmemcpy(&(packed_data[SOURCE_AVATAR]), LLUUID::null.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[SOURCE_AVATAR]), LLUUID::null.mData, MVT_LLUUID, 16);
}
// pack both target object and position
// position interpreted as offset if target object is non-null
if (mTargetObject)
{
- htonmemcpy(&(packed_data[TARGET_OBJECT]), mTargetObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[TARGET_OBJECT]), mTargetObject->mID.mData, MVT_LLUUID, 16);
}
else
{
- htonmemcpy(&(packed_data[TARGET_OBJECT]), LLUUID::null.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[TARGET_OBJECT]), LLUUID::null.mData, MVT_LLUUID, 16);
}
- htonmemcpy(&(packed_data[TARGET_POS]), mTargetOffsetGlobal.mdV, MVT_LLVector3d, 24);
+ htolememcpy(&(packed_data[TARGET_POS]), mTargetOffsetGlobal.mdV, MVT_LLVector3d, 24);
U8 lookAtTypePacked = (U8)mTargetType;
- htonmemcpy(&(packed_data[LOOKAT_TYPE]), &lookAtTypePacked, MVT_U8, 1);
+ htolememcpy(&(packed_data[LOOKAT_TYPE]), &lookAtTypePacked, MVT_U8, 1);
mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, PKT_SIZE);
@@ -325,7 +325,7 @@ void LLHUDEffectLookAt::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
}
mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, PKT_SIZE, blocknum);
- htonmemcpy(source_id.mData, &(packed_data[SOURCE_AVATAR]), MVT_LLUUID, 16);
+ htolememcpy(source_id.mData, &(packed_data[SOURCE_AVATAR]), MVT_LLUUID, 16);
LLViewerObject *objp = gObjectList.findObject(source_id);
if (objp && objp->isAvatar())
@@ -338,11 +338,11 @@ void LLHUDEffectLookAt::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
return;
}
- htonmemcpy(target_id.mData, &(packed_data[TARGET_OBJECT]), MVT_LLUUID, 16);
+ htolememcpy(target_id.mData, &(packed_data[TARGET_OBJECT]), MVT_LLUUID, 16);
objp = gObjectList.findObject(target_id);
- htonmemcpy(new_target.mdV, &(packed_data[TARGET_POS]), MVT_LLVector3d, 24);
+ htolememcpy(new_target.mdV, &(packed_data[TARGET_POS]), MVT_LLVector3d, 24);
if (objp)
{
@@ -358,7 +358,7 @@ void LLHUDEffectLookAt::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
}
U8 lookAtTypeUnpacked = 0;
- htonmemcpy(&lookAtTypeUnpacked, &(packed_data[LOOKAT_TYPE]), MVT_U8, 1);
+ htolememcpy(&lookAtTypeUnpacked, &(packed_data[LOOKAT_TYPE]), MVT_U8, 1);
mTargetType = (ELookAtType)lookAtTypeUnpacked;
if (mTargetType == LOOKAT_TARGET_NONE)
diff --git a/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp
index cc772c8f5c..ecf6d42d69 100644
--- a/indra/newview/llhudeffectpointat.cpp
+++ b/indra/newview/llhudeffectpointat.cpp
@@ -107,28 +107,28 @@ void LLHUDEffectPointAt::packData(LLMessageSystem *mesgsys)
if (mSourceObject)
{
- htonmemcpy(&(packed_data[SOURCE_AVATAR]), mSourceObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[SOURCE_AVATAR]), mSourceObject->mID.mData, MVT_LLUUID, 16);
}
else
{
- htonmemcpy(&(packed_data[SOURCE_AVATAR]), LLUUID::null.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[SOURCE_AVATAR]), LLUUID::null.mData, MVT_LLUUID, 16);
}
// pack both target object and position
// position interpreted as offset if target object is non-null
if (mTargetObject)
{
- htonmemcpy(&(packed_data[TARGET_OBJECT]), mTargetObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[TARGET_OBJECT]), mTargetObject->mID.mData, MVT_LLUUID, 16);
}
else
{
- htonmemcpy(&(packed_data[TARGET_OBJECT]), LLUUID::null.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[TARGET_OBJECT]), LLUUID::null.mData, MVT_LLUUID, 16);
}
- htonmemcpy(&(packed_data[TARGET_POS]), mTargetOffsetGlobal.mdV, MVT_LLVector3d, 24);
+ htolememcpy(&(packed_data[TARGET_POS]), mTargetOffsetGlobal.mdV, MVT_LLVector3d, 24);
U8 pointAtTypePacked = (U8)mTargetType;
- htonmemcpy(&(packed_data[POINTAT_TYPE]), &pointAtTypePacked, MVT_U8, 1);
+ htolememcpy(&(packed_data[POINTAT_TYPE]), &pointAtTypePacked, MVT_U8, 1);
mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, PKT_SIZE);
@@ -164,10 +164,10 @@ void LLHUDEffectPointAt::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
}
mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, PKT_SIZE, blocknum);
- htonmemcpy(source_id.mData, &(packed_data[SOURCE_AVATAR]), MVT_LLUUID, 16);
- htonmemcpy(target_id.mData, &(packed_data[TARGET_OBJECT]), MVT_LLUUID, 16);
- htonmemcpy(new_target.mdV, &(packed_data[TARGET_POS]), MVT_LLVector3d, 24);
- htonmemcpy(&pointAtTypeUnpacked, &(packed_data[POINTAT_TYPE]), MVT_U8, 1);
+ htolememcpy(source_id.mData, &(packed_data[SOURCE_AVATAR]), MVT_LLUUID, 16);
+ htolememcpy(target_id.mData, &(packed_data[TARGET_OBJECT]), MVT_LLUUID, 16);
+ htolememcpy(new_target.mdV, &(packed_data[TARGET_POS]), MVT_LLVector3d, 24);
+ htolememcpy(&pointAtTypeUnpacked, &(packed_data[POINTAT_TYPE]), MVT_U8, 1);
LLViewerObject *objp = gObjectList.findObject(source_id);
if (objp && objp->isAvatar())
diff --git a/indra/newview/llhudeffecttrail.cpp b/indra/newview/llhudeffecttrail.cpp
index fc6efdb840..2ba8aa422b 100644
--- a/indra/newview/llhudeffecttrail.cpp
+++ b/indra/newview/llhudeffecttrail.cpp
@@ -87,15 +87,15 @@ void LLHUDEffectSpiral::packData(LLMessageSystem *mesgsys)
if (mSourceObject)
{
- htonmemcpy(packed_data, mSourceObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(packed_data, mSourceObject->mID.mData, MVT_LLUUID, 16);
}
if (mTargetObject)
{
- htonmemcpy(packed_data + 16, mTargetObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(packed_data + 16, mTargetObject->mID.mData, MVT_LLUUID, 16);
}
if (!mPositionGlobal.isExactlyZero())
{
- htonmemcpy(packed_data + 32, mPositionGlobal.mdV, MVT_LLVector3d, 24);
+ htolememcpy(packed_data + 32, mPositionGlobal.mdV, MVT_LLVector3d, 24);
}
mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 56);
}
@@ -116,9 +116,9 @@ void LLHUDEffectSpiral::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData,
packed_data, EFFECT_SIZE, blocknum, EFFECT_SIZE);
- htonmemcpy(object_id.mData, packed_data, MVT_LLUUID, 16);
- htonmemcpy(target_object_id.mData, packed_data + 16, MVT_LLUUID, 16);
- htonmemcpy(mPositionGlobal.mdV, packed_data + 32, MVT_LLVector3d, 24);
+ htolememcpy(object_id.mData, packed_data, MVT_LLUUID, 16);
+ htolememcpy(target_object_id.mData, packed_data + 16, MVT_LLUUID, 16);
+ htolememcpy(mPositionGlobal.mdV, packed_data + 32, MVT_LLVector3d, 24);
LLViewerObject *objp = NULL;
diff --git a/indra/newview/llimagefiltersmanager.cpp b/indra/newview/llimagefiltersmanager.cpp
index c23cdc8103..3b8adc1610 100644
--- a/indra/newview/llimagefiltersmanager.cpp
+++ b/indra/newview/llimagefiltersmanager.cpp
@@ -1,6 +1,6 @@
/**
* @file llimagefiltersmanager.cpp
- * @brief Load image filters list and retrieve their path. Mostly used for Flickr UI at the moment.
+ * @brief Load image filters list and retrieve their path.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/llimagefiltersmanager.h b/indra/newview/llimagefiltersmanager.h
index f1ed3cf1c3..d06212d85a 100644
--- a/indra/newview/llimagefiltersmanager.h
+++ b/indra/newview/llimagefiltersmanager.h
@@ -1,6 +1,6 @@
/**
* @file llimagefiltersmanager.h
- * @brief Load image filters list and retrieve their path. Mostly used for Flickr UI at the moment.
+ * @brief Load image filters list and retrieve their path.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index 3606a439a6..e3705e82b9 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -715,7 +715,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
{
info = new LLOfferInfo();
- info->mIM = IM_GROUP_NOTICE;
+ info->mIM = dialog;
info->mFromID = from_id;
info->mFromGroup = from_group;
info->mTransactionID = session_id;
@@ -896,12 +896,18 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
if (is_muted)
{
// Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331)
- LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
- fetch_item->startFetch();
- delete fetch_item;
-
- // Same as closing window
- info->forceResponse(IOR_DECLINE);
+ if (IM_INVENTORY_OFFERED == dialog)
+ {
+ LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
+ fetch_item->startFetch();
+ delete fetch_item;
+ // Same as closing window
+ info->forceResponse(IOR_DECLINE);
+ }
+ else
+ {
+ info->forceResponse(IOR_MUTE);
+ }
}
// old logic: busy mode must not affect interaction with objects (STORM-565)
// new logic: inventory offers from in-world objects should be auto-declined (CHUI-519)
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 349ba6183b..6d2d533c9d 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -4662,7 +4662,7 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
{
LLInventoryObject::object_list_t inventory_objects;
object->getInventoryContents(inventory_objects);
- int contents_count = inventory_objects.size()-1; //subtract one for containing folder
+ int contents_count = inventory_objects.size();
LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count, cat_and_wear->mFolderResponded,
cat_and_wear->mReplace);
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 16385928b4..e8bc915f22 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -42,7 +42,7 @@
#include "llviewerfoldertype.h"
#include "llradiogroup.h"
#include "llstartup.h"
-
+#include <boost/regex.hpp>
// linden library includes
#include "llclipboard.h"
#include "lltrans.h"
@@ -116,7 +116,39 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item)
break;
}
- bool passed = (mFilterSubString.size() ? desc.find(mFilterSubString) != std::string::npos : true);
+
+ bool passed = true;
+ if (!mExactToken.empty() && (mSearchType == SEARCHTYPE_NAME))
+ {
+ passed = false;
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep(" ");
+ tokenizer tokens(desc, sep);
+
+ for (auto token_iter : tokens)
+ {
+ if (token_iter == mExactToken)
+ {
+ passed = true;
+ break;
+ }
+ }
+ }
+ else if ((mFilterTokens.size() > 0) && (mSearchType == SEARCHTYPE_NAME))
+ {
+ for (auto token_iter : mFilterTokens)
+ {
+ if (desc.find(token_iter) == std::string::npos)
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ passed = (mFilterSubString.size() ? desc.find(mFilterSubString) != std::string::npos : true);
+ }
+
passed = passed && checkAgainstFilterType(listener);
passed = passed && checkAgainstPermissions(listener);
passed = passed && checkAgainstFilterLinks(listener);
@@ -693,6 +725,38 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
if (mFilterSubString != filter_sub_string_new)
{
+
+ mFilterTokens.clear();
+ if (filter_sub_string_new.find_first_of("+") != std::string::npos)
+ {
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep("+");
+ tokenizer tokens(filter_sub_string_new, sep);
+
+ for (auto token_iter : tokens)
+ {
+ mFilterTokens.push_back(token_iter);
+ }
+ }
+
+ std::string old_token = mExactToken;
+ mExactToken.clear();
+ bool exact_token_changed = false;
+ if (mFilterTokens.empty() && filter_sub_string_new.size() > 2)
+ {
+ boost::regex mPattern = boost::regex("\"\\s*([^<]*)?\\s*\"",
+ boost::regex::perl | boost::regex::icase);
+ boost::match_results<std::string::const_iterator> matches;
+ mExactToken = (boost::regex_match(filter_sub_string_new, matches, mPattern) && matches[1].matched)
+ ? matches[1]
+ : LLStringUtil::null;
+ if ((old_token.empty() && !mExactToken.empty())
+ || (!old_token.empty() && mExactToken.empty()))
+ {
+ exact_token_changed = true;
+ }
+ }
+
// hitting BACKSPACE, for example
const BOOL less_restrictive = mFilterSubString.size() >= filter_sub_string_new.size()
&& !mFilterSubString.substr(0, filter_sub_string_new.size()).compare(filter_sub_string_new);
@@ -702,7 +766,11 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
&& !filter_sub_string_new.substr(0, mFilterSubString.size()).compare(mFilterSubString);
mFilterSubString = filter_sub_string_new;
- if (less_restrictive)
+ if (exact_token_changed)
+ {
+ setModified(FILTER_RESTART);
+ }
+ else if (less_restrictive)
{
setModified(FILTER_LESS_RESTRICTIVE);
}
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 4a1fec8454..3f24211f41 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -327,6 +327,9 @@ private:
std::string mEmptyLookupMessage;
ESearchType mSearchType;
+
+ std::vector<std::string> mFilterTokens;
+ std::string mExactToken;
};
#endif
diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp
index b405d3dca2..6a79a0c68c 100644
--- a/indra/newview/llnotificationlistitem.cpp
+++ b/indra/newview/llnotificationlistitem.cpp
@@ -262,6 +262,7 @@ std::set<std::string> LLTransactionNotificationListItem::getTypes()
std::set<std::string> types;
types.insert("PaymentReceived");
types.insert("PaymentSent");
+ types.insert("UploadPayment");
return types;
}
diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp
index 23747a8efd..1a3e946127 100644
--- a/indra/newview/llpanelsnapshotoptions.cpp
+++ b/indra/newview/llpanelsnapshotoptions.cpp
@@ -32,8 +32,6 @@
#include "llfloatersnapshot.h" // FIXME: create a snapshot model
#include "llfloaterreg.h"
-#include "llfloaterflickr.h"
-#include "llfloatertwitter.h"
/**
* Provides several ways to save a snapshot.
@@ -58,8 +56,6 @@ private:
void onSaveToEmail();
void onSaveToInventory();
void onSaveToComputer();
- void onSendToTwitter();
- void onSendToFlickr();
LLFloaterSnapshotBase* mSnapshotFloater;
};
@@ -72,8 +68,7 @@ LLPanelSnapshotOptions::LLPanelSnapshotOptions()
mCommitCallbackRegistrar.add("Snapshot.SaveToEmail", boost::bind(&LLPanelSnapshotOptions::onSaveToEmail, this));
mCommitCallbackRegistrar.add("Snapshot.SaveToInventory", boost::bind(&LLPanelSnapshotOptions::onSaveToInventory, this));
mCommitCallbackRegistrar.add("Snapshot.SaveToComputer", boost::bind(&LLPanelSnapshotOptions::onSaveToComputer, this));
- mCommitCallbackRegistrar.add("Snapshot.SendToTwitter", boost::bind(&LLPanelSnapshotOptions::onSendToTwitter, this));
- mCommitCallbackRegistrar.add("Snapshot.SendToFlickr", boost::bind(&LLPanelSnapshotOptions::onSendToFlickr, this));
+
LLGlobalEconomy::getInstance()->addObserver(this);
}
@@ -135,26 +130,3 @@ void LLPanelSnapshotOptions::onSaveToComputer()
openPanel("panel_snapshot_local");
}
-void LLPanelSnapshotOptions::onSendToTwitter()
-{
- LLFloaterReg::hideInstance("snapshot");
-
- LLFloaterTwitter* twitter_floater = dynamic_cast<LLFloaterTwitter*>(LLFloaterReg::getInstance("twitter"));
- if (twitter_floater)
- {
- twitter_floater->showPhotoPanel();
- }
- LLFloaterReg::showInstance("twitter");
-}
-
-void LLPanelSnapshotOptions::onSendToFlickr()
-{
- LLFloaterReg::hideInstance("snapshot");
-
- LLFloaterFlickr* flickr_floater = dynamic_cast<LLFloaterFlickr*>(LLFloaterReg::getInstance("flickr"));
- if (flickr_floater)
- {
- flickr_floater->showPhotoPanel();
- }
- LLFloaterReg::showInstance("flickr");
-}
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 90f8f84ea4..f849fecaf6 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -153,6 +153,53 @@ struct LLDeRezInfo
// Imports
//
+//-----------------------------------------------------------------------------
+// ~LLSelectionCallbackData()
+//-----------------------------------------------------------------------------
+
+LLSelectionCallbackData::LLSelectionCallbackData()
+{
+ LLSelectMgr *instance = LLSelectMgr::getInstance();
+ LLObjectSelectionHandle selection = instance->getSelection();
+ if (!selection->getNumNodes())
+ {
+ return;
+ }
+ mSelectedObjects = new LLObjectSelection();
+
+ for (LLObjectSelection::iterator iter = selection->begin();
+ iter != selection->end();)
+ {
+ LLObjectSelection::iterator curiter = iter++;
+
+ LLSelectNode *nodep = *curiter;
+ LLViewerObject* objectp = nodep->getObject();
+
+ if (!objectp)
+ {
+ mSelectedObjects->mSelectType = SELECT_TYPE_WORLD;
+ }
+ else
+ {
+ LLSelectNode* new_nodep = new LLSelectNode(*nodep);
+ mSelectedObjects->addNode(new_nodep);
+
+ if (objectp->isHUDAttachment())
+ {
+ mSelectedObjects->mSelectType = SELECT_TYPE_HUD;
+ }
+ else if (objectp->isAttachment())
+ {
+ mSelectedObjects->mSelectType = SELECT_TYPE_ATTACHMENT;
+ }
+ else
+ {
+ mSelectedObjects->mSelectType = SELECT_TYPE_WORLD;
+ }
+ }
+ }
+}
+
//
// Functions
@@ -4119,20 +4166,20 @@ void LLSelectMgr::packMultipleUpdate(LLSelectNode* node, void *user_data)
if (type & UPD_POSITION)
{
- htonmemcpy(&data[offset], &(object->getPosition().mV), MVT_LLVector3, 12);
+ htolememcpy(&data[offset], &(object->getPosition().mV), MVT_LLVector3, 12);
offset += 12;
}
if (type & UPD_ROTATION)
{
LLQuaternion quat = object->getRotation();
LLVector3 vec = quat.packToVector3();
- htonmemcpy(&data[offset], &(vec.mV), MVT_LLQuaternion, 12);
+ htolememcpy(&data[offset], &(vec.mV), MVT_LLQuaternion, 12);
offset += 12;
}
if (type & UPD_SCALE)
{
//LL_INFOS() << "Sending object scale " << object->getScale() << LL_ENDL;
- htonmemcpy(&data[offset], &(object->getScale().mV), MVT_LLVector3, 12);
+ htolememcpy(&data[offset], &(object->getScale().mV), MVT_LLVector3, 12);
offset += 12;
}
gMessageSystem->addBinaryDataFast(_PREHASH_Data, data, offset);
@@ -4475,9 +4522,19 @@ void LLSelectMgr::selectionSetObjectSaleInfo(const LLSaleInfo& sale_info)
void LLSelectMgr::sendAttach(U8 attachment_point, bool replace)
{
- LLViewerObject* attach_object = mSelectedObjects->getFirstRootObject();
+ sendAttach(mSelectedObjects, attachment_point, replace);
+}
+
+void LLSelectMgr::sendAttach(LLObjectSelectionHandle selection_handle, U8 attachment_point, bool replace)
+{
+ if (selection_handle.isNull())
+ {
+ return;
+ }
- if (!attach_object || !isAgentAvatarValid() || mSelectedObjects->mSelectType != SELECT_TYPE_WORLD)
+ LLViewerObject* attach_object = selection_handle->getFirstRootObject();
+
+ if (!attach_object || !isAgentAvatarValid() || selection_handle->mSelectType != SELECT_TYPE_WORLD)
{
return;
}
@@ -4495,6 +4552,7 @@ void LLSelectMgr::sendAttach(U8 attachment_point, bool replace)
}
sendListToRegions(
+ selection_handle,
"ObjectAttach",
packAgentIDAndSessionAndAttachment,
packObjectIDAndRotation,
@@ -4506,6 +4564,7 @@ void LLSelectMgr::sendAttach(U8 attachment_point, bool replace)
// After "ObjectAttach" server will unsubscribe us from properties updates
// so either deselect objects or resend selection after attach packet reaches server
// In case of build_mode LLPanelObjectInventory::refresh() will deal with selection
+ // Still unsubscribe even in case selection_handle is not current selection
deselectAll();
}
}
@@ -5047,7 +5106,17 @@ void LLSelectMgr::packPermissions(LLSelectNode* node, void *user_data)
void LLSelectMgr::sendListToRegions(const std::string& message_name,
void (*pack_header)(void *user_data),
void (*pack_body)(LLSelectNode* node, void *user_data),
- void (*log_func)(LLSelectNode* node, void *user_data),
+ void (*log_func)(LLSelectNode* node, void *user_data),
+ void *user_data,
+ ESendType send_type)
+{
+ sendListToRegions(mSelectedObjects, message_name, pack_header, pack_body, log_func, user_data, send_type);
+}
+void LLSelectMgr::sendListToRegions(LLObjectSelectionHandle selected_handle,
+ const std::string& message_name,
+ void (*pack_header)(void *user_data),
+ void (*pack_body)(LLSelectNode* node, void *user_data),
+ void (*log_func)(LLSelectNode* node, void *user_data),
void *user_data,
ESendType send_type)
{
@@ -5073,7 +5142,7 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name,
return true;
}
} func;
- getSelection()->applyToNodes(&func);
+ selected_handle->applyToNodes(&func);
std::queue<LLSelectNode*> nodes_to_send;
@@ -5116,25 +5185,25 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name,
{
case SEND_ONLY_ROOTS:
if(message_name == "ObjectBuy")
- getSelection()->applyToRootNodes(&pushroots);
+ selected_handle->applyToRootNodes(&pushroots);
else
- getSelection()->applyToRootNodes(&pushall);
+ selected_handle->applyToRootNodes(&pushall);
break;
case SEND_INDIVIDUALS:
- getSelection()->applyToNodes(&pushall);
+ selected_handle->applyToNodes(&pushall);
break;
case SEND_ROOTS_FIRST:
// first roots...
- getSelection()->applyToNodes(&pushroots);
+ selected_handle->applyToNodes(&pushroots);
// then children...
- getSelection()->applyToNodes(&pushnonroots);
+ selected_handle->applyToNodes(&pushnonroots);
break;
case SEND_CHILDREN_FIRST:
// first children...
- getSelection()->applyToNodes(&pushnonroots);
+ selected_handle->applyToNodes(&pushnonroots);
// then roots...
- getSelection()->applyToNodes(&pushroots);
+ selected_handle->applyToNodes(&pushroots);
break;
default:
@@ -6686,8 +6755,7 @@ void LLSelectMgr::updateSelectionCenter()
if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && isAgentAvatarValid())
{
// reset hud ZOOM
- gAgentCamera.mHUDTargetZoom = 1.f;
- gAgentCamera.mHUDCurZoom = 1.f;
+ resetAgentHUDZoom();
}
mShowSelection = FALSE;
@@ -7060,8 +7128,11 @@ BOOL LLSelectMgr::setForceSelection(BOOL force)
void LLSelectMgr::resetAgentHUDZoom()
{
- gAgentCamera.mHUDTargetZoom = 1.f;
- gAgentCamera.mHUDCurZoom = 1.f;
+ if (gAgentCamera.mHUDTargetZoom != 1)
+ {
+ gAgentCamera.mHUDTargetZoom = 1.f;
+ gAgentCamera.mHUDCurZoom = 1.f;
+ }
}
void LLSelectMgr::getAgentHUDZoom(F32 &target_zoom, F32 &current_zoom) const
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 3e8bfdb00e..3bed484b58 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -239,6 +239,7 @@ class LLObjectSelection : public LLRefCount
{
friend class LLSelectMgr;
friend class LLSafeHandle<LLObjectSelection>;
+ friend class LLSelectionCallbackData;
protected:
~LLObjectSelection();
@@ -396,6 +397,16 @@ extern template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance()
// For use with getFirstTest()
struct LLSelectGetFirstTest;
+// temporary storage, Ex: to attach objects after autopilot
+class LLSelectionCallbackData
+{
+public:
+ LLSelectionCallbackData();
+ LLObjectSelectionHandle getSelection() { return mSelectedObjects; }
+private:
+ LLObjectSelectionHandle mSelectedObjects;
+};
+
class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
{
LLSINGLETON(LLSelectMgr);
@@ -740,6 +751,7 @@ public:
// canceled
void sendBuy(const LLUUID& buyer_id, const LLUUID& category_id, const LLSaleInfo sale_info);
void sendAttach(U8 attachment_point, bool replace);
+ void sendAttach(LLObjectSelectionHandle selection_handle, U8 attachment_point, bool replace);
void sendDetach();
void sendDropAttachment();
void sendLink();
@@ -787,6 +799,13 @@ private:
void (*log_func)(LLSelectNode* node, void *user_data),
void *user_data,
ESendType send_type);
+ void sendListToRegions( LLObjectSelectionHandle selected_handle,
+ const std::string& message_name,
+ void (*pack_header)(void *user_data),
+ void (*pack_body)(LLSelectNode* node, void *user_data),
+ void (*log_func)(LLSelectNode* node, void *user_data),
+ void *user_data,
+ ESendType send_type);
static void packAgentID( void *);
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 4ebcffa554..6e2b4a00fc 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -485,7 +485,7 @@ void LLSidepanelAppearance::fetchInventory()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject* attached_object = (*attachment_iter);
+ LLViewerObject* attached_object = attachment_iter->get();
if (!attached_object) continue;
const LLUUID& item_id = attached_object->getAttachmentItemID();
if (item_id.isNull()) continue;
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index 2503e2a5e2..d508621b41 100644
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -49,6 +49,29 @@
#include "llviewerregion.h"
+class PropertiesChangedCallback : public LLInventoryCallback
+{
+public:
+ PropertiesChangedCallback(LLHandle<LLPanel> sidepanel_handle, LLUUID &item_id, S32 id)
+ : mHandle(sidepanel_handle), mItemId(item_id), mId(id)
+ {}
+
+ void fire(const LLUUID &inv_item)
+ {
+ // inv_item can be null for some reason
+ LLSidepanelItemInfo* sidepanel = dynamic_cast<LLSidepanelItemInfo*>(mHandle.get());
+ if (sidepanel)
+ {
+ // sidepanel waits only for most recent update
+ sidepanel->onUpdateCallback(mItemId, mId);
+ }
+ }
+private:
+ LLHandle<LLPanel> mHandle;
+ LLUUID mItemId;
+ S32 mId;
+};
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLItemPropertiesObserver
//
@@ -68,7 +91,7 @@ public:
}
virtual void changed(U32 mask);
private:
- LLSidepanelItemInfo* mFloater;
+ LLSidepanelItemInfo* mFloater; // Not a handle because LLSidepanelItemInfo is managing LLItemPropertiesObserver
};
void LLItemPropertiesObserver::changed(U32 mask)
@@ -115,7 +138,7 @@ public:
S32 serial_num,
void* user_data);
private:
- LLSidepanelItemInfo* mFloater;
+ LLSidepanelItemInfo* mFloater; // Not a handle because LLSidepanelItemInfo is managing LLObjectInventoryObserver
};
/*virtual*/
@@ -138,6 +161,7 @@ LLSidepanelItemInfo::LLSidepanelItemInfo(const LLPanel::Params& p)
: LLSidepanelInventorySubpanel(p)
, mItemID(LLUUID::null)
, mObjectInventoryObserver(NULL)
+ , mUpdatePendingId(-1)
{
mPropertiesObserver = new LLItemPropertiesObserver(this);
}
@@ -168,19 +192,19 @@ BOOL LLSidepanelItemInfo::postBuild()
// owner permissions
// Permissions debug text
// group permissions
- getChild<LLUICtrl>("CheckShareWithGroup")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this));
+ getChild<LLUICtrl>("CheckShareWithGroup")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this, _1));
// everyone permissions
- getChild<LLUICtrl>("CheckEveryoneCopy")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this));
+ getChild<LLUICtrl>("CheckEveryoneCopy")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this, _1));
// next owner permissions
- getChild<LLUICtrl>("CheckNextOwnerModify")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this));
- getChild<LLUICtrl>("CheckNextOwnerCopy")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this));
- getChild<LLUICtrl>("CheckNextOwnerTransfer")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this));
+ getChild<LLUICtrl>("CheckNextOwnerModify")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this, _1));
+ getChild<LLUICtrl>("CheckNextOwnerCopy")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this, _1));
+ getChild<LLUICtrl>("CheckNextOwnerTransfer")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this, _1));
// Mark for sale or not, and sale info
- getChild<LLUICtrl>("CheckPurchase")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this));
+ getChild<LLUICtrl>("CheckPurchase")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this, _1));
// Change sale type, and sale info
- getChild<LLUICtrl>("ComboBoxSaleType")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this));
+ getChild<LLUICtrl>("ComboBoxSaleType")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this, _1));
// "Price" label for edit
- getChild<LLUICtrl>("Edit Cost")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this));
+ getChild<LLUICtrl>("Edit Cost")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this, _1));
refresh();
return TRUE;
}
@@ -192,11 +216,16 @@ void LLSidepanelItemInfo::setObjectID(const LLUUID& object_id)
// Start monitoring changes in the object inventory to update
// selected inventory item properties in Item Profile panel. See STORM-148.
startObjectInventoryObserver();
+ mUpdatePendingId = -1;
}
void LLSidepanelItemInfo::setItemID(const LLUUID& item_id)
{
- mItemID = item_id;
+ if (mItemID != item_id)
+ {
+ mItemID = item_id;
+ mUpdatePendingId = -1;
+ }
}
const LLUUID& LLSidepanelItemInfo::getObjectID() const
@@ -209,6 +238,15 @@ const LLUUID& LLSidepanelItemInfo::getItemID() const
return mItemID;
}
+void LLSidepanelItemInfo::onUpdateCallback(const LLUUID& item_id, S32 received_update_id)
+{
+ if (mItemID == item_id && mUpdatePendingId == received_update_id)
+ {
+ mUpdatePendingId = -1;
+ refresh();
+ }
+}
+
void LLSidepanelItemInfo::reset()
{
LLSidepanelInventorySubpanel::reset();
@@ -242,24 +280,16 @@ void LLSidepanelItemInfo::refresh()
"LabelItemName",
"LabelItemDesc",
"LabelCreatorName",
- "LabelOwnerName",
- "CheckOwnerModify",
- "CheckOwnerCopy",
- "CheckOwnerTransfer",
- "CheckShareWithGroup",
- "CheckEveryoneCopy",
- "CheckNextOwnerModify",
- "CheckNextOwnerCopy",
- "CheckNextOwnerTransfer",
- "CheckPurchase",
- "Edit Cost"
+ "LabelOwnerName"
};
for(size_t t=0; t<LL_ARRAY_SIZE(no_item_names); ++t)
{
getChildView(no_item_names[t])->setEnabled(false);
}
-
+
+ setPropertiesFieldsEnabled(false);
+
const std::string hide_names[]={
"BaseMaskDebug",
"OwnerMaskDebug",
@@ -297,6 +327,11 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
llassert(item);
if (!item) return;
+ if (mUpdatePendingId != -1)
+ {
+ return;
+ }
+
// do not enable the UI for incomplete items.
BOOL is_complete = item->isFinished();
const BOOL cannot_restrict_permissions = LLInventoryType::cannotRestrictPermissions(item->getInventoryType());
@@ -726,6 +761,26 @@ void LLSidepanelItemInfo::stopObjectInventoryObserver()
mObjectInventoryObserver = NULL;
}
+void LLSidepanelItemInfo::setPropertiesFieldsEnabled(bool enabled)
+{
+ const std::string fields[] = {
+ "CheckOwnerModify",
+ "CheckOwnerCopy",
+ "CheckOwnerTransfer",
+ "CheckShareWithGroup",
+ "CheckEveryoneCopy",
+ "CheckNextOwnerModify",
+ "CheckNextOwnerCopy",
+ "CheckNextOwnerTransfer",
+ "CheckPurchase",
+ "Edit Cost"
+ };
+ for (size_t t = 0; t<LL_ARRAY_SIZE(fields); ++t)
+ {
+ getChildView(fields[t])->setEnabled(false);
+ }
+}
+
void LLSidepanelItemInfo::onClickCreator()
{
LLViewerInventoryItem* item = findItem();
@@ -793,10 +848,18 @@ void LLSidepanelItemInfo::onCommitDescription()
}
}
-// static
-void LLSidepanelItemInfo::onCommitPermissions()
+void LLSidepanelItemInfo::onCommitPermissions(LLUICtrl* ctrl)
+{
+ if (ctrl)
+ {
+ // will be enabled by response from server
+ ctrl->setEnabled(false);
+ }
+ updatePermissions();
+}
+
+void LLSidepanelItemInfo::updatePermissions()
{
- //LL_INFOS() << "LLSidepanelItemInfo::onCommitPermissions()" << LL_ENDL;
LLViewerInventoryItem* item = findItem();
if(!item) return;
@@ -884,19 +947,17 @@ void LLSidepanelItemInfo::onCommitPermissions()
}
// static
-void LLSidepanelItemInfo::onCommitSaleInfo()
+void LLSidepanelItemInfo::onCommitSaleInfo(LLUICtrl* ctrl)
{
+ if (ctrl)
+ {
+ // will be enabled by response from server
+ ctrl->setEnabled(false);
+ }
//LL_INFOS() << "LLSidepanelItemInfo::onCommitSaleInfo()" << LL_ENDL;
updateSaleInfo();
}
-// static
-void LLSidepanelItemInfo::onCommitSaleType()
-{
- //LL_INFOS() << "LLSidepanelItemInfo::onCommitSaleType()" << LL_ENDL;
- updateSaleInfo();
-}
-
void LLSidepanelItemInfo::updateSaleInfo()
{
LLViewerInventoryItem* item = findItem();
@@ -977,7 +1038,12 @@ void LLSidepanelItemInfo::onCommitChanges(LLPointer<LLViewerInventoryItem> item)
if (mObjectID.isNull())
{
// This is in the agent's inventory.
- item->updateServer(FALSE);
+ // Mark update as pending and wait only for most recent one in case user requested for couple
+ // Once update arrives or any of ids change drop pending id.
+ mUpdatePendingId++;
+ LLPointer<LLInventoryCallback> callback = new PropertiesChangedCallback(getHandle(), mItemID, mUpdatePendingId);
+ update_inventory_item(item.get(), callback);
+ //item->updateServer(FALSE);
gInventory.updateItem(item);
gInventory.notifyObservers();
}
@@ -1002,6 +1068,7 @@ void LLSidepanelItemInfo::onCommitChanges(LLPointer<LLViewerInventoryItem> item)
// prevents flashing in content tab and some duplicated request.
object->dirtyInventory();
}
+ setPropertiesFieldsEnabled(false);
}
}
}
@@ -1030,7 +1097,6 @@ void LLSidepanelItemInfo::save()
{
onCommitName();
onCommitDescription();
- onCommitPermissions();
- onCommitSaleInfo();
- onCommitSaleType();
+ updatePermissions();
+ updateSaleInfo();
}
diff --git a/indra/newview/llsidepaneliteminfo.h b/indra/newview/llsidepaneliteminfo.h
index 74cf7afe35..5f29254182 100644
--- a/indra/newview/llsidepaneliteminfo.h
+++ b/indra/newview/llsidepaneliteminfo.h
@@ -57,6 +57,9 @@ public:
const LLUUID& getObjectID() const;
const LLUUID& getItemID() const;
+ // if received update and item id (from callback) matches internal ones, update UI
+ void onUpdateCallback(const LLUUID& item_id, S32 received_update_id);
+
protected:
/*virtual*/ void refresh();
/*virtual*/ void save();
@@ -71,12 +74,16 @@ private:
void startObjectInventoryObserver();
void stopObjectInventoryObserver();
+ void setPropertiesFieldsEnabled(bool enabled);
LLUUID mItemID; // inventory UUID for the inventory item.
LLUUID mObjectID; // in-world task UUID, or null if in agent inventory.
LLItemPropertiesObserver* mPropertiesObserver; // for syncing changes to item
LLObjectInventoryObserver* mObjectInventoryObserver; // for syncing changes to items inside an object
-
+
+ // We can send multiple properties updates simultaneously, make sure only last response counts and there won't be a race condition.
+ S32 mUpdatePendingId;
+
//
// UI Elements
//
@@ -85,9 +92,9 @@ protected:
void onClickOwner();
void onCommitName();
void onCommitDescription();
- void onCommitPermissions();
- void onCommitSaleInfo();
- void onCommitSaleType();
+ void onCommitPermissions(LLUICtrl* ctrl);
+ void updatePermissions();
+ void onCommitSaleInfo(LLUICtrl* ctrl);
void updateSaleInfo();
void onCommitChanges(LLPointer<LLViewerInventoryItem> item);
};
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index f03c7abc4d..7fa06f51e3 100644
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -174,9 +174,6 @@ BOOL LLSidepanelTaskInfo::postBuild()
void LLSidepanelTaskInfo::disableAll()
{
- mDAPermModify->setEnabled(FALSE);
- mDAPermModify->setValue(LLStringUtil::null);
-
mDACreatorName->setValue(LLStringUtil::null);
mDACreatorName->setEnabled(FALSE);
@@ -184,18 +181,42 @@ void LLSidepanelTaskInfo::disableAll()
mDAOwnerName->setValue(LLStringUtil::null);
mDAOwnerName->setEnabled(FALSE);
- mDAButtonSetGroup->setEnabled(FALSE);
-
mDAObjectName->setValue(LLStringUtil::null);
mDAObjectName->setEnabled(FALSE);
mDAName->setEnabled(FALSE);
mDADescription->setEnabled(FALSE);
mDAObjectDescription->setValue(LLStringUtil::null);
mDAObjectDescription->setEnabled(FALSE);
-
+
+ mDAPathfindingAttributes->setEnabled(FALSE);
+ mDAPathfindingAttributes->setValue(LLStringUtil::null);
+
+ mDAButtonSetGroup->setEnabled(FALSE);
+ mDAButtonDeed->setEnabled(FALSE);
+
+ mDAPermModify->setEnabled(FALSE);
+ mDAPermModify->setValue(LLStringUtil::null);
+ mDAEditCost->setValue(LLStringUtil::null);
+ mDAComboSaleType->setValue(LLSaleInfo::FS_COPY);
+
+ disablePermissions();
+
+ mDAB->setVisible(FALSE);
+ mDAO->setVisible(FALSE);
+ mDAG->setVisible(FALSE);
+ mDAE->setVisible(FALSE);
+ mDAN->setVisible(FALSE);
+ mDAF->setVisible(FALSE);
+
+ mOpenBtn->setEnabled(FALSE);
+ mPayBtn->setEnabled(FALSE);
+ mBuyBtn->setEnabled(FALSE);
+}
+
+void LLSidepanelTaskInfo::disablePermissions()
+{
mDACheckboxShareWithGroup->setValue(FALSE);
mDACheckboxShareWithGroup->setEnabled(FALSE);
- mDAButtonDeed->setEnabled(FALSE);
mDACheckboxAllowEveryoneMove->setValue(FALSE);
mDACheckboxAllowEveryoneMove->setEnabled(FALSE);
@@ -217,33 +238,17 @@ void LLSidepanelTaskInfo::disableAll()
//checkbox include in search
mDASearchCheck->setValue(FALSE);
mDASearchCheck->setEnabled(FALSE);
-
- mDAComboSaleType->setValue(LLSaleInfo::FS_COPY);
+
mDAComboSaleType->setEnabled(FALSE);
-
- mDAEditCost->setValue(LLStringUtil::null);
+
mDAEditCost->setEnabled(FALSE);
-
+
mDALabelClickAction->setEnabled(FALSE);
if (mDAComboClickAction)
{
mDAComboClickAction->setEnabled(FALSE);
mDAComboClickAction->clear();
}
-
- mDAPathfindingAttributes->setEnabled(FALSE);
- mDAPathfindingAttributes->setValue(LLStringUtil::null);
-
- mDAB->setVisible(FALSE);
- mDAO->setVisible(FALSE);
- mDAG->setVisible(FALSE);
- mDAE->setVisible(FALSE);
- mDAN->setVisible(FALSE);
- mDAF->setVisible(FALSE);
-
- mOpenBtn->setEnabled(FALSE);
- mPayBtn->setEnabled(FALSE);
- mBuyBtn->setEnabled(FALSE);
}
void LLSidepanelTaskInfo::refresh()
@@ -972,6 +977,12 @@ void LLSidepanelTaskInfo::onCommitPerm(LLUICtrl *ctrl, void *data, U8 field, U32
BOOL new_state = check->get();
LLSelectMgr::getInstance()->selectionSetObjectPermissions(field, new_state, perm);
+
+ LLSidepanelTaskInfo* self = (LLSidepanelTaskInfo*)data;
+ if (self)
+ {
+ self->disablePermissions();
+ }
}
// static
diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h
index cbfb07874b..dc259cb22d 100644
--- a/indra/newview/llsidepaneltaskinfo.h
+++ b/indra/newview/llsidepaneltaskinfo.h
@@ -95,6 +95,7 @@ protected:
static void doClickAction(U8 click_action);
void disableAll();
+ void disablePermissions();
private:
LLNameBox* mLabelGroupName; // group name
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index f5fea9dece..8fef3ff1c0 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -34,8 +34,6 @@
#include "lleconomy.h"
#include "llfloaterperms.h"
#include "llfloaterreg.h"
-#include "llfloaterflickr.h"
-#include "llfloatertwitter.h"
#include "llimagefilter.h"
#include "llimagefiltersmanager.h"
#include "llimagebmp.h"
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index b22c030bf8..02cd4fd4d6 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1632,7 +1632,14 @@ bool idle_startup()
if (!gAgentMovementCompleted && timeout.getElapsedTimeF32() > STATE_AGENT_WAIT_TIMEOUT)
{
LL_WARNS("AppInit") << "Backing up to login screen!" << LL_ENDL;
- LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
+ if (gRememberPassword)
+ {
+ LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
+ }
+ else
+ {
+ LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status);
+ }
reset_login();
}
return FALSE;
@@ -2367,7 +2374,14 @@ void use_circuit_callback(void**, S32 result)
{
// Make sure user knows something bad happened. JC
LL_WARNS("AppInit") << "Backing up to login screen!" << LL_ENDL;
- LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
+ if (gRememberPassword)
+ {
+ LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
+ }
+ else
+ {
+ LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status);
+ }
reset_login();
}
else
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 9eda33d3d2..b8c227334d 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -243,16 +243,24 @@ BOOL LLStatusBar::postBuild()
mPanelNearByMedia->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
mPanelNearByMedia->setVisible(FALSE);
+ updateBalancePanelPosition();
+
// Hook up and init for filtering
mFilterEdit = getChild<LLSearchEditor>( "search_menu_edit" );
mSearchPanel = getChild<LLPanel>( "menu_search_panel" );
- mSearchPanel->setVisible(gSavedSettings.getBOOL("MenuSearch"));
+ BOOL search_panel_visible = gSavedSettings.getBOOL("MenuSearch");
+ mSearchPanel->setVisible(search_panel_visible);
mFilterEdit->setKeystrokeCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this));
mFilterEdit->setCommitCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this));
collectSearchableItems();
gSavedSettings.getControl("MenuSearch")->getCommitSignal()->connect(boost::bind(&LLStatusBar::updateMenuSearchVisibility, this, _2));
+ if (search_panel_visible)
+ {
+ updateMenuSearchPosition();
+ }
+
return TRUE;
}
@@ -363,17 +371,7 @@ void LLStatusBar::setBalance(S32 balance)
std::string label_str = getString("buycurrencylabel", string_args);
mBoxBalance->setValue(label_str);
- // Resize the L$ balance background to be wide enough for your balance plus the buy button
- {
- const S32 HPAD = 24;
- LLRect balance_rect = mBoxBalance->getTextBoundingRect();
- LLRect buy_rect = getChildView("buyL")->getRect();
- LLRect shop_rect = getChildView("goShop")->getRect();
- LLView* balance_bg_view = getChildView("balance_bg");
- LLRect balance_bg_rect = balance_bg_view->getRect();
- balance_bg_rect.mLeft = balance_bg_rect.mRight - (buy_rect.getWidth() + shop_rect.getWidth() + balance_rect.getWidth() + HPAD);
- balance_bg_view->setShape(balance_bg_rect);
- }
+ updateBalancePanelPosition();
// If the search panel is shown, move this according to the new balance width. Parcel text will reshape itself in setParcelInfoText
if (mSearchPanel && mSearchPanel->getVisible())
@@ -661,6 +659,19 @@ void LLStatusBar::updateMenuSearchPosition()
mSearchPanel->setShape( searchRect );
}
+void LLStatusBar::updateBalancePanelPosition()
+{
+ // Resize the L$ balance background to be wide enough for your balance plus the buy button
+ const S32 HPAD = 24;
+ LLRect balance_rect = mBoxBalance->getTextBoundingRect();
+ LLRect buy_rect = getChildView("buyL")->getRect();
+ LLRect shop_rect = getChildView("goShop")->getRect();
+ LLView* balance_bg_view = getChildView("balance_bg");
+ LLRect balance_bg_rect = balance_bg_view->getRect();
+ balance_bg_rect.mLeft = balance_bg_rect.mRight - (buy_rect.getWidth() + shop_rect.getWidth() + balance_rect.getWidth() + HPAD);
+ balance_bg_view->setShape(balance_bg_rect);
+}
+
// Implements secondlife:///app/balance/request to request a L$ balance
// update via UDP message system. JC
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index 403d590aca..cad877f799 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -114,7 +114,8 @@ private:
std::unique_ptr< ll::statusbar::SearchData > mSearchData;
void collectSearchableItems();
void updateMenuSearchVisibility( const LLSD& data );
- void updateMenuSearchPosition();
+ void updateMenuSearchPosition(); // depends onto balance position
+ void updateBalancePanelPosition();
private:
LLTextBox *mTextTime;
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index e5af47ab6c..e2deb7ce1d 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -53,6 +53,7 @@ const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by
const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate)
const S32 TEXTURE_FAST_CACHE_ENTRY_OVERHEAD = sizeof(S32) * 4; //w, h, c, level
const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = 16 * 16 * 4 + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD;
+const F32 TEXTURE_LAZY_PURGE_TIME_LIMIT = .004f; // 4ms. Would be better to autoadjust, but there is a major cache rework in progress.
class LLTextureCacheWorker : public LLWorkerClass
{
@@ -837,6 +838,7 @@ LLTextureCache::LLTextureCache(bool threaded)
mFastCachePoolp(NULL),
mFastCachePadBuffer(NULL)
{
+ mHeaderAPRFilePoolp = new LLVolatileAPRPool(); // is_local = true, because this pool is for headers, headers are under own mutex
}
LLTextureCache::~LLTextureCache()
@@ -845,6 +847,7 @@ LLTextureCache::~LLTextureCache()
writeUpdatedEntries() ;
delete mFastCachep;
delete mFastCachePoolp;
+ delete mHeaderAPRFilePoolp;
ll_aligned_free_16(mFastCachePadBuffer);
}
@@ -1013,10 +1016,11 @@ void LLTextureCache::purgeCache(ELLPath location, bool remove_dir)
if(LLFile::isdir(mTexturesDirName))
{
std::string file_name = gDirUtilp->getExpandedFilename(location, entries_filename);
- LLAPRFile::remove(file_name, getLocalAPRFilePool());
+ // mHeaderAPRFilePoolp because we are under header mutex, and can be in main thread
+ LLAPRFile::remove(file_name, mHeaderAPRFilePoolp);
file_name = gDirUtilp->getExpandedFilename(location, cache_filename);
- LLAPRFile::remove(file_name, getLocalAPRFilePool());
+ LLAPRFile::remove(file_name, mHeaderAPRFilePoolp);
purgeAllTextures(true);
}
@@ -1093,7 +1097,7 @@ LLAPRFile* LLTextureCache::openHeaderEntriesFile(bool readonly, S32 offset)
{
llassert_always(mHeaderAPRFile == NULL);
apr_int32_t flags = readonly ? APR_READ|APR_BINARY : APR_READ|APR_WRITE|APR_BINARY;
- mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags, getLocalAPRFilePool());
+ mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags, mHeaderAPRFilePoolp);
if(offset > 0)
{
mHeaderAPRFile->seek(APR_SET, offset);
@@ -1116,10 +1120,10 @@ void LLTextureCache::readEntriesHeader()
{
// mHeaderEntriesInfo initializes to default values so safe not to read it
llassert_always(mHeaderAPRFile == NULL);
- if (LLAPRFile::isExist(mHeaderEntriesFileName, getLocalAPRFilePool()))
+ if (LLAPRFile::isExist(mHeaderEntriesFileName, mHeaderAPRFilePoolp))
{
LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
- getLocalAPRFilePool());
+ mHeaderAPRFilePoolp);
}
else //create an empty entries header.
{
@@ -1151,7 +1155,7 @@ void LLTextureCache::writeEntriesHeader()
if (!mReadOnly)
{
LLAPRFile::writeEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
- getLocalAPRFilePool());
+ mHeaderAPRFilePoolp);
}
}
@@ -1669,6 +1673,91 @@ void LLTextureCache::purgeAllTextures(bool purge_directories)
LL_INFOS() << "The entire texture cache is cleared." << LL_ENDL ;
}
+void LLTextureCache::purgeTexturesLazy(F32 time_limit_sec)
+{
+ if (mReadOnly)
+ {
+ return;
+ }
+
+ if (!mThreaded)
+ {
+ LLAppViewer::instance()->pauseMainloopTimeout();
+ }
+
+ // time_limit doesn't account for lock time
+ LLMutexLock lock(&mHeaderMutex);
+
+ if (mPurgeEntryList.empty())
+ {
+ // Read the entries list and form list of textures to purge
+ std::vector<Entry> entries;
+ U32 num_entries = openAndReadEntries(entries);
+ if (!num_entries)
+ {
+ return; // nothing to purge
+ }
+
+ // Use mTexturesSizeMap to collect UUIDs of textures with bodies
+ typedef std::set<std::pair<U32, S32> > time_idx_set_t;
+ std::set<std::pair<U32, S32> > time_idx_set;
+ for (size_map_t::iterator iter1 = mTexturesSizeMap.begin();
+ iter1 != mTexturesSizeMap.end(); ++iter1)
+ {
+ if (iter1->second > 0)
+ {
+ id_map_t::iterator iter2 = mHeaderIDMap.find(iter1->first);
+ if (iter2 != mHeaderIDMap.end())
+ {
+ S32 idx = iter2->second;
+ time_idx_set.insert(std::make_pair(entries[idx].mTime, idx));
+ }
+ else
+ {
+ LL_ERRS("TextureCache") << "mTexturesSizeMap / mHeaderIDMap corrupted." << LL_ENDL;
+ }
+ }
+ }
+
+ S64 cache_size = mTexturesSizeTotal;
+ S64 purged_cache_size = (sCacheMaxTexturesSize * (S64)((1.f - TEXTURE_CACHE_PURGE_AMOUNT) * 100)) / 100;
+ for (time_idx_set_t::iterator iter = time_idx_set.begin();
+ iter != time_idx_set.end(); ++iter)
+ {
+ S32 idx = iter->second;
+ if (cache_size >= purged_cache_size)
+ {
+ cache_size -= entries[idx].mBodySize;
+ mPurgeEntryList.push_back(std::pair<S32, Entry>(idx, entries[idx]));
+ }
+ else
+ {
+ break;
+ }
+ }
+ LL_DEBUGS("TextureCache") << "Formed Purge list of " << mPurgeEntryList.size() << " entries" << LL_ENDL;
+ }
+ else
+ {
+ // Remove collected entried
+ LLTimer timer;
+ while (!mPurgeEntryList.empty() && timer.getElapsedTimeF32() < time_limit_sec)
+ {
+ S32 idx = mPurgeEntryList.back().first;
+ Entry entry = mPurgeEntryList.back().second;
+ mPurgeEntryList.pop_back();
+ // make sure record is still valid
+ id_map_t::iterator iter_header = mHeaderIDMap.find(entry.mID);
+ if (iter_header != mHeaderIDMap.end() && iter_header->second == idx)
+ {
+ std::string tex_filename = getTextureFileName(entry.mID);
+ removeEntry(idx, entry, tex_filename);
+ writeEntryToHeaderImmediately(idx, entry);
+ }
+ }
+ }
+}
+
void LLTextureCache::purgeTextures(bool validate)
{
if (mReadOnly)
@@ -1746,7 +1835,8 @@ void LLTextureCache::purgeTextures(bool validate)
if (uuididx == validate_idx)
{
LL_DEBUGS("TextureCache") << "Validating: " << filename << "Size: " << entries[idx].mBodySize << LL_ENDL;
- S32 bodysize = LLAPRFile::size(filename, getLocalAPRFilePool());
+ // mHeaderAPRFilePoolp because this is under header mutex in main thread
+ S32 bodysize = LLAPRFile::size(filename, mHeaderAPRFilePoolp);
if (bodysize != entries[idx].mBodySize)
{
LL_WARNS("TextureCache") << "TEXTURE CACHE BODY HAS BAD SIZE: " << bodysize << " != " << entries[idx].mBodySize
@@ -1928,11 +2018,10 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio
}
if (mDoPurge)
{
- // NOTE: This may cause an occasional hiccup,
- // but it really needs to be done on the control thread
- // (i.e. here)
- purgeTextures(false);
- mDoPurge = FALSE;
+ // NOTE: Needs to be done on the control thread
+ // (i.e. here)
+ purgeTexturesLazy(TEXTURE_LAZY_PURGE_TIME_LIMIT);
+ mDoPurge = !mPurgeEntryList.empty();
}
LLMutexLock lock(&mWorkersMutex);
LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,
@@ -2146,7 +2235,7 @@ void LLTextureCache::openFastCache(bool first_time)
{
mFastCachePadBuffer = (U8*)ll_aligned_malloc_16(TEXTURE_FAST_CACHE_ENTRY_SIZE);
}
- mFastCachePoolp = new LLVolatileAPRPool();
+ mFastCachePoolp = new LLVolatileAPRPool(); // is_local= true by default, so not thread safe by default
if (LLAPRFile::isExist(mFastCacheFileName, mFastCachePoolp))
{
mFastCachep = new LLAPRFile(mFastCacheFileName, APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ;
@@ -2230,7 +2319,9 @@ void LLTextureCache::removeCachedTexture(const LLUUID& id)
mTexturesSizeMap.erase(id);
}
mHeaderIDMap.erase(id);
- LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool());
+ // We are inside header's mutex so mHeaderAPRFilePoolp is safe to use,
+ // but getLocalAPRFilePool() is not safe, it might be in use by worker
+ LLAPRFile::remove(getTextureFileName(id), mHeaderAPRFilePoolp);
}
//called after mHeaderMutex is locked.
@@ -2242,7 +2333,10 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
{
if (entry.mBodySize == 0) // Always attempt to remove when mBodySize > 0.
{
- if (LLAPRFile::isExist(filename, getLocalAPRFilePool())) // Sanity check. Shouldn't exist when body size is 0.
+ // Sanity check. Shouldn't exist when body size is 0.
+ // We are inside header's mutex so mHeaderAPRFilePoolp is safe to use,
+ // but getLocalAPRFilePool() is not safe, it might be in use by worker
+ if (LLAPRFile::isExist(filename, mHeaderAPRFilePoolp))
{
LL_WARNS("TextureCache") << "Entry has body size of zero but file " << filename << " exists. Deleting this file, too." << LL_ENDL;
}
@@ -2262,7 +2356,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
if (file_maybe_exists)
{
- LLAPRFile::remove(filename, getLocalAPRFilePool());
+ LLAPRFile::remove(filename, mHeaderAPRFilePoolp);
}
}
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index 81ea7aeee2..6046f2b9df 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -139,7 +139,7 @@ public:
U32 getEntries() { return mHeaderEntriesInfo.mEntries; }
U32 getMaxEntries() { return sCacheMaxEntries; };
BOOL isInCache(const LLUUID& id) ;
- BOOL isInLocal(const LLUUID& id) ;
+ BOOL isInLocal(const LLUUID& id) ; //not thread safe at the moment
protected:
// Accessed by LLTextureCacheWorker
@@ -155,6 +155,7 @@ private:
void readHeaderCache();
void clearCorruptedCache();
void purgeAllTextures(bool purge_directories);
+ void purgeTexturesLazy(F32 time_limit_sec);
void purgeTextures(bool validate);
LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset);
void closeHeaderEntriesFile();
@@ -189,6 +190,11 @@ private:
LLMutex mFastCacheMutex;
LLAPRFile* mHeaderAPRFile;
LLVolatileAPRPool* mFastCachePoolp;
+
+ // mLocalAPRFilePoolp is not thread safe and is meant only for workers
+ // howhever mHeaderEntriesFileName is accessed not from workers' threads
+ // so it needs own pool (not thread safe by itself, relies onto header's mutex)
+ LLVolatileAPRPool* mHeaderAPRFilePoolp;
typedef std::map<handle_t, LLTextureCacheWorker*> handle_map_t;
handle_map_t mReaders;
@@ -225,6 +231,8 @@ private:
typedef std::map<S32, Entry> idx_entry_map_t;
idx_entry_map_t mUpdatedEntryMap;
+ typedef std::vector<std::pair<S32, Entry> > idx_entry_vector_t;
+ idx_entry_vector_t mPurgeEntryList;
// Statics
static F32 sHeaderCacheVersion;
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index 3831f7d67d..a4806ceaf6 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -721,9 +721,14 @@ void LLToolGrabBase::handleHoverActive(S32 x, S32 y, MASK mask)
!objectp->isHUDAttachment() &&
objectp->getRoot() == gAgentAvatarp->getRoot())
{
- // force focus to point in space where we were looking previously
- gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
- gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ // we are essentially editing object position
+ if (!gSavedSettings.getBOOL("EditCameraMovement"))
+ {
+ // force focus to point in space where we were looking previously
+ // Example of use: follow cam scripts shouldn't affect you when movng objects arouns
+ gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ }
}
else
{
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 54df5198c8..3955d7a72f 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -874,37 +874,9 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)
static bool needs_tooltip(LLSelectNode* nodep)
{
- if (!nodep)
+ if (!nodep || !nodep->mValid)
return false;
-
- LLViewerObject* object = nodep->getObject();
- LLViewerObject *parent = (LLViewerObject *)object->getParent();
- if (object->flagHandleTouch()
- || (parent && parent->flagHandleTouch())
- || object->flagTakesMoney()
- || (parent && parent->flagTakesMoney())
- || object->flagAllowInventoryAdd()
- )
- {
- return true;
- }
-
- U8 click_action = final_click_action(object);
- if (click_action != 0)
- {
- return true;
- }
-
- if (nodep->mValid)
- {
- bool anyone_copy = anyone_copy_selection(nodep);
- bool for_sale = for_sale_selection(nodep);
- if (anyone_copy || for_sale)
- {
- return true;
- }
- }
- return false;
+ return true;
}
diff --git a/indra/newview/lltwitterconnect.cpp b/indra/newview/lltwitterconnect.cpp
deleted file mode 100644
index b2d2fa9d77..0000000000
--- a/indra/newview/lltwitterconnect.cpp
+++ /dev/null
@@ -1,576 +0,0 @@
-/**
- * @file lltwitterconnect.h
- * @author Merov, Cho
- * @brief Connection to Twitter Service
- *
- * $LicenseInfo:firstyear=2013&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2013, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "lltwitterconnect.h"
-#include "llflickrconnect.h"
-
-#include "llagent.h"
-#include "llcallingcard.h" // for LLAvatarTracker
-#include "llcommandhandler.h"
-#include "llnotificationsutil.h"
-#include "llurlaction.h"
-#include "llimagepng.h"
-#include "llimagejpeg.h"
-#include "lltrans.h"
-#include "llevents.h"
-#include "llviewerregion.h"
-
-#include "llfloaterwebcontent.h"
-#include "llfloaterreg.h"
-#include "llcorehttputil.h"
-
-boost::scoped_ptr<LLEventPump> LLTwitterConnect::sStateWatcher(new LLEventStream("TwitterConnectState"));
-boost::scoped_ptr<LLEventPump> LLTwitterConnect::sInfoWatcher(new LLEventStream("TwitterConnectInfo"));
-boost::scoped_ptr<LLEventPump> LLTwitterConnect::sContentWatcher(new LLEventStream("TwitterConnectContent"));
-
-// Local functions
-void log_twitter_connect_error(const std::string& request, U32 status, const std::string& reason, const std::string& code, const std::string& description)
-{
- // Note: 302 (redirect) is *not* an error that warrants logging
- if (status != 302)
- {
- LL_WARNS("TwitterConnect") << request << " request failed with a " << status << " " << reason << ". Reason: " << code << " (" << description << ")" << LL_ENDL;
- }
-}
-
-void toast_user_for_twitter_success()
-{
- LLSD args;
- args["MESSAGE"] = LLTrans::getString("twitter_post_success");
- LLNotificationsUtil::add("TwitterConnect", args);
-}
-
-class LLTwitterConnectHandler : public LLCommandHandler
-{
-public:
- LLTwitterConnectHandler() : LLCommandHandler("fbc", UNTRUSTED_THROTTLE) {}
-
- bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
- {
- if (tokens.size() >= 1)
- {
- if (tokens[0].asString() == "connect")
- {
- if (tokens.size() >= 2 && tokens[1].asString() == "twitter")
- {
- // this command probably came from the twitter_web browser, so close it
- LLFloaterReg::hideInstance("twitter_web");
-
- // connect to twitter
- if (query_map.has("oauth_token"))
- {
- LLTwitterConnect::instance().connectToTwitter(query_map["oauth_token"], query_map.get("oauth_verifier"));
- }
- return true;
- }
- else if (tokens.size() >= 2 && tokens[1].asString() == "flickr")
- {
- // this command probably came from the flickr_web browser, so close it
- LLFloaterReg::hideInstance("flickr_web");
-
- // connect to flickr
- if (query_map.has("oauth_token"))
- {
- LLFlickrConnect::instance().connectToFlickr(query_map["oauth_token"], query_map.get("oauth_verifier"));
- }
- return true;
- }
- }
- }
- return false;
- }
-};
-LLTwitterConnectHandler gTwitterConnectHandler;
-
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLTwitterConnect::twitterConnectCoro(std::string requestToken, std::string oauthVerifier)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- LLSD body;
- if (!requestToken.empty())
- body["request_token"] = requestToken;
- if (!oauthVerifier.empty())
- body["oauth_verifier"] = oauthVerifier;
-
- LLSD result = httpAdapter->putAndSuspend(httpRequest, getTwitterConnectURL("/connection"), body, httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- if ( status == LLCore::HttpStatus(HTTP_FOUND) )
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openTwitterWeb(location);
- }
- }
- else
- {
- LL_WARNS("TwitterConnect") << "Connection failed " << status.toString() << LL_ENDL;
- setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
- log_twitter_connect_error("Connect", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- }
- else
- {
- LL_DEBUGS("TwitterConnect") << "Connect successful. " << LL_ENDL;
- setConnectionState(LLTwitterConnect::TWITTER_CONNECTED);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-bool LLTwitterConnect::testShareStatus(LLSD &result)
-{
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (status)
- return true;
-
- if (status == LLCore::HttpStatus(HTTP_FOUND))
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("TwitterConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openTwitterWeb(location);
- }
- }
- if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
- {
- LL_DEBUGS("TwitterConnect") << "Not connected. " << LL_ENDL;
- connectToTwitter();
- }
- else
- {
- LL_WARNS("TwitterConnect") << "HTTP Status error " << status.toString() << LL_ENDL;
- setConnectionState(LLTwitterConnect::TWITTER_POST_FAILED);
- log_twitter_connect_error("Share", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- return false;
-}
-
-void LLTwitterConnect::twitterShareCoro(std::string route, LLSD share)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->postAndSuspend(httpRequest, getTwitterConnectURL(route, true), share, httpOpts);
-
- if (testShareStatus(result))
- {
- toast_user_for_twitter_success();
- LL_DEBUGS("TwitterConnect") << "Post successful. " << LL_ENDL;
- setConnectionState(LLTwitterConnect::TWITTER_POSTED);
- }
-}
-
-void LLTwitterConnect::twitterShareImageCoro(LLPointer<LLImageFormatted> image, std::string status)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- std::string imageFormat;
- if (dynamic_cast<LLImagePNG*>(image.get()))
- {
- imageFormat = "png";
- }
- else if (dynamic_cast<LLImageJPEG*>(image.get()))
- {
- imageFormat = "jpg";
- }
- else
- {
- LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
- return;
- }
-
- // All this code is mostly copied from LLWebProfile::post()
- const std::string boundary = "----------------------------0123abcdefab";
-
- std::string contentType = "multipart/form-data; boundary=" + boundary;
- httpHeaders->append("Content-Type", contentType.c_str());
-
- LLCore::BufferArray::ptr_t raw = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); //
- LLCore::BufferArrayStream body(raw.get());
-
- // *NOTE: The order seems to matter.
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"status\"\r\n\r\n"
- << status << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
- << "Content-Type: image/" << imageFormat << "\r\n\r\n";
-
- // Insert the image data.
- // *FIX: Treating this as a string will probably screw it up ...
- U8* image_data = image->getData();
- for (S32 i = 0; i < image->getDataSize(); ++i)
- {
- body << image_data[i];
- }
-
- body << "\r\n--" << boundary << "--\r\n";
-
- LLSD result = httpAdapter->postAndSuspend(httpRequest, getTwitterConnectURL("/share/photo", true), raw, httpOpts, httpHeaders);
-
- if (testShareStatus(result))
- {
- toast_user_for_twitter_success();
- LL_DEBUGS("TwitterConnect") << "Post successful. " << LL_ENDL;
- setConnectionState(LLTwitterConnect::TWITTER_POSTED);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLTwitterConnect::twitterDisconnectCoro()
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->deleteAndSuspend(httpRequest, getTwitterConnectURL("/connection"), httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status && (status != LLCore::HttpStatus(HTTP_NOT_FOUND)))
- {
- LL_WARNS("TwitterConnect") << "Disconnect failed!" << LL_ENDL;
- setConnectionState(LLTwitterConnect::TWITTER_DISCONNECT_FAILED);
-
- log_twitter_connect_error("Disconnect", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- else
- {
- LL_DEBUGS("TwitterConnect") << "Disconnect successful. " << LL_ENDL;
- clearInfo();
- setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLTwitterConnect::twitterConnectedCoro(bool autoConnect)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setFollowRedirects(false);
- setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS);
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, getTwitterConnectURL("/connection", true), httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
- {
- LL_DEBUGS("TwitterConnect") << "Not connected. " << LL_ENDL;
- if (autoConnect)
- {
- connectToTwitter();
- }
- else
- {
- setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED);
- }
- }
- else
- {
- LL_WARNS("TwitterConnect") << "Failed to test connection:" << status.toTerseString() << LL_ENDL;
-
- setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
- log_twitter_connect_error("Connected", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- }
- else
- {
- LL_DEBUGS("TwitterConnect") << "Connect successful. " << LL_ENDL;
- setConnectionState(LLTwitterConnect::TWITTER_CONNECTED);
- }
-
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLTwitterConnect::twitterInfoCoro()
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, getTwitterConnectURL("/info", true), httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (status == LLCore::HttpStatus(HTTP_FOUND))
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("TwitterConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openTwitterWeb(location);
- }
- }
- else if (!status)
- {
- LL_WARNS("TwitterConnect") << "Twitter Info failed: " << status.toString() << LL_ENDL;
- log_twitter_connect_error("Info", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- else
- {
- LL_INFOS("TwitterConnect") << "Twitter: Info received" << LL_ENDL;
- result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
- storeInfo(result);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-LLTwitterConnect::LLTwitterConnect()
-: mConnectionState(TWITTER_NOT_CONNECTED),
- mConnected(false),
- mInfo(),
- mRefreshInfo(false),
- mReadFromMaster(false)
-{
-}
-
-void LLTwitterConnect::openTwitterWeb(std::string url)
-{
- LLFloaterWebContent::Params p;
- p.url(url);
- p.show_chrome(true);
- p.allow_back_forward_navigation(false);
- p.clean_browser(true);
- LLFloater *floater = LLFloaterReg::showInstance("twitter_web", p);
- //the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems).
- //So when showing the internal web browser, set focus to it's containing floater "twitter_web". When a mouse event
- //occurs on the "webbrowser" panel part of the floater, a mouse cursor will properly show and the "webbrowser" will gain focus.
- //twitter_web floater contains the "webbrowser" panel. JIRA: ACME-744
- gFocusMgr.setKeyboardFocus( floater );
-
- //LLUrlAction::openURLExternal(url);
-}
-
-std::string LLTwitterConnect::getTwitterConnectURL(const std::string& route, bool include_read_from_master)
-{
- std::string url("");
- LLViewerRegion *regionp = gAgent.getRegion();
- if (regionp)
- {
- //url = "http://pdp15.lindenlab.com/twitter/agent/" + gAgentID.asString(); // TEMPORARY FOR TESTING - CHO
- url = regionp->getCapability("TwitterConnect");
- url += route;
-
- if (include_read_from_master && mReadFromMaster)
- {
- url += "?read_from_master=true";
- }
- }
- return url;
-}
-
-void LLTwitterConnect::connectToTwitter(const std::string& request_token, const std::string& oauth_verifier)
-{
- setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS);
-
- LLCoros::instance().launch("LLTwitterConnect::twitterConnectCoro",
- boost::bind(&LLTwitterConnect::twitterConnectCoro, this, request_token, oauth_verifier));
-}
-
-void LLTwitterConnect::disconnectFromTwitter()
-{
- setConnectionState(LLTwitterConnect::TWITTER_DISCONNECTING);
-
- LLCoros::instance().launch("LLTwitterConnect::twitterDisconnectCoro",
- boost::bind(&LLTwitterConnect::twitterDisconnectCoro, this));
-}
-
-void LLTwitterConnect::checkConnectionToTwitter(bool auto_connect)
-{
- LLCoros::instance().launch("LLTwitterConnect::twitterConnectedCoro",
- boost::bind(&LLTwitterConnect::twitterConnectedCoro, this, auto_connect));
-}
-
-void LLTwitterConnect::loadTwitterInfo()
-{
- if(mRefreshInfo)
- {
- LLCoros::instance().launch("LLTwitterConnect::twitterInfoCoro",
- boost::bind(&LLTwitterConnect::twitterInfoCoro, this));
- }
-}
-
-void LLTwitterConnect::uploadPhoto(const std::string& image_url, const std::string& status)
-{
- LLSD body;
- body["image"] = image_url;
- body["status"] = status;
-
- setConnectionState(LLTwitterConnect::TWITTER_POSTING);
-
- LLCoros::instance().launch("LLTwitterConnect::twitterShareCoro",
- boost::bind(&LLTwitterConnect::twitterShareCoro, this, "/share/photo", body));
-}
-
-void LLTwitterConnect::uploadPhoto(LLPointer<LLImageFormatted> image, const std::string& status)
-{
- setConnectionState(LLTwitterConnect::TWITTER_POSTING);
-
- LLCoros::instance().launch("LLTwitterConnect::twitterShareImageCoro",
- boost::bind(&LLTwitterConnect::twitterShareImageCoro, this, image, status));
-}
-
-void LLTwitterConnect::updateStatus(const std::string& status)
-{
- LLSD body;
- body["status"] = status;
-
- setConnectionState(LLTwitterConnect::TWITTER_POSTING);
-
- LLCoros::instance().launch("LLTwitterConnect::twitterShareCoro",
- boost::bind(&LLTwitterConnect::twitterShareCoro, this, "/share/status", body));
-}
-
-void LLTwitterConnect::storeInfo(const LLSD& info)
-{
- mInfo = info;
- mRefreshInfo = false;
-
- sInfoWatcher->post(info);
-}
-
-const LLSD& LLTwitterConnect::getInfo() const
-{
- return mInfo;
-}
-
-void LLTwitterConnect::clearInfo()
-{
- mInfo = LLSD();
-}
-
-void LLTwitterConnect::setDataDirty()
-{
- mRefreshInfo = true;
-}
-
-void LLTwitterConnect::setConnectionState(LLTwitterConnect::EConnectionState connection_state)
-{
- if(connection_state == TWITTER_CONNECTED)
- {
- mReadFromMaster = true;
- setConnected(true);
- setDataDirty();
- }
- else if(connection_state == TWITTER_NOT_CONNECTED)
- {
- setConnected(false);
- }
- else if(connection_state == TWITTER_POSTED)
- {
- mReadFromMaster = false;
- }
-
- if (mConnectionState != connection_state)
- {
- // set the connection state before notifying watchers
- mConnectionState = connection_state;
-
- LLSD state_info;
- state_info["enum"] = connection_state;
- sStateWatcher->post(state_info);
- }
-}
-
-void LLTwitterConnect::setConnected(bool connected)
-{
- mConnected = connected;
-}
diff --git a/indra/newview/lltwitterconnect.h b/indra/newview/lltwitterconnect.h
deleted file mode 100644
index e77048cc35..0000000000
--- a/indra/newview/lltwitterconnect.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * @file lltwitterconnect.h
- * @author Merov, Cho
- * @brief Connection to Twitter Service
- *
- * $LicenseInfo:firstyear=2013&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2013, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLTWITTERCONNECT_H
-#define LL_LLTWITTERCONNECT_H
-
-#include "llsingleton.h"
-#include "llimage.h"
-#include "llcoros.h"
-#include "lleventcoro.h"
-
-class LLEventPump;
-
-/**
- * @class LLTwitterConnect
- *
- * Manages authentication to, and interaction with, a web service allowing the
- * the viewer to post status updates and upload photos to Twitter.
- */
-class LLTwitterConnect : public LLSingleton<LLTwitterConnect>
-{
- LLSINGLETON(LLTwitterConnect);
- LOG_CLASS(LLTwitterConnect);
-public:
- enum EConnectionState
- {
- TWITTER_NOT_CONNECTED = 0,
- TWITTER_CONNECTION_IN_PROGRESS = 1,
- TWITTER_CONNECTED = 2,
- TWITTER_CONNECTION_FAILED = 3,
- TWITTER_POSTING = 4,
- TWITTER_POSTED = 5,
- TWITTER_POST_FAILED = 6,
- TWITTER_DISCONNECTING = 7,
- TWITTER_DISCONNECT_FAILED = 8
- };
-
- void connectToTwitter(const std::string& request_token = "", const std::string& oauth_verifier = ""); // Initiate the complete Twitter connection. Please use checkConnectionToTwitter() in normal use.
- void disconnectFromTwitter(); // Disconnect from the Twitter service.
- void checkConnectionToTwitter(bool auto_connect = false); // Check if an access token is available on the Twitter service. If not, call connectToTwitter().
-
- void loadTwitterInfo();
- void uploadPhoto(const std::string& image_url, const std::string& status);
- void uploadPhoto(LLPointer<LLImageFormatted> image, const std::string& status);
- void updateStatus(const std::string& status);
-
- void storeInfo(const LLSD& info);
- const LLSD& getInfo() const;
- void clearInfo();
- void setDataDirty();
-
- void setConnectionState(EConnectionState connection_state);
- void setConnected(bool connected);
- bool isConnected() { return mConnected; }
- bool isTransactionOngoing() { return ((mConnectionState == TWITTER_CONNECTION_IN_PROGRESS) || (mConnectionState == TWITTER_POSTING) || (mConnectionState == TWITTER_DISCONNECTING)); }
- EConnectionState getConnectionState() { return mConnectionState; }
-
- void openTwitterWeb(std::string url);
-
-private:
-
- std::string getTwitterConnectURL(const std::string& route = "", bool include_read_from_master = false);
-
- EConnectionState mConnectionState;
- BOOL mConnected;
- LLSD mInfo;
- bool mRefreshInfo;
- bool mReadFromMaster;
-
- static boost::scoped_ptr<LLEventPump> sStateWatcher;
- static boost::scoped_ptr<LLEventPump> sInfoWatcher;
- static boost::scoped_ptr<LLEventPump> sContentWatcher;
-
- bool testShareStatus(LLSD &result);
- void twitterConnectCoro(std::string requestToken, std::string oauthVerifier);
- void twitterDisconnectCoro();
- void twitterConnectedCoro(bool autoConnect);
- void twitterInfoCoro();
- void twitterShareCoro(std::string route, LLSD share);
- void twitterShareImageCoro(LLPointer<LLImageFormatted> image, std::string status);
-};
-
-#endif // LL_LLTWITTERCONNECT_H
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index d8526e63ca..6df849674f 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1087,7 +1087,7 @@ void render_hud_attachments()
// clamp target zoom level to reasonable values
gAgentCamera.mHUDTargetZoom = llclamp(gAgentCamera.mHUDTargetZoom, 0.1f, 1.f);
// smoothly interpolate current zoom level
- gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.mHUDTargetZoom, LLSmoothInterpolation::getInterpolant(0.03f));
+ gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.getAgentHUDTargetZoom(), LLSmoothInterpolation::getInterpolant(0.03f));
if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
{
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 4f51c74c57..286b1fcb00 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -68,7 +68,6 @@
#include "llfloaterexperiences.h"
#include "llfloaterexperiencepicker.h"
#include "llfloaterevent.h"
-#include "llfloaterflickr.h"
#include "llfloaterfonttest.h"
#include "llfloatergesture.h"
#include "llfloatergodtools.h"
@@ -134,7 +133,6 @@
#include "llfloatertos.h"
#include "llfloatertoybox.h"
#include "llfloatertranslationsettings.h"
-#include "llfloatertwitter.h"
#include "llfloateruipreview.h"
#include "llfloatervoiceeffect.h"
#include "llfloaterwebcontent.h"
@@ -356,11 +354,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>);
LLFloaterReg::add("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
- LLFloaterReg::add("flickr_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
- LLFloaterReg::add("twitter_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
-
- LLFloaterReg::add("flickr", "floater_flickr.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFlickr>);
- LLFloaterReg::add("twitter", "floater_twitter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTwitter>);
LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>);
LLFloaterUIPreviewUtil::registerFloater();
diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp
index cf9243a871..8a597ed7e6 100644
--- a/indra/newview/llviewerjointattachment.cpp
+++ b/indra/newview/llviewerjointattachment.cpp
@@ -225,7 +225,7 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
iter != mAttachedObjects.end();
++iter)
{
- LLViewerObject *attached_object = (*iter);
+ LLViewerObject *attached_object = iter->get();
if (attached_object == object)
{
break;
@@ -327,7 +327,7 @@ void LLViewerJointAttachment::setAttachmentVisibility(BOOL visible)
iter != mAttachedObjects.end();
++iter)
{
- LLViewerObject *attached_obj = (*iter);
+ LLViewerObject *attached_obj = iter->get();
if (!attached_obj || attached_obj->mDrawable.isNull() ||
!(attached_obj->mDrawable->getSpatialBridge()))
continue;
@@ -366,7 +366,7 @@ S32 LLViewerJointAttachment::getNumAnimatedObjects() const
iter != mAttachedObjects.end();
++iter)
{
- const LLViewerObject *attached_object = *iter;
+ const LLViewerObject *attached_object = iter->get();
if (attached_object->isAnimatedObject())
{
count++;
@@ -384,7 +384,7 @@ void LLViewerJointAttachment::clampObjectPosition()
iter != mAttachedObjects.end();
++iter)
{
- if (LLViewerObject *attached_object = (*iter))
+ if (LLViewerObject *attached_object = iter->get())
{
// *NOTE: object can drift when hitting maximum radius
LLVector3 attachmentPos = attached_object->getPosition();
@@ -406,7 +406,7 @@ void LLViewerJointAttachment::calcLOD()
iter != mAttachedObjects.end();
++iter)
{
- if (LLViewerObject *attached_object = (*iter))
+ if (LLViewerObject *attached_object = iter->get())
{
maxarea = llmax(maxarea,attached_object->getMaxScale() * attached_object->getMidScale());
LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
@@ -445,7 +445,7 @@ BOOL LLViewerJointAttachment::isObjectAttached(const LLViewerObject *viewer_obje
iter != mAttachedObjects.end();
++iter)
{
- const LLViewerObject* attached_object = (*iter);
+ const LLViewerObject* attached_object = iter->get();
if (attached_object == viewer_object)
{
return TRUE;
@@ -460,7 +460,7 @@ const LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &o
iter != mAttachedObjects.end();
++iter)
{
- const LLViewerObject* attached_object = (*iter);
+ const LLViewerObject* attached_object = iter->get();
if (attached_object->getAttachmentItemID() == object_id)
{
return attached_object;
@@ -475,7 +475,7 @@ LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &object_
iter != mAttachedObjects.end();
++iter)
{
- LLViewerObject* attached_object = (*iter);
+ LLViewerObject* attached_object = iter->get();
if (attached_object->getAttachmentItemID() == object_id)
{
return attached_object;
diff --git a/indra/newview/llviewerjointattachment.h b/indra/newview/llviewerjointattachment.h
index 9641ab4208..e5edf2c06b 100644
--- a/indra/newview/llviewerjointattachment.h
+++ b/indra/newview/llviewerjointattachment.h
@@ -95,7 +95,7 @@ public:
LLViewerObject *getAttachedObject(const LLUUID &object_id);
// list of attachments for this joint
- typedef std::vector<LLViewerObject *> attachedobjs_vec_t;
+ typedef std::vector<LLPointer<LLViewerObject> > attachedobjs_vec_t;
attachedobjs_vec_t mAttachedObjects;
protected:
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index a6363b5aab..00c85cd3c6 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -6709,10 +6709,10 @@ private:
static void onNearAttachObject(BOOL success, void *user_data);
void confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point);
-
- struct CallbackData
+ class CallbackData : public LLSelectionCallbackData
{
- CallbackData(LLViewerJointAttachment* point, bool replace) : mAttachmentPoint(point), mReplace(replace) {}
+ public:
+ CallbackData(LLViewerJointAttachment* point, bool replace) : LLSelectionCallbackData(), mAttachmentPoint(point), mReplace(replace) {}
LLViewerJointAttachment* mAttachmentPoint;
bool mReplace;
@@ -6753,8 +6753,8 @@ void LLObjectAttachToAvatar::onNearAttachObject(BOOL success, void *user_data)
// interpret 0 as "default location"
attachment_id = 0;
}
- LLSelectMgr::getInstance()->sendAttach(attachment_id, cb_data->mReplace);
- }
+ LLSelectMgr::getInstance()->sendAttach(cb_data->getSelection(), attachment_id, cb_data->mReplace);
+ }
LLObjectAttachToAvatar::setObjectSelection(NULL);
delete cb_data;
@@ -6877,7 +6877,7 @@ class LLAttachmentDetachFromPoint : public view_listener_t
iter != attachment->mAttachedObjects.end();
iter++)
{
- LLViewerObject *attached_object = (*iter);
+ LLViewerObject *attached_object = iter->get();
ids_to_remove.push_back(attached_object->getAttachmentItemID());
}
}
@@ -6903,7 +6903,7 @@ static bool onEnableAttachmentLabel(LLUICtrl* ctrl, const LLSD& data)
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- const LLViewerObject* attached_object = (*attachment_iter);
+ const LLViewerObject* attached_object = attachment_iter->get();
if (attached_object)
{
LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID());
@@ -7016,7 +7016,7 @@ class LLAttachmentEnableDrop : public view_listener_t
{
// make sure item is in your inventory (it could be a delayed attach message being sent from the sim)
// so check to see if the item is in the inventory already
- item = gInventory.getItem((*attachment_iter)->getAttachmentItemID());
+ item = gInventory.getItem(attachment_iter->get()->getAttachmentItemID());
if (!item)
{
// Item does not exist, make an observer to enable the pie menu
@@ -7398,7 +7398,7 @@ void handle_dump_attachments(void*)
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject *attached_object = (*attachment_iter);
+ LLViewerObject *attached_object = attachment_iter->get();
BOOL visible = (attached_object != NULL &&
attached_object->mDrawable.notNull() &&
!attached_object->mDrawable->isRenderType(0));
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index b0ad81614a..fe67182bc4 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1671,8 +1671,20 @@ void LLOfferInfo::fromLLSD(const LLSD& params)
*this = params;
}
-void LLOfferInfo::send_auto_receive_response(void)
-{
+void LLOfferInfo::sendReceiveResponse(bool accept, const LLUUID &destination_folder_id)
+{
+ if(IM_INVENTORY_OFFERED == mIM)
+ {
+ // add buddy to recent people list
+ LLRecentPeople::instance().add(mFromID);
+ }
+
+ if (mTransactionID.isNull())
+ {
+ // Not provided, message won't work
+ return;
+ }
+
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -1691,23 +1703,42 @@ void LLOfferInfo::send_auto_receive_response(void)
msg->addU32Fast(_PREHASH_ParentEstateID, 0);
msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
-
- // Auto Receive Message. The math for the dialog works, because the accept
+
+ // ACCEPT. The math for the dialog works, because the accept
// for inventory_offered, task_inventory_offer or
// group_notice_inventory is 1 greater than the offer integer value.
// Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED,
// or IM_GROUP_NOTICE_INVENTORY_ACCEPTED
- msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1));
- msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData),
- sizeof(mFolderID.mData));
- // send the message
- msg->sendReliable(mHost);
-
- if(IM_INVENTORY_OFFERED == mIM)
+ // Decline for inventory_offered, task_inventory_offer or
+ // group_notice_inventory is 2 greater than the offer integer value.
+
+ EInstantMessage im = mIM;
+ if (mIM == IM_GROUP_NOTICE_REQUESTED)
{
- // add buddy to recent people list
- LLRecentPeople::instance().add(mFromID);
+ // Request has no responder dialogs
+ im = IM_GROUP_NOTICE;
+ }
+
+ if (accept)
+ {
+ msg->addU8Fast(_PREHASH_Dialog, (U8)(im + 1));
+ msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(destination_folder_id.mData),
+ sizeof(destination_folder_id.mData));
}
+ else
+ {
+ msg->addU8Fast(_PREHASH_Dialog, (U8)(im + 2));
+ msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE);
+ }
+ // send the message
+ msg->sendReliable(mHost);
+
+ // transaction id is usable only once
+ // Note: a bit of a hack, clicking group notice attachment will not close notice
+ // so we reset no longer usable transaction id to know not to send message again
+ // Once capabilities for responses will be implemented LLOfferInfo will have to
+ // remember that it already responded in another way and ignore IOR_DECLINE
+ mTransactionID.setNull();
}
void LLOfferInfo::handleRespond(const LLSD& notification, const LLSD& response)
@@ -1767,7 +1798,10 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
// TODO: when task inventory offers can also be handled the new way, migrate the code that sets these strings here:
from_string = chatHistory_string = mFromName;
-
+
+ // accept goes to proper folder, decline gets accepted to trash, muted gets declined
+ bool accept_to_trash = true;
+
LLNotificationFormPtr modified_form(notification_ptr ? new LLNotificationForm(*notification_ptr->getForm()) : new LLNotificationForm());
switch(button)
@@ -1799,11 +1833,11 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
}
break;
case IM_GROUP_NOTICE:
+ case IM_GROUP_NOTICE_REQUESTED:
opener = new LLOpenTaskGroupOffer;
- send_auto_receive_response();
+ sendReceiveResponse(true, mFolderID);
break;
case IM_TASK_INVENTORY_OFFERED:
- case IM_GROUP_NOTICE_REQUESTED:
// This is an offer from a task or group.
// We don't use a new instance of an opener
// We instead use the singular observer gOpenTaskOffer
@@ -1838,6 +1872,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
{
modified_form->setElementEnabled("Mute", false);
}
+ accept_to_trash = false; // for notices, but IOR_MUTE normally doesn't happen for notices
// MUTE falls through to decline
case IOR_DECLINE:
{
@@ -1851,21 +1886,32 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::getInstance()->isLinden(mFromName) ) // muting for SL-42269
{
chat.mMuted = TRUE;
+ accept_to_trash = false; // will send decline message
}
// *NOTE dzaporozhan
// Disabled logging to old chat floater to fix crash in group notices - EXT-4149
// LLFloaterChat::addChatHistory(chat);
- LLDiscardAgentOffer* discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID);
- discard_agent_offer->startFetch();
- if ((catp && gInventory.isCategoryComplete(mObjectID)) || (itemp && itemp->isFinished()))
+ if (mObjectID.notNull()) //make sure we can discard
{
- discard_agent_offer->done();
+ LLDiscardAgentOffer* discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID);
+ discard_agent_offer->startFetch();
+ if ((catp && gInventory.isCategoryComplete(mObjectID)) || (itemp && itemp->isFinished()))
+ {
+ discard_agent_offer->done();
+ }
+ else
+ {
+ opener = discard_agent_offer;
+ }
}
- else
+ else if (mIM == IM_GROUP_NOTICE)
{
- opener = discard_agent_offer;
+ // group notice needs to request object to trash so that user will see it later
+ // Note: muted agent offers go to trash, not sure if we should do same for notices
+ LLUUID trash = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ sendReceiveResponse(accept_to_trash, trash);
}
if (modified_form != NULL)
@@ -1878,9 +1924,14 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
}
default:
// close button probably
- // The item has already been fetched and is in your inventory, we simply won't highlight it
+ // In case of agent offers item has already been fetched and is in your inventory, we simply won't highlight it
// OR delete it if the notification gets killed, since we don't want that to be a vector for
// losing inventory offers.
+ if (mIM == IM_GROUP_NOTICE)
+ {
+ LLUUID trash = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ sendReceiveResponse(true, trash);
+ }
break;
}
@@ -1925,29 +1976,10 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
}
}
}
-
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_MessageBlock);
- msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
- msg->addUUIDFast(_PREHASH_ToAgentID, mFromID);
- msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
- msg->addUUIDFast(_PREHASH_ID, mTransactionID);
- msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
- std::string name;
- LLAgentUI::buildFullname(name);
- msg->addStringFast(_PREHASH_FromAgentName, name);
- msg->addStringFast(_PREHASH_Message, "");
- msg->addU32Fast(_PREHASH_ParentEstateID, 0);
- msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
- msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
- LLInventoryObserver* opener = NULL;
-
+
std::string from_string; // Used in the pop-up.
std::string chatHistory_string; // Used in chat history.
+
if (mFromObject == TRUE)
{
if (mFromGroup)
@@ -1991,23 +2023,15 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
from_string = chatHistory_string = mFromName;
}
- bool is_do_not_disturb = gAgent.isDoNotDisturb();
-
+ LLUUID destination;
+ bool accept = true;
+
+ // If user accepted, accept to proper folder, if user discarded, accept to trash.
switch(button)
{
case IOR_ACCEPT:
- // ACCEPT. The math for the dialog works, because the accept
- // for inventory_offered, task_inventory_offer or
- // group_notice_inventory is 1 greater than the offer integer value.
- // Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED,
- // or IM_GROUP_NOTICE_INVENTORY_ACCEPTED
- msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1));
- msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData),
- sizeof(mFolderID.mData));
- // send the message
- msg->sendReliable(mHost);
-
- //don't spam them if they are getting flooded
+ destination = mFolderID;
+ //don't spam user if flooded
if (check_offer_throttle(mFromName, true))
{
log_message = "<nolink>" + chatHistory_string + "</nolink> " + LLTrans::getString("InvOfferGaveYou") + " " + getSanitizedDescription() + LLTrans::getString(".");
@@ -2015,66 +2039,24 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
args["MESSAGE"] = log_message;
LLNotificationsUtil::add("SystemMessageTip", args);
}
-
- // we will want to open this item when it comes back.
- LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << mTransactionID
- << LL_ENDL;
- switch (mIM)
- {
- case IM_TASK_INVENTORY_OFFERED:
- case IM_GROUP_NOTICE:
- case IM_GROUP_NOTICE_REQUESTED:
- {
- // This is an offer from a task or group.
- // We don't use a new instance of an opener
- // We instead use the singular observer gOpenTaskOffer
- // Since it already exists, we don't need to actually do anything
- }
- break;
- default:
- LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
- break;
- } // end switch (mIM)
break;
-
case IOR_MUTE:
// MUTE falls through to decline
+ accept = false;
case IOR_DECLINE:
- // DECLINE. The math for the dialog works, because the decline
- // for inventory_offered, task_inventory_offer or
- // group_notice_inventory is 2 greater than the offer integer value.
- // Generates IM_INVENTORY_DECLINED, IM_TASK_INVENTORY_DECLINED,
- // or IM_GROUP_NOTICE_INVENTORY_DECLINED
default:
// close button probably (or any of the fall-throughs from above)
- msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 2));
- msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE);
- // send the message
- msg->sendReliable(mHost);
-
- if (gSavedSettings.getBOOL("LogInventoryDecline"))
- {
- LLStringUtil::format_map_t log_message_args;
- log_message_args["DESC"] = mDesc;
- log_message_args["NAME"] = mFromName;
- log_message = LLTrans::getString("InvOfferDecline", log_message_args);
-
- LLSD args;
- args["MESSAGE"] = log_message;
- LLNotificationsUtil::add("SystemMessageTip", args);
- }
-
- if (is_do_not_disturb && (!mFromGroup && !mFromObject))
+ destination = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if (accept && LLMuteList::getInstance()->isMuted(mFromID, mFromName))
{
- send_do_not_disturb_message(msg,mFromID);
+ // Note: muted offers are usually declined automatically,
+ // but user can mute object after receiving message
+ accept = false;
}
break;
}
-
- if(opener)
- {
- gInventory.addObserver(opener);
- }
+
+ sendReceiveResponse(accept, destination);
if(!mPersist)
{
@@ -4045,6 +4027,8 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationList);
S32 num_source_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationSourceList);
+ LL_DEBUGS("Messaging", "Motion") << "Processing " << num_blocks << " Animations" << LL_ENDL;
+
//clear animation flags
avatarp->mSignaledAnimations.clear();
@@ -4057,8 +4041,6 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
mesgsys->getUUIDFast(_PREHASH_AnimationList, _PREHASH_AnimID, animation_id, i);
mesgsys->getS32Fast(_PREHASH_AnimationList, _PREHASH_AnimSequenceID, anim_sequence_id, i);
- LL_DEBUGS("Messaging") << "Anim sequence ID: " << anim_sequence_id << LL_ENDL;
-
avatarp->mSignaledAnimations[animation_id] = anim_sequence_id;
// *HACK: Disabling flying mode if it has been enabled shortly before the agent
@@ -4097,6 +4079,14 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
avatarp->mAnimationSources.insert(LLVOAvatar::AnimationSourceMap::value_type(object_id, animation_id));
}
}
+ LL_DEBUGS("Messaging", "Motion") << "Anim sequence ID: " << anim_sequence_id
+ << " Animation id: " << animation_id
+ << " From block: " << object_id << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("Messaging", "Motion") << "Anim sequence ID: " << anim_sequence_id
+ << " Animation id: " << animation_id << LL_ENDL;
}
}
}
@@ -5163,12 +5153,27 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
}
}
- // Error Notification can come with and without reason
- if (notificationID == "JoinGroupError" && llsdBlock.has("reason"))
- {
- LLNotificationsUtil::add("JoinGroupErrorReason", llsdBlock);
- return true;
- }
+ // Error Notification can come with and without reason
+ if (notificationID == "JoinGroupError")
+ {
+ if (llsdBlock.has("reason"))
+ {
+ LLNotificationsUtil::add("JoinGroupErrorReason", llsdBlock);
+ return true;
+ }
+ if (llsdBlock.has("group_id"))
+ {
+ LLGroupData agent_gdatap;
+ bool is_member = gAgent.getGroupData(llsdBlock["group_id"].asUUID(), agent_gdatap);
+ if (is_member)
+ {
+ LLSD args;
+ args["reason"] = LLTrans::getString("AlreadyInGroup");
+ LLNotificationsUtil::add("JoinGroupErrorReason", args);
+ return true;
+ }
+ }
+ }
LLNotificationsUtil::add(notificationID, llsdBlock);
return true;
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index 2d6636f30d..78829a6a56 100644
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -254,7 +254,7 @@ public:
/*virtual*/ void fromLLSD(const LLSD& params);
/*virtual*/ void handleRespond(const LLSD& notification, const LLSD& response);
- void send_auto_receive_response(void);
+ void send_auto_receive_response() { sendReceiveResponse(true, mFolderID); }
// TODO - replace all references with handleRespond()
bool inventory_offer_callback(const LLSD& notification, const LLSD& response);
@@ -264,6 +264,7 @@ private:
void initRespondFunctionMap();
std::string getSanitizedDescription();
+ void sendReceiveResponse(bool accept, const LLUUID &destination_folder_id);
typedef boost::function<bool (const LLSD&, const LLSD&)> respond_function_t;
typedef std::map<std::string, respond_function_t> respond_function_map_t;
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index c7a77d4d2a..17e61d3a0d 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -142,6 +142,9 @@ const F32 PHYSICS_TIMESTEP = 1.f / 45.f;
const U32 MAX_INV_FILE_READ_FAILS = 25;
const S32 MAX_OBJECT_BINARY_DATA_SIZE = 60 + 16;
+const F64 INVENTORY_UPDATE_WAIT_TIME_DESYNC = 5; // seconds
+const F64 INVENTORY_UPDATE_WAIT_TIME_OUTDATED = 1;
+
static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object");
// static
@@ -269,6 +272,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mPixelArea(1024.f),
mInventory(NULL),
mInventorySerialNum(0),
+ mExpectedInventorySerialNum(0),
mInvRequestState(INVENTORY_REQUEST_STOPPED),
mInvRequestXFerId(0),
mInventoryDirty(FALSE),
@@ -1279,7 +1283,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
{
case (60 + 16):
// pull out collision normal for avatar
- htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+ htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
((LLVOAvatar*)this)->setFootPlane(collision_plane);
count += sizeof(LLVector4);
// fall through
@@ -1287,23 +1291,23 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
this_update_precision = 32;
// this is a terse update
// pos
- htonmemcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
count += sizeof(LLVector3);
// vel
- htonmemcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
count += sizeof(LLVector3);
// acc
- htonmemcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
count += sizeof(LLVector3);
// theta
{
LLVector3 vec;
- htonmemcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
new_rot.unpackFromVector3(vec);
}
count += sizeof(LLVector3);
// omega
- htonmemcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
if (new_angv.isExactlyZero())
{
// reset rotation time
@@ -1319,7 +1323,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
break;
case(32 + 16):
// pull out collision normal for avatar
- htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+ htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
((LLVOAvatar*)this)->setFootPlane(collision_plane);
count += sizeof(LLVector4);
// fall through
@@ -1329,7 +1333,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
// This is a terse 16 update, so treat data as an array of U16's.
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1340,7 +1344,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1351,7 +1355,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
U16_to_F32(val[VZ], -size, size)));
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1362,7 +1366,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
U16_to_F32(val[VZ], -size, size)));
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Quat, 4);
+ htolememcpy(valswizzle, &data[count], MVT_U16Quat, 4);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1374,7 +1378,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1570,7 +1574,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
{
case(60 + 16):
// pull out collision normal for avatar
- htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+ htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
((LLVOAvatar*)this)->setFootPlane(collision_plane);
count += sizeof(LLVector4);
// fall through
@@ -1578,23 +1582,23 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
// this is a terse 32 update
// pos
this_update_precision = 32;
- htonmemcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
count += sizeof(LLVector3);
// vel
- htonmemcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
count += sizeof(LLVector3);
// acc
- htonmemcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
count += sizeof(LLVector3);
// theta
{
LLVector3 vec;
- htonmemcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
new_rot.unpackFromVector3(vec);
}
count += sizeof(LLVector3);
// omega
- htonmemcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
if (new_angv.isExactlyZero())
{
// reset rotation time
@@ -1610,7 +1614,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
break;
case(32 + 16):
// pull out collision normal for avatar
- htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+ htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
((LLVOAvatar*)this)->setFootPlane(collision_plane);
count += sizeof(LLVector4);
// fall through
@@ -1620,7 +1624,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1631,7 +1635,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1642,7 +1646,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
U16_to_F32(val[VZ], -size, size));
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1653,7 +1657,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
U16_to_F32(val[VZ], -size, size));
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Quat, 8);
+ htolememcpy(valswizzle, &data[count], MVT_U16Quat, 8);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1665,7 +1669,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -2802,13 +2806,13 @@ void LLViewerObject::doUpdateInventory(
{
// best guess.
perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), item->getPermissions().getGroup(), is_atomic);
- --mInventorySerialNum;
+ --mExpectedInventorySerialNum;
}
else
{
// dummy it up.
perm.setOwnerAndGroup(LLUUID::null, LLUUID::null, LLUUID::null, is_atomic);
- --mInventorySerialNum;
+ --mExpectedInventorySerialNum;
}
}
LLViewerInventoryItem* oldItem = item;
@@ -2816,7 +2820,11 @@ void LLViewerObject::doUpdateInventory(
new_item->setPermissions(perm);
mInventory->push_front(new_item);
doInventoryCallback();
- ++mInventorySerialNum;
+ ++mExpectedInventorySerialNum;
+ }
+ else if (is_new)
+ {
+ ++mExpectedInventorySerialNum;
}
}
@@ -2883,7 +2891,7 @@ void LLViewerObject::moveInventory(const LLUUID& folder_id,
if(!item->getPermissions().allowCopyBy(gAgent.getID()))
{
deleteInventoryItem(item_id);
- ++mInventorySerialNum;
+ ++mExpectedInventorySerialNum;
}
}
}
@@ -2974,6 +2982,8 @@ void LLViewerObject::fetchInventoryFromServer()
if (!isInventoryPending())
{
delete mInventory;
+
+ // Results in processTaskInv
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_RequestTaskInventory);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -2983,11 +2993,44 @@ void LLViewerObject::fetchInventoryFromServer()
msg->addU32Fast(_PREHASH_LocalID, mLocalID);
msg->sendReliable(mRegionp->getHost());
- // this will get reset by dirtyInventory or doInventoryCallback
+ // This will get reset by doInventoryCallback or processTaskInv
mInvRequestState = INVENTORY_REQUEST_PENDING;
}
}
+void LLViewerObject::fetchInventoryDelayed(const F64 &time_seconds)
+{
+ // unless already waiting, drop previous request and shedule an update
+ if (mInvRequestState != INVENTORY_REQUEST_WAIT)
+ {
+ if (mInvRequestXFerId != 0)
+ {
+ // abort download.
+ gXferManager->abortRequestById(mInvRequestXFerId, -1);
+ mInvRequestXFerId = 0;
+ }
+ mInvRequestState = INVENTORY_REQUEST_WAIT; // affects isInventoryPending()
+ LLCoros::instance().launch("LLViewerObject::fetchInventoryDelayedCoro()",
+ boost::bind(&LLViewerObject::fetchInventoryDelayedCoro, mID, time_seconds));
+ }
+}
+
+//static
+void LLViewerObject::fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds)
+{
+ llcoro::suspendUntilTimeout(time_seconds);
+ LLViewerObject *obj = gObjectList.findObject(task_inv);
+ if (obj)
+ {
+ // Might be good idea to prolong delay here in case expected serial changed.
+ // As it is, it will get a response with obsolete serial and will delay again.
+
+ // drop waiting state to unlock isInventoryPending()
+ obj->mInvRequestState = INVENTORY_REQUEST_STOPPED;
+ obj->fetchInventoryFromServer();
+ }
+}
+
LLControlAvatar *LLViewerObject::getControlAvatar()
{
return getRootEdit()->mControlAvatar.get();
@@ -3146,74 +3189,97 @@ S32 LLFilenameAndTask::sCount = 0;
// static
void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
{
- LLUUID task_id;
- msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_TaskID, task_id);
- LLViewerObject* object = gObjectList.findObject(task_id);
- if(!object)
- {
- LL_WARNS() << "LLViewerObject::processTaskInv object "
- << task_id << " does not exist." << LL_ENDL;
- return;
- }
+ LLUUID task_id;
+ msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_TaskID, task_id);
+ LLViewerObject* object = gObjectList.findObject(task_id);
+ if (!object)
+ {
+ LL_WARNS() << "LLViewerObject::processTaskInv object "
+ << task_id << " does not exist." << LL_ENDL;
+ return;
+ }
- LLFilenameAndTask* ft = new LLFilenameAndTask;
- ft->mTaskID = task_id;
- // we can receive multiple task updates simultaneously, make sure we will not rewrite newer with older update
- msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, ft->mSerial);
+ LLFilenameAndTask* ft = new LLFilenameAndTask;
+ ft->mTaskID = task_id;
+ // we can receive multiple task updates simultaneously, make sure we will not rewrite newer with older update
+ msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, ft->mSerial);
- if (ft->mSerial < object->mInventorySerialNum)
- {
- // viewer did some changes to inventory that were not saved yet.
- LL_DEBUGS() << "Task inventory serial might be out of sync, server serial: " << ft->mSerial << " client serial: " << object->mInventorySerialNum << LL_ENDL;
- object->mInventorySerialNum = ft->mSerial;
- }
+ if (ft->mSerial == object->mInventorySerialNum
+ && ft->mSerial < object->mExpectedInventorySerialNum)
+ {
+ // Loop Protection.
+ // We received same serial twice.
+ // Viewer did some changes to inventory that couldn't be saved server side
+ // or something went wrong to cause serial to be out of sync.
+ // Drop xfer and restart after some time, assign server's value as expected
+ LL_WARNS() << "Task inventory serial might be out of sync, server serial: " << ft->mSerial << " client expected serial: " << object->mExpectedInventorySerialNum << LL_ENDL;
+ object->mExpectedInventorySerialNum = ft->mSerial;
+ object->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_DESYNC);
+ }
+ else if (ft->mSerial < object->mExpectedInventorySerialNum)
+ {
+ // Out of date message, record to current serial for loop protection, but do not load it
+ // Drop xfer and restart after some time
+ if (ft->mSerial < object->mInventorySerialNum)
+ {
+ LL_WARNS() << "Task serial decreased. Potentially out of order packet or desync." << LL_ENDL;
+ }
+ object->mInventorySerialNum = ft->mSerial;
+ object->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_OUTDATED);
+ }
+ else if (ft->mSerial >= object->mExpectedInventorySerialNum)
+ {
+ // We received version we expected or newer. Load it.
+ object->mInventorySerialNum = ft->mSerial;
+ object->mExpectedInventorySerialNum = ft->mSerial;
- std::string unclean_filename;
- msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, unclean_filename);
- ft->mFilename = LLDir::getScrubbedFileName(unclean_filename);
+ std::string unclean_filename;
+ msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, unclean_filename);
+ ft->mFilename = LLDir::getScrubbedFileName(unclean_filename);
- if(ft->mFilename.empty())
- {
- LL_DEBUGS() << "Task has no inventory" << LL_ENDL;
- // mock up some inventory to make a drop target.
- if(object->mInventory)
- {
- object->mInventory->clear(); // will deref and delete it
- }
- else
- {
- object->mInventory = new LLInventoryObject::object_list_t();
- }
- LLPointer<LLInventoryObject> obj;
- obj = new LLInventoryObject(object->mID, LLUUID::null,
- LLAssetType::AT_CATEGORY,
- "Contents");
- object->mInventory->push_front(obj);
- object->doInventoryCallback();
- delete ft;
- return;
- }
- U64 new_id = gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename),
- ft->mFilename, LL_PATH_CACHE,
- object->mRegionp->getHost(),
- TRUE,
- &LLViewerObject::processTaskInvFile,
- (void**)ft,
- LLXferManager::HIGH_PRIORITY);
- if (object->mInvRequestState == INVENTORY_XFER)
- {
- if (new_id > 0 && new_id != object->mInvRequestXFerId)
- {
- // we started new download.
- gXferManager->abortRequestById(object->mInvRequestXFerId, -1);
- object->mInvRequestXFerId = new_id;
- }
- }
- else
- {
- object->mInvRequestState = INVENTORY_XFER;
- object->mInvRequestXFerId = new_id;
- }
+ if (ft->mFilename.empty())
+ {
+ LL_DEBUGS() << "Task has no inventory" << LL_ENDL;
+ // mock up some inventory to make a drop target.
+ if (object->mInventory)
+ {
+ object->mInventory->clear(); // will deref and delete it
+ }
+ else
+ {
+ object->mInventory = new LLInventoryObject::object_list_t();
+ }
+ LLPointer<LLInventoryObject> obj;
+ obj = new LLInventoryObject(object->mID, LLUUID::null,
+ LLAssetType::AT_CATEGORY,
+ "Contents");
+ object->mInventory->push_front(obj);
+ object->doInventoryCallback();
+ delete ft;
+ return;
+ }
+ U64 new_id = gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename),
+ ft->mFilename, LL_PATH_CACHE,
+ object->mRegionp->getHost(),
+ TRUE,
+ &LLViewerObject::processTaskInvFile,
+ (void**)ft,
+ LLXferManager::HIGH_PRIORITY);
+ if (object->mInvRequestState == INVENTORY_XFER)
+ {
+ if (new_id > 0 && new_id != object->mInvRequestXFerId)
+ {
+ // we started new download.
+ gXferManager->abortRequestById(object->mInvRequestXFerId, -1);
+ object->mInvRequestXFerId = new_id;
+ }
+ }
+ else
+ {
+ object->mInvRequestState = INVENTORY_XFER;
+ object->mInvRequestXFerId = new_id;
+ }
+ }
}
void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status)
@@ -3227,6 +3293,13 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS
&& ft->mSerial >= object->mInventorySerialNum)
{
object->mInventorySerialNum = ft->mSerial;
+ LL_DEBUGS() << "Receiving inventory task file for serial " << object->mInventorySerialNum << " taskid: " << ft->mTaskID << LL_ENDL;
+ if (ft->mSerial < object->mExpectedInventorySerialNum)
+ {
+ // User managed to change something while inventory was loading
+ LL_DEBUGS() << "Processing file that is potentially out of date for task: " << ft->mTaskID << LL_ENDL;
+ }
+
if (object->loadTaskInvFile(ft->mFilename))
{
@@ -3376,7 +3449,7 @@ void LLViewerObject::removeInventory(const LLUUID& item_id)
msg->addUUIDFast(_PREHASH_ItemID, item_id);
msg->sendReliable(mRegionp->getHost());
deleteInventoryItem(item_id);
- ++mInventorySerialNum;
+ ++mExpectedInventorySerialNum;
}
bool LLViewerObject::isTextureInInventory(LLViewerInventoryItem* item)
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 873b300489..e9ae26939a 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -474,6 +474,8 @@ public:
void updateInventoryLocal(LLInventoryItem* item, U8 key); // Update without messaging.
void updateTextureInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
LLInventoryObject* getInventoryObject(const LLUUID& item_id);
+
+ // Get content except for root category
void getInventoryContents(LLInventoryObject::object_list_t& objects);
LLInventoryObject* getInventoryRoot();
LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id);
@@ -623,9 +625,13 @@ private:
static void initObjectDataMap();
- // forms task inventory request if none are pending
+ // forms task inventory request if none are pending, marks request as pending
void fetchInventoryFromServer();
+ // forms task inventory request after some time passed, marks request as pending
+ void fetchInventoryDelayed(const F64 &time_seconds);
+ static void fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds);
+
public:
//
// Viewer-side only types - use the LL_PCODE_APP mask.
@@ -804,12 +810,14 @@ protected:
typedef std::list<LLInventoryCallbackInfo*> callback_list_t;
callback_list_t mInventoryCallbacks;
S16 mInventorySerialNum;
+ S16 mExpectedInventorySerialNum;
enum EInventoryRequestState
{
INVENTORY_REQUEST_STOPPED,
- INVENTORY_REQUEST_PENDING,
- INVENTORY_XFER
+ INVENTORY_REQUEST_WAIT, // delay before requesting
+ INVENTORY_REQUEST_PENDING, // just did fetchInventoryFromServer()
+ INVENTORY_XFER // processed response from 'fetch', now doing an xfer
};
EInventoryRequestState mInvRequestState;
U64 mInvRequestXFerId;
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 2bf04dc204..63e48d1dd0 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -1921,7 +1921,7 @@ void LLViewerObjectList::generatePickList(LLCamera &camera)
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- if (LLViewerObject* attached_object = (*attachment_iter))
+ if (LLViewerObject* attached_object = attachment_iter->get())
{
mSelectPickList.insert(attached_object);
LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 5b227c641b..75e707aaa3 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -2895,8 +2895,6 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("EstateAccess");
capabilityNames.append("EstateChangeInfo");
capabilityNames.append("EventQueueGet");
- capabilityNames.append("FlickrConnect");
- capabilityNames.append("TwitterConnect");
capabilityNames.append("FetchLib2");
capabilityNames.append("FetchLibDescendents2");
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 61f4ee463d..c214984e1d 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -938,6 +938,12 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
mLeftMouseDown = down;
buttonname = "Left Double Click";
break;
+ case LLMouseHandler::CLICK_BUTTON4:
+ buttonname = "Button 4";
+ break;
+ case LLMouseHandler::CLICK_BUTTON5:
+ buttonname = "Button 5";
+ break;
}
LLView::sMouseHandlerMessage.clear();
@@ -1115,7 +1121,7 @@ BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK m
BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
{
BOOL down = TRUE;
- LLVoiceClient::getInstance()->middleMouseState(true);
+ LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, true);
handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
// Always handled as far as the OS is concerned.
@@ -1267,17 +1273,47 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi
return result;
}
-
+
BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
{
BOOL down = FALSE;
- LLVoiceClient::getInstance()->middleMouseState(false);
+ LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, false);
handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
// Always handled as far as the OS is concerned.
return TRUE;
}
+BOOL LLViewerWindow::handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask, S32 button, bool down)
+{
+ switch (button)
+ {
+ case 4:
+ LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON4, down);
+ handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON4, down);
+ break;
+ case 5:
+ LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON5, down);
+ handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON5, down);
+ break;
+ default:
+ break;
+ }
+
+ // Always handled as far as the OS is concerned.
+ return TRUE;
+}
+
+BOOL LLViewerWindow::handleOtherMouseDown(LLWindow *window, LLCoordGL pos, MASK mask, S32 button)
+{
+ return handleOtherMouse(window, pos, mask, button, TRUE);
+}
+
+BOOL LLViewerWindow::handleOtherMouseUp(LLWindow *window, LLCoordGL pos, MASK mask, S32 button)
+{
+ return handleOtherMouse(window, pos, mask, button, FALSE);
+}
+
// WARNING: this is potentially called multiple times per frame
void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask)
{
@@ -3329,7 +3365,8 @@ void LLViewerWindow::updateUI()
LLRect screen_sticky_rect = mRootView->getLocalRect();
S32 local_x, local_y;
- if (gSavedSettings.getBOOL("DebugShowXUINames"))
+ static LLCachedControl<bool> debug_show_xui_names(gSavedSettings, "DebugShowXUINames", 0);
+ if (debug_show_xui_names)
{
LLToolTip::Params params;
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 071a3632dd..d084642fdc 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -192,7 +192,10 @@ public:
/*virtual*/ BOOL handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
/*virtual*/ BOOL handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
/*virtual*/ BOOL handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
- /*virtual*/ BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
+ /*virtual*/ BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
+ /*virtual*/ BOOL handleOtherMouseDown(LLWindow *window, LLCoordGL pos, MASK mask, S32 button);
+ /*virtual*/ BOOL handleOtherMouseUp(LLWindow *window, LLCoordGL pos, MASK mask, S32 button);
+ BOOL handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask, S32 button, bool down);
/*virtual*/ LLWindowCallbacks::DragNDropResult handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, LLWindowCallbacks::DragNDropAction action, std::string data);
void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask);
void handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index ca1216b89d..3b51d07f96 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -78,6 +78,7 @@
#include "llselectmgr.h"
#include "llsprite.h"
#include "lltargetingmotion.h"
+#include "lltoolmgr.h"
#include "lltoolmorph.h"
#include "llviewercamera.h"
#include "llviewertexlayer.h"
@@ -1376,7 +1377,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
++attachment_iter)
{
// Don't we need to look at children of attached_object as well?
- const LLViewerObject* attached_object = (*attachment_iter);
+ const LLViewerObject* attached_object = attachment_iter->get();
if (attached_object && !attached_object->isHUDAttachment())
{
const LLVOVolume *vol = dynamic_cast<const LLVOVolume*>(attached_object);
@@ -1799,7 +1800,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject* attached_object = (*attachment_iter);
+ LLViewerObject* attached_object = attachment_iter->get();
if (attached_object && !attached_object->isDead() && attachment->getValid())
{
@@ -1863,7 +1864,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject* attached_object = (*attachment_iter);
+ LLViewerObject* attached_object = attachment_iter->get();
if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
{
@@ -2687,7 +2688,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject* attached_object = (*attachment_iter);
+ LLViewerObject* attached_object = attachment_iter->get();
BOOL visibleAttachment = visible || (attached_object &&
!(attached_object->mDrawable->getSpatialBridge() &&
attached_object->mDrawable->getSpatialBridge()->getRadius() < 2.0));
@@ -4568,7 +4569,7 @@ void LLVOAvatar::updateVisibility()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- if (LLViewerObject *attached_object = (*attachment_iter))
+ if (LLViewerObject *attached_object = attachment_iter->get())
{
if(attached_object->mDrawable->isVisible())
{
@@ -5646,7 +5647,7 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
}
else
{
- LL_WARNS() << "Failed to start motion!" << LL_ENDL;
+ LL_WARNS("Motion") << "Failed to start motion!" << LL_ENDL;
}
}
else //stop animation
@@ -5753,13 +5754,13 @@ LLUUID LLVOAvatar::remapMotionID(const LLUUID& id)
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset)
{
- LL_DEBUGS() << "motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL;
+ LL_DEBUGS("Motion") << "motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL;
LLUUID remap_id = remapMotionID(id);
if (remap_id != id)
{
- LL_DEBUGS() << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL;
+ LL_DEBUGS("Motion") << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL;
}
if (isSelf() && remap_id == ANIM_AGENT_AWAY)
@@ -5775,13 +5776,13 @@ BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset)
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::stopMotion(const LLUUID& id, BOOL stop_immediate)
{
- LL_DEBUGS() << "motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL;
+ LL_DEBUGS("Motion") << "Motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL;
LLUUID remap_id = remapMotionID(id);
if (remap_id != id)
{
- LL_DEBUGS() << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL;
+ LL_DEBUGS("Motion") << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL;
}
if (isSelf())
@@ -5992,7 +5993,7 @@ void LLVOAvatar::rebuildAttachmentOverrides()
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator at_it = attachment_pt->mAttachedObjects.begin();
at_it != attachment_pt->mAttachedObjects.end(); ++at_it)
{
- LLViewerObject *vo = *at_it;
+ LLViewerObject *vo = at_it->get();
// Attached animated objects affect joints in their control
// avs, not the avs to which they are attached.
if (vo && !vo->isAnimatedObject())
@@ -6043,7 +6044,7 @@ void LLVOAvatar::updateAttachmentOverrides()
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator at_it = attachment_pt->mAttachedObjects.begin();
at_it != attachment_pt->mAttachedObjects.end(); ++at_it)
{
- LLViewerObject *vo = *at_it;
+ LLViewerObject *vo = at_it->get();
// Attached animated objects affect joints in their control
// avs, not the avs to which they are attached.
if (vo && !vo->isAnimatedObject())
@@ -7146,29 +7147,33 @@ void LLVOAvatar::lazyAttach()
for (U32 i = 0; i < mPendingAttachment.size(); i++)
{
LLPointer<LLViewerObject> cur_attachment = mPendingAttachment[i];
- if (cur_attachment->mDrawable)
+ // Object might have died while we were waiting for drawable
+ if (!cur_attachment->isDead())
{
- if (isSelf())
+ if (cur_attachment->mDrawable)
{
- const LLUUID& item_id = cur_attachment->getAttachmentItemID();
- LLViewerInventoryItem *item = gInventory.getItem(item_id);
- LL_DEBUGS("Avatar") << "ATT attaching object "
- << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
+ if (isSelf())
+ {
+ const LLUUID& item_id = cur_attachment->getAttachmentItemID();
+ LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ LL_DEBUGS("Avatar") << "ATT attaching object "
+ << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
+ }
+ if (!attachObject(cur_attachment))
+ { // Drop it
+ LL_WARNS() << "attachObject() failed for "
+ << cur_attachment->getID()
+ << " item " << cur_attachment->getAttachmentItemID()
+ << LL_ENDL;
+ // MAINT-3312 backout
+ //still_pending.push_back(cur_attachment);
+ }
}
- if (!attachObject(cur_attachment))
- { // Drop it
- LL_WARNS() << "attachObject() failed for "
- << cur_attachment->getID()
- << " item " << cur_attachment->getAttachmentItemID()
- << LL_ENDL;
- // MAINT-3312 backout
- //still_pending.push_back(cur_attachment);
+ else
+ {
+ still_pending.push_back(cur_attachment);
}
}
- else
- {
- still_pending.push_back(cur_attachment);
- }
}
mPendingAttachment = still_pending;
@@ -7188,7 +7193,7 @@ void LLVOAvatar::resetHUDAttachments()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- const LLViewerObject* attached_object = (*attachment_iter);
+ const LLViewerObject* attached_object = attachment_iter->get();
if (attached_object && attached_object->mDrawable.notNull())
{
gPipeline.markMoved(attached_object->mDrawable);
@@ -7320,6 +7325,19 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
{
gAgentCamera.changeCameraToMouselook();
}
+
+ if (gAgentCamera.getFocusOnAvatar() && LLToolMgr::getInstance()->inEdit())
+ {
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
+ if (node && node->mValid)
+ {
+ LLViewerObject* root_object = node->getObject();
+ if (root_object == sit_object)
+ {
+ LLFloaterTools::sPreviousFocusOnAvatar = true;
+ }
+ }
+ }
}
if (mDrawable.isNull())
@@ -7505,7 +7523,7 @@ LLViewerObject * LLVOAvatar::findAttachmentByID( const LLUUID & target_id ) cons
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject *attached_object = (*attachment_iter);
+ LLViewerObject *attached_object = attachment_iter->get();
if (attached_object &&
attached_object->getID() == target_id)
{
@@ -7927,7 +7945,7 @@ void LLVOAvatar::updateMeshVisibility()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject *objectp = (*attachment_iter);
+ LLViewerObject *objectp = attachment_iter->get();
if (objectp)
{
for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++)
@@ -8244,7 +8262,7 @@ void LLVOAvatar::updateMeshTextures()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject* attached_object = (*attachment_iter);
+ LLViewerObject* attached_object = attachment_iter->get();
if (attached_object && !attached_object->isDead())
{
attached_object->refreshBakeTexture();
@@ -8482,7 +8500,7 @@ LLBBox LLVOAvatar::getHUDBBox() const
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- const LLViewerObject* attached_object = (*attachment_iter);
+ const LLViewerObject* attached_object = attachment_iter->get();
if (attached_object == NULL)
{
LL_WARNS() << "HUD attached object is NULL!" << LL_ENDL;
@@ -9848,7 +9866,7 @@ void LLVOAvatar::getAssociatedVolumes(std::vector<LLVOVolume*>& volumes)
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attach_iter = attachment->mAttachedObjects.begin();
attach_iter != attach_end; ++attach_iter)
{
- LLViewerObject* attached_object = *attach_iter;
+ LLViewerObject* attached_object = attach_iter->get();
LLVOVolume *volume = dynamic_cast<LLVOVolume*>(attached_object);
if (volume)
{
@@ -10366,7 +10384,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- const LLViewerObject* attached_object = (*attachment_iter);
+ const LLViewerObject* attached_object = attachment_iter->get();
accountRenderComplexityForObject(attached_object, max_attachment_complexity,
textures, cost, hud_complexity_list);
}
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index d8c8cb0461..cc590fc947 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -125,7 +125,7 @@ LLVoiceClient::LLVoiceClient(LLPumpIO *pump)
mPTTDirty(true),
mPTT(true),
mUsePTT(true),
- mPTTIsMiddleMouse(false),
+ mPTTMouseButton(0),
mPTTKey(0),
mPTTIsToggle(false),
mUserPTTState(false),
@@ -639,13 +639,22 @@ bool LLVoiceClient::getPTTIsToggle()
void LLVoiceClient::setPTTKey(std::string &key)
{
+ // Value is stored as text for readability
if(key == "MiddleMouse")
{
- mPTTIsMiddleMouse = true;
+ mPTTMouseButton = LLMouseHandler::CLICK_MIDDLE;
+ }
+ else if(key == "MouseButton4")
+ {
+ mPTTMouseButton = LLMouseHandler::CLICK_BUTTON4;
+ }
+ else if (key == "MouseButton5")
+ {
+ mPTTMouseButton = LLMouseHandler::CLICK_BUTTON5;
}
else
{
- mPTTIsMiddleMouse = false;
+ mPTTMouseButton = 0;
if(!LLKeyboard::keyFromString(key, &mPTTKey))
{
// If the call failed, don't match any key.
@@ -682,7 +691,7 @@ void LLVoiceClient::keyDown(KEY key, MASK mask)
return;
}
- if (!mPTTIsMiddleMouse && LLAgent::isActionAllowed("speak") && (key == mPTTKey))
+ if (mPTTMouseButton == 0 && LLAgent::isActionAllowed("speak") && (key == mPTTKey))
{
bool down = gKeyboard->getKeyDown(mPTTKey);
if (down)
@@ -694,7 +703,7 @@ void LLVoiceClient::keyDown(KEY key, MASK mask)
}
void LLVoiceClient::keyUp(KEY key, MASK mask)
{
- if (!mPTTIsMiddleMouse && (key == mPTTKey))
+ if (mPTTMouseButton == 0 && (key == mPTTKey))
{
bool down = gKeyboard->getKeyDown(mPTTKey);
if (!down)
@@ -703,9 +712,9 @@ void LLVoiceClient::keyUp(KEY key, MASK mask)
}
}
}
-void LLVoiceClient::middleMouseState(bool down)
+void LLVoiceClient::updateMouseState(S32 click, bool down)
{
- if(mPTTIsMiddleMouse && LLAgent::isActionAllowed("speak"))
+ if(mPTTMouseButton == click && LLAgent::isActionAllowed("speak"))
{
inputUserControlState(down);
}
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index f95b853c31..3d04e1f0db 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -417,8 +417,8 @@ public:
// PTT key triggering
void keyDown(KEY key, MASK mask);
void keyUp(KEY key, MASK mask);
- void middleMouseState(bool down);
-
+ void updateMouseState(S32 click, bool down);
+
boost::signals2::connection MicroChangedCallback(const micro_changed_signal_t::slot_type& cb ) { return mMicroChangedSignal.connect(cb); }
@@ -486,7 +486,7 @@ protected:
bool mPTT;
bool mUsePTT;
- bool mPTTIsMiddleMouse;
+ S32 mPTTMouseButton;
KEY mPTTKey;
bool mPTTIsToggle;
bool mUserPTTState;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index bd73c234a6..bc5b3534c7 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -11434,7 +11434,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- if (LLViewerObject* attached_object = (*attachment_iter))
+ if (LLViewerObject* attached_object = attachment_iter->get())
{
markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
}
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 59bf26d40a..07df3f0667 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -133,7 +133,6 @@ with the same filename but different name
<texture name="Command_Chat_Icon" file_name="toolbar_icons/chat.png" preload="true" />
<texture name="Command_Compass_Icon" file_name="toolbar_icons/land.png" preload="true" />
<texture name="Command_Destinations_Icon" file_name="toolbar_icons/destinations.png" preload="true" />
- <texture name="Command_Flickr_Icon" file_name="toolbar_icons/flickr.png" preload="true" />
<texture name="Command_Gestures_Icon" file_name="toolbar_icons/gestures.png" preload="true" />
<texture name="Command_Grid_Status_Icon" file_name="toolbar_icons/grid_status.png" preload="true" />
<texture name="Command_HowTo_Icon" file_name="toolbar_icons/howto.png" preload="true" />
@@ -154,7 +153,6 @@ with the same filename but different name
<texture name="Command_Search_Icon" file_name="toolbar_icons/search.png" preload="true" />
<texture name="Command_Snapshot_Icon" file_name="toolbar_icons/snapshot.png" preload="true" />
<texture name="Command_Speak_Icon" file_name="toolbar_icons/speak.png" preload="true" />
- <texture name="Command_Twitter_Icon" file_name="toolbar_icons/twitter.png" preload="true" />
<texture name="Command_View_Icon" file_name="toolbar_icons/view.png" preload="true" />
<texture name="Command_Voice_Icon" file_name="toolbar_icons/nearbyvoice.png" preload="true" />
<texture name="Caret_Bottom_Icon" file_name="toolbar_icons/caret_bottom.png" preload="true" scale.left="1" scale.top="23" scale.right="15" scale.bottom="1" />
diff --git a/indra/newview/skins/default/xui/en/floater_flickr.xml b/indra/newview/skins/default/xui/en/floater_flickr.xml
deleted file mode 100644
index 3b9c4894c1..0000000000
--- a/indra/newview/skins/default/xui/en/floater_flickr.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<floater
- positioning="cascading"
- can_close="true"
- can_resize="false"
- help_topic="floater_flickr"
- layout="topleft"
- name="floater_flickr"
- save_rect="true"
- single_instance="true"
- reuse_instance="true"
- title="SHARE TO FLICKR"
- height="590"
- width="272">
- <panel
- height="590"
- width="272"
- visible="true"
- name="background"
- follows="all"
- top="0"
- left="0">
- <tab_container
- name="tabs"
- tab_group="1"
- tab_min_width="70"
- tab_height="21"
- tab_position="top"
- top="7"
- height="555"
- follows="all"
- halign="center">
- <panel
- filename="panel_flickr_photo.xml"
- class="llflickrphotopanel"
- follows="all"
- label="PHOTO"
- name="panel_flickr_photo"/>
- <panel
- filename="panel_flickr_account.xml"
- class="llflickraccountpanel"
- follows="all"
- label="ACCOUNT"
- name="panel_flickr_account"/>
- </tab_container>
- <panel
- name="connection_status_panel"
- follows="left|bottom|right"
- height="24">
- <text
- name="connection_error_text"
- type="string"
- follows="left|bottom|right"
- bottom="-5"
- left="10"
- width="250"
- height="20"
- wrap="true"
- halign="left"
- valign="center"
- text_color="DrYellow"
- font="SansSerif">
- Error
- </text>
- <loading_indicator
- follows="left|bottom|right"
- height="24"
- width="24"
- name="connection_loading_indicator"
- top_delta="-2"
- left="10"
- visible="true"/>
- <text
- name="connection_loading_text"
- type="string"
- follows="left|bottom|right"
- top_delta="2"
- left_pad="5"
- width="250"
- height="20"
- wrap="true"
- halign="left"
- valign="center"
- text_color="EmphasisColor"
- font="SansSerif">
- Loading...
- </text>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_twitter.xml b/indra/newview/skins/default/xui/en/floater_twitter.xml
deleted file mode 100644
index 5e8dfb8a52..0000000000
--- a/indra/newview/skins/default/xui/en/floater_twitter.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<floater
- positioning="cascading"
- can_close="true"
- can_resize="false"
- help_topic="floater_twitter"
- layout="topleft"
- name="floater_twitter"
- save_rect="true"
- single_instance="true"
- reuse_instance="true"
- title="TWITTER"
- height="462"
- width="272">
- <tab_container
- name="tabs"
- tab_group="1"
- tab_min_width="70"
- tab_height="21"
- tab_position="top"
- top="7"
- height="457"
- halign="center">
- <panel
- filename="panel_twitter_photo.xml"
- class="lltwitterphotopanel"
- follows="all"
- label="COMPOSE"
- name="panel_twitter_photo"/>
- <panel
- filename="panel_twitter_account.xml"
- class="lltwitteraccountpanel"
- follows="all"
- label="ACCOUNT"
- name="panel_twitter_account"/>
- </tab_container>
- <text
- name="connection_error_text"
- type="string"
- follows="left|bottom|right"
- bottom="-5"
- left="10"
- width="252"
- height="20"
- wrap="true"
- halign="left"
- valign="center"
- text_color="DrYellow"
- font="SansSerif">
- Error
- </text>
- <loading_indicator
- follows="left|bottom|right"
- height="24"
- width="24"
- name="connection_loading_indicator"
- top_delta="-2"
- left="10"
- visible="true"/>
- <text
- name="connection_loading_text"
- type="string"
- follows="left|bottom|right"
- top_delta="2"
- left_pad="5"
- width="223"
- height="20"
- wrap="true"
- halign="left"
- valign="center"
- text_color="EmphasisColor"
- font="SansSerif">
- Loading...
- </text>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
index c1458977ca..5cae643e44 100644
--- a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
@@ -12,6 +12,16 @@
function="Gesture.Action.ToogleActiveState" />
</menu_item_call>
<menu_item_call
+ label="Rename"
+ layout="topleft"
+ name="rename">
+ <on_click
+ function="Gesture.Action.Rename" />
+ <on_enable
+ function="Gesture.EnableAction"
+ parameter="rename_gesture" />
+ </menu_item_call>
+ <menu_item_call
label="Copy"
layout="topleft"
name="copy_gesture">
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 1d95577802..d2df17ff94 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -17,9 +17,11 @@
</menu_item_call>
<menu_item_call
label="Appearance..."
- name="ChangeOutfit">
+ name="ChangeOutfit"
+ shortcut="control|O">
<menu_item_call.on_click
- function="CustomizeAvatar" />
+ function="Floater.ToggleOrBringToFront"
+ parameter="appearance" />
<menu_item_call.on_enable
function="Edit.EnableCustomizeAvatar" />
</menu_item_call>
@@ -305,21 +307,6 @@
parameter="conversation" />
</menu_item_check>
<menu_item_separator/>
- <menu_item_call
- label="Twitter..."
- name="Twitter">
- <menu_item_call.on_click
- function="Floater.Toggle"
- parameter="twitter"/>
- </menu_item_call>
- <menu_item_call
- label="Flickr..."
- name="Flickr">
- <menu_item_call.on_click
- function="Floater.Toggle"
- parameter="flickr"/>
- </menu_item_call>
- <menu_item_separator/>
<menu
label="Voice morphing"
name="VoiceMorphing"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index f72767cceb..af9602ea11 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -2480,6 +2480,13 @@ Sorry, but the system was unable to complete your region crossing in a timely fa
</notification>
<notification
icon="alertmodal.tga"
+ name="preexisting_tport"
+ type="alertmodal">
+ <tag>fail</tag>
+Sorry, but the system was unable to start your teleport. Please try again in a few minutes.
+ </notification>
+ <notification
+ icon="alertmodal.tga"
name="no_host"
type="alertmodal">
<tag>fail</tag>
@@ -3093,6 +3100,29 @@ See https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
<notification
icon="alertmodal.tga"
+ label="Rename Gesture"
+ name="RenameGesture"
+ type="alertmodal">
+ New gesture name:
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="new_name" type="text" width="300">
+ [NAME]
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="RemoveFromFriends"
type="alertmodal">
<tag>friendship</tag>
@@ -3547,6 +3577,30 @@ You can either check your Internet connection and try again in a few minutes, cl
<notification
icon="alertmodal.tga"
+ name="LoginPacketNeverReceivedNoTP"
+ type="alertmodal">
+ <tag>fail</tag>
+We&apos;re having trouble connecting. There may be a problem with your Internet connection or the [SECOND_LIFE_GRID].
+
+You can either check your Internet connection and try again in a few minutes or click Help to view the [SUPPORT_SITE].
+ <url option="1" name="url">
+ http://secondlife.com/support/
+ </url>
+ <form name="form">
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Help"
+ text="Help"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="WelcomeChooseSex"
type="alertmodal">
Your character will appear in a moment.
@@ -6711,20 +6765,6 @@ Please select at least one type of content to search (General, Moderate, or Adul
<notification
icon="notify.tga"
- name="FlickrConnect"
- type="notifytip">
- [MESSAGE]
- </notification>
-
- <notification
- icon="notify.tga"
- name="TwitterConnect"
- type="notifytip">
- [MESSAGE]
- </notification>
-
- <notification
- icon="notify.tga"
name="PaymentReceived"
log_to_im="true"
persist="true"
diff --git a/indra/newview/skins/default/xui/en/panel_flickr_account.xml b/indra/newview/skins/default/xui/en/panel_flickr_account.xml
deleted file mode 100644
index 5c2f335780..0000000000
--- a/indra/newview/skins/default/xui/en/panel_flickr_account.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<panel
- height="540"
- width="272"
- layout="topleft"
- name="panel_flickr_account">
- <string
- name="flickr_connected"
- value="You are connected to Flickr as:" />
- <string
- name="flickr_disconnected"
- value="Not connected to Flickr" />
- <text
- layout="topleft"
- length="1"
- follows="top|left"
- font="SansSerif"
- height="16"
- left="10"
- name="account_caption_label"
- top="5"
- type="string">
- Not connected to Flickr.
- </text>
- <text
- layout="topleft"
- top_pad="2"
- length="1"
- follows="top|left"
- font="SansSerif"
- height="16"
- left="10"
- name="account_name_label"
- parse_urls="true"
- type="string"/>
- <panel
- layout="topleft"
- name="panel_buttons"
- height="345"
- left="0">
- <button
- layout="topleft"
- follows="left|top|right"
- top_pad="9"
- visible="true"
- left="10"
- right="-10"
- height="23"
- label="Connect..."
- name="connect_btn"
- width="210">
- <commit_callback function="SocialSharing.Connect"/>
- </button>
-
- <button
- layout="topleft"
- follows="left|top|right"
- top_delta="0"
- left="10"
- right="-10"
- height="23"
- label="Disconnect"
- name="disconnect_btn"
- width="210"
- visible="false">
- <commit_callback function="SocialSharing.Disconnect"/>
- </button>
- <text
- layout="topleft"
- length="1"
- follows="top|left"
- height="16"
- left="10"
- name="account_learn_more_label"
- top_pad="5"
- type="string">
- [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Flickr/ta-p/2435609 Learn about posting to Flickr]
- </text>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
deleted file mode 100644
index 7fb2291423..0000000000
--- a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
+++ /dev/null
@@ -1,259 +0,0 @@
- <panel
- height="540"
- width="272"
- follows="all"
- layout="topleft"
- name="panel_flickr_photo">
- <combo_box
- control_name="FlickrPhotoResolution"
- follows="left|top"
- layout="topleft"
- top="7"
- left="10"
- name="resolution_combobox"
- tool_tip="Image resolution"
- height="21"
- width="124">
- <combo_box.item
- label="Current Window"
- name="CurrentWindow"
- value="[i0,i0]" />
- <combo_box.item
- label="640x480"
- name="640x480"
- value="[i640,i480]" />
- <combo_box.item
- label="800x600"
- name="800x600"
- value="[i800,i600]" />
- <combo_box.item
- label="1024x768"
- name="1024x768"
- value="[i1024,i768]" />
- </combo_box>
- <combo_box
- control_name="FlickrPhotoFilters"
- follows="left|top"
- layout="topleft"
- name="filters_combobox"
- tool_tip="Image filters"
- top_delta="0"
- left_pad="4"
- height="21"
- width="124">
- <combo_box.item
- label="No Filter"
- name="NoFilter"
- value="NoFilter" />
- </combo_box>
- <panel
- height="150"
- width="250"
- visible="true"
- name="thumbnail_placeholder"
- top_pad="5"
- follows="left|top|right"
- layout="topleft"
- right="-10"
- left="10">
- </panel>
- <text
- follows="left|top"
- layout="topleft"
- font="SansSerif"
- text_color="EmphasisColor"
- height="14"
- top_pad="2"
- left="10"
- length="1"
- halign="center"
- name="working_lbl"
- translate="false"
- type="string"
- visible="true"
- width="251">
- Refreshing...
- </text>
- <view_border
- bevel_style="in"
- follows="left|top"
- layout="topleft"
- height="1"
- left="10"
- name="refresh_border"
- width="250"
- top_pad="0"/>
- <button
- follows="left|top"
- layout="topleft"
- height="23"
- label="Refresh"
- left="10"
- top_pad="5"
- name="new_snapshot_btn"
- tool_tip="Click to refresh"
- visible="true"
- width="100" >
- <button.commit_callback
- function="SocialSharing.RefreshPhoto" />
- </button>
- <button
- follows="right|top"
- layout="topleft"
- height="23"
- label="Preview"
- right="-10"
- top_delta="0"
- name="big_preview_btn"
- tool_tip="Click to toggle preview"
- is_toggle="true"
- visible="true"
- width="100" >
- <button.commit_callback
- function="SocialSharing.BigPreview" />
- </button>
- <text
- length="1"
- follows="top|left|right"
- layout="topleft"
- font="SansSerif"
- height="16"
- left="10"
- name="title_label"
- top_pad="10"
- type="string">
- Title:
- </text>
- <line_editor
- follows="left|top"
- layout="topleft"
- height="20"
- width="250"
- left="10"
- length="1"
- max_length="256"
- name="photo_title"
- type="string">
- </line_editor>
- <text
- length="1"
- follows="top|left|right"
- layout="topleft"
- font="SansSerif"
- height="16"
- left="10"
- right="-10"
- name="description_label"
- top_pad="10"
- width="25"
- type="string">
- Description:
- </text>
- <text_editor
- follows="left|top"
- layout="topleft"
- height="50"
- width="249"
- left="10"
- length="1"
- max_length="700"
- name="photo_description"
- spellcheck="true"
- type="string"
- word_wrap="true">
- </text_editor>
- <check_box
- follows="left|top"
- layout="topleft"
- initial_value="true"
- label="Include SL location at end of description"
- name="add_location_cb"
- left="9"
- height="16"
- top_pad="8"/>
- <text
- length="1"
- follows="top|left"
- layout="topleft"
- font="SansSerif"
- height="16"
- left="10"
- name="tags_label"
- top_pad="6"
- type="string">
- Tags:
- </text>
- <text
- length="1"
- follows="top|left"
- layout="topleft"
- font="SansSerifSmall"
- text_color="White_50"
- height="30"
- name="tags_help_label"
- left="51"
- top_pad="-16"
- type="string">
-Separate tags with spaces
-Use "" for multi-word tags
- </text>
- <text_editor
- follows="left|top"
- layout="topleft"
- height="50"
- width="249"
- left="10"
- length="1"
- max_length="700"
- name="photo_tags"
- type="string"
- word_wrap="true">
- </text_editor>
- <combo_box
- control_name="FlickrPhotoRating"
- follows="left|top"
- layout="topleft"
- top_pad="7"
- left="10"
- name="rating_combobox"
- tool_tip="Flickr content rating"
- height="21"
- width="250">
- <combo_box.item
- label="Safe Flickr rating"
- name="SafeRating"
- value="1" />
- <combo_box.item
- label="Moderate Flickr rating"
- name="ModerateRating"
- value="2" />
- <combo_box.item
- label="Restricted Flickr rating"
- name="RestrictedRating"
- value="3" />
- </combo_box>
- <button
- follows="left|top"
- layout="topleft"
- top_pad="7"
- left="10"
- height="23"
- label="Share"
- name="post_photo_btn"
- width="100">
- <button.commit_callback
- function="SocialSharing.SendPhoto" />
- </button>
- <button
- follows="right|top"
- layout="topleft"
- height="23"
- label="Cancel"
- name="cancel_photo_btn"
- right="-10"
- top_delta="0"
- width="100">
- <button.commit_callback
- function="SocialSharing.Cancel" />
- </button>
- </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index 4f0bb9d3b7..8296438d4c 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -143,6 +143,32 @@
name="ui_scale_slider"
top_pad="-14"
width="250" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left="33"
+ name="HUD Size:"
+ top_pad="20"
+ width="100">
+ HUD Scale:
+ </text>
+ <slider
+ control_name="HUDScaleFactor"
+ decimal_digits="2"
+ follows="left|top"
+ height="17"
+ increment="0.1"
+ initial_value="1"
+ layout="topleft"
+ left_pad="0"
+ max_val="2.0"
+ min_val="1.0"
+ name="ui_scale_slider"
+ top_pad="-14"
+ width="250" />
<check_box
control_name="ShowScriptErrors"
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
index 8f2e81b9f7..649403184d 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
@@ -13,6 +13,14 @@
name="middle_mouse">
Middle Mouse
</panel.string>
+ <panel.string
+ name="button4_mouse">
+ Mouse Button 4
+ </panel.string>
+ <panel.string
+ name="button5_mouse">
+ Mouse Button 5
+ </panel.string>
<slider
control_name="AudioLevelMaster"
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
index 981b9ab881..2fe4cf8183 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
@@ -61,40 +61,6 @@
font="SansSerif"
halign="left"
height="22"
- image_overlay="Command_Twitter_Icon"
- image_overlay_alignment="left"
- image_top_pad="0"
- imgoverlay_label_space="10"
- label="Share to Twitter"
- layout="topleft"
- left_delta="0"
- name="send_to_twitter_btn"
- top_pad="5">
- <button.commit_callback
- function="Snapshot.SendToTwitter"/>
- </button>
- <button
- follows="left|top"
- font="SansSerif"
- halign="left"
- height="22"
- image_overlay="Command_Flickr_Icon"
- image_overlay_alignment="left"
- image_top_pad="0"
- imgoverlay_label_space="10"
- label="Share to Flickr"
- layout="topleft"
- left_delta="0"
- name="send_to_flickr_btn"
- top_pad="5">
- <button.commit_callback
- function="Snapshot.SendToFlickr"/>
- </button>
- <button
- follows="left|top"
- font="SansSerif"
- halign="left"
- height="22"
image_overlay="Snapshot_Email"
image_overlay_alignment="left"
image_top_pad="0"
diff --git a/indra/newview/skins/default/xui/en/panel_twitter_account.xml b/indra/newview/skins/default/xui/en/panel_twitter_account.xml
deleted file mode 100644
index b9049a0bba..0000000000
--- a/indra/newview/skins/default/xui/en/panel_twitter_account.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<panel
- height="400"
- width="272"
- layout="topleft"
- name="panel_twitter_account">
- <string
- name="twitter_connected"
- value="You are connected to Twitter as:" />
- <string
- name="twitter_disconnected"
- value="Not connected to Twitter" />
- <text
- layout="topleft"
- length="1"
- follows="top|left"
- font="SansSerif"
- height="16"
- left="10"
- name="account_caption_label"
- top="5"
- type="string">
- Not connected to Twitter.
- </text>
- <text
- layout="topleft"
- top_pad="2"
- length="1"
- follows="top|left"
- font="SansSerif"
- height="16"
- left="10"
- name="account_name_label"
- parse_urls="true"
- type="string"/>
- <panel
- layout="topleft"
- follows="top|left"
- name="panel_buttons"
- height="345"
- top_pad="3"
- left="0">
- <button
- layout="topleft"
- follows="left|top|right"
- top_pad="9"
- left="10"
- right="-10"
- visible="true"
- height="23"
- label="Connect..."
- name="connect_btn"
- width="210">
- <commit_callback function="SocialSharing.Connect"/>
- </button>
-
- <button
- layout="topleft"
- follows="left|top|right"
- top_delta="0"
- left="10"
- right="-10"
- height="23"
- label="Disconnect"
- name="disconnect_btn"
- width="210"
- visible="false">
- <commit_callback function="SocialSharing.Disconnect"/>
- </button>
- <text
- layout="topleft"
- length="1"
- follows="top|left"
- height="16"
- left="10"
- name="account_learn_more_label"
- top_pad="5"
- type="string">
- [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Twitter/ta-p/2435453 Learn about posting to Twitter]
- </text>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_twitter_photo.xml b/indra/newview/skins/default/xui/en/panel_twitter_photo.xml
deleted file mode 100644
index 8774d09a03..0000000000
--- a/indra/newview/skins/default/xui/en/panel_twitter_photo.xml
+++ /dev/null
@@ -1,196 +0,0 @@
- <panel
- height="420"
- width="304"
- layout="topleft"
- name="panel_twitter_photo">
- <text
- length="1"
- layout="topleft"
- follows="top|left|right"
- font="SansSerif"
- height="16"
- left="10"
- name="status_label"
- top="5"
- type="string">
- What's happening?
- </text>
- <text
- length="1"
- follows="top|left"
- layout="topleft"
- font="SansSerif"
- text_color="EmphasisColor"
- halign="right"
- height="16"
- width="30"
- left="227"
- name="status_counter_label"
- top="5"
- type="string">
- 140
- </text>
- <text_editor
- follows="left|top"
- layout="topleft"
- height="87"
- width="250"
- left="10"
- length="1"
- max_length="140"
- name="photo_status"
- spellcheck="true"
- type="string"
- word_wrap="true">
- </text_editor>
- <check_box
- follows="left|top"
- layout="topleft"
- initial_value="true"
- label="Include SL location"
- name="add_location_cb"
- left="10"
- height="16"
- top_pad="8"/>
- <check_box
- follows="left|top"
- layout="topleft"
- initial_value="true"
- label="Include a photo"
- name="add_photo_cb"
- left="10"
- height="16"
- top_pad="1"/>
- <combo_box
- control_name="TwitterPhotoResolution"
- follows="left|top"
- layout="topleft"
- top_pad="5"
- left="10"
- name="resolution_combobox"
- tool_tip="Image resolution"
- height="21"
- width="124">
- <combo_box.item
- label="Current Window"
- name="CurrentWindow"
- value="[i0,i0]" />
- <combo_box.item
- label="640x480"
- name="640x480"
- value="[i640,i480]" />
- <combo_box.item
- label="800x600"
- name="800x600"
- value="[i800,i600]" />
- <combo_box.item
- label="1024x768"
- name="1024x768"
- value="[i1024,i768]" />
- </combo_box>
- <combo_box
- control_name="TwitterPhotoFilters"
- follows="right|top"
- layout="topleft"
- name="filters_combobox"
- tool_tip="Image filters"
- top_delta="0"
- right="-10"
- height="21"
- width="124">
- <combo_box.item
- label="No Filter"
- name="NoFilter"
- value="NoFilter" />
- </combo_box>
- <panel
- layout="topleft"
- height="150"
- width="250"
- visible="true"
- name="thumbnail_placeholder"
- top_pad="5"
- right="-10"
- follows="left|top|right"
- left="10">
- </panel>
- <text
- follows="left|top"
- layout="topleft"
- font="SansSerif"
- text_color="EmphasisColor"
- height="14"
- top_pad="2"
- left="10"
- length="1"
- halign="center"
- name="working_lbl"
- translate="false"
- type="string"
- visible="true"
- width="251">
- Refreshing...
- </text>
- <view_border
- bevel_style="in"
- follows="left|top"
- layout="topleft"
- height="1"
- left="10"
- name="refresh_border"
- width="250"
- top_pad="0"/>
- <button
- follows="left|top"
- layout="topleft"
- height="23"
- label="Refresh"
- left="10"
- top_pad="5"
- name="new_snapshot_btn"
- tool_tip="Click to refresh"
- visible="true"
- width="100" >
- <button.commit_callback
- function="SocialSharing.RefreshPhoto" />
- </button>
- <button
- follows="right|top"
- layout="topleft"
- height="23"
- label="Preview"
- right="-10"
- top_delta="0"
- name="big_preview_btn"
- tool_tip="Click to toggle preview"
- is_toggle="true"
- visible="true"
- width="100" >
- <button.commit_callback
- function="SocialSharing.BigPreview" />
- </button>
- <button
- follows="left|top"
- layout="topleft"
- top_pad="3"
- left="10"
- height="23"
- label="Tweet"
- name="post_photo_btn"
- width="100">
- <button.commit_callback
- function="SocialSharing.SendPhoto" />
- </button>
- <button
- follows="right|top"
- layout="topleft"
- height="23"
- label="Cancel"
- name="cancel_photo_btn"
- right="-10"
- top_delta="0"
- width="100">
- <button.commit_callback
- function="SocialSharing.Cancel" />
- </button>
- </panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index ca6973bebd..8516d50486 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -201,21 +201,7 @@ Please try logging in again in a minute.</string>
<string name="YouHaveBeenDisconnected">You have been disconnected from the region you were in.</string>
<string name="SentToInvalidRegion">You were sent to an invalid region.</string>
<string name="TestingDisconnect">Testing viewer disconnect</string>
-
- <!-- SLShare: Flickr and Twitter -->
- <string name="SocialFlickrConnecting">Connecting to Flickr...</string>
- <string name="SocialFlickrPosting">Posting...</string>
- <string name="SocialFlickrDisconnecting">Disconnecting from Flickr...</string>
- <string name="SocialFlickrErrorConnecting">Problem connecting to Flickr</string>
- <string name="SocialFlickrErrorPosting">Problem posting to Flickr</string>
- <string name="SocialFlickrErrorDisconnecting">Problem disconnecting from Flickr</string>
- <string name="SocialTwitterConnecting">Connecting to Twitter...</string>
- <string name="SocialTwitterPosting">Posting...</string>
- <string name="SocialTwitterDisconnecting">Disconnecting from Twitter...</string>
- <string name="SocialTwitterErrorConnecting">Problem connecting to Twitter</string>
- <string name="SocialTwitterErrorPosting">Problem posting to Twitter</string>
- <string name="SocialTwitterErrorDisconnecting">Problem disconnecting from Twitter</string>
-
+
<!-- SLShare: User Friendly Filter Names Translation -->
<string name="BlackAndWhite">Black &amp; White</string>
<string name="Colors1970">1970&apos;s Colors</string>
@@ -2637,6 +2623,7 @@ If you continue to receive this message, please contact Second Life support for
<string name="Debits">Debits</string>
<string name="Total">Total</string>
<string name="NoGroupDataFound">No group data found for group </string>
+ <string name="AlreadyInGroup">You are already in this group </string>
<!-- floater IM bonus_info: When a Linden with Admin/god status receives a new IM this displays the estate (Mainland vs. teen grid) of the source avatar.
This is to help Lindens when answering questions. -->
@@ -3659,13 +3646,6 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
Drag items from inventory here
</string>
- <string name="flickr_post_success">
- You posted to Flickr.
- </string>
- <string name="twitter_post_success">
- You posted to Twitter.
- </string>
-
<string name="no_session_message">
(IM Session Doesn't Exist)
</string>
@@ -4091,7 +4071,6 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Conversations_Label">Conversations</string>
<string name="Command_Compass_Label">Compass</string>
<string name="Command_Destinations_Label">Destinations</string>
- <string name="Command_Flickr_Label">Flickr</string>
<string name="Command_Gestures_Label">Gestures</string>
<string name="Command_Grid_Status_Label">Grid status</string>
<string name="Command_HowTo_Label">How to</string>
@@ -4111,7 +4090,6 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Search_Label">Search</string>
<string name="Command_Snapshot_Label">Snapshot</string>
<string name="Command_Speak_Label">Speak</string>
- <string name="Command_Twitter_Label">Twitter</string>
<string name="Command_View_Label">Camera controls</string>
<string name="Command_Voice_Label">Voice settings</string>
@@ -4123,7 +4101,6 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Conversations_Tooltip">Converse with everyone</string>
<string name="Command_Compass_Tooltip">Compass</string>
<string name="Command_Destinations_Tooltip">Destinations of interest</string>
- <string name="Command_Flickr_Tooltip">Upload to Flickr</string>
<string name="Command_Gestures_Tooltip">Gestures for your avatar</string>
<string name="Command_Grid_Status_Tooltip">Show current Grid status</string>
<string name="Command_HowTo_Tooltip">How to do common tasks</string>
@@ -4143,7 +4120,6 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Search_Tooltip">Find places, events, people</string>
<string name="Command_Snapshot_Tooltip">Take a picture</string>
<string name="Command_Speak_Tooltip">Speak with people nearby using your microphone</string>
- <string name="Command_Twitter_Tooltip">Twitter</string>
<string name="Command_View_Tooltip">Changing camera angle</string>
<string name="Command_Voice_Tooltip">Volume controls for calls and people near you in world</string>
diff --git a/indra/newview/skins/default/xui/en/teleport_strings.xml b/indra/newview/skins/default/xui/en/teleport_strings.xml
index 5a9a16d344..57f8bb542d 100644
--- a/indra/newview/skins/default/xui/en/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/en/teleport_strings.xml
@@ -39,6 +39,9 @@ Go to &apos;Welcome Island Public&apos; to repeat the tutorial.
<message name="expired_region_handoff">
Sorry, but the system was unable to complete your region crossing in a timely fashion. Please try again in a few minutes.
</message>
+ <message name="preexisting_tport">
+ Sorry, but the system was unable to start your teleport. Please try again in a few minutes.
+ </message>
<message name="no_host">
Unable to find teleport destination. The destination may be temporarily unavailable or no longer exists. Please try again in a few minutes.
</message>
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index e74fe374d2..43e8c37fc6 100644
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -1436,9 +1436,9 @@
<usetemplate name="okcancelbuttons" notext="Продолжить" yestext="Создать аккаунт..."/>
</notification>
<notification name="LoginPacketNeverReceived">
- Возникли неполадки при подключении. Возможно, проблема с вашим подключением к интернету или [SECOND_LIFE_GRID].
+ Возникли неполадки при подключении. Возможно, проблема с вашим подключением к интернету или [SECOND_LIFE_GRID] временно недоступна.
-Варианты ваших действий: проверьте подключение к интернету и повторите попытку через несколько минут, нажмите кнопку «Справка» для перехода к [SUPPORT_SITE] или кнопку «Телепортация», чтобы телепортироваться домой.
+Вы можете проверить подключение к интернету, повторить попытку через несколько минут, нажать кнопку «Справка» для перехода на [SUPPORT_SITE] или нажать кнопку «Телепортация», чтобы телепортироваться домой.
<url name="url">
http://secondlife.com/support/
</url>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index a4cda0ba78..a403760670 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1332,7 +1332,6 @@ class DarwinManifest(ViewerManifest):
print "Converting temp disk image to final disk image"
self.run_command(['hdiutil', 'convert', sparsename, '-format', 'UDZO',
'-imagekey', 'zlib-level=9', '-o', finalname])
- self.run_command(['hdiutil', 'internet-enable', '-yes', finalname])
# get rid of the temp file
self.package_file = finalname
self.remove(sparsename)