summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorTofu Linden <tofu.linden@lindenlab.com>2009-11-12 17:58:40 +0000
committerTofu Linden <tofu.linden@lindenlab.com>2009-11-12 17:58:40 +0000
commite5a2b1c458a86006959b924986288c48689a9bd3 (patch)
tree1a9b8fc244234b76ef5f37c14133e5f716c1c53c /indra
parent74cb5c82a4e5eeb1ef722f73c96f64c4750db2be (diff)
parenta5f6da09757c371e08b4c184d18fd50388c0afe9 (diff)
merge.
Diffstat (limited to 'indra')
-rw-r--r--indra/llui/llurlentry.cpp44
-rw-r--r--indra/llui/llurlentry.h12
-rw-r--r--indra/llui/llurlregistry.cpp1
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/app_settings/settings.xml24
-rw-r--r--indra/newview/llagentlistener.cpp2
-rw-r--r--indra/newview/llagentwearables.cpp7
-rw-r--r--indra/newview/llappearancemgr.cpp21
-rw-r--r--indra/newview/llappearancemgr.h1
-rw-r--r--indra/newview/llbottomtray.cpp36
-rw-r--r--indra/newview/llbottomtray.h7
-rw-r--r--indra/newview/llfloatersearch.cpp16
-rw-r--r--indra/newview/llinspectremoteobject.cpp200
-rw-r--r--indra/newview/llinspectremoteobject.h40
-rw-r--r--indra/newview/llinventorymodel.cpp55
-rw-r--r--indra/newview/llinventorymodel.h28
-rw-r--r--indra/newview/llinventorypanel.cpp24
-rw-r--r--indra/newview/llinventorypanel.h2
-rw-r--r--indra/newview/lllogininstance.cpp3
-rw-r--r--indra/newview/llnearbychatbar.cpp30
-rw-r--r--indra/newview/llnearbychatbar.h10
-rw-r--r--indra/newview/llpanelmaininventory.cpp5
-rw-r--r--indra/newview/llspeakbutton.cpp10
-rw-r--r--indra/newview/llspeakbutton.h5
-rw-r--r--indra/newview/llurldispatcher.cpp6
-rw-r--r--indra/newview/llviewerfloaterreg.cpp2
-rw-r--r--indra/newview/llviewermenu.cpp6
-rw-r--r--indra/newview/llviewermessage.cpp27
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_search.xml4
-rw-r--r--indra/newview/skins/default/xui/en/inspect_remote_object.xml99
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml5
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml6
-rw-r--r--indra/newview/tests/lllogininstance_test.cpp1
-rw-r--r--indra/viewer_components/login/lllogin.cpp29
-rw-r--r--indra/viewer_components/login/tests/lllogin_test.cpp37
36 files changed, 658 insertions, 153 deletions
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index dae4b512d1..219fae84be 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -512,50 +512,6 @@ std::string LLUrlEntryTeleport::getLocation(const std::string &url) const
return ::getStringAfterToken(url, "app/teleport/");
}
-///
-/// LLUrlEntryObjectIM Describes a Second Life object instant msg Url, e.g.,
-/// secondlife:///app/objectim/<sessionid>
-///
-LLUrlEntryObjectIM::LLUrlEntryObjectIM()
-{
- mPattern = boost::regex("secondlife:///app/objectim/[\\da-f-]+\\??\\S*",
- boost::regex::perl|boost::regex::icase);
- mMenuName = "menu_url_objectim.xml";
- mTooltip = LLTrans::getString("TooltipObjectIMUrl");
-}
-
-std::string LLUrlEntryObjectIM::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
-{
- LLURI uri(url);
- LLSD params = uri.queryMap();
- if (params.has("name"))
- {
- // look for a ?name=<obj-name> param in the url
- // and use that as the label if present.
- std::string name = params.get("name");
- LLStringUtil::trim(name);
- if (name.empty())
- {
- name = LLTrans::getString("Unnamed");
- }
- return name;
- }
-
- return unescapeUrl(url);
-}
-
-std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const
-{
- LLURI uri(url);
- LLSD params = uri.queryMap();
- if (params.has("slurl"))
- {
- return params.get("slurl");
- }
-
- return "";
-}
-
//
// LLUrlEntrySL Describes a generic SLURL, e.g., a Url that starts
// with secondlife:// (used as a catch-all for cases not matched above)
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 4507572b1e..7970b48eb5 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -209,18 +209,6 @@ public:
};
///
-/// LLUrlEntryObjectIM Describes a Second Life object instant msg Url, e.g.,
-/// secondlife:///app/objectim/<sessionid>?name=Foo
-///
-class LLUrlEntryObjectIM : public LLUrlEntryBase
-{
-public:
- LLUrlEntryObjectIM();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ std::string getLocation(const std::string &url) const;
-};
-
-///
/// LLUrlEntrySL Describes a generic SLURL, e.g., a Url that starts
/// with secondlife:// (used as a catch-all for cases not matched above)
///
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index 60275b60bc..a6922b019b 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -52,7 +52,6 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(new LLUrlEntryParcel());
registerUrl(new LLUrlEntryTeleport());
registerUrl(new LLUrlEntryWorldMap());
- registerUrl(new LLUrlEntryObjectIM());
registerUrl(new LLUrlEntryPlace());
registerUrl(new LLUrlEntrySL());
registerUrl(new LLUrlEntrySLLabel());
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index e69d3f417f..b129bca1f3 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -246,6 +246,7 @@ set(viewer_SOURCE_FILES
llinspectavatar.cpp
llinspectgroup.cpp
llinspectobject.cpp
+ llinspectremoteobject.cpp
llinventorybridge.cpp
llinventoryclipboard.cpp
llinventoryfilter.cpp
@@ -741,6 +742,7 @@ set(viewer_HEADER_FILES
llinspectavatar.h
llinspectgroup.h
llinspectobject.h
+ llinspectremoteobject.h
llinventorybridge.h
llinventoryclipboard.h
llinventoryfilter.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 15fa057230..eb4148f92f 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4259,7 +4259,29 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>LogMessages</key>
+ <key>LoginSRVTimeout</key>
+ <map>
+ <key>Comment</key>
+ <string>Duration in seconds of the login SRV request timeout</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>10.0</real>
+ </map>
+ <key>LoginSRVPump</key>
+ <map>
+ <key>Comment</key>
+ <string>Name of the message pump that handles SRV request</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>LLAres</string>
+ </map>
+ <key>LogMessages</key>
<map>
<key>Comment</key>
<string>Log network traffic</string>
diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp
index 3da6a4e3f4..b3ed7c353e 100644
--- a/indra/newview/llagentlistener.cpp
+++ b/indra/newview/llagentlistener.cpp
@@ -48,7 +48,7 @@ void LLAgentListener::requestTeleport(LLSD const & event_data) const
params.append(event_data["y"]);
params.append(event_data["z"]);
LLCommandDispatcher::dispatch("teleport", params, LLSD(), NULL, true);
- // *TODO - lookup other LLCommandHandlers for "agent", "classified", "event", "group", "floater", "objectim", "parcel", "login", login_refresh", "balance", "chat"
+ // *TODO - lookup other LLCommandHandlers for "agent", "classified", "event", "group", "floater", "parcel", "login", login_refresh", "balance", "chat"
// should we just compose LLCommandHandler and LLDispatchListener?
}
else
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 9938c3db2b..9b4986247f 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -887,9 +887,8 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
lldebugs << " " << LLWearableDictionary::getTypeLabel(type) << llendl;
}
- // What we do here is get the complete information on the items in
- // the inventory, and set up an observer that will wait for that to
- // happen.
+ // Get the complete information on the items in the inventory and set up an observer
+ // that will trigger when the complete information is fetched.
LLInventoryFetchDescendentsObserver::folder_ref_t folders;
folders.push_back(current_outfit_id);
outfit->fetchDescendents(folders);
@@ -2023,6 +2022,8 @@ void LLInitialWearablesFetch::done()
else
{
processWearablesMessage();
+ // Create links for attachments that may have arrived before the COF existed.
+ LLAppearanceManager::linkRegisteredAttachments();
}
delete this;
}
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index d14de1c301..0901289dac 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1123,6 +1123,7 @@ void LLAppearanceManager::wearItem( LLInventoryItem* item, bool do_update )
{
if (do_update)
LLAppearanceManager::updateAppearanceFromCOF();
+ return;
}
else
{
@@ -1134,6 +1135,7 @@ void LLAppearanceManager::wearItem( LLInventoryItem* item, bool do_update )
LLAssetType::AT_LINK,
cb);
}
+ return;
}
/* static */
@@ -1281,3 +1283,22 @@ void LLAppearanceManager::unregisterAttachment(const LLUUID& item_id)
//llinfos << "no link changes, inv link not enabled" << llendl;
}
}
+
+/* static */
+void LLAppearanceManager::linkRegisteredAttachments()
+{
+ for (std::set<LLUUID>::iterator it = sRegisteredAttachments.begin();
+ it != sRegisteredAttachments.end();
+ ++it)
+ {
+ LLUUID item_id = *it;
+ LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ if (item)
+ {
+ wearItem(item, false);
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
+ gInventory.notifyObservers();
+ }
+ }
+ sRegisteredAttachments.clear();
+}
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 56f54dfc23..7dea16b6cf 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -71,6 +71,7 @@ public:
static void unregisterAttachment(const LLUUID& item_id);
static void registerAttachment(const LLUUID& item_id);
static void setAttachmentInvLinkEnable(bool val);
+ static void linkRegisteredAttachments();
private:
static void filterWearableItems(LLInventoryModel::item_array_t& items, S32 max_per_type);
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 204d7d23fa..ab685b69ad 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -40,6 +40,7 @@
#include "llimfloater.h" // for LLIMFloater
#include "lllayoutstack.h"
#include "llnearbychatbar.h"
+#include "llspeakbutton.h"
#include "llsplitbutton.h"
#include "llsyswellwindow.h"
#include "llfloatercamera.h"
@@ -185,6 +186,28 @@ void LLBottomTray::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID&
}
}
+// virtual
+void LLBottomTray::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ // Time it takes to connect to voice channel might be pretty long,
+ // so don't expect user login or STATUS_VOICE_ENABLED to be followed by STATUS_JOINED.
+ BOOL enable = FALSE;
+
+ switch (status)
+ {
+ // Do not add STATUS_VOICE_ENABLED because voice chat is
+ // inactive until STATUS_JOINED
+ case STATUS_JOINED:
+ enable = TRUE;
+ break;
+ default:
+ enable = FALSE;
+ break;
+ }
+
+ mSpeakBtn->setEnabled(enable);
+}
+
//virtual
void LLBottomTray::onFocusLost()
{
@@ -280,6 +303,19 @@ BOOL LLBottomTray::postBuild()
mSnapshotPanel = getChild<LLPanel>("snapshot_panel");
setRightMouseDownCallback(boost::bind(&LLBottomTray::showBottomTrayContextMenu,this, _2, _3,_4));
+ mSpeakBtn = getChild<LLSpeakButton>("talk");
+
+ // Speak button should be initially disabled because
+ // it takes some time between logging in to world and connecting to voice channel.
+ mSpeakBtn->setEnabled(FALSE);
+
+ // Localization tool doesn't understand custom buttons like <talk_button>
+ mSpeakBtn->setSpeakToolTip( getString("SpeakBtnToolTip") );
+ mSpeakBtn->setShowToolTip( getString("VoiceControlBtnToolTip") );
+
+ // Registering Chat Bar to receive Voice client status change notifications.
+ gVoiceClient->addObserver(this);
+
if (mChicletPanel && mToolbarStack && mNearbyChatBar)
{
verifyChildControlsSizes();
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index 6509fea63d..c88bdeda1c 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -33,7 +33,7 @@
#ifndef LL_LLBOTTOMPANEL_H
#define LL_LLBOTTOMPANEL_H
-#include <llmenugl.h>
+#include "llmenugl.h"
#include "llpanel.h"
#include "llimview.h"
@@ -51,6 +51,7 @@ class LLBottomTray
: public LLSingleton<LLBottomTray>
, public LLPanel
, public LLIMSessionObserver
+ , public LLVoiceClientStatusObserver
{
LOG_CLASS(LLBottomTray);
friend class LLSingleton<LLBottomTray>;
@@ -75,6 +76,10 @@ public:
virtual void onFocusLost();
virtual void setVisible(BOOL visible);
+ // Implements LLVoiceClientStatusObserver::onChange() to enable the speak
+ // button when voice is available
+ /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
void showBottomTrayContextMenu(S32 x, S32 y, MASK mask);
void showGestureButton(BOOL visible);
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index ca2cdffcf8..e2df2ffdf7 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -124,9 +124,19 @@ void LLFloaterSearch::search(const LLSD &key)
url += "&p=" + search_token.asString();
// also append the user's preferred maturity (can be changed via prefs)
- std::string maturity = "pg";
- if (gAgent.prefersMature()) maturity += ",mature";
- if (gAgent.prefersAdult()) maturity += ",adult";
+ std::string maturity;
+ if (gAgent.prefersAdult())
+ {
+ maturity = "42"; // PG,Mature,Adult
+ }
+ else if (gAgent.prefersMature())
+ {
+ maturity = "21"; // PG,Mature
+ }
+ else
+ {
+ maturity = "13"; // PG
+ }
url += "&r=" + maturity;
// and load the URL in the web view
diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp
new file mode 100644
index 0000000000..e4d2eec242
--- /dev/null
+++ b/indra/newview/llinspectremoteobject.cpp
@@ -0,0 +1,200 @@
+/**
+ * @file llinspectremoteobject.cpp
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llinspectremoteobject.h"
+#include "llinspect.h"
+#include "llslurl.h"
+#include "llmutelist.h"
+#include "llurlaction.h"
+#include "llpanelblockedlist.h"
+#include "llfloaterreg.h"
+#include "llui.h"
+#include "lluictrl.h"
+
+class LLViewerObject;
+
+//////////////////////////////////////////////////////////////////////////////
+// LLInspectRemoteObject
+//////////////////////////////////////////////////////////////////////////////
+
+// Remote Object Inspector, a small information window used to
+// display information about potentially-remote objects. Used
+// to display details about objects sending messages to the user.
+class LLInspectRemoteObject : public LLInspect
+{
+ friend class LLFloaterReg;
+
+public:
+ LLInspectRemoteObject(const LLSD& object_id);
+ virtual ~LLInspectRemoteObject() {};
+
+ /*virtual*/ BOOL postBuild(void);
+ /*virtual*/ void onOpen(const LLSD& avatar_id);
+
+ void onClickMap();
+ void onClickBlock();
+ void onClickClose();
+
+private:
+ void update();
+ static void nameCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data);
+
+private:
+ LLUUID mObjectID;
+ LLUUID mOwnerID;
+ std::string mOwner;
+ std::string mSLurl;
+ std::string mName;
+ bool mGroupOwned;
+};
+
+LLInspectRemoteObject::LLInspectRemoteObject(const LLSD& sd) :
+ LLInspect(LLSD()),
+ mObjectID(NULL),
+ mOwnerID(NULL),
+ mOwner(""),
+ mSLurl(""),
+ mName(""),
+ mGroupOwned(false)
+{
+}
+
+/*virtual*/
+BOOL LLInspectRemoteObject::postBuild(void)
+{
+ // hook up the inspector's buttons
+ getChild<LLUICtrl>("map_btn")->setCommitCallback(
+ boost::bind(&LLInspectRemoteObject::onClickMap, this));
+ getChild<LLUICtrl>("block_btn")->setCommitCallback(
+ boost::bind(&LLInspectRemoteObject::onClickBlock, this));
+ getChild<LLUICtrl>("close_btn")->setCommitCallback(
+ boost::bind(&LLInspectRemoteObject::onClickClose, this));
+
+ return TRUE;
+}
+
+/*virtual*/
+void LLInspectRemoteObject::onOpen(const LLSD& data)
+{
+ // Start animation
+ LLInspect::onOpen(data);
+
+ // Extract appropriate object information from input LLSD
+ // (Eventually, it might be nice to query server for details
+ // rather than require caller to pass in the information.)
+ mObjectID = data["object_id"].asUUID();
+ mName = data["name"].asString();
+ mOwnerID = data["owner_id"].asUUID();
+ mGroupOwned = data["group_owned"].asBoolean();
+ mSLurl = data["slurl"].asString();
+
+ // work out the owner's name
+ mOwner = "";
+ if (gCacheName)
+ {
+ gCacheName->get(mOwnerID, mGroupOwned, nameCallback, this);
+ }
+
+ // update the inspector with the current object state
+ update();
+
+ // Position the inspector relative to the mouse cursor
+ LLUI::positionViewNearMouse(this);
+}
+
+void LLInspectRemoteObject::onClickMap()
+{
+ std::string url = "secondlife://" + mSLurl;
+ LLUrlAction::showLocationOnMap(url);
+ closeFloater();
+}
+
+void LLInspectRemoteObject::onClickBlock()
+{
+ LLMute::EType mute_type = mGroupOwned ? LLMute::GROUP : LLMute::AGENT;
+ LLMute mute(mOwnerID, mOwner, mute_type);
+ LLMuteList::getInstance()->add(mute);
+ LLPanelBlockedList::showPanelAndSelect(mute.mID);
+ closeFloater();
+}
+
+void LLInspectRemoteObject::onClickClose()
+{
+ closeFloater();
+}
+
+//static
+void LLInspectRemoteObject::nameCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data)
+{
+ LLInspectRemoteObject *self = (LLInspectRemoteObject*)data;
+ self->mOwner = first;
+ if (!last.empty())
+ {
+ self->mOwner += " " + last;
+ }
+ self->update();
+}
+
+void LLInspectRemoteObject::update()
+{
+ // show the object name as the inspector's title
+ getChild<LLUICtrl>("object_name")->setValue(mName);
+
+ // show the object's owner - click it to show profile
+ std::string owner = mOwner;
+ if (! mOwnerID.isNull())
+ {
+ if (mGroupOwned)
+ {
+ owner = LLSLURL::buildCommand("group", mOwnerID, "about");
+ }
+ else
+ {
+ owner = LLSLURL::buildCommand("agent", mOwnerID, "about");
+ }
+ }
+ getChild<LLUICtrl>("object_owner")->setValue(owner);
+
+ // display the object's SLurl - click it to teleport
+ std::string url = "secondlife:///app/teleport/" + mSLurl;
+ getChild<LLUICtrl>("object_slurl")->setValue(url);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// LLInspectRemoteObjectUtil
+//////////////////////////////////////////////////////////////////////////////
+void LLInspectRemoteObjectUtil::registerFloater()
+{
+ LLFloaterReg::add("inspect_remote_object", "inspect_remote_object.xml",
+ &LLFloaterReg::build<LLInspectRemoteObject>);
+}
diff --git a/indra/newview/llinspectremoteobject.h b/indra/newview/llinspectremoteobject.h
new file mode 100644
index 0000000000..e756f1caf4
--- /dev/null
+++ b/indra/newview/llinspectremoteobject.h
@@ -0,0 +1,40 @@
+/**
+ * @file llinspectremoteobject.h
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLINSPECTREMOTEOBJECT_H
+#define LLINSPECTREMOTEOBJECT_H
+
+namespace LLInspectRemoteObjectUtil
+{
+ void registerFloater();
+}
+
+#endif
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index e7d7eb19d0..c57e41e9b3 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -176,6 +176,7 @@ LLInventoryModel::LLInventoryModel()
mRootFolderID(),
mLibraryRootFolderID(),
mLibraryOwnerID(),
+ mIsNotifyObservers(FALSE),
mIsAgentInvUsable(false)
{
}
@@ -537,7 +538,10 @@ void LLInventoryModel::updateLinkedItems(const LLUUID& object_id)
item_array,
LLInventoryModel::INCLUDE_TRASH,
is_linked_item_match);
-
+ if (cat_array.empty() && item_array.empty())
+ {
+ return;
+ }
for (LLInventoryModel::cat_array_t::iterator cat_iter = cat_array.begin();
cat_iter != cat_array.end();
cat_iter++)
@@ -639,6 +643,7 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)
new_item = old_item;
LLUUID old_parent_id = old_item->getParentUUID();
LLUUID new_parent_id = item->getParentUUID();
+
if(old_parent_id != new_parent_id)
{
// need to update the parent-child tree
@@ -1133,6 +1138,15 @@ BOOL LLInventoryModel::containsObserver(LLInventoryObserver* observer) const
// The optional argument 'service_name' is used by Agent Inventory Service [DEV-20328]
void LLInventoryModel::notifyObservers(const std::string service_name)
{
+ if (mIsNotifyObservers)
+ {
+ // Within notifyObservers, something called notifyObservers
+ // again. This type of recursion is unsafe because it causes items to be
+ // processed twice, and this can easily lead to infinite loops.
+ llwarns << "Call was made to notifyObservers within notifyObservers!" << llendl;
+ return;
+ }
+ mIsNotifyObservers = TRUE;
for (observer_list_t::iterator iter = mObservers.begin();
iter != mObservers.end(); )
{
@@ -1154,12 +1168,21 @@ void LLInventoryModel::notifyObservers(const std::string service_name)
mModifyMask = LLInventoryObserver::NONE;
mChangedItemIDs.clear();
+ mIsNotifyObservers = FALSE;
}
// store flag for change
// and id of object change applies to
void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent)
{
+ if (mIsNotifyObservers)
+ {
+ // Something marked an item for change within a call to notifyObservers
+ // (which is in the process of processing the list of items marked for change).
+ // This means the change may fail to be processed.
+ llwarns << "Adding changed mask within notify observers! Change will likely be lost." << llendl;
+ }
+
mModifyMask |= mask;
if (referent.notNull())
{
@@ -1833,13 +1856,13 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
{
//llinfos << "LLInventoryModel::addItem()" << llendl;
-
- // This can happen if assettype enums change. This can be a backwards compatibility issue
- // in some viewer prototypes prior to when the AT_LINK enum changed from 23 to 24.
+ // This can happen if assettype enums from llassettype.h ever change.
+ // For example, there is a known backwards compatibility issue in some viewer prototypes prior to when
+ // the AT_LINK enum changed from 23 to 24.
if ((item->getType() == LLAssetType::AT_NONE)
|| LLAssetType::lookup(item->getType()) == LLAssetType::badLookup())
{
- llwarns << "Got bad asset type for item ( name: " << item->getName() << " type: " << item->getType() << " inv-type: " << item->getInventoryType() << " ), ignoring." << llendl;
+ llwarns << "Got bad asset type for item [ name: " << item->getName() << " type: " << item->getType() << " inv-type: " << item->getInventoryType() << " ], ignoring." << llendl;
return;
}
if(item)
@@ -1848,7 +1871,7 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
// The item will show up as a broken link.
if (item->getIsBrokenLink())
{
- llinfos << "Adding broken link ( name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << llendl;
+ llinfos << "Adding broken link [ name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << llendl;
}
mItemMap[item->getUUID()] = item;
}
@@ -2176,7 +2199,7 @@ bool LLInventoryModel::loadSkeleton(
// Add all the items loaded which are parented to a
// category with a correctly cached parent
- count = items.count();
+ S32 bad_link_count = 0;
cat_map_t::iterator unparented = mCategoryMap.end();
for(item_array_t::const_iterator item_iter = items.begin();
item_iter != items.end();
@@ -2193,7 +2216,11 @@ bool LLInventoryModel::loadSkeleton(
// This can happen if the linked object's baseobj is removed from the cache but the linked object is still in the cache.
if (item->getIsBrokenLink())
{
- llinfos << "Attempted to add cached link item without baseobj present ( name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ). Ignoring and invalidating " << cat->getName() << " . " << llendl;
+ bad_link_count++;
+ lldebugs << "Attempted to add cached link item without baseobj present ( name: "
+ << item->getName() << " itemID: " << item->getUUID()
+ << " assetID: " << item->getAssetUUID()
+ << " ). Ignoring and invalidating " << cat->getName() << " . " << llendl;
invalid_categories.insert(cit->second);
continue;
}
@@ -2203,6 +2230,12 @@ bool LLInventoryModel::loadSkeleton(
}
}
}
+ if (bad_link_count > 0)
+ {
+ llinfos << "Attempted to add " << bad_link_count
+ << " cached link items without baseobj present. "
+ << "The corresponding categories were invalidated." << llendl;
+ }
}
else
{
@@ -3307,6 +3340,12 @@ void LLInventoryModel::processInventoryDescendents(LLMessageSystem* msg,void**)
for(i = 0; i < count; ++i)
{
titem->unpackMessage(msg, _PREHASH_ItemData, i);
+ // If the item has already been added (e.g. from link prefetch), then it doesn't need to be re-added.
+ if (gInventory.getItem(titem->getUUID()))
+ {
+ llinfos << "Skipping prefetched item [ Name: " << titem->getName() << " | Type: " << titem->getActualType() << " | ItemUUID: " << titem->getUUID() << " ] " << llendl;
+ continue;
+ }
gInventory.updateItem(titem);
}
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index faf026887a..ebfb0a7000 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -473,23 +473,12 @@ protected:
cat_array_t* getUnlockedCatArray(const LLUUID& id);
item_array_t* getUnlockedItemArray(const LLUUID& id);
-protected:
+private:
// Variables used to track what has changed since the last notify.
U32 mModifyMask;
typedef std::set<LLUUID> changed_items_t;
changed_items_t mChangedItemIDs;
- // Information for tracking the actual inventory. We index this
- // information in a lot of different ways so we can access
- // the inventory using several different identifiers.
- // mInventory member data is the 'master' list of inventory, and
- // mCategoryMap and mItemMap store uuid->object mappings.
- typedef std::map<LLUUID, LLPointer<LLViewerInventoryCategory> > cat_map_t;
- typedef std::map<LLUUID, LLPointer<LLViewerInventoryItem> > item_map_t;
- //inv_map_t mInventory;
- cat_map_t mCategoryMap;
- item_map_t mItemMap;
-
std::map<LLUUID, bool> mCategoryLock;
std::map<LLUUID, bool> mItemLock;
@@ -525,6 +514,21 @@ protected:
// This flag is used to handle an invalid inventory state.
bool mIsAgentInvUsable;
+private:
+ // Information for tracking the actual inventory. We index this
+ // information in a lot of different ways so we can access
+ // the inventory using several different identifiers.
+ // mInventory member data is the 'master' list of inventory, and
+ // mCategoryMap and mItemMap store uuid->object mappings.
+ typedef std::map<LLUUID, LLPointer<LLViewerInventoryCategory> > cat_map_t;
+ typedef std::map<LLUUID, LLPointer<LLViewerInventoryItem> > item_map_t;
+ //inv_map_t mInventory;
+ cat_map_t mCategoryMap;
+ item_map_t mItemMap;
+
+ // Flag set when notifyObservers is being called, to look for bugs
+ // where it's called recursively.
+ BOOL mIsNotifyObservers;
public:
// *NOTE: DEBUG functionality
void dumpInventory() const;
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 9a71e53441..dfd4af5c28 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -191,11 +191,9 @@ BOOL LLInventoryPanel::postBuild()
{
rebuildViewsFor(mStartFolderID);
mHasInventoryConnection = true;
+ defaultOpenInventory();
}
- // bit of a hack to make sure the inventory is open.
- mFolders->openFolder(preferred_type != LLFolderType::FT_NONE ? LLViewerFolderType::lookupNewCategoryName(preferred_type) : "My Inventory");
-
if (mSortOrderSetting != INHERIT_SORT_ORDER)
{
setSortOrder(gSavedSettings.getU32(mSortOrderSetting));
@@ -300,6 +298,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
{
rebuildViewsFor(mStartFolderID);
mHasInventoryConnection = true;
+ defaultOpenInventory();
return;
}
@@ -561,6 +560,25 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
}
}
+// bit of a hack to make sure the inventory is open.
+void LLInventoryPanel::defaultOpenInventory()
+{
+ const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString);
+ if (preferred_type != LLFolderType::FT_NONE)
+ {
+ const std::string& top_level_folder_name = LLViewerFolderType::lookupNewCategoryName(preferred_type);
+ mFolders->openFolder(top_level_folder_name);
+ }
+ else
+ {
+ // Get the first child (it should be "My Inventory") and
+ // open it up by name (just to make sure the first child is actually a folder).
+ LLView* first_child = mFolders->getFirstChild();
+ const std::string& first_child_name = first_child->getName();
+ mFolders->openFolder(first_child_name);
+ }
+}
+
struct LLConfirmPurgeData
{
LLUUID mID;
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 9f74fad5c1..e398c44105 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -165,7 +165,7 @@ protected:
// Given the id and the parent, build all of the folder views.
void rebuildViewsFor(const LLUUID& id);
virtual void buildNewViews(const LLUUID& id); // made virtual to support derived classes. EXT-719
-
+ void defaultOpenInventory(); // open the first level of inventory
protected:
LLInventoryModel* mInventory;
LLInventoryObserver* mInventoryObserver;
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 945294f3f2..a01426ea87 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -182,6 +182,9 @@ void LLLoginInstance::constructAuthParams(const LLSD& credentials)
mRequestData["method"] = "login_to_simulator";
mRequestData["params"] = request_params;
mRequestData["options"] = requested_options;
+
+ mRequestData["cfg_srv_timeout"] = gSavedSettings.getF32("LoginSRVTimeout");
+ mRequestData["cfg_srv_pump"] = gSavedSettings.getString("LoginSRVPump");
}
bool LLLoginInstance::handleLoginEvent(const LLSD& event)
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index 3993431311..94b8791147 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -36,7 +36,6 @@
#include "lltrans.h"
#include "llnearbychatbar.h"
-#include "llspeakbutton.h"
#include "llbottomtray.h"
#include "llagent.h"
#include "llgesturemgr.h"
@@ -234,14 +233,6 @@ BOOL LLNearbyChatBar::postBuild()
mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
mOutputMonitor->setVisible(FALSE);
- mSpeakBtn = getParent()->getChild<LLSpeakButton>("talk");
-
- // Speak button should be initially disabled because
- // it takes some time between logging in to world and connecting to voice channel.
- mSpeakBtn->setEnabled(FALSE);
-
- // Registering Chat Bar to receive Voice client status change notifications.
- gVoiceClient->addObserver(this);
return TRUE;
}
@@ -733,27 +724,6 @@ public:
}
};
-void LLNearbyChatBar::onChange(EStatusType status, const std::string &channelURI, bool proximal)
-{
- // Time it takes to connect to voice channel might be pretty long,
- // so don't expect user login or STATUS_VOICE_ENABLED to be followed by STATUS_JOINED.
- BOOL enable = FALSE;
-
- switch (status)
- {
- // Do not add STATUS_VOICE_ENABLED because voice chat is
- // inactive until STATUS_JOINED
- case STATUS_JOINED:
- enable = TRUE;
- break;
- default:
- enable = FALSE;
- break;
- }
-
- mSpeakBtn->setEnabled(enable);
-}
-
// Creating the object registers with the dispatcher.
LLChatHandler gChatHandler;
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index 56ee706a97..224118e088 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -42,9 +42,6 @@
#include "llspeakers.h"
-class LLSpeakButton;
-
-
class LLGestureComboBox
: public LLComboBox
, public LLGestureManagerObserver
@@ -76,7 +73,6 @@ protected:
class LLNearbyChatBar
: public LLPanel
-, public LLVoiceClientStatusObserver
{
public:
// constructor for inline chat-bars (e.g. hosted in chat history window)
@@ -105,11 +101,6 @@ public:
S32 getMinWidth() const;
S32 getMaxWidth() const;
- /**
- * Implements LLVoiceClientStatusObserver::onChange()
- */
- /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
-
protected:
static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata);
@@ -127,7 +118,6 @@ protected:
static S32 sLastSpecialChatChannel;
LLLineEditor* mChatBox;
- LLSpeakButton* mSpeakBtn;
LLOutputMonitorCtrl* mOutputMonitor;
LLLocalSpeakerMgr* mSpeakerMgr;
};
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 15a75cb930..e3b2ab77aa 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -204,11 +204,6 @@ void LLPanelMainInventory::initListCommandsHandlers()
mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelMainInventory::onGearButtonClick, this));
mListCommands->childSetAction("trash_btn", boost::bind(&LLPanelMainInventory::onTrashButtonClick, this));
mListCommands->childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this));
- /*
- mListCommands->getChild<LLButton>("add_btn")->setHeldDownCallback(boost::bind(&LLPanelMainInventory::onAddButtonHeldDown, this));
- static const LLSD add_landmark_command("add_landmark");
- mListCommands->childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddAction, this, add_landmark_command));
- */
LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>("trash_btn");
trash_btn->setDragAndDropHandler(boost::bind(&LLPanelMainInventory::handleDragAndDropToTrash, this
diff --git a/indra/newview/llspeakbutton.cpp b/indra/newview/llspeakbutton.cpp
index 57ea018f25..51d53b2674 100644
--- a/indra/newview/llspeakbutton.cpp
+++ b/indra/newview/llspeakbutton.cpp
@@ -133,6 +133,16 @@ LLSpeakButton::~LLSpeakButton()
LLTransientFloaterMgr::getInstance()->removeControlView(mShowBtn);
}
+void LLSpeakButton::setSpeakToolTip(const std::string& msg)
+{
+ mSpeakBtn->setToolTip(msg);
+}
+
+void LLSpeakButton::setShowToolTip(const std::string& msg)
+{
+ mShowBtn->setToolTip(msg);
+}
+
void LLSpeakButton::onMouseDown_SpeakBtn()
{
bool down = true;
diff --git a/indra/newview/llspeakbutton.h b/indra/newview/llspeakbutton.h
index e213c562dd..02c8ab3890 100644
--- a/indra/newview/llspeakbutton.h
+++ b/indra/newview/llspeakbutton.h
@@ -62,6 +62,11 @@ public:
/*virtual*/ ~LLSpeakButton();
/*virtual*/ void draw();
+ // *HACK: Need to put tooltips in a translatable location,
+ // the panel that contains this button.
+ void setSpeakToolTip(const std::string& msg);
+ void setShowToolTip(const std::string& msg);
+
protected:
friend class LLUICtrlFactory;
LLSpeakButton(const Params& p);
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index a3daca6fa4..9e064d8135 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -364,9 +364,9 @@ bool LLURLDispatcher::dispatchRightClick(const std::string& url)
bool LLURLDispatcher::dispatchFromTextEditor(const std::string& url)
{
// *NOTE: Text editors are considered sources of trusted URLs
- // in order to make objectim and avatar profile links in chat
- // history work. While a malicious resident could chat an app
- // SLURL, the receiving resident will see it and must affirmatively
+ // in order to make avatar profile links in chat history work.
+ // While a malicious resident could chat an app SLURL, the
+ // receiving resident will see it and must affirmatively
// click on it.
// *TODO: Make this trust model more refined. JC
const bool trusted_browser = true;
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 7cd660110f..7772f613f0 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -112,6 +112,7 @@
#include "llinspectavatar.h"
#include "llinspectgroup.h"
#include "llinspectobject.h"
+#include "llinspectremoteobject.h"
#include "llmediaremotectrl.h"
#include "llmoveview.h"
#include "llnearbychat.h"
@@ -176,6 +177,7 @@ void LLViewerFloaterReg::registerFloaters()
LLInspectAvatarUtil::registerFloater();
LLInspectGroupUtil::registerFloater();
LLInspectObjectUtil::registerFloater();
+ LLInspectRemoteObjectUtil::registerFloater();
LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);
LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 976d89a5b7..728fb7c616 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -1879,7 +1879,9 @@ class LLAdvancedDebugAvatarTextures : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
+#ifndef LL_RELEASE_FOR_DOWNLOAD
handle_debug_avatar_textures(NULL);
+#endif
return true;
}
};
@@ -1893,7 +1895,9 @@ class LLAdvancedDumpAvatarLocalTextures : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
+#ifndef LL_RELEASE_FOR_DOWNLOAD
handle_dump_avatar_local_textures(NULL);
+#endif
return true;
}
};
@@ -7860,10 +7864,8 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedCheckDebugCharacterVis(), "Advanced.CheckDebugCharacterVis");
view_listener_t::addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments");
view_listener_t::addMenu(new LLAdvancedRebakeTextures(), "Advanced.RebakeTextures");
- #ifndef LL_RELEASE_FOR_DOWNLOAD
view_listener_t::addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures");
view_listener_t::addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures");
- #endif
// Advanced > Network
view_listener_t::addMenu(new LLAdvancedEnableMessageLog(), "Advanced.EnableMessageLog");
view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 1a4c849f25..4088eafe16 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1431,6 +1431,17 @@ bool goto_url_callback(const LLSD& notification, const LLSD& response)
}
static LLNotificationFunctorRegistration goto_url_callback_reg("GotoURL", goto_url_callback);
+bool inspect_remote_object_callback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ LLFloaterReg::showInstance("inspect_remote_object", notification["payload"]);
+ }
+ return false;
+}
+static LLNotificationFunctorRegistration inspect_remote_object_callback_reg("ServerObjectMessage", inspect_remote_object_callback);
+
void process_improved_im(LLMessageSystem *msg, void **user_data)
{
if (gNoRender)
@@ -1943,9 +1954,23 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
return;
}
+ // Build a link to open the object IM info window.
+ std::string location = ll_safe_string((char*)binary_bucket, binary_bucket_size-1);
+
LLSD substitutions;
+ substitutions["NAME"] = name;
substitutions["MSG"] = message;
- LLNotifications::instance().add("ServerObjectMessage", substitutions);
+
+ LLSD payload;
+ payload["object_id"] = session_id;
+ payload["owner_id"] = from_id;
+ payload["slurl"] = location;
+ payload["name"] = name;
+ if (from_group)
+ {
+ payload["groupowned"] = "true";
+ }
+ LLNotifications::instance().add("ServerObjectMessage", substitutions, payload);
}
break;
case IM_FROM_TASK_AS_ALERT:
diff --git a/indra/newview/skins/default/xui/en/floater_inventory.xml b/indra/newview/skins/default/xui/en/floater_inventory.xml
index 30639f955f..b48c962413 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory.xml
@@ -36,10 +36,10 @@
filename="panel_main_inventory.xml"
follows="all"
layout="topleft"
+ hide_top_panel="true"
left="0"
label="Inventory Panel"
name="Inventory Panel"
top="15"
- width="467">
-</panel>
+ width="467" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_search.xml b/indra/newview/skins/default/xui/en/floater_search.xml
index b9cf456842..d9498586af 100644
--- a/indra/newview/skins/default/xui/en/floater_search.xml
+++ b/indra/newview/skins/default/xui/en/floater_search.xml
@@ -25,7 +25,7 @@
Done
</floater.string>
<layout_stack
- bottom="400"
+ bottom="512"
follows="left|right|top|bottom"
layout="topleft"
left="10"
@@ -54,7 +54,7 @@
layout="topleft"
left_delta="0"
name="status_text"
- top_pad="4"
+ top_pad="5"
width="150" />
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/en/inspect_remote_object.xml b/indra/newview/skins/default/xui/en/inspect_remote_object.xml
new file mode 100644
index 0000000000..07c684d904
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/inspect_remote_object.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!--
+ Not can_close / no title to avoid window chrome
+ Single instance - only have one at a time, recycle it each spawn
+-->
+<floater
+ legacy_header_height="18"
+ bevel_style="in"
+ bg_opaque_image="Inspector_Background"
+ can_close="false"
+ can_minimize="false"
+ height="145"
+ layout="topleft"
+ name="inspect_remote_object"
+ single_instance="true"
+ sound_flags="0"
+ visible="true"
+ width="300">
+ <text
+ follows="all"
+ font="SansSerifLargeBold"
+ height="16"
+ left="8"
+ name="object_name"
+ text_color="White"
+ top="5"
+ use_ellipses="true"
+ width="290">
+ Test Object Name That Is Really Long
+ </text>
+ <text
+ follows="all"
+ font="SansSerif"
+ height="20"
+ left="8"
+ name="object_owner_label"
+ width="55"
+ top_pad="20">
+ Owner:
+ </text>
+ <text
+ follows="top|left"
+ font="SansSerif"
+ height="20"
+ left_pad="10"
+ name="object_owner"
+ use_ellipses="true"
+ width="200"
+ word_wrap="false">
+ Longavatarname Johnsonlongstonnammer
+ </text>
+ <text
+ follows="top|left"
+ font="SansSerif"
+ height="20"
+ left="8"
+ name="object_slurl_label"
+ top_pad="10"
+ width="55">
+ Location:
+ </text>
+ <text
+ follows="top|left"
+ height="20"
+ left_pad="10"
+ name="object_slurl"
+ width="240"
+ use_ellipses="true"
+ word_wrap="false">
+ http://slurl.com/Ahern/50/50/50
+ </text>
+ <button
+ follows="top|left"
+ font="SansSerif"
+ height="20"
+ label="Map"
+ left="10"
+ name="map_btn"
+ top="114"
+ width="75" />
+ <button
+ follows="top|left"
+ font="SansSerif"
+ height="20"
+ label="Block"
+ left_pad="5"
+ name="block_btn"
+ top_delta="0"
+ width="75" />
+ <button
+ follows="top|left"
+ font="SansSerif"
+ height="20"
+ label="Close"
+ right="-10"
+ name="close_btn"
+ top_delta="0"
+ width="75" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 96c6d970c2..ff0cd7ffeb 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4696,7 +4696,12 @@ The objects on the selected parcel that are NOT owned by you have been returned
icon="notify.tga"
name="ServerObjectMessage"
type="notify">
+Message from [NAME]:
[MSG]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="OK"
+ yestext="Inspect"/>
</notification>
<notification
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 8188016455..3c16a439d9 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -13,6 +13,8 @@
chrome="true"
border_visible="false"
width="1000">
+ <string name="SpeakBtnToolTip">Turns microphone on/off</string>
+ <string name="VoiceControlBtnToolTip">Shows/hides voice control panel</string>
<layout_stack
mouse_opaque="false"
border_size="0"
@@ -70,9 +72,7 @@
left="0"
name="talk"
top="3"
- width="100"
- speak_button.tool_tip="Turns microphone on/off"
- show_button.tool_tip="Shows/hides voice control panel" />
+ width="100" />
</layout_panel>
<icon
auto_resize="false"
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index d31a81e128..7b28a3b72c 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -76,6 +76,7 @@ LLControlGroup::LLControlGroup(const std::string& name) :
LLControlGroup::~LLControlGroup() {}
void LLControlGroup::setBOOL(const std::string& name, BOOL val) {}
BOOL LLControlGroup::getBOOL(const std::string& name) { return FALSE; }
+F32 LLControlGroup::getF32(const std::string& name) { return 0.0f; }
U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only) { return 1; }
void LLControlGroup::setString(const std::string& name, const std::string& val) {}
std::string LLControlGroup::getString(const std::string& name) { return "test_string"; }
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index 7a30315b9a..b14c59ab9a 100644
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -70,7 +70,7 @@ public:
LLEventPump& getEventPump() { return mPump; }
private:
- void sendProgressEvent(const std::string& state, const std::string& change,
+ LLSD getProgressEventLLSD(const std::string& state, const std::string& change,
const LLSD& data = LLSD())
{
LLSD status_data;
@@ -87,7 +87,13 @@ private:
{
status_data["data"] = data;
}
+ return status_data;
+ }
+ void sendProgressEvent(const std::string& state, const std::string& change,
+ const LLSD& data = LLSD())
+ {
+ LLSD status_data = getProgressEventLLSD(state, change, data);
mPump.post(status_data);
}
@@ -140,15 +146,28 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD credential
// Request SRV record.
LL_INFOS("LLLogin") << "Requesting SRV record from " << uri << LL_ENDL;
- // *NOTE:Mani - Completely arbitrary timeout value for SRV request.
- filter.errorAfter(5, "SRV Request timed out!");
+ // *NOTE:Mani - Completely arbitrary default timeout value for SRV request.
+ F32 seconds_to_timeout = 5.0f;
+ if(credentials.has("cfg_srv_timeout"))
+ {
+ seconds_to_timeout = credentials["cfg_srv_timeout"].asReal();
+ }
+
+ filter.eventAfter(seconds_to_timeout,
+ getProgressEventLLSD("offline", "fail.login"));
+
+ std::string srv_pump_name = "LLAres";
+ if(credentials.has("cfg_srv_pump"))
+ {
+ srv_pump_name = credentials["cfg_srv_pump"].asString();
+ }
- // Make request
+ // Make request
LLSD request;
request["op"] = "rewriteURI";
request["uri"] = uri;
request["reply"] = replyPump.getName();
- rewrittenURIs = postAndWait(self, request, "LLAres", filter);
+ rewrittenURIs = postAndWait(self, request, srv_pump_name, filter);
} // we no longer need the filter
LLEventPump& xmlrpcPump(LLEventPumps::instance().obtain("LLXMLRPCTransaction"));
diff --git a/indra/viewer_components/login/tests/lllogin_test.cpp b/indra/viewer_components/login/tests/lllogin_test.cpp
index a8ae2883d5..56c21016bd 100644
--- a/indra/viewer_components/login/tests/lllogin_test.cpp
+++ b/indra/viewer_components/login/tests/lllogin_test.cpp
@@ -47,6 +47,7 @@ public:
bool call(const LLSD& event)
{
mDebug(STRINGIZE("LoginListener called!: " << event));
+
mLastEvent = event;
return false;
}
@@ -414,4 +415,40 @@ namespace tut
ensure_equals("Failed to offline", listener.lastEvent()["state"].asString(), "offline");
}
+
+ template<> template<>
+ void llviewerlogin_object::test<5>()
+ {
+ DEBUG;
+ // Test SRV request timeout.
+ set_test_name("LLLogin SRV timeout testing");
+
+ // Testing normal login procedure.
+ LLEventStream llaresPump("LLAres"); // Dummy LLAres pump.
+
+ // LLAresListener dummyLLAres("dummy_llares");
+ // dummyLLAres.listenTo(llaresPump);
+
+ LLLogin login;
+ LoginListener listener("test_ear");
+ listener.listenTo(login.getEventPump());
+
+ LLSD credentials;
+ credentials["first"] = "these";
+ credentials["last"] = "don't";
+ credentials["passwd"] = "matter";
+ credentials["cfg_srv_timeout"] = 0.0f;
+
+ login.connect("login.bar.com", credentials);
+
+ ensure_equals("SRV State", listener.lastEvent()["change"].asString(), "srvrequest");
+
+ // Get the mainloop eventpump, which needs a pinging in order to drive the
+ // SRV timeout.
+ LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
+ LLSD frame_event;
+ mainloop.post(frame_event);
+
+ ensure_equals("SRV Failure", listener.lastEvent()["change"].asString(), "fail.login");
+ }
}