summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authordolphin <dolphin@lindenlab.com>2013-08-21 15:43:09 -0700
committerdolphin <dolphin@lindenlab.com>2013-08-21 15:43:09 -0700
commit257110c11e5546f0a5a07b087694cfc9059367b4 (patch)
tree2fdd2a90fd32a17a950a055068d9eb39686ba96f /indra
parent98628066eb27d4f2616479538ae20a07bf92cd98 (diff)
Added new fields to the experience cache.
Experience profile moved to it's own floater, will probalby be moving again. XP profile displays most data, though the presentation is not final Fixed a bug with the XP selection combobox in the script editor
Diffstat (limited to 'indra')
-rw-r--r--indra/llmessage/llexperiencecache.cpp61
-rw-r--r--indra/llmessage/llexperiencecache.h17
-rwxr-xr-xindra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/llfloaterexperienceprofile.cpp215
-rw-r--r--indra/newview/llfloaterexperienceprofile.h70
-rwxr-xr-xindra/newview/llpreviewscript.cpp20
-rwxr-xr-xindra/newview/llpreviewscript.h4
-rwxr-xr-xindra/newview/llviewerfloaterreg.cpp6
-rw-r--r--indra/newview/skins/default/xui/en/floater_experienceprofile.xml293
9 files changed, 662 insertions, 26 deletions
diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp
index 219e68b51c..2e260ecdef 100644
--- a/indra/llmessage/llexperiencecache.cpp
+++ b/indra/llmessage/llexperiencecache.cpp
@@ -37,11 +37,10 @@
namespace LLExperienceCache
{
- typedef std::map<LLUUID, LLUUID> PrivateKeyMap;
- PrivateKeyMap experinceKeyMap;
-
- void mapPrivateKeys(const LLSD& legacyKeys);
+ typedef std::map<LLUUID, LLUUID> KeyMap;
+ KeyMap privateToPublicKeyMap;
+ void mapKeys(const LLSD& legacyKeys);
std::string sLookupURL;
@@ -66,6 +65,7 @@ namespace LLExperienceCache
signal_map_t sSignalMap;
+
bool max_age_from_cache_control(const std::string& cache_control, S32 *max_age);
void eraseExpired();
@@ -89,6 +89,17 @@ namespace LLExperienceCache
sPendingQueue.erase(row[OWNER_ID].asUUID());
}
+ if(!row.has(OWNER_ID))
+ {
+ if(row.has(AGENT_ID) && row[AGENT_ID].asUUID().notNull())
+ {
+ row[OWNER_ID]=row[AGENT_ID];
+ }
+ else
+ {
+ row[OWNER_ID]=row[GROUP_ID];
+ }
+ }
//signal
signal_map_t::iterator sig_it = sSignalMap.find(public_key);
@@ -119,7 +130,7 @@ namespace LLExperienceCache
void bootstrap(const LLSD& legacyKeys, int initialExpiration)
{
- mapPrivateKeys(legacyKeys);
+ mapKeys(legacyKeys);
LLSD::array_const_iterator it = legacyKeys.beginArray();
for(/**/; it != legacyKeys.endArray(); ++it)
{
@@ -302,7 +313,8 @@ namespace LLExperienceCache
exp[EXPIRES]=DEFAULT_EXPIRATION;
exp[EXPERIENCE_ID] = id;
exp[PROPERTIES]=PROPERTY_INVALID;
- exp["DoesNotExist"]=true;
+ exp[MISSING]=true;
+ exp[QUOTA] = DEFAULT_QUOTA;
processExperience(id, exp);
LL_INFOS("ExperienceCache") << "Error result for " << id << LL_ENDL ;
@@ -324,14 +336,22 @@ namespace LLExperienceCache
ask_queue_t::const_iterator it = mKeys.begin();
for ( ; it != mKeys.end(); ++it)
{
+
LLSD exp;
+ //leave the properties alone if we already have a cache entry for this xp
+ if(!get(it->first, exp))
+ {
+ exp[PROPERTIES]=PROPERTY_INVALID;
+ }
exp[EXPIRES]=retry_timestamp;
exp[EXPERIENCE_ID] = it->first;
exp["key_type"] = it->second;
exp["uuid"] = it->first;
exp["error"] = (LLSD::Integer)status;
- exp[PROPERTIES]=PROPERTY_INVALID;
+ exp[QUOTA] = DEFAULT_QUOTA;
+
LLExperienceCache::processExperience(it->first, exp);
+ LL_INFOS("ExperienceCache") << "Error result for " << it->first << LL_ENDL ;
}
}
@@ -514,22 +534,25 @@ namespace LLExperienceCache
cache_t::iterator cur = it;
LLSD& exp = cur->second;
++it;
+
if(exp.has(EXPIRES) && exp[EXPIRES].asReal() < now)
{
- if(exp.has(EXPERIENCE_ID))
+ if(!exp.has(EXPERIENCE_ID))
{
- LLUUID id = exp[EXPERIENCE_ID].asUUID();
- S32 properties = PROPERTY_INVALID;
- if(exp.has(PROPERTIES))
- {
- properties = exp[PROPERTIES].asInteger();
+ LL_INFOS("ExperienceCache") << "Removing experience with no id " << LL_ENDL ;
+ sCache.erase(cur);
}
- if(id.notNull() && ((properties & PROPERTY_INVALID) == 0))
+ else
+ {
+ LLUUID id = exp[EXPERIENCE_ID].asUUID();
+ LLUUID private_key = exp.has(LLExperienceCache::PRIVATE_KEY) ? exp[LLExperienceCache::PRIVATE_KEY].asUUID():LLUUID::null;
+ if(private_key.notNull() || !exp.has("DoesNotExist"))
{
fetch(id, true);
}
else
{
+ LL_INFOS("ExperienceCache") << "Removing invalid experience " << id << LL_ENDL ;
sCache.erase(cur);
}
}
@@ -616,15 +639,14 @@ namespace LLExperienceCache
}
-
-void LLExperienceCache::mapPrivateKeys( const LLSD& legacyKeys )
+void LLExperienceCache::mapKeys( const LLSD& legacyKeys )
{
LLSD::array_const_iterator exp = legacyKeys.beginArray();
for(/**/ ; exp != legacyKeys.endArray() ; ++exp)
{
if(exp->has(LLExperienceCache::EXPERIENCE_ID) && exp->has(LLExperienceCache::PRIVATE_KEY))
{
- experinceKeyMap[(*exp)[LLExperienceCache::PRIVATE_KEY].asUUID()]=(*exp)[LLExperienceCache::EXPERIENCE_ID].asUUID();
+ privateToPublicKeyMap[(*exp)[LLExperienceCache::PRIVATE_KEY].asUUID()]=(*exp)[LLExperienceCache::EXPERIENCE_ID].asUUID();
}
}
}
@@ -635,9 +657,8 @@ LLUUID LLExperienceCache::getExperienceId(const LLUUID& private_key, bool null_i
if (private_key.isNull())
return LLUUID::null;
-
- PrivateKeyMap::const_iterator it=experinceKeyMap.find(private_key);
- if(it == experinceKeyMap.end())
+ KeyMap::const_iterator it=privateToPublicKeyMap.find(private_key);
+ if(it == privateToPublicKeyMap.end())
{
if(null_if_not_found)
{
diff --git a/indra/llmessage/llexperiencecache.h b/indra/llmessage/llexperiencecache.h
index fb00ea31f0..8b3443e5a9 100644
--- a/indra/llmessage/llexperiencecache.h
+++ b/indra/llmessage/llexperiencecache.h
@@ -40,13 +40,21 @@ class LLUUID;
namespace LLExperienceCache
{
const std::string PRIVATE_KEY = "private_id";
+ const std::string MISSING = "DoesNotExist";
+ const std::string AGENT_ID = "agent_id";
+ const std::string GROUP_ID = "group_id";
const std::string EXPERIENCE_ID = "public_id";
const std::string OWNER_ID = "owner_id";
const std::string NAME = "name";
const std::string PROPERTIES = "properties";
const std::string EXPIRES = "expiration";
- const std::string DESCRIPTION = "description";
+ const std::string DESCRIPTION = "description";
+ const std::string QUOTA = "quota";
+ const std::string MATURITY = "maturity";
+ const std::string METADATA = "extended_metadata";
+ const std::string SLURL = "slurl";
+
// should be in sync with experience-api/experiences/models.py
const int PROPERTY_INVALID = 1 << 0;
@@ -54,10 +62,12 @@ namespace LLExperienceCache
const int PROPERTY_GRID = 1 << 4;
const int PROPERTY_PRIVATE = 1 << 5;
const int PROPERTY_DISABLED = 1 << 6;
- const int PROPERTY_SUSPENDED = 1 << 7;
+ const int PROPERTY_SUSPENDED = 1 << 7;
+ // default values
const static F64 DEFAULT_EXPIRATION = 600.0;
+ const static S32 DEFAULT_QUOTA = 128; // this is megabytes
// Callback types for get() below
typedef boost::signals2::signal<void (const LLSD& experience)>
@@ -79,7 +89,7 @@ namespace LLExperienceCache
void erase(const LLUUID& key);
bool fetch(const LLUUID& key, bool refresh=false);
- void insert(LLSD& experience_data);
+ void insert(const LLSD& experience_data);
bool get(const LLUUID& key, LLSD& experience_data);
// If name information is in cache, callback will be called immediately.
@@ -87,6 +97,7 @@ namespace LLExperienceCache
const cache_t& getCached();
+ // maps an experience private key to the experience id
LLUUID getExperienceId(const LLUUID& private_key, bool null_if_not_found=false);
};
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 9caff9e038..1c86884a80 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -227,6 +227,7 @@ set(viewer_SOURCE_FILES
llfloatereditwater.cpp
llfloaterenvironmentsettings.cpp
llfloaterevent.cpp
+ llfloaterexperienceprofile.cpp
llfloaterexperiences.cpp
llfloaterfonttest.cpp
llfloatergesture.cpp
@@ -813,6 +814,7 @@ set(viewer_HEADER_FILES
llfloatereditwater.h
llfloaterenvironmentsettings.h
llfloaterevent.h
+ llfloaterexperienceprofile.h
llfloaterexperiences.h
llfloaterfonttest.h
llfloatergesture.h
diff --git a/indra/newview/llfloaterexperienceprofile.cpp b/indra/newview/llfloaterexperienceprofile.cpp
new file mode 100644
index 0000000000..821a1de6f7
--- /dev/null
+++ b/indra/newview/llfloaterexperienceprofile.cpp
@@ -0,0 +1,215 @@
+/**
+ * @file llfloaterexperienceprofile.cpp
+ * @brief llfloaterexperienceprofile and related class definitions
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterexperienceprofile.h"
+#include "llexperiencecache.h"
+#include "llfloaterworldmap.h"
+#include "llfloaterreg.h"
+#include "lllayoutstack.h"
+#include "lltextbox.h"
+#include "llsdserialize.h"
+#include "llexpandabletextbox.h"
+#include "lltexturectrl.h"
+#include "lltrans.h"
+
+#define XML_PANEL_EXPERIENCE_PROFILE "floater_experienceprofile.xml"
+#define TF_NAME "experience_title"
+#define TF_DESC "experience_description"
+#define TF_SLURL "LocationTextText"
+#define TF_MRKT "marketplace"
+#define TF_MATURITY "ContentRatingText"
+#define TF_OWNER "OwnerText"
+
+#define IMG_LOGO "logo"
+
+#define PNL_IMAGE "image_panel"
+#define PNL_DESC "description panel"
+#define PNL_LOC "location panel"
+#define PNL_MRKT "marketplace panel"
+
+#define BTN_TP "teleport_btn"
+#define BTN_MAP "show_on_map_btn"
+#define BTN_EDIT "edit_btn"
+
+
+LLFloaterExperienceProfile::LLFloaterExperienceProfile(const LLSD& data)
+ : LLFloater(data)
+ , mExperienceId(data.asUUID())
+ , mImagePanel(NULL)
+ , mDescriptionPanel(NULL)
+ , mLocationPanel(NULL)
+ , mMarketplacePanel(NULL)
+{
+
+}
+
+LLFloaterExperienceProfile::~LLFloaterExperienceProfile()
+{
+
+}
+
+
+BOOL LLFloaterExperienceProfile::postBuild()
+{
+ mImagePanel = getChild<LLLayoutPanel>(PNL_IMAGE);
+ mDescriptionPanel = getChild<LLLayoutPanel>(PNL_DESC);
+ mLocationPanel = getChild<LLLayoutPanel>(PNL_LOC);
+ mMarketplacePanel = getChild<LLLayoutPanel>(PNL_MRKT);
+
+ if (mExperienceId.notNull())
+ {
+ LLExperienceCache::fetch(mExperienceId, true);
+ LLExperienceCache::get(mExperienceId, boost::bind(&LLFloaterExperienceProfile::experienceCallback,
+ getDerivedHandle<LLFloaterExperienceProfile>(), _1));
+ }
+
+
+ childSetAction(BTN_TP, boost::bind(&LLFloaterExperienceProfile::onClickTeleport, this));
+ childSetAction(BTN_MAP, boost::bind(&LLFloaterExperienceProfile::onClickMap, this));
+ childSetAction(BTN_EDIT, boost::bind(&LLFloaterExperienceProfile::onClickEdit, this));
+
+ return TRUE;
+}
+
+void LLFloaterExperienceProfile::experienceCallback(LLHandle<LLFloaterExperienceProfile> handle, const LLSD& experience )
+{
+ LLFloaterExperienceProfile* pllpep = handle.get();
+ if(pllpep)
+ {
+ pllpep->refreshExperience(experience);
+ }
+}
+
+void LLFloaterExperienceProfile::onClickMap()
+{
+// LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+// LLFloaterReg::showInstance("world_map", "center");
+
+}
+
+void LLFloaterExperienceProfile::onClickTeleport()
+{
+// if (!getPosGlobal().isExactlyZero())
+// {
+// gAgent.teleportViaLocation(getPosGlobal());
+// LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+// }
+
+}
+
+void LLFloaterExperienceProfile::onClickEdit()
+{
+
+}
+
+std::string LLFloaterExperienceProfile::getMaturityString(U8 maturity)
+{
+ if(maturity <= SIM_ACCESS_MIN)
+ return LLTrans::getString("SIM_ACCESS_MIN");
+ if(maturity <= SIM_ACCESS_PG)
+ return LLTrans::getString("SIM_ACCESS_PG");
+ if(maturity <= SIM_ACCESS_MATURE)
+ return LLTrans::getString("SIM_ACCESS_MATURE");
+ if(maturity <= SIM_ACCESS_ADULT)
+ return LLTrans::getString("SIM_ACCESS_ADULT");
+
+ return LLStringUtil::null;
+}
+
+
+void LLFloaterExperienceProfile::refreshExperience( const LLSD& experience )
+{
+ mExperienceDetails = experience;
+
+ if(experience.has(LLExperienceCache::MISSING))
+ {
+ mImagePanel->setVisible(FALSE);
+ mDescriptionPanel->setVisible(FALSE);
+ mLocationPanel->setVisible(FALSE);
+ mMarketplacePanel->setVisible(FALSE);
+ }
+
+ LLTextBox* child = getChild<LLTextBox>(TF_NAME);
+ child->setText(experience[LLExperienceCache::NAME].asString());
+
+ std::string value = experience[LLExperienceCache::DESCRIPTION].asString();
+ LLExpandableTextBox* exchild = getChild<LLExpandableTextBox>(TF_DESC);
+ exchild->setText(value);
+ mDescriptionPanel->setVisible(value.length()>0);
+
+ value = experience[LLExperienceCache::SLURL].asString();
+ child = getChild<LLTextBox>(TF_SLURL);
+ child->setText(value);
+ mLocationPanel->setVisible(value.length()>0);
+
+ child = getChild<LLTextBox>(TF_MATURITY);
+ child->setText(getMaturityString((U8)(experience[LLExperienceCache::MATURITY].asInteger())));
+
+ child = getChild<LLTextBox>(TF_OWNER);
+ child->setText(experience[LLExperienceCache::OWNER_ID].asString());
+
+ value=experience[LLExperienceCache::METADATA].asString();
+ if(value.empty())
+ return;
+
+ LLPointer<LLSDParser> parser = new LLSDXMLParser();
+
+ LLSD data;
+
+ std::istringstream is = std::istringstream(value);
+ if(LLSDParser::PARSE_FAILURE != parser->parse(is, data, value.size()))
+ {
+ if(data.has(TF_MRKT))
+ {
+ value=data[TF_MRKT].asString();
+
+ child = getChild<LLTextBox>(TF_MRKT);
+ child->setText(value);
+ mMarketplacePanel->setVisible(TRUE);
+ }
+ else
+ {
+ mMarketplacePanel->setVisible(FALSE);
+ }
+
+ if(data.has(IMG_LOGO))
+ {
+ LLTextureCtrl* logo = getChild<LLTextureCtrl>(IMG_LOGO);
+ logo->setImageAssetID(data[IMG_LOGO].asUUID());
+ mImagePanel->setVisible(TRUE);
+ }
+ }
+
+
+
+
+
+
+
+}
diff --git a/indra/newview/llfloaterexperienceprofile.h b/indra/newview/llfloaterexperienceprofile.h
new file mode 100644
index 0000000000..1d1e4c50cf
--- /dev/null
+++ b/indra/newview/llfloaterexperienceprofile.h
@@ -0,0 +1,70 @@
+/**
+ * @file llfloaterexperienceprofile.h
+ * @brief llfloaterexperienceprofile and related class definitions
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+
+#ifndef LL_LLFLOATEREXPERIENCEPROFILE_H
+#define LL_LLFLOATEREXPERIENCEPROFILE_H
+
+#include "llfloater.h"
+#include "lluuid.h"
+#include "llsd.h"
+
+class LLLayoutPanel;
+
+class LLFloaterExperienceProfile : public LLFloater
+{
+ LOG_CLASS(LLFloaterExperienceProfile);
+public:
+ LLFloaterExperienceProfile(const LLSD& data);
+ virtual ~LLFloaterExperienceProfile();
+
+ void setExperienceId( const LLUUID& experience_id );
+
+protected:
+
+ void onClickMap();
+ void onClickTeleport();
+ void onClickEdit();
+
+
+ static void experienceCallback(LLHandle<LLFloaterExperienceProfile> handle, const LLSD& experience);
+ void refreshExperience(const LLSD& experience);
+ BOOL postBuild();
+ std::string getMaturityString(U8 maturity);
+ LLUUID mExperienceId;
+ LLSD mExperienceDetails;
+
+ LLLayoutPanel* mImagePanel;
+ LLLayoutPanel* mDescriptionPanel;
+ LLLayoutPanel* mLocationPanel;
+ LLLayoutPanel* mMarketplacePanel;
+
+private:
+
+};
+
+#endif // LL_LLFLOATEREXPERIENCEPROFILE_H
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index f5a6ec3dd3..7c2638d82b 100755
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -87,6 +87,7 @@
#include "llviewercontrol.h"
#include "llappviewer.h"
#include "llexperiencecache.h"
+#include "llfloaterexperienceprofile.h"
#include "llexperienceassociationresponder.h"
const std::string HELLO_LSL =
@@ -407,6 +408,22 @@ void LLLiveLSLEditor::experienceChanged()
}
}
+void LLLiveLSLEditor::onViewProfile( LLUICtrl *ui, void* userdata )
+{
+ LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata;
+
+ LLUUID id;
+ if(self->mExperienceEnabled->get())
+ {
+ id=self->mScriptEd->getAssociatedExperience();
+ if(id.notNull())
+ {
+ LLFloaterReg::showInstance("experience_profile", id, true);
+ }
+ }
+
+}
+
void LLLiveLSLEditor::onToggleExperience( LLUICtrl *ui, void* userdata )
{
LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata;
@@ -1306,7 +1323,7 @@ void LLLiveLSLEditor::addExperienceInfo(const LLSD& experience, BOOL enabled)
void LLLiveLSLEditor::buildExperienceList()
{
- mExperiences->clear();
+ mExperiences->clearRows();
bool foundAssociated=false;
for(LLSD::array_const_iterator it = mExperienceIds.beginArray(); it != mExperienceIds.endArray(); ++it)
{
@@ -1916,6 +1933,7 @@ BOOL LLLiveLSLEditor::postBuild()
mExperienceEnabled = getChild<LLCheckBoxCtrl>("enable_xp");
childSetCommitCallback("enable_xp", onToggleExperience, this);
+ childSetCommitCallback("view_profile", onViewProfile, this);
return LLPreview::postBuild();
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index faeb4a5b8a..4e76238c71 100755
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -49,6 +49,7 @@ class LLKeywordToken;
class LLVFS;
class LLViewerInventoryItem;
class LLScriptEdContainer;
+class LLFloaterExperienceProfile;
// Inner, implementation class. LLPreviewScript and LLLiveLSLEditor each own one of these.
class LLScriptEdCore : public LLPanel
@@ -234,6 +235,7 @@ public:
static void setAssociatedExperience( LLHandle<LLLiveLSLEditor> editor, const LLSD& experience );
static void onToggleExperience(LLUICtrl *ui, void* userdata);
+ static void onViewProfile(LLUICtrl *ui, void* userdata);
void addExperienceInfo( const LLSD& experience, BOOL enabled );
void setExperienceIds(const LLSD& experience_ids);
@@ -300,6 +302,8 @@ private:
LLComboBox *mExperiences;
LLCheckBoxCtrl *mExperienceEnabled;
LLSD mExperienceIds;
+
+ LLHandle<LLFloater> mExperienceProfile;
};
#endif // LL_LLPREVIEWSCRIPT_H
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index c6296a20d7..13ceaf491c 100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -58,6 +58,7 @@
#include "llfloatereditsky.h"
#include "llfloatereditwater.h"
#include "llfloaterenvironmentsettings.h"
+#include "llfloaterexperienceprofile.h"
#include "llfloaterexperiences.h"
#include "llfloaterevent.h"
#include "llfloaterdestinations.h"
@@ -207,8 +208,9 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("env_edit_water", "floater_edit_water_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEditWater>);
LLFloaterReg::add("env_edit_day_cycle", "floater_edit_day_cycle.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEditDayCycle>);
- LLFloaterReg::add("event", "floater_event.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEvent>);
- LLFloaterReg::add("experiences", "floater_experiences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperiences>);
+ LLFloaterReg::add("event", "floater_event.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEvent>);
+ LLFloaterReg::add("experiences", "floater_experiences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperiences>);
+ LLFloaterReg::add("experience_profile", "floater_experienceprofile.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperienceProfile>);
LLFloaterReg::add("font_test", "floater_font_test.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFontTest>);
diff --git a/indra/newview/skins/default/xui/en/floater_experienceprofile.xml b/indra/newview/skins/default/xui/en/floater_experienceprofile.xml
new file mode 100644
index 0000000000..d9990f3a59
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_experienceprofile.xml
@@ -0,0 +1,293 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+
+<floater
+ positioning="cascading"
+ can_close="true"
+ enabled="true"
+ can_resize="true"
+ height="580"
+ min_height="350"
+ min_width="300"
+ layout="topleft"
+ name="floater_experience_profile"
+ save_rect="yes"
+ single_instance="false"
+ reuse_instance="false"
+ title="EXPERIENCE PROFILE"
+ width="358">
+ <panel
+ background_visible="true"
+ follows="all"
+ height="570"
+ layout="topleft"
+ left="5"
+ min_height="350"
+ top="5"
+ width="348"
+ name="panel_experience_info">
+ <text
+ follows="top|left|right"
+ font="SansSerifHugeBold"
+ height="26"
+ layout="topleft"
+ left_pad="4"
+ name="title"
+ text_color="White"
+ top="2"
+ value="Experience Profile"
+ use_ellipses="true"
+ left="3"
+ right="-3"/>
+ <scroll_container
+ color="DkGray2"
+ follows="all"
+ height="532"
+ layout="topleft"
+ left="9"
+ name="xp_scroll"
+ opaque="true"
+ top_pad="10"
+ width="330">
+ <panel
+ bg_alpha_color="DkGray2"
+ follows="top|left"
+ height="480"
+ layout="topleft"
+ left="0"
+ min_height="480"
+ name="scrolling_panel"
+ top="0"
+ width="315"
+ min_width="315">
+ <layout_stack
+ follows="all"
+ height="480"
+ layout="topleft"
+ left="0"
+ top="0"
+ orientation="vertical"
+ width="315">
+ <layout_panel
+ follows="all"
+ height="197"
+ layout="topleft"
+ left="0"
+ top="0"
+ auto_resize="false"
+ visible="false"
+ width="315"
+ name="image_panel">
+ <texture_picker
+ enabled="false"
+ fallback_image="default_land_picture.j2c"
+ follows="left|top"
+ height="197"
+ layout="topleft"
+ left="10"
+ name="logo"
+ top="10"
+ width="290" />
+ </layout_panel>
+ <layout_panel
+ follows="all"
+ height="19"
+ layout="topleft"
+ left="0"
+ top="5"
+ width="313"
+ auto_resize="false"
+ >
+ <text
+ follows="left|top|right"
+ font="SansSerifLarge"
+ height="14"
+ layout="topleft"
+ left="10"
+ name="experience_title"
+ text_color="white"
+ top="0"
+ use_ellipses="true"
+ value="Kyle's Superhero RPG"
+ width="288"/>
+ </layout_panel>
+ <layout_panel
+ follows=""
+ height="50"
+ layout="topleft"
+ left="0"
+ top="0"
+ auto_resize="false"
+ width="315"
+ visible="false"
+ name="description panel">
+ <expandable_text
+ follows="left|top|right"
+ font="SansSerif"
+ height="50"
+ layout="topleft"
+ left="7"
+ name="experience_description"
+ top="0"
+ value="It is mainly just a lot of men in tights on patrol for evil-doers. It is mainly just a lot of men in tights on patrol for evil-doers. It is mainly just a lot of men in tights on patrol for evil-doers. It is mainly just a lot of men in tights on patrol for evil-doers. It is mainly just a lot of men in tights on patrol for evil-doers. "
+ width="293"/>
+ </layout_panel>
+ <layout_panel
+ follows="all"
+ height="69"
+ layout="topleft"
+ left="0"
+ top="5"
+ width="313"
+ visible="false"
+ auto_resize="false"
+ name="location panel"
+ >
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="Location"
+ width="290">
+ Location:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="18"
+ layout="topleft"
+ left="10"
+ valign="center"
+ name="LocationTextText"
+ width="288">
+ someplace
+ </text>
+ <button
+ follows="bottom|left"
+ height="23"
+ label="Teleport"
+ layout="topleft"
+ name="teleport_btn"
+ width="151"
+ left="10"/>
+ <button
+ follows="bottom|left"
+ height="23"
+ label="Map"
+ layout="topleft"
+ name="map_btn"
+ top_pad="-23"
+ width="101"
+ left_pad="5"/>
+ </layout_panel>
+ <layout_panel
+ follows="all"
+ height="53"
+ layout="topleft"
+ left="0"
+ top="5"
+ width="313"
+ visible="false"
+ auto_resize="false"
+ name="marketplace panel"
+
+ >
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ width="290">
+ Marketplace store:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="18"
+ layout="topleft"
+ left="10"
+ valign="center"
+ name="marketplace"
+ width="288">
+ someplace
+ </text>
+ </layout_panel>
+ <layout_panel
+ follows="left|top|right"
+ height="69"
+ left="0"
+ top="0"
+ auto_resize="false"
+ width="315"
+ >
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="ContentRating"
+ width="100">
+ Rating:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="18"
+ layout="topleft"
+ left_pad="2"
+ valign="center"
+ name="ContentRatingText"
+ top_delta="-2"
+ width="188">
+ Adult
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="Owner"
+ width="100">
+ Owner:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="18"
+ layout="topleft"
+ left_pad="2"
+ valign="center"
+ name="OwnerText"
+ top_delta="-2"
+ width="188">
+ Kyle
+ </text>
+ <button
+ follows="bottom|left"
+ height="23"
+ label="Edit"
+ layout="topleft"
+ name="edit_btn"
+ top_pad="0"
+ width="151"
+ left="10"/>
+
+ </layout_panel>
+ </layout_stack>
+ </panel>
+ </scroll_container>
+
+ </panel>
+</floater>