summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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>