summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llui/llurlentry.cpp10
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/llagentcamera.cpp6
-rw-r--r--indra/newview/llagentcamera.h1
-rw-r--r--indra/newview/llappviewer.cpp3
-rw-r--r--indra/newview/llfloatermodelpreview.cpp9
-rw-r--r--indra/newview/llfloaterproperties.cpp2
-rw-r--r--indra/newview/llimprocessing.cpp20
-rw-r--r--indra/newview/llselectmgr.cpp101
-rw-r--r--indra/newview/llselectmgr.h19
-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/lltexturecache.cpp95
-rw-r--r--indra/newview/lltexturecache.h3
-rw-r--r--indra/newview/lltoolpie.cpp32
-rw-r--r--indra/newview/llviewerdisplay.cpp2
-rw-r--r--indra/newview/llviewermenu.cpp10
-rw-r--r--indra/newview/llviewermessage.cpp198
-rw-r--r--indra/newview/llviewermessage.h3
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml6
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml7
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_advanced.xml26
-rw-r--r--indra/newview/skins/default/xui/en/teleport_strings.xml3
25 files changed, 540 insertions, 248 deletions
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index cd9b52d164..0dbd7ceb25 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -454,13 +454,13 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
}
//
-// LLUrlEntrySeconlifeURL Describes *secondlife.com/ and *lindenlab.com/ urls to substitute icon 'hand.png' before link
+// LLUrlEntrySeconlifeURL Describes *secondlife.com/ *lindenlab.com/ and *tilia-inc.com/ urls to substitute icon 'hand.png' before link
//
LLUrlEntrySecondlifeURL::LLUrlEntrySecondlifeURL()
{
- mPattern = boost::regex("((http://([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com)"
+ mPattern = boost::regex("((http://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com)"
"|"
- "(https://([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com(:\\d{1,5})?))"
+ "(https://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(:\\d{1,5})?))"
"\\/\\S*",
boost::regex::perl|boost::regex::icase);
@@ -495,11 +495,11 @@ std::string LLUrlEntrySecondlifeURL::getTooltip(const std::string &url) const
}
//
-// LLUrlEntrySimpleSecondlifeURL Describes *secondlife.com and *lindenlab.com urls to substitute icon 'hand.png' before link
+// LLUrlEntrySimpleSecondlifeURL Describes *secondlife.com *lindenlab.com and *tilia-inc.com urls to substitute icon 'hand.png' before link
//
LLUrlEntrySimpleSecondlifeURL::LLUrlEntrySimpleSecondlifeURL()
{
- mPattern = boost::regex("https?://([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com(?!\\S)",
+ mPattern = boost::regex("https?://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(?!\\S)",
boost::regex::perl|boost::regex::icase);
mIcon = "Hand";
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 49601ae98f..472a76a7e2 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -13133,6 +13133,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 92a3026096..fd8797481d 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()
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/llappviewer.cpp b/indra/newview/llappviewer.cpp
index c8dcbb87c1..12a459b2b8 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2145,6 +2145,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/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index cb58cfdd0a..7705c1a76f 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/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/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index d59c301210..5b9ef7e60a 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/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index d2db6f6649..b726e841f8 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -152,6 +152,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
@@ -4472,9 +4519,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;
}
@@ -4492,6 +4549,7 @@ void LLSelectMgr::sendAttach(U8 attachment_point, bool replace)
}
sendListToRegions(
+ selection_handle,
"ObjectAttach",
packAgentIDAndSessionAndAttachment,
packObjectIDAndRotation,
@@ -4503,6 +4561,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();
}
}
@@ -5044,7 +5103,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)
{
@@ -5070,7 +5139,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;
@@ -5113,25 +5182,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:
@@ -6607,8 +6676,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;
@@ -6981,8 +7049,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/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/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index e5af47ab6c..f3bb574191 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
{
@@ -1669,6 +1670,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)
@@ -1928,11 +2014,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,
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index 81ea7aeee2..da59290930 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -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();
@@ -225,6 +226,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/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 2a87bce134..47227f987d 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/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 5924dbc260..a3d946c4d4 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/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 52b2c631fa..1566736f17 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -6672,10 +6672,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;
@@ -6716,8 +6716,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;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 6e5c77e4a9..3fda51f856 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)
{
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/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 87a0bb7d70..e52ef2a877 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>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index f72767cceb..72efb4921a 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>
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/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>