summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rwxr-xr-xindra/newview/CMakeLists.txt8
-rwxr-xr-xindra/newview/app_settings/keywords.ini19
-rwxr-xr-xindra/newview/llappviewer.cpp50
-rwxr-xr-xindra/newview/llappviewer.h5
-rwxr-xr-xindra/newview/llappviewerwin32.cpp17
-rw-r--r--indra/newview/llexperienceassociationresponder.cpp97
-rw-r--r--indra/newview/llexperienceassociationresponder.h58
-rw-r--r--indra/newview/llfloaterexperienceprofile.cpp646
-rw-r--r--indra/newview/llfloaterexperienceprofile.h91
-rw-r--r--indra/newview/llfloaterexperiences.cpp14
-rw-r--r--indra/newview/llfloaterexperiences.h45
-rw-r--r--indra/newview/llpanelexperiences.cpp302
-rw-r--r--indra/newview/llpanelexperiences.h119
-rwxr-xr-xindra/newview/llpreviewscript.cpp218
-rwxr-xr-xindra/newview/llpreviewscript.h43
-rwxr-xr-xindra/newview/llsidepaneliteminfo.cpp35
-rwxr-xr-xindra/newview/llsidepaneliteminfo.h2
-rwxr-xr-xindra/newview/llstartup.cpp12
-rwxr-xr-xindra/newview/llstartup.h1
-rwxr-xr-xindra/newview/llviewerfloaterreg.cpp8
-rwxr-xr-xindra/newview/llviewerregion.cpp11
-rwxr-xr-xindra/newview/llvoavatar.cpp3
-rw-r--r--indra/newview/skins/default/xui/en/floater_experienceprofile.xml537
-rw-r--r--indra/newview/skins/default/xui/en/floater_experiences.xml29
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_live_lsleditor.xml167
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_viewer.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_experience_info.xml377
-rw-r--r--indra/newview/skins/default/xui/en/panel_experiences.xml40
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_script_ed.xml403
-rw-r--r--indra/newview/skins/default/xui/en/panel_script_experience.xml97
-rwxr-xr-xindra/newview/skins/default/xui/en/role_actions.xml12
-rwxr-xr-xindra/newview/skins/default/xui/en/sidepanel_item_info.xml895
-rwxr-xr-xindra/newview/skins/default/xui/en/strings.xml4
33 files changed, 3640 insertions, 733 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 3a09bc530c..65067ce054 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -188,6 +188,7 @@ set(viewer_SOURCE_FILES
lleventnotifier.cpp
lleventpoll.cpp
llexpandabletextbox.cpp
+ llexperienceassociationresponder.cpp
llexternaleditor.cpp
llface.cpp
llfasttimerview.cpp
@@ -226,6 +227,8 @@ set(viewer_SOURCE_FILES
llfloatereditwater.cpp
llfloaterenvironmentsettings.cpp
llfloaterevent.cpp
+ llfloaterexperienceprofile.cpp
+ llfloaterexperiences.cpp
llfloaterfonttest.cpp
llfloatergesture.cpp
llfloatergodtools.cpp
@@ -396,6 +399,7 @@ set(viewer_SOURCE_FILES
llpanelclassified.cpp
llpanelcontents.cpp
llpaneleditwearable.cpp
+ llpanelexperiences.cpp
llpanelface.cpp
llpanelgenerictip.cpp
llpanelgroup.cpp
@@ -772,6 +776,7 @@ set(viewer_HEADER_FILES
lleventnotifier.h
lleventpoll.h
llexpandabletextbox.h
+ llexperienceassociationresponder.h
llexternaleditor.h
llface.h
llfasttimerview.h
@@ -810,6 +815,8 @@ set(viewer_HEADER_FILES
llfloatereditwater.h
llfloaterenvironmentsettings.h
llfloaterevent.h
+ llfloaterexperienceprofile.h
+ llfloaterexperiences.h
llfloaterfonttest.h
llfloatergesture.h
llfloatergodtools.h
@@ -973,6 +980,7 @@ set(viewer_HEADER_FILES
llpanelclassified.h
llpanelcontents.h
llpaneleditwearable.h
+ llpanelexperiences.h
llpanelface.h
llpanelgenerictip.h
llpanelgroup.h
diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini
index a87310955f..5de79b4bf5 100755
--- a/indra/newview/app_settings/keywords.ini
+++ b/indra/newview/app_settings/keywords.ini
@@ -52,6 +52,7 @@ remote_data remote_data(integer event_type, key channel, key message_id, str
http_response http_response(key request_id, integer status, list metadata, string body):Triggered when task receives a response to one of its llHTTPRequests
http_request http_request(key id, string method, string body):Triggered when task receives an http request against a public URL
+
# integer constants
[word .1, .1, .5]
TRUE Integer constant for Boolean operations
@@ -668,6 +669,24 @@ TEXTURE_TRANSPARENT UUID for the "White - Transparent" texture
URL_REQUEST_GRANTED Used with http_request when a public URL is successfully granted
URL_REQUEST_DENIED Used with http_request when a public URL is not available
+XP_ERROR_NONE No error was detected
+XP_ERROR_THROTTLED The call failed due to too many recent calls.
+XP_ERROR_EXPERIENCES_DISABLED The region currently has experiences disabled.
+XP_ERROR_INVALID_PARAMETERS One of the string arguments was too big to fit in the key-value store.
+XP_ERROR_NOT_PERMITTED This experience is not allowed to run on the current region.
+XP_ERROR_NO_EXPERIENCE This script is not associated with an experience.
+XP_ERROR_NOT_FOUND The sim was unable to verify the validity of the experience. Retrying after a short wait is advised.
+XP_ERROR_INVALID_EXPERIENCE The script is associated with an experience that no longer exists.
+XP_ERROR_EXPERIENCE_DISABLED The experience owner has temporarily disabled the experience.
+XP_ERROR_EXPERIENCE_SUSPENDED The experience has been suspended by Linden Customer Support.
+XP_ERROR_QUOTA_EXCEEDED An attempted write data to the key-value store failed due to the data quota being met.
+XP_ERROR_STORE_DISABLED The key-value store is currently disabled on this region.
+XP_ERROR_STORAGE_EXCEPTION Unable to communicate with the key-value store.
+XP_ERROR_KEY_NOT_FOUND The requested key does not exist.
+XP_ERROR_RETRY_UPDATE A checked update failed due to an out of date request.
+XP_ERROR_UNKNOWN_ERROR Other unknown error.
+
+
# float constants
[word .3, .1, .5]
PI 3.1415926535897932384626433832795
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 02eb67bf80..d4cb2be92e 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -100,6 +100,7 @@
// Linden library includes
#include "llavatarnamecache.h"
#include "lldiriterator.h"
+#include "llexperiencecache.h"
#include "llimagej2c.h"
#include "llmemory.h"
#include "llprimitive.h"
@@ -4395,7 +4396,7 @@ void LLAppViewer::loadNameCache()
}
void LLAppViewer::saveNameCache()
- {
+{
// display names cache
std::string filename =
gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml");
@@ -4403,7 +4404,7 @@ void LLAppViewer::saveNameCache()
if(name_cache_stream.is_open())
{
LLAvatarNameCache::exportFile(name_cache_stream);
-}
+ }
if (!gCacheName) return;
@@ -4416,6 +4417,32 @@ void LLAppViewer::saveNameCache()
}
}
+
+void LLAppViewer::saveExperienceCache()
+{
+ std::string filename =
+ gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "experience_cache.xml");
+ LL_INFOS("ExperienceCache") << "Saving " << filename << LL_ENDL;
+ llofstream cache_stream(filename);
+ if(cache_stream.is_open())
+ {
+ LLExperienceCache::exportFile(cache_stream);
+ }
+}
+
+void LLAppViewer::loadExperienceCache()
+{
+ std::string filename =
+ gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "experience_cache.xml");
+ LL_INFOS("ExperienceCache") << "Loading " << filename << LL_ENDL;
+ llifstream cache_stream(filename);
+ if(cache_stream.is_open())
+ {
+ LLExperienceCache::importFile(cache_stream);
+ }
+}
+
+
/*! @brief This class is an LLFrameTimer that can be created with
an elapsed time that starts counting up from the given value
rather than 0.0.
@@ -4610,7 +4637,7 @@ void LLAppViewer::idle()
// floating throughout the various object lists.
//
idleNameCache();
-
+ idleExperienceCache();
idleNetwork();
@@ -5030,6 +5057,22 @@ void LLAppViewer::idleNameCache()
LLAvatarNameCache::idle();
}
+void LLAppViewer::idleExperienceCache()
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region) return;
+
+ std::string lookup_url=region->getCapability("GetExperienceInfo");
+ if(!lookup_url.empty() && *lookup_url.rbegin() != '/')
+ {
+ lookup_url += '/';
+ }
+
+ LLExperienceCache::setLookupURL(lookup_url);
+
+ LLExperienceCache::idle();
+}
+
//
// Handle messages, and all message related stuff
//
@@ -5192,6 +5235,7 @@ void LLAppViewer::disconnectViewer()
}
saveNameCache();
+ saveExperienceCache();
// close inventory interface, close all windows
LLFloaterInventory::cleanup();
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 3ae8a78845..e30c9f7f16 100755
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -119,6 +119,10 @@ public:
void loadNameCache();
void saveNameCache();
+ void loadExperienceCache();
+ void saveExperienceCache();
+
+
void removeMarkerFile(bool leave_logout_marker = false);
// LLAppViewer testing helpers.
@@ -224,6 +228,7 @@ private:
void idle();
void idleShutdown();
// update avatar SLID and display name caches
+ void idleExperienceCache();
void idleNameCache();
void idleNetwork();
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 3cf3c739d9..80a80f4298 100755
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -172,21 +172,20 @@ void ll_nvapi_init(NvDRSSessionHandle hSession)
nvapi_error(status);
return;
}
+
+ // (5) Now we apply (or save) our changes to the system
+ status = NvAPI_DRS_SaveSettings(hSession);
+ if (status != NVAPI_OK)
+ {
+ nvapi_error(status);
+ return;
+ }
}
else if (status != NVAPI_OK)
{
nvapi_error(status);
return;
}
-
-
-
- // (5) Now we apply (or save) our changes to the system
- status = NvAPI_DRS_SaveSettings(hSession);
- if (status != NVAPI_OK)
- {
- nvapi_error(status);
- }
}
//#define DEBUGGING_SEH_FILTER 1
diff --git a/indra/newview/llexperienceassociationresponder.cpp b/indra/newview/llexperienceassociationresponder.cpp
new file mode 100644
index 0000000000..33ada4906d
--- /dev/null
+++ b/indra/newview/llexperienceassociationresponder.cpp
@@ -0,0 +1,97 @@
+/**
+ * @file llexperienceassociationresponder.cpp
+ * @brief llexperienceassociationresponder implementation. This class combines
+ * a lookup for a script association and an experience details request. The first
+ * is always async, but the second may be cached locally.
+ *
+ * $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 "llexperienceassociationresponder.h"
+#include "llexperiencecache.h"
+#include "llviewerregion.h"
+#include "llagent.h"
+
+ExperienceAssociationResponder::ExperienceAssociationResponder(ExperienceAssociationResponder::callback_t callback):mCallback(callback)
+{
+ ref();
+}
+
+void ExperienceAssociationResponder::fetchAssociatedExperience( const LLUUID& object_id, const LLUUID& item_id, callback_t callback )
+{
+ LLSD request;
+ request["object-id"]=object_id;
+ request["item-id"]=item_id;
+ fetchAssociatedExperience(request, callback);
+}
+
+void ExperienceAssociationResponder::fetchAssociatedExperience(LLSD& request, callback_t callback)
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ std::string lookup_url=region->getCapability("GetMetadata");
+ if(!lookup_url.empty())
+ {
+ LLSD fields;
+ fields.append("experience");
+ request["fields"] = fields;
+ LLHTTPClient::post(lookup_url, request, new ExperienceAssociationResponder(callback));
+ }
+ }
+}
+
+void ExperienceAssociationResponder::error( U32 status, const std::string& reason )
+{
+ LLSD msg;
+ msg["error"]=(LLSD::Integer)status;
+ msg["message"]=reason;
+ LL_INFOS("ExperienceAssociation") << "Failed to look up associated experience: " << status << ": " << reason << LL_ENDL;
+
+ sendResult(msg);
+
+}
+void ExperienceAssociationResponder::result( const LLSD& content )
+{
+ if(!content.has("experience"))
+ {
+
+ LLSD msg;
+ msg["message"]="no experience";
+ msg["error"]=-1;
+ sendResult(msg);
+ return;
+ }
+
+ LLExperienceCache::get(content["experience"].asUUID(), boost::bind(&ExperienceAssociationResponder::sendResult, this, _1));
+
+}
+
+void ExperienceAssociationResponder::sendResult( const LLSD& experience )
+{
+ mCallback(experience);
+ unref();
+}
+
+
+
diff --git a/indra/newview/llexperienceassociationresponder.h b/indra/newview/llexperienceassociationresponder.h
new file mode 100644
index 0000000000..8ff62a3dbc
--- /dev/null
+++ b/indra/newview/llexperienceassociationresponder.h
@@ -0,0 +1,58 @@
+#include "llhttpclient.h"
+#include "llsd.h"
+/**
+ * @file llexperienceassociationresponder.h
+ * @brief llexperienceassociationresponder 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_LLEXPERIENCEASSOCIATIONRESPONDER_H
+#define LL_LLEXPERIENCEASSOCIATIONRESPONDER_H
+
+#include "llhttpclient.h"
+#include "llsd.h"
+
+class ExperienceAssociationResponder : public LLHTTPClient::Responder
+{
+public:
+ typedef boost::function<void(const LLSD& experience)> callback_t;
+
+ ExperienceAssociationResponder(callback_t callback);
+
+ virtual void result(const LLSD& content);
+ virtual void error(U32 status, const std::string& reason);
+
+ static void fetchAssociatedExperience(const LLUUID& object_it, const LLUUID& item_id, callback_t callback);
+
+private:
+ static void fetchAssociatedExperience(LLSD& request, callback_t callback);
+
+ void sendResult(const LLSD& experience);
+
+ callback_t mCallback;
+
+};
+
+#endif // LL_LLEXPERIENCEASSOCIATIONRESPONDER_H
diff --git a/indra/newview/llfloaterexperienceprofile.cpp b/indra/newview/llfloaterexperienceprofile.cpp
new file mode 100644
index 0000000000..a565b5c8e7
--- /dev/null
+++ b/indra/newview/llfloaterexperienceprofile.cpp
@@ -0,0 +1,646 @@
+/**
+ * @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 "llagent.h"
+#include "llexpandabletextbox.h"
+#include "llexperiencecache.h"
+#include "llfloaterexperienceprofile.h"
+#include "llfloaterreg.h"
+#include "llhttpclient.h"
+#include "lllayoutstack.h"
+#include "llsdserialize.h"
+#include "llslurl.h"
+#include "lltabcontainer.h"
+#include "lltextbox.h"
+#include "lltexturectrl.h"
+#include "lltrans.h"
+#include "llviewerregion.h"
+#include "lllineeditor.h"
+#include "llcombobox.h"
+#include "llcheckboxctrl.h"
+#include "llnotificationsutil.h"
+#include "llappviewer.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 EDIT "edit_"
+
+#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_EDIT "edit_btn"
+#define BTN_ALLOW "allow_btn"
+#define BTN_FORGET "forget_btn"
+#define BTN_BLOCK "block_btn"
+#define BTN_CANCEL "cancel_btn"
+#define BTN_SAVE "save_btn"
+#define BTN_ENABLE "enable_btn"
+#define BTN_PRIVATE "private_btn"
+
+
+LLFloaterExperienceProfile::LLFloaterExperienceProfile(const LLSD& data)
+ : LLFloater(data)
+ , mExperienceId(data.asUUID())
+ , mImagePanel(NULL)
+ , mDescriptionPanel(NULL)
+ , mLocationPanel(NULL)
+ , mMarketplacePanel(NULL)
+ , mSaveCompleteAction(NOTHING)
+ , mDirty(false)
+ , mForceClose(false)
+{
+
+}
+
+
+LLFloaterExperienceProfile::~LLFloaterExperienceProfile()
+{
+
+}
+
+template<class T>
+class HandleResponder : public LLHTTPClient::Responder
+{
+public:
+ HandleResponder(const LLHandle<T>& parent):mParent(parent){}
+ LLHandle<T> mParent;
+
+ virtual void error(U32 status, const std::string& reason)
+ {
+ llwarns << "HandleResponder failed with code: " << status<< ", reason: " << reason << llendl;
+ }
+};
+
+class ExperienceUpdateResponder : public HandleResponder<LLFloaterExperienceProfile>
+{
+public:
+ ExperienceUpdateResponder(const LLHandle<LLFloaterExperienceProfile>& parent):HandleResponder<LLFloaterExperienceProfile>(parent)
+ {
+ }
+
+ virtual void result(const LLSD& content)
+ {
+ LLFloaterExperienceProfile* parent=mParent.get();
+ if(parent)
+ {
+ parent->onSaveComplete(content);
+ }
+ }
+};
+
+
+
+class ExperiencePreferencesResponder : public HandleResponder<LLFloaterExperienceProfile>
+{
+public:
+ ExperiencePreferencesResponder(const LLHandle<LLFloaterExperienceProfile>& parent):HandleResponder<LLFloaterExperienceProfile>(parent)
+ {
+ }
+
+
+ virtual void result(const LLSD& content)
+ {
+ LLFloaterExperienceProfile* parent=mParent.get();
+ if(parent)
+ {
+ parent->setPreferences(content);
+ }
+ }
+};
+
+
+class IsAdminResponder : public HandleResponder<LLFloaterExperienceProfile>
+{
+public:
+ IsAdminResponder(const LLHandle<LLFloaterExperienceProfile>& parent):HandleResponder<LLFloaterExperienceProfile>(parent)
+ {
+ }
+
+ virtual void result(const LLSD& content)
+ {
+ LLFloaterExperienceProfile* parent = mParent.get();
+ if(!parent)
+ return;
+
+ bool enabled = true;
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ {
+ enabled = false;
+ }
+ else
+ {
+ std::string url=region->getCapability("UpdateExperience");
+ if(url.empty())
+ enabled = false;
+ }
+
+ parent->getChild<LLButton>(BTN_EDIT)->setVisible(enabled && content["status"].asBoolean());
+ }
+};
+
+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));
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ std::string lookup_url=region->getCapability("IsExperienceAdmin");
+ if(!lookup_url.empty())
+ {
+ LLHTTPClient::get(lookup_url+"?experience_id="+mExperienceId.asString(), new IsAdminResponder(getDerivedHandle<LLFloaterExperienceProfile>()));
+ }
+
+ lookup_url=region->getCapability("ExperiencePreferences");
+ if(!lookup_url.empty())
+ {
+ LLHTTPClient::get(lookup_url+"?"+mExperienceId.asString(), new ExperiencePreferencesResponder(getDerivedHandle<LLFloaterExperienceProfile>()));
+ }
+ }
+ }
+
+ childSetAction(BTN_EDIT, boost::bind(&LLFloaterExperienceProfile::onClickEdit, this));
+ childSetAction(BTN_ALLOW, boost::bind(&LLFloaterExperienceProfile::onClickPermission, this, "Allow"));
+ childSetAction(BTN_FORGET, boost::bind(&LLFloaterExperienceProfile::onClickForget, this));
+ childSetAction(BTN_BLOCK, boost::bind(&LLFloaterExperienceProfile::onClickPermission, this, "Block"));
+ childSetAction(BTN_CANCEL, boost::bind(&LLFloaterExperienceProfile::onClickCancel, this));
+ childSetAction(BTN_SAVE, boost::bind(&LLFloaterExperienceProfile::onClickSave, this));
+
+
+ getChild<LLUICtrl>(EDIT TF_NAME)->setCommitCallback(boost::bind(&LLFloaterExperienceProfile::onFieldChanged, this));
+ getChild<LLUICtrl>(EDIT TF_DESC)->setCommitCallback(boost::bind(&LLFloaterExperienceProfile::onFieldChanged, this));
+ getChild<LLUICtrl>(EDIT TF_SLURL)->setCommitCallback(boost::bind(&LLFloaterExperienceProfile::onFieldChanged, this));
+ getChild<LLUICtrl>(EDIT TF_MATURITY)->setCommitCallback(boost::bind(&LLFloaterExperienceProfile::onFieldChanged, this));
+ getChild<LLUICtrl>(EDIT TF_MRKT)->setCommitCallback(boost::bind(&LLFloaterExperienceProfile::onFieldChanged, this));
+ getChild<LLLineEditor>(EDIT TF_NAME)->setCommitCallback(boost::bind(&LLFloaterExperienceProfile::onFieldChanged, this));
+ childSetAction(EDIT BTN_ENABLE, boost::bind(&LLFloaterExperienceProfile::onFieldChanged, this));
+ childSetAction(EDIT BTN_PRIVATE, boost::bind(&LLFloaterExperienceProfile::onFieldChanged, this));
+
+ getChild<LLTextEditor>(EDIT TF_DESC)->setCommitOnFocusLost(TRUE);
+
+ return TRUE;
+}
+
+void LLFloaterExperienceProfile::experienceCallback(LLHandle<LLFloaterExperienceProfile> handle, const LLSD& experience )
+{
+ LLFloaterExperienceProfile* pllpep = handle.get();
+ if(pllpep)
+ {
+ pllpep->refreshExperience(experience);
+ }
+}
+
+void LLFloaterExperienceProfile::onClickEdit()
+{
+ LLTabContainer* tabs = getChild<LLTabContainer>("tab_container");
+
+ tabs->selectTabByName("edit_panel_experience_info");
+}
+
+
+void LLFloaterExperienceProfile::onClickCancel()
+{
+ changeToView();
+}
+
+void LLFloaterExperienceProfile::onClickSave()
+{
+ doSave(NOTHING);
+}
+
+
+void LLFloaterExperienceProfile::onClickPermission(const char* perm)
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ return;
+
+ std::string lookup_url=region->getCapability("ExperiencePreferences");
+ if(lookup_url.empty())
+ return;
+ LLSD permission;
+ LLSD data;
+ permission["permission"]=perm;
+
+ data[mExperienceId.asString()]=permission;
+ LLHTTPClient::put(lookup_url, data, new ExperiencePreferencesResponder(getDerivedHandle<LLFloaterExperienceProfile>()));
+
+}
+
+
+void LLFloaterExperienceProfile::onClickForget()
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ return;
+
+ std::string lookup_url=region->getCapability("ExperiencePreferences");
+ if(lookup_url.empty())
+ return;
+
+ LLHTTPClient::del(lookup_url+"?"+mExperienceId.asString(), new ExperiencePreferencesResponder(getDerivedHandle<LLFloaterExperienceProfile>()));
+}
+
+bool LLFloaterExperienceProfile::setMaturityString( U8 maturity, LLTextBox* child, LLComboBox* combo )
+{
+ LLStyle::Params style;
+ std::string access;
+ if(maturity <= SIM_ACCESS_PG)
+ {
+ style.image(LLUI::getUIImage(getString("maturity_icon_general")));
+ access = LLTrans::getString("SIM_ACCESS_PG");
+ combo->setCurrentByIndex(2);
+ }
+ else if(maturity <= SIM_ACCESS_MATURE)
+ {
+ style.image(LLUI::getUIImage(getString("maturity_icon_moderate")));
+ access = LLTrans::getString("SIM_ACCESS_MATURE");
+ combo->setCurrentByIndex(1);
+ }
+ else if(maturity <= SIM_ACCESS_ADULT)
+ {
+ style.image(LLUI::getUIImage(getString("maturity_icon_adult")));
+ access = LLTrans::getString("SIM_ACCESS_ADULT");
+ combo->setCurrentByIndex(0);
+ }
+ else
+ {
+ return false;
+ }
+
+ child->setText(LLStringUtil::null);
+
+ child->appendImageSegment(style);
+
+ child->appendText(access, false);
+
+ return true;
+}
+
+
+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());
+
+ LLLineEditor* linechild = getChild<LLLineEditor>(EDIT TF_NAME);
+ linechild->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);
+
+ LLTextEditor* edit_child = getChild<LLTextEditor>(EDIT TF_DESC);
+ edit_child->setText(value);
+
+ value = experience[LLExperienceCache::SLURL].asString();
+ child = getChild<LLTextBox>(TF_SLURL);
+ child->setText(value);
+ mLocationPanel->setVisible(value.length()>0);
+
+ linechild = getChild<LLLineEditor>(EDIT TF_SLURL);
+ linechild->setText(value);
+
+ setMaturityString((U8)(experience[LLExperienceCache::MATURITY].asInteger()), getChild<LLTextBox>(TF_MATURITY), getChild<LLComboBox>(EDIT TF_MATURITY));
+
+ child = getChild<LLTextBox>(TF_OWNER);
+
+ LLUUID id = experience[LLExperienceCache::GROUP_ID].asUUID();
+ if(id.notNull())
+ {
+ value = LLSLURL("group", id, "inspect").getSLURLString();
+ }
+ else
+ {
+ id = experience[LLExperienceCache::AGENT_ID].asUUID();
+ value = LLSLURL("agent", id, "inspect").getSLURLString();
+ }
+ child->setText(value);
+
+ value=experience[LLExperienceCache::METADATA].asString();
+ if(value.empty())
+ return;
+
+ LLPointer<LLSDParser> parser = new LLSDXMLParser();
+
+ LLSD data;
+
+ std::istringstream is(value);
+ if(LLSDParser::PARSE_FAILURE != parser->parse(is, data, value.size()))
+ {
+ value="";
+ 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);
+ }
+
+ linechild = getChild<LLLineEditor>(EDIT TF_MRKT);
+ linechild->setText(value);
+
+ if(data.has(IMG_LOGO))
+ {
+ LLTextureCtrl* logo = getChild<LLTextureCtrl>(IMG_LOGO);
+ logo->setImageAssetID(data[IMG_LOGO].asUUID());
+ mImagePanel->setVisible(TRUE);
+
+ logo = getChild<LLTextureCtrl>(EDIT IMG_LOGO);
+ logo->setImageAssetID(data[IMG_LOGO].asUUID());
+ }
+ }
+
+ LLCheckBoxCtrl* enable = getChild<LLCheckBoxCtrl>(EDIT BTN_ENABLE);
+ enable->set( 0 == (mExperienceDetails[LLExperienceCache::PROPERTIES].asInteger() & LLExperienceCache::PROPERTY_DISABLED));
+
+ enable = getChild<LLCheckBoxCtrl>(EDIT BTN_PRIVATE);
+ enable->set( 0 != (mExperienceDetails[LLExperienceCache::PROPERTIES].asInteger() & LLExperienceCache::PROPERTY_PRIVATE));
+
+ mDirty=false;
+ setCanClose(!mDirty);
+
+ getChild<LLButton>(BTN_SAVE)->setEnabled(mDirty);
+}
+
+void LLFloaterExperienceProfile::setPreferences( const LLSD& content )
+{
+ const LLSD& experiences = content["experiences"];
+ const LLSD& blocked = content["blocked"];
+ LLButton* button;
+
+
+ for(LLSD::array_const_iterator it = experiences.beginArray(); it != experiences.endArray() ; ++it)
+ {
+ if(it->asUUID()==mExperienceId)
+ {
+ button=getChild<LLButton>(BTN_ALLOW);
+ button->setEnabled(FALSE);
+
+ button=getChild<LLButton>(BTN_FORGET);
+ button->setEnabled(TRUE);
+
+ button=getChild<LLButton>(BTN_BLOCK);
+ button->setEnabled(TRUE);
+ return;
+ }
+ }
+
+ for(LLSD::array_const_iterator it = blocked.beginArray(); it != blocked.endArray() ; ++it)
+ {
+ if(it->asUUID()==mExperienceId)
+ {
+ button=getChild<LLButton>(BTN_ALLOW);
+ button->setEnabled(TRUE);
+
+ button=getChild<LLButton>(BTN_FORGET);
+ button->setEnabled(TRUE);
+
+ button=getChild<LLButton>(BTN_BLOCK);
+ button->setEnabled(FALSE);
+ return;
+ }
+ }
+
+
+ button=getChild<LLButton>(BTN_ALLOW);
+ button->setEnabled(TRUE);
+
+ button=getChild<LLButton>(BTN_FORGET);
+ button->setEnabled(FALSE);
+
+ button=getChild<LLButton>(BTN_BLOCK);
+ button->setEnabled(TRUE);
+}
+
+void LLFloaterExperienceProfile::onFieldChanged()
+{
+ mDirty=true;
+ setCanClose(!mDirty);
+ getChild<LLButton>(BTN_SAVE)->setEnabled(mDirty);
+}
+
+
+BOOL LLFloaterExperienceProfile::canClose()
+{
+ if(mForceClose || !mDirty)
+ {
+ return TRUE;
+ }
+ else
+ {
+ // Bring up view-modal dialog: Save changes? Yes, No, Cancel
+ LLNotificationsUtil::add("SaveChanges", LLSD(), LLSD(), boost::bind(&LLFloaterExperienceProfile::handleSaveChangesDialog, this, _1, _2, CLOSE));
+ return FALSE;
+ }
+}
+
+bool LLFloaterExperienceProfile::handleSaveChangesDialog( const LLSD& notification, const LLSD& response, PostSaveAction action )
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch( option )
+ {
+ case 0: // "Yes"
+ // close after saving
+ doSave( action );
+ break;
+
+ case 1: // "No"
+ if(action != NOTHING)
+ {
+ mForceClose = TRUE;
+ if(action==CLOSE)
+ {
+ closeFloater();
+ }
+ else
+ {
+ changeToView();
+ }
+ }
+ break;
+
+ case 2: // "Cancel"
+ default:
+ // If we were quitting, we didn't really mean it.
+ LLAppViewer::instance()->abortQuit();
+ break;
+ }
+ return false;
+}
+
+void LLFloaterExperienceProfile::doSave( int success_action )
+{
+ mSaveCompleteAction=success_action;
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ return;
+
+ std::string url=region->getCapability("UpdateExperience");
+ if(url.empty())
+ return;
+
+ LLSD package=mExperienceDetails;
+
+ package[LLExperienceCache::NAME] = getChild<LLLineEditor>(EDIT TF_NAME)->getText();
+ package[LLExperienceCache::DESCRIPTION] = getChild<LLTextEditor>(EDIT TF_DESC)->getText();
+ package[LLExperienceCache::SLURL] = getChild<LLLineEditor>(EDIT TF_SLURL)->getText();
+
+ package[LLExperienceCache::MATURITY] = getChild<LLComboBox>(EDIT TF_MATURITY)->getSelectedValue().asInteger();
+
+ LLSD metadata;
+
+ metadata[TF_MRKT] = getChild<LLLineEditor>(EDIT TF_MRKT)->getText();
+ metadata[IMG_LOGO] = getChild<LLTextureCtrl>(EDIT IMG_LOGO)->getImageAssetID();
+
+ LLPointer<LLSDXMLFormatter> formatter = new LLSDXMLFormatter();
+
+ std::ostringstream os;
+ if(formatter->format(metadata, os))
+ {
+ package[LLExperienceCache::METADATA]=os.str();
+ }
+
+ int properties = package[LLExperienceCache::PROPERTIES].asInteger();
+ LLCheckBoxCtrl* enable = getChild<LLCheckBoxCtrl>(EDIT BTN_ENABLE);
+ if(enable->get())
+ {
+ properties &= ~LLExperienceCache::PROPERTY_DISABLED;
+ }
+ else
+ {
+ properties |= LLExperienceCache::PROPERTY_DISABLED;
+ }
+
+ enable = getChild<LLCheckBoxCtrl>(EDIT BTN_PRIVATE);
+ if(enable->get())
+ {
+ properties |= LLExperienceCache::PROPERTY_PRIVATE;
+ }
+ else
+ {
+ properties &= ~LLExperienceCache::PROPERTY_PRIVATE;
+ }
+
+ package[LLExperienceCache::PROPERTIES] = properties;
+
+ LLHTTPClient::post(url, package, new ExperienceUpdateResponder(getDerivedHandle<LLFloaterExperienceProfile>()));
+}
+
+void LLFloaterExperienceProfile::onSaveComplete( const LLSD& content )
+{
+ LLUUID id = getExperienceId();
+
+ if(!content.has("experience_keys"))
+ {
+ llwarns << "LLFloaterExperienceProfile::onSaveComplete called with bad content" << llendl;
+ return;
+ }
+
+ const LLSD& experiences = content["experience_keys"];
+
+ LLSD::array_const_iterator it = experiences.beginArray();
+ if(it == experiences.endArray())
+ {
+ llwarns << "LLFloaterExperienceProfile::onSaveComplete called with empty content" << llendl;
+ return;
+ }
+
+ if(!it->has(LLExperienceCache::EXPERIENCE_ID) || ((*it)[LLExperienceCache::EXPERIENCE_ID].asUUID() != id))
+ {
+ llwarns << "LLFloaterExperienceProfile::onSaveComplete called with unexpected experience id" << llendl;
+ return;
+ }
+
+ refreshExperience(*it);
+ LLExperienceCache::insert(*it);
+ LLExperienceCache::fetch(id, true);
+
+ if(mSaveCompleteAction==VIEW)
+ {
+ LLTabContainer* tabs = getChild<LLTabContainer>("tab_container");
+ tabs->selectTabByName("panel_experience_info");
+ }
+ else if(mSaveCompleteAction == CLOSE)
+ {
+ closeFloater();
+ }
+}
+
+void LLFloaterExperienceProfile::changeToView()
+{
+ if(mForceClose || !mDirty)
+ {
+ refreshExperience(mExperienceDetails);
+ LLTabContainer* tabs = getChild<LLTabContainer>("tab_container");
+
+ tabs->selectTabByName("panel_experience_info");
+ }
+ else
+ {
+ // Bring up view-modal dialog: Save changes? Yes, No, Cancel
+ LLNotificationsUtil::add("SaveChanges", LLSD(), LLSD(), boost::bind(&LLFloaterExperienceProfile::handleSaveChangesDialog, this, _1, _2, VIEW));
+ }
+}
diff --git a/indra/newview/llfloaterexperienceprofile.h b/indra/newview/llfloaterexperienceprofile.h
new file mode 100644
index 0000000000..1f1e135c01
--- /dev/null
+++ b/indra/newview/llfloaterexperienceprofile.h
@@ -0,0 +1,91 @@
+/**
+ * @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 LLTextBox;
+class LLComboBox;
+
+class LLFloaterExperienceProfile : public LLFloater
+{
+ LOG_CLASS(LLFloaterExperienceProfile);
+public:
+ enum PostSaveAction
+ {
+ NOTHING,
+ CLOSE,
+ VIEW,
+ };
+
+
+ LLFloaterExperienceProfile(const LLSD& data);
+ virtual ~LLFloaterExperienceProfile();
+
+ LLUUID getExperienceId() const { return mExperienceId; }
+ void setPreferences( const LLSD& content );
+ void refreshExperience(const LLSD& experience);
+ void onSaveComplete( const LLSD& content );
+ virtual BOOL canClose();
+
+protected:
+ void onClickEdit();
+ void onClickPermission(const char* permission);
+ void onClickForget();
+ void onClickCancel();
+
+ void changeToView();
+
+ void onClickSave();
+
+ void onFieldChanged();
+
+ static void experienceCallback(LLHandle<LLFloaterExperienceProfile> handle, const LLSD& experience);
+
+ BOOL postBuild();
+ bool setMaturityString(U8 maturity, LLTextBox* child, LLComboBox* combo);
+ bool handleSaveChangesDialog(const LLSD& notification, const LLSD& response, PostSaveAction action);
+ void doSave( int success_action );
+ LLUUID mExperienceId;
+ LLSD mExperienceDetails;
+
+ LLLayoutPanel* mImagePanel;
+ LLLayoutPanel* mDescriptionPanel;
+ LLLayoutPanel* mLocationPanel;
+ LLLayoutPanel* mMarketplacePanel;
+ int mSaveCompleteAction;
+ bool mDirty;
+ bool mForceClose;
+};
+
+#endif // LL_LLFLOATEREXPERIENCEPROFILE_H
diff --git a/indra/newview/llfloaterexperiences.cpp b/indra/newview/llfloaterexperiences.cpp
new file mode 100644
index 0000000000..b862b41bba
--- /dev/null
+++ b/indra/newview/llfloaterexperiences.cpp
@@ -0,0 +1,14 @@
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelexperiences.h"
+#include "llfloaterexperiences.h"
+
+LLFloaterExperiences::LLFloaterExperiences(const LLSD& data)
+ :LLFloater(data)
+{
+}
+
+BOOL LLFloaterExperiences::postBuild()
+{
+ return TRUE;
+}
diff --git a/indra/newview/llfloaterexperiences.h b/indra/newview/llfloaterexperiences.h
new file mode 100644
index 0000000000..1e5f216f8d
--- /dev/null
+++ b/indra/newview/llfloaterexperiences.h
@@ -0,0 +1,45 @@
+/**
+ * @file llfloaterexperiences.h
+ * @brief LLFloaterExperiences class definition
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLFLOATEREXPERIENCES_H
+#define LL_LLFLOATEREXPERIENCES_H
+
+#include "llfloater.h"
+
+class LLFloaterExperiences :
+ public LLFloater
+{
+public:
+ LLFloaterExperiences(const LLSD& data);
+
+protected:
+ /*virtual*/ BOOL postBuild();
+
+private:
+
+};
+
+#endif //LL_LLFLOATEREXPERIENCES_H
diff --git a/indra/newview/llpanelexperiences.cpp b/indra/newview/llpanelexperiences.cpp
new file mode 100644
index 0000000000..617ceef615
--- /dev/null
+++ b/indra/newview/llpanelexperiences.cpp
@@ -0,0 +1,302 @@
+#include "llviewerprecompiledheaders.h"
+
+
+#include "llpanelprofile.h"
+#include "lluictrlfactory.h"
+#include "llexperiencecache.h"
+#include "llagent.h"
+
+#include "llpanelexperiences.h"
+
+
+static LLRegisterPanelClassWrapper<LLPanelExperiences> register_experiences_panel("experiences_panel");
+
+
+LLPanelExperiences::LLPanelExperiences( )
+ : mExperiencesList(NULL),
+ mExperiencesAccTab(NULL),
+ mProfilePanel(NULL),
+ mPanelExperienceInfo(NULL),
+ mNoExperiences(false)
+{
+
+}
+
+void* LLPanelExperiences::create( void* data )
+{
+ return new LLPanelExperiences();
+}
+
+void ExperienceResult(LLHandle<LLPanelExperiences> panel, const LLSD& experience)
+{
+ LLPanelExperiences* experiencePanel = panel.get();
+ if(experiencePanel)
+ {
+ experiencePanel->addExperienceInfo(experience);
+ }
+}
+
+class LLExperienceListResponder : public LLHTTPClient::Responder
+{
+public:
+ LLExperienceListResponder(const LLHandle<LLPanelExperiences>& parent):mParent(parent)
+ {
+ }
+
+ LLHandle<LLPanelExperiences> mParent;
+
+ virtual void result(const LLSD& content)
+ {
+ if(mParent.isDead())
+ return;
+
+ LLSD experiences = content["experiences"];
+ LLSD::array_const_iterator it = experiences.beginArray();
+ for( /**/ ; it != experiences.endArray(); ++it)
+ {
+ LLUUID public_key = it->asUUID();
+
+ LLExperienceCache::get(public_key, boost::bind(ExperienceResult, mParent, _1));
+ }
+ }
+};
+
+void LLPanelExperiences::addExperienceInfo(const LLSD& experience)
+{
+ LLExperienceItem* item = new LLExperienceItem();
+ if(experience.has(LLExperienceCache::NAME))
+ {
+ item->setExperienceName(experience[LLExperienceCache::NAME].asString());
+ }
+ else if(experience.has("error"))
+ {
+ item->setExperienceName(experience["error"].asString());
+ }
+
+ if(experience.has(LLExperienceCache::DESCRIPTION))
+ {
+ item->setExperienceDescription(experience[LLExperienceCache::DESCRIPTION].asString());
+ }
+
+ mExperiencesList->addItem(item);
+
+}
+
+
+BOOL LLPanelExperiences::postBuild( void )
+{
+ mExperiencesList = getChild<LLFlatListView>("experiences_list");
+ if(hasString("no_experiences"))
+ {
+ mExperiencesList->setNoItemsCommentText(getString("no_experiences"));
+ }
+
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ std::string lookup_url=region->getCapability("GetExperiences");
+ if(!lookup_url.empty())
+ {
+ LLHTTPClient::get(lookup_url, new LLExperienceListResponder(getDerivedHandle<LLPanelExperiences>()));
+ }
+ }
+
+ mExperiencesAccTab = getChild<LLAccordionCtrlTab>("tab_experiences");
+ mExperiencesAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelExperiences::onAccordionStateChanged, this, mExperiencesAccTab));
+ mExperiencesAccTab->setDisplayChildren(true);
+
+ return TRUE;
+}
+
+void LLPanelExperiences::onOpen( const LLSD& key )
+{
+ LLPanel::onOpen(key);
+}
+
+void LLPanelExperiences::onClosePanel()
+{
+ if (mPanelExperienceInfo)
+ {
+ onPanelExperienceClose(mPanelExperienceInfo);
+ }
+}
+
+void LLPanelExperiences::updateData()
+{
+ if(isDirty())
+ {
+ mNoExperiences = false;
+ }
+}
+
+LLExperienceItem* LLPanelExperiences::getSelectedExperienceItem()
+{
+ LLPanel* selected_item = mExperiencesList->getSelectedItem();
+ if (!selected_item) return NULL;
+
+ return dynamic_cast<LLExperienceItem*>(selected_item);
+}
+
+void LLPanelExperiences::setProfilePanel( LLPanelProfile* profile_panel )
+{
+ mProfilePanel = profile_panel;
+}
+
+void LLPanelExperiences::onListCommit( const LLFlatListView* f_list )
+{
+ if(f_list == mExperiencesList)
+ {
+ mExperiencesList->resetSelection(true);
+ }
+ else
+ {
+ llwarns << "Unknown list" << llendl;
+ }
+
+ //updateButtons();
+}
+
+void LLPanelExperiences::onAccordionStateChanged( const LLAccordionCtrlTab* acc_tab )
+{
+ if(!mExperiencesAccTab->getDisplayChildren())
+ {
+ mExperiencesList->resetSelection(true);
+ }
+
+}
+
+void LLPanelExperiences::openExperienceInfo()
+{
+ LLSD selected_value = mExperiencesList->getSelectedValue();
+ if(selected_value.isUndefined())
+ {
+ return;
+ }
+
+ LLExperienceItem* experience = (LLExperienceItem*)mExperiencesList->getSelectedItem();
+
+ createExperienceInfoPanel();
+
+ LLSD params;
+ params["experience_name"] = experience->getExperienceName();
+ params["experience_desc"] = experience->getExperienceDescription();
+
+ getProfilePanel()->openPanel(mPanelExperienceInfo, params);
+
+}
+
+
+void LLPanelExperiences::createExperienceInfoPanel()
+{
+ if(!mPanelExperienceInfo)
+ {
+ mPanelExperienceInfo = LLPanelExperienceInfo::create();
+ mPanelExperienceInfo->setExitCallback(boost::bind(&LLPanelExperiences::onPanelExperienceClose, this, mPanelExperienceInfo));
+ mPanelExperienceInfo->setVisible(FALSE);
+ }
+}
+
+void LLPanelExperiences::onPanelExperienceClose( LLPanel* panel )
+{
+ getProfilePanel()->closePanel(panel);
+}
+
+LLPanelProfile* LLPanelExperiences::getProfilePanel()
+{
+ llassert_always(NULL != mProfilePanel);
+
+ return mProfilePanel;
+}
+
+
+
+
+
+
+
+
+
+
+
+LLExperienceItem::LLExperienceItem()
+{
+ buildFromFile("panel_experience_info.xml");
+}
+
+void LLExperienceItem::init( LLSD* experience_data )
+{
+ if(experience_data)
+ {
+ setExperienceDescription(experience_data->has(LLExperienceCache::DESCRIPTION)?(*experience_data)[LLExperienceCache::DESCRIPTION].asString() : std::string());
+ setExperienceName(experience_data->has(LLExperienceCache::NAME)?(*experience_data)[LLExperienceCache::NAME].asString() : std::string());
+ }
+}
+
+void LLExperienceItem::setExperienceDescription( const std::string& val )
+{
+ mExperienceDescription = val;
+ getChild<LLUICtrl>("experience_desc")->setValue(val);
+}
+
+void LLExperienceItem::setExperienceName( const std::string& val )
+{
+ mExperienceName = val;
+ getChild<LLUICtrl>("experience_name")->setValue(val);
+}
+
+BOOL LLExperienceItem::postBuild()
+{
+ return TRUE;
+}
+
+void LLExperienceItem::update()
+{
+
+}
+
+void LLExperienceItem::processProperties( void* data, EAvatarProcessorType type )
+{
+
+}
+
+LLExperienceItem::~LLExperienceItem()
+{
+
+}
+
+
+void LLPanelExperienceInfo::setExperienceName( const std::string& name )
+{
+ getChild<LLUICtrl>("experience_name")->setValue(name);
+}
+
+void LLPanelExperienceInfo::setExperienceDesc( const std::string& desc )
+{
+ getChild<LLUICtrl>("experience_desc")->setValue(desc);
+}
+
+void LLPanelExperienceInfo::onOpen( const LLSD& key )
+{
+ setExperienceName(key["experience_name"]);
+ setExperienceDesc(key["experience_desc"]);
+
+ /*
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(
+ getAvatarId(), this);
+ LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(
+ getAvatarId(), getPickId());
+ */
+}
+
+LLPanelExperienceInfo* LLPanelExperienceInfo::create()
+{
+ LLPanelExperienceInfo* panel = new LLPanelExperienceInfo();
+ panel->buildFromFile("panel_experience_info.xml");
+ return panel;
+}
+
+void LLPanelExperienceInfo::setExitCallback( const commit_callback_t& cb )
+{
+ getChild<LLButton>("back_btn")->setClickedCallback(cb);
+}
diff --git a/indra/newview/llpanelexperiences.h b/indra/newview/llpanelexperiences.h
new file mode 100644
index 0000000000..1fe3f6ae1d
--- /dev/null
+++ b/indra/newview/llpanelexperiences.h
@@ -0,0 +1,119 @@
+/**
+ * @file llpanelpicks.h
+ * @brief LLPanelPicks and related class definitions
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLPANELEXPERIENCES_H
+#define LL_LLPANELEXPERIENCES_H
+
+#include "llaccordionctrltab.h"
+#include "llflatlistview.h"
+#include "llpanelavatar.h"
+
+class LLExperienceItem;
+class LLPanelProfile;
+
+class LLPanelExperienceInfo
+ : public LLPanel
+{
+public:
+ static LLPanelExperienceInfo* create();
+
+ void onOpen(const LLSD& key);
+ void setExperienceName( const std::string& name );
+ void setExperienceDesc( const std::string& desc );
+
+
+ virtual void setExitCallback(const commit_callback_t& cb);
+};
+
+
+class LLPanelExperiences
+ : public LLPanel /*LLPanelProfileTab*/
+{
+public:
+ LLPanelExperiences();
+
+ static void* create(void* data);
+
+ /*virtual*/ BOOL postBuild(void);
+
+ /*virtual*/ void onOpen(const LLSD& key);
+
+ /*virtual*/ void onClosePanel();
+
+ void updateData();
+
+ LLExperienceItem* getSelectedExperienceItem();
+
+ void setProfilePanel(LLPanelProfile* profile_panel);
+ void addExperienceInfo(const LLSD& experience);
+protected:
+
+ void onListCommit(const LLFlatListView* f_list);
+ void onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab);
+
+
+ void openExperienceInfo();
+ void createExperienceInfoPanel();
+ void onPanelExperienceClose(LLPanel* panel);
+ LLPanelProfile* getProfilePanel();
+private:
+ LLFlatListView* mExperiencesList;
+ LLAccordionCtrlTab* mExperiencesAccTab;
+ LLPanelProfile* mProfilePanel;
+ LLPanelExperienceInfo* mPanelExperienceInfo;
+ bool mNoExperiences;
+};
+
+
+class LLExperienceItem
+ : public LLPanel
+ //, public LLAvatarPropertiesObserver
+{
+public:
+ LLExperienceItem();
+ ~LLExperienceItem();
+
+ void init(LLSD* experience_data);
+ /*virtual*/ BOOL postBuild();
+ void update();
+
+ /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
+
+ void setCreatorID(const LLUUID& val) { mCreatorID = val; }
+ void setExperienceDescription(const std::string& val);
+ void setExperienceName(const std::string& val);
+
+ const LLUUID& getCreatorID() const { return mCreatorID; }
+ const std::string& getExperienceName() const { return mExperienceName; }
+ const std::string& getExperienceDescription() const { return mExperienceDescription; }
+
+protected:
+ LLUUID mCreatorID;
+
+ std::string mExperienceName;
+ std::string mExperienceDescription;
+};
+#endif // LL_LLPANELEXPERIENCES_H
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index e533be7f24..1d3c7a3f20 100755
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -87,6 +87,9 @@
#include "llviewercontrol.h"
#include "llappviewer.h"
#include "llfloatergotoline.h"
+#include "llexperiencecache.h"
+#include "llfloaterexperienceprofile.h"
+#include "llexperienceassociationresponder.h"
const std::string HELLO_LSL =
"default\n"
@@ -119,6 +122,26 @@ static bool have_script_upload_cap(LLUUID& object_id)
return object && (! object->getRegion()->getCapability("UpdateScriptTask").empty());
}
+
+class ExperienceResponder : public LLHTTPClient::Responder
+{
+public:
+ ExperienceResponder(const LLHandle<LLLiveLSLEditor>& parent):mParent(parent)
+ {
+ }
+
+ LLHandle<LLLiveLSLEditor> mParent;
+
+ virtual void result(const LLSD& content)
+ {
+ LLLiveLSLEditor* parent = mParent.get();
+ if(!parent)
+ return;
+
+ parent->setExperienceIds(content["experience_ids"]);
+ }
+};
+
/// ---------------------------------------------------------------------------
/// LLLiveLSLFile
/// ---------------------------------------------------------------------------
@@ -392,6 +415,55 @@ LLScriptEdCore::~LLScriptEdCore()
delete mLiveFile;
}
+void LLLiveLSLEditor::experienceChanged()
+{
+ if(mScriptEd->getAssociatedExperience() != mExperiences->getSelectedValue().asUUID())
+ {
+ mScriptEd->enableSave(getIsModifiable());
+ //getChildView("Save_btn")->setEnabled(TRUE);
+ mScriptEd->setAssociatedExperience(mExperiences->getSelectedValue().asUUID());
+ updateExperiencePanel();
+ }
+}
+
+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;
+
+ LLUUID id;
+ if(self->mExperienceEnabled->get())
+ {
+ if(self->mScriptEd->getAssociatedExperience().isNull())
+ {
+ id=self->mExperienceIds.beginArray()->asUUID();
+ }
+ }
+
+ if(id != self->mScriptEd->getAssociatedExperience())
+ {
+ self->mScriptEd->enableSave(self->getIsModifiable());
+ }
+ self->mScriptEd->setAssociatedExperience(id);
+
+ self->updateExperiencePanel();
+}
+
BOOL LLScriptEdCore::postBuild()
{
mErrorList = getChild<LLScrollListCtrl>("lsl errors");
@@ -407,7 +479,7 @@ BOOL LLScriptEdCore::postBuild()
childSetAction("Edit_btn", boost::bind(&LLScriptEdCore::openInExternalEditor, this));
initMenu();
-
+
std::vector<std::string> funcs;
std::vector<std::string> tooltips;
@@ -1212,6 +1284,106 @@ bool LLScriptEdCore::enableLoadFromFileMenu(void* userdata)
return (self && self->mEditor) ? self->mEditor->canLoadOrSaveToFile() : FALSE;
}
+LLUUID LLScriptEdCore::getAssociatedExperience()const
+{
+ return mAssociatedExperience;
+}
+
+void LLLiveLSLEditor::setExperienceIds( const LLSD& experience_ids )
+{
+ mExperienceIds=experience_ids;
+ updateExperiencePanel();
+}
+
+
+void LLLiveLSLEditor::updateExperiencePanel()
+{
+ BOOL editable = getIsModifiable();
+
+ if(mScriptEd->getAssociatedExperience().isNull())
+ {
+ mExperienceEnabled->set(FALSE);
+ mExperiences->setVisible(FALSE);
+ if(mExperienceIds.size()>0)
+ {
+ mExperienceEnabled->setEnabled(TRUE);
+ mExperienceEnabled->setToolTip(getString("add_experiences"));
+ }
+ else
+ {
+ mExperienceEnabled->setEnabled(FALSE);
+ mExperienceEnabled->setToolTip(getString("no_experiences"));
+ }
+ getChild<LLButton>("view_profile")->setVisible(FALSE);
+ }
+ else
+ {
+ mExperienceEnabled->setToolTip(getString("experience_enabled"));
+ mExperienceEnabled->setEnabled(editable);
+ mExperienceEnabled->set(TRUE);
+ mExperiences->setVisible(TRUE);
+ getChild<LLButton>("view_profile")->setVisible(TRUE);
+ buildExperienceList();
+ }
+}
+
+void LLLiveLSLEditor::addExperienceInfo(const LLSD& experience, BOOL enabled)
+{
+ LLUUID id = experience[LLExperienceCache::EXPERIENCE_ID].asUUID();
+ EAddPosition position = (id == mScriptEd->getAssociatedExperience())?ADD_TOP:ADD_BOTTOM;
+ LLScrollListItem* item=mExperiences->add(experience[LLExperienceCache::NAME], id, position );
+ if(!enabled)
+ {
+ item->setEnabled(FALSE);
+ }
+}
+
+void LLLiveLSLEditor::buildExperienceList()
+{
+ mExperiences->clearRows();
+ bool foundAssociated=false;
+ for(LLSD::array_const_iterator it = mExperienceIds.beginArray(); it != mExperienceIds.endArray(); ++it)
+ {
+ LLUUID id = it->asUUID();
+ foundAssociated |= (id == mScriptEd->getAssociatedExperience());
+ LLExperienceCache::get(id, boost::bind(&LLLiveLSLEditor::addExperienceInfo, this, _1, TRUE));
+ }
+
+ if(!foundAssociated )
+ {
+ LLExperienceCache::get(mScriptEd->getAssociatedExperience(), boost::bind(&LLLiveLSLEditor::addExperienceInfo, this, _1, FALSE));
+ }
+
+}
+
+
+void LLScriptEdCore::setAssociatedExperience( const LLUUID& experience_id )
+{
+ mAssociatedExperience = experience_id;
+}
+
+
+
+void LLLiveLSLEditor::requestExperiences()
+{
+ if (!getIsModifiable())
+ {
+ return;
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ std::string lookup_url=region->getCapability("GetCreatorExperiences");
+ if(!lookup_url.empty())
+ {
+ LLHTTPClient::get(lookup_url, new ExperienceResponder(getDerivedHandle<LLLiveLSLEditor>()));
+ }
+ }
+}
+
+
+
/// ---------------------------------------------------------------------------
/// LLScriptEdContainer
/// ---------------------------------------------------------------------------
@@ -1771,6 +1943,16 @@ BOOL LLLiveLSLEditor::postBuild()
mScriptEd->mEditor->makePristine();
mScriptEd->mEditor->setFocus(TRUE);
+
+ mExperiences = getChild<LLComboBox>("Experiences...");
+ mExperiences->setCommitCallback(boost::bind(&LLLiveLSLEditor::experienceChanged, this));
+
+ mExperienceEnabled = getChild<LLCheckBoxCtrl>("enable_xp");
+
+ childSetCommitCallback("enable_xp", onToggleExperience, this);
+ childSetCommitCallback("view_profile", onViewProfile, this);
+
+
return LLPreview::postBuild();
}
@@ -1819,8 +2001,8 @@ void LLLiveLSLEditor::loadAsset()
|| gAgent.isGodlike()))
{
mItem = new LLViewerInventoryItem(item);
- //llinfos << "asset id " << mItem->getAssetUUID() << llendl;
}
+ ExperienceAssociationResponder::fetchAssociatedExperience(item->getParentUUID(), item->getUUID(), boost::bind(&LLLiveLSLEditor::setAssociatedExperience, getDerivedHandle<LLLiveLSLEditor>(), _1));
if(!gAgent.isGodlike()
&& (item
@@ -1881,7 +2063,7 @@ void LLLiveLSLEditor::loadAsset()
LLHost host(object->getRegion()->getIP(),
object->getRegion()->getPort());
gMessageSystem->sendReliable(host);
- */
+ */
}
}
else
@@ -1904,6 +2086,8 @@ void LLLiveLSLEditor::loadAsset()
time_corrected());
mAssetStatus = PREVIEW_ASSET_LOADED;
}
+
+ requestExperiences();
}
// static
@@ -1914,7 +2098,7 @@ void LLLiveLSLEditor::onLoadComplete(LLVFS *vfs, const LLUUID& asset_id,
lldebugs << "LLLiveLSLEditor::onLoadComplete: got uuid " << asset_id
<< llendl;
LLUUID* xored_id = (LLUUID*)user_data;
-
+
LLLiveLSLEditor* instance = LLFloaterReg::findTypedInstance<LLLiveLSLEditor>("preview_scriptedit", *xored_id);
if(instance )
@@ -2167,8 +2351,8 @@ void LLLiveLSLEditor::saveIfNeeded(bool sync /*= true*/)
mPendingUploads++;
BOOL is_running = getChild<LLCheckBoxCtrl>( "running")->get();
if (!url.empty())
- {
- uploadAssetViaCaps(url, filename, mObjectUUID, mItemUUID, is_running);
+ {
+ uploadAssetViaCaps(url, filename, mObjectUUID, mItemUUID, is_running, mScriptEd->getAssociatedExperience());
}
else if (gAssetStorage)
{
@@ -2176,11 +2360,7 @@ void LLLiveLSLEditor::saveIfNeeded(bool sync /*= true*/)
}
}
-void LLLiveLSLEditor::uploadAssetViaCaps(const std::string& url,
- const std::string& filename,
- const LLUUID& task_id,
- const LLUUID& item_id,
- BOOL is_running)
+void LLLiveLSLEditor::uploadAssetViaCaps( const std::string& url, const std::string& filename, const LLUUID& task_id, const LLUUID& item_id, BOOL is_running, const LLUUID& experience_public_id )
{
llinfos << "Update Task Inventory via capability " << url << llendl;
LLSD body;
@@ -2188,6 +2368,7 @@ void LLLiveLSLEditor::uploadAssetViaCaps(const std::string& url,
body["item_id"] = item_id;
body["is_script_running"] = is_running;
body["target"] = monoChecked() ? "mono" : "lsl2";
+ body["experience"] = experience_public_id;
LLHTTPClient::post(url, body,
new LLUpdateTaskInventoryResponder(body, filename, LLAssetType::AT_LSL_TEXT));
}
@@ -2439,3 +2620,18 @@ BOOL LLLiveLSLEditor::monoChecked() const
}
return FALSE;
}
+
+void LLLiveLSLEditor::setAssociatedExperience( LLHandle<LLLiveLSLEditor> editor, const LLSD& experience )
+{
+ LLLiveLSLEditor* scriptEd = editor.get();
+ if(scriptEd)
+ {
+ LLUUID id;
+ if(experience.has(LLExperienceCache::EXPERIENCE_ID))
+ {
+ id=experience[LLExperienceCache::EXPERIENCE_ID].asUUID();
+ }
+ scriptEd->mScriptEd->setAssociatedExperience(id);
+ scriptEd->updateExperiencePanel();
+ }
+}
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 9fb0a4fb63..29d1443d6c 100755
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -34,7 +34,7 @@
#include "llcombobox.h"
#include "lliconctrl.h"
#include "llframetimer.h"
-#include "llfloatergotoline.h"
+//#include "llfloatergotoline.h"
class LLLiveLSLFile;
class LLMessageSystem;
@@ -51,6 +51,7 @@ class LLVFS;
class LLViewerInventoryItem;
class LLScriptEdContainer;
class LLFloaterGotoLine;
+class LLFloaterExperienceProfile;
// Inner, implementation class. LLPreviewScript and LLLiveLSLEditor each own one of these.
class LLScriptEdCore : public LLPanel
@@ -103,12 +104,14 @@ public:
static void onBtnInsertSample(void*);
static void onBtnInsertFunction(LLUICtrl*, void*);
static void onBtnLoadFromFile(void*);
- static void onBtnSaveToFile(void*);
+ static void onBtnSaveToFile(void*);
static bool enableSaveToFileMenu(void* userdata);
static bool enableLoadFromFileMenu(void* userdata);
- virtual bool hasAccelerators() const { return true; }
+ virtual bool hasAccelerators() const { return true; }
+ LLUUID getAssociatedExperience()const;
+ void setAssociatedExperience( const LLUUID& experience_id );
private:
void onBtnHelp();
@@ -136,8 +139,8 @@ private:
void (*mLoadCallback)(void* userdata);
void (*mSaveCallback)(void* userdata, BOOL close_after_save);
void (*mSearchReplaceCallback) (void* userdata);
- void* mUserdata;
- LLComboBox *mFunctions;
+ void* mUserdata;
+ LLComboBox *mFunctions;
BOOL mForceClose;
LLPanel* mCodePanel;
LLScrollListCtrl* mErrorList;
@@ -149,6 +152,7 @@ private:
BOOL mEnableSave;
BOOL mHasScriptData;
LLLiveLSLFile* mLiveFile;
+ LLUUID mAssociatedExperience;
LLScriptEdContainer* mContainer; // parent view
};
@@ -230,7 +234,19 @@ public:
/*virtual*/ BOOL postBuild();
- void setIsNew() { mIsNew = TRUE; }
+ void setIsNew() { mIsNew = TRUE; }
+
+ 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);
+ void buildExperienceList();
+ void updateExperiencePanel();
+ void requestExperiences();
+ void experienceChanged();
+ void addAssociatedExperience(const LLSD& experience);
private:
virtual BOOL canClose();
@@ -240,11 +256,7 @@ private:
virtual void loadAsset();
void loadAsset(BOOL is_new);
/*virtual*/ void saveIfNeeded(bool sync = true);
- void uploadAssetViaCaps(const std::string& url,
- const std::string& filename,
- const LLUUID& task_id,
- const LLUUID& item_id,
- BOOL is_running);
+ void uploadAssetViaCaps(const std::string& url, const std::string& filename, const LLUUID& task_id, const LLUUID& item_id, BOOL is_running, const LLUUID& experience_public_id);
void uploadAssetLegacy(const std::string& filename,
LLViewerObject* object,
const LLTransactionID& tid,
@@ -285,9 +297,16 @@ private:
S32 mPendingUploads;
BOOL getIsModifiable() const { return mIsModifiable; } // Evaluated on load assert
-
+
LLCheckBoxCtrl* mMonoCheckbox;
BOOL mIsModifiable;
+
+
+ LLComboBox *mExperiences;
+ LLCheckBoxCtrl *mExperienceEnabled;
+ LLSD mExperienceIds;
+
+ LLHandle<LLFloater> mExperienceProfile;
};
#endif // LL_LLPREVIEWSCRIPT_H
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index 92c2863ffd..040c4ee72d 100755
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -43,6 +43,8 @@
#include "llviewercontrol.h"
#include "llviewerinventory.h"
#include "llviewerobjectlist.h"
+#include "llexperiencecache.h"
+#include "llexperienceassociationresponder.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -316,6 +318,15 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
is_obj_modify = object->permOwnerModify();
}
+ if(item->getInventoryType() == LLInventoryType::IT_LSL)
+ {
+ getChildView("LabelItemExperienceTitle")->setVisible(TRUE);
+ LLTextBox* tb = getChild<LLTextBox>("LabelItemExperience");
+ tb->setText(getString("loading_experience"));
+ tb->setVisible(TRUE);
+ ExperienceAssociationResponder::fetchAssociatedExperience(item->getParentUUID(), item->getUUID(), boost::bind(&LLSidepanelItemInfo::setAssociatedExperience, getDerivedHandle<LLSidepanelItemInfo>(), _1));
+ }
+
//////////////////////
// ITEM NAME & DESC //
//////////////////////
@@ -666,6 +677,30 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
}
}
+
+void LLSidepanelItemInfo::setAssociatedExperience( LLHandle<LLSidepanelItemInfo> hInfo, const LLSD& experience )
+{
+ LLSidepanelItemInfo* info = hInfo.get();
+ if(info)
+ {
+ LLUUID id;
+ if(experience.has(LLExperienceCache::EXPERIENCE_ID) && experience.has(LLExperienceCache::NAME))
+ {
+ id=experience[LLExperienceCache::EXPERIENCE_ID].asUUID();
+ }
+ LLTextBox* xpName = info->getChild<LLTextBox>("LabelItemExperience");
+ if(id.isNull())
+ {
+ xpName->setText(info->getString("no_experience"));
+ }
+ else
+ {
+ xpName->setText(experience[LLExperienceCache::NAME].asString());
+ }
+ }
+}
+
+
void LLSidepanelItemInfo::startObjectInventoryObserver()
{
if (!mObjectInventoryObserver)
diff --git a/indra/newview/llsidepaneliteminfo.h b/indra/newview/llsidepaneliteminfo.h
index 12aaca923e..2e24e58a2a 100755
--- a/indra/newview/llsidepaneliteminfo.h
+++ b/indra/newview/llsidepaneliteminfo.h
@@ -67,6 +67,8 @@ protected:
void refreshFromItem(LLViewerInventoryItem* item);
private:
+ static void setAssociatedExperience( LLHandle<LLSidepanelItemInfo> hInfo, const LLSD& experience );
+
void startObjectInventoryObserver();
void stopObjectInventoryObserver();
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 67a76460a7..8997a46aa0 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -48,6 +48,7 @@
#include "llares.h"
#include "llavatarnamecache.h"
+#include "llexperiencecache.h"
#include "lllandmark.h"
#include "llcachename.h"
#include "lldir.h"
@@ -1407,6 +1408,9 @@ bool idle_startup()
LLStartUp::initNameCache();
display_startup();
+ LLStartUp::initExperienceCache();
+ display_startup();
+
// update the voice settings *after* gCacheName initialization
// so that we can construct voice UI that relies on the name cache
LLVoiceClient::getInstance()->updateSettings();
@@ -2820,6 +2824,13 @@ void LLStartUp::initNameCache()
LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames"));
}
+
+void LLStartUp::initExperienceCache()
+{
+ LLAppViewer::instance()->loadExperienceCache();
+ LLExperienceCache::initClass();
+}
+
void LLStartUp::cleanupNameCache()
{
LLAvatarNameCache::cleanupClass();
@@ -3516,3 +3527,4 @@ void transition_back_to_login_panel(const std::string& emsg)
reset_login(); // calls LLStartUp::setStartupState( STATE_LOGIN_SHOW );
gSavedSettings.setBOOL("AutoLogin", FALSE);
}
+
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index 760e38890b..00e03bcda6 100755
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -91,6 +91,7 @@ public:
static void fontInit();
static void initNameCache();
+ static void initExperienceCache();
static void cleanupNameCache();
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index c6b28b9e5e..13ceaf491c 100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -58,6 +58,8 @@
#include "llfloatereditsky.h"
#include "llfloatereditwater.h"
#include "llfloaterenvironmentsettings.h"
+#include "llfloaterexperienceprofile.h"
+#include "llfloaterexperiences.h"
#include "llfloaterevent.h"
#include "llfloaterdestinations.h"
#include "llfloaterfonttest.h"
@@ -206,8 +208,10 @@ 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("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>);
LLFloaterReg::add("gestures", "floater_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGesture>);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 8422708add..60e0df90a2 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1596,7 +1596,16 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
}
capabilityNames.append("GetDisplayNames");
- capabilityNames.append("GetMesh");
+ capabilityNames.append("GetExperiences");
+ capabilityNames.append("GetExperienceInfo");
+ capabilityNames.append("GetAdminExperiences");
+ capabilityNames.append("GetCreatorExperiences");
+ capabilityNames.append("ExperiencePreferences");
+ capabilityNames.append("UpdateExperience");
+ capabilityNames.append("IsExperienceAdmin");
+ capabilityNames.append("IsExperienceContributor");
+ capabilityNames.append("GetMesh");
+ capabilityNames.append("GetMetadata");
capabilityNames.append("GetObjectCost");
capabilityNames.append("GetObjectPhysicsData");
capabilityNames.append("GetTexture");
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 1a050800b4..15d5dd63c7 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -43,6 +43,7 @@
#include "llanimationstates.h"
#include "llavatarnamecache.h"
#include "llavatarpropertiesprocessor.h"
+#include "llexperiencecache.h"
#include "llphysicsmotion.h"
#include "llviewercontrol.h"
#include "llcallingcard.h" // IDEVO for LLAvatarTracker
@@ -2037,7 +2038,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
idleUpdateBelowWater(); // wind effect uses this
idleUpdateWindEffect();
}
-
+
idleUpdateNameTag( root_pos_last );
idleUpdateRenderCost();
}
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..f47042ea33
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_experienceprofile.xml
@@ -0,0 +1,537 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+
+<floater
+ positioning="cascading"
+ can_close="true"
+ enabled="true"
+ can_resize="true"
+ title="EXPERIENCE PROFILE"
+ width="358">
+ <floater.string
+ name="maturity_icon_general">
+ "Parcel_PG_Light"
+ </floater.string>
+ <floater.string
+ name="maturity_icon_moderate">
+ "Parcel_M_Light"
+ </floater.string>
+ <floater.string
+ name="maturity_icon_adult">
+ "Parcel_R_Light"
+ </floater.string>
+ <text
+ follows="top|left|right"
+ font="SansSerifHugeBold"
+ height="26"
+ layout="topleft"
+ left_pad="4"
+ name="edit_title"
+ text_color="White"
+ top="2"
+ value="Experience Profile"
+ use_ellipses="true"
+ left="3"
+ right="-3"/>
+ <tab_container
+ hide_tabs="true"
+ follows="all"
+ height="540"
+ layout="topleft"
+ left="5"
+ min_height="250"
+ top_pad="3"
+ width="348"
+ name="tab_container">
+ <panel
+ background_visible="true"
+ follows="all"
+ height="570"
+ layout="topleft"
+ left="0"
+ min_height="250"
+ top="0"
+ width="348"
+ name="panel_experience_info">
+ <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="46"
+ 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>
+ </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="92"
+ 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="-3"
+ 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="3"
+ width="120"
+ left="73"
+ visible="false"/>
+ <button
+ follows="bottom|left"
+ height="23"
+ label="Allow"
+ layout="topleft"
+ name="allow_btn"
+ width="80"
+ top_pad="3"
+ left="10"
+ enabled="false"/>
+ <button
+ follows="bottom|left"
+ height="23"
+ label="Forget"
+ layout="topleft"
+ name="forget_btn"
+ width="80"
+ top_pad="-23"
+ left_pad="3"
+ enabled="false"/>
+ <button
+ follows="bottom|left"
+ height="23"
+ label="Block"
+ layout="topleft"
+ name="block_btn"
+ width="80"
+ top_pad="-23"
+ left_pad="3"
+ enabled="false"/>
+
+ </layout_panel>
+ </layout_stack>
+ </panel>
+ </scroll_container>
+ </panel>
+ <panel
+ background_visible="true"
+ follows="all"
+ layout="topleft"
+ height="540"
+ left="0"
+ top="0"
+ width="348"
+ name="edit_panel_experience_info">
+ <scroll_container
+ color="DkGray2"
+ follows="all"
+ height="525"
+ layout="topleft"
+ left="9"
+ name="edit_xp_scroll"
+ opaque="true"
+ top_pad="10"
+ width="330">
+ <panel
+ bg_alpha_color="DkGray2"
+ follows="top|left|right"
+ height="525"
+ layout="topleft"
+ left="0"
+ name="edit_scrolling_panel"
+ top="0"
+ width="310">
+ <texture_picker
+ enabled="true"
+ fallback_image="default_land_picture.j2c"
+ follows="left|top"
+ height="197"
+ layout="topleft"
+ left="10"
+ name="edit_logo"
+ top="10"
+ width="290" />
+ <text
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="10"
+ name="edit_experience_title_label"
+ use_ellipses="true"
+ value="Name:"
+ right="-10"/>
+ <line_editor
+ follows="left|top|right"
+ height="19"
+ layout="topleft"
+ left="10"
+ name="edit_experience_title"
+ max_length_bytes="63"
+ text_color="black"
+ right="-10"/>
+ <text
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="10"
+ top_pad="10"
+ name="edit_experience_desc_label"
+ use_ellipses="true"
+ value="Description:"
+ right="-10"/>
+ <text_editor
+ follows="left|top|right"
+ height="57"
+ layout="topleft"
+ left="11"
+ name="edit_experience_description"
+ max_length="2048"
+ text_color="black"
+ right="-11"
+ word_wrap="true"/>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="10"
+ top_pad="10"
+ name="edit_Location"
+ right="-10">
+ Location:
+ </text>
+ <line_editor
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="19"
+ layout="topleft"
+ left="10"
+ max_length_bytes="255"
+ valign="center"
+ name="edit_LocationTextText"
+ right="-10"/>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ top_pad="10"
+ layout="topleft"
+ left="10"
+ right="-10">
+ Marketplace store:
+ </text>
+ <line_editor
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="19"
+ layout="topleft"
+ left="10"
+ max_length_bytes="255"
+ valign="center"
+ name="edit_marketplace"
+ right="-10"/>
+ <text
+ top_pad="10"
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="edit_ContentRating"
+ right="-10">
+ Rating:
+ </text>
+ <icons_combo_box
+ follows="right|top"
+ height="20"
+ label="Moderate"
+ layout="topleft"
+ right="-10"
+ top_pad="-17"
+ name="edit_ContentRatingText"
+ width="105">
+ <icons_combo_box.drop_down_button
+ image_overlay="Parcel_M_Light"
+ image_overlay_alignment="left"
+ imgoverlay_label_space="3"
+ pad_left="3"/>
+ <icons_combo_box.item
+ label="Adult"
+ name="Adult"
+ value="42">
+ <item.columns
+ halign="center"
+ type="icon"
+ value="Parcel_R_Light"
+ width="20"/>
+ </icons_combo_box.item>
+ <icons_combo_box.item
+ label="Moderate"
+ name="Mature"
+ value="21">
+ <item.columns
+ halign="center"
+ type="icon"
+ value="Parcel_M_Light"
+ width="20"/>
+ </icons_combo_box.item>
+ <icons_combo_box.item
+ label="General"
+ name="PG"
+ value="13">
+ <item.columns
+ halign="center"
+ type="icon"
+ value="Parcel_PG_Light"
+ width="20"/>
+ </icons_combo_box.item>
+ </icons_combo_box>
+ <check_box width="140"
+ height="21"
+ left="10"
+ layout="topleft"
+ follows="top|left"
+ label="Enable Experience"
+ name="edit_enable_btn"/>
+ <check_box width="130"
+ height="21"
+ top_pad="-21"
+ right="-10"
+ layout="topleft"
+ follows="top|left"
+ label="Hide In Search"
+ name="edit_private_btn"/>
+ <button
+ follows="top|left"
+ height="23"
+ label="Cancel"
+ layout="topleft"
+ name="cancel_btn"
+ width="120"
+ top_pad="15"
+ left="10"
+ visible="true"/>
+ <button
+ follows="top|right"
+ height="23"
+ label="Save"
+ layout="topleft"
+ name="save_btn"
+ top_pad="-23"
+ width="120"
+ right="-10"
+ visible="true"/>
+ </panel>
+ </scroll_container>
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_experiences.xml b/indra/newview/skins/default/xui/en/floater_experiences.xml
new file mode 100644
index 0000000000..57541c8b35
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_experiences.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+
+<floater
+ positioning="cascading"
+ can_close="true"
+ can_resize="true"
+ height="400"
+ help_topic="sidebar_experiences"
+ min_height="300"
+ min_width="300"
+ layout="topleft"
+ name="floater_experiences"
+ save_rect="false"
+ single_instance="true"
+ reuse_instance="false"
+ title="EXPERIENCES"
+ width="400">
+ <panel
+ top="3"
+ left="3"
+ layout="topleft"
+ right="-3"
+ follows="all"
+ height="300"
+ class="experiences_panel"
+ filename="panel_experiences.xml"
+ >
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml
index 5cd7cd196d..d8c2a753a1 100755
--- a/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml
+++ b/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml
@@ -1,71 +1,110 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- legacy_header_height="18"
- bevel_style="none"
- border_style="line"
- can_resize="true"
- height="580"
- layout="topleft"
- min_height="271"
- min_width="290"
- name="script ed float"
- help_topic="script_ed_float"
- save_rect="true"
- title="SCRIPT: NEW SCRIPT"
- width="508">
- <floater.string
- name="not_allowed">
- You can not view or edit this script, since it has been set as &quot;no copy&quot;. You need full permissions to view or edit a script inside an object.
- </floater.string>
- <floater.string
- name="script_running">
- Running
- </floater.string>
- <floater.string
- name="Title">
- SCRIPT: [NAME]
- </floater.string>
- <panel
- bevel_style="none"
+ legacy_header_height="18"
+ bevel_style="none"
+ border_style="line"
+ can_resize="true"
+ height="582"
+ layout="topleft"
+ min_height="271"
+ min_width="328"
+ name="script ed float"
+ help_topic="script_ed_float"
+ save_rect="true"
+ title="SCRIPT: NEW SCRIPT"
+ width="508">
+ <floater.string
+ name="not_allowed">
+ You can not view or edit this script, since it has been set as &quot;no copy&quot;. You need full permissions to view or edit a script inside an object.
+ </floater.string>
+ <floater.string
+ name="script_running">
+ Running
+ </floater.string>
+ <floater.string
+ name="Title">
+ SCRIPT: [NAME]
+ </floater.string>
+ <floater.string
+ name="experience_enabled">
+ Uncheck to remove the current experience
+ </floater.string>
+ <floater.string
+ name="no_experiences">
+ You are not authorized for any experiences
+ </floater.string>
+ <floater.string
+ name="add_experiences">
+ Select to add an experience
+ </floater.string>
+ <panel
+ bevel_style="none"
- border_style="line"
- follows="left|top|right|bottom"
- height="522"
- layout="topleft"
- left="10"
- name="script ed panel"
- top="20"
- width="497" />
- <button
- follows="left|bottom"
- height="23"
- label="Reset"
- label_selected="Reset"
- layout="topleft"
- name="Reset"
- left="10"
- width="85" />
- <check_box
+ border_style="line"
+ follows="left|top|right|bottom"
+ height="499"
+ layout="topleft"
+ left="10"
+ name="script ed panel"
+ top="16"
+ width="501" />
+ <button
+ follows="left|bottom"
+ height="23"
+ label="Reset"
+ label_selected="Reset"
+ layout="topleft"
+ name="Reset"
+ left="10"
+ width="85" />
+ <check_box
left_delta="90"
top_delta="3"
- enabled="false"
- follows="left|bottom"
- font="SansSerif"
- height="18"
- initial_value="true"
- label="Running"
- layout="topleft"
- name="running"
- width="205" />
- <check_box
+ enabled="false"
+ follows="left|bottom"
+ font="SansSerif"
+ height="18"
+ initial_value="true"
+ label="Running"
+ layout="topleft"
+ name="running"
+ width="205" />
+ <check_box
left_delta="140"
- enabled="true"
- follows="left|bottom"
- font="SansSerif"
- height="18"
- initial_value="true"
- label="Mono"
- layout="topleft"
- name="mono"
- width="100" />
+ enabled="true"
+ follows="left|bottom"
+ font="SansSerif"
+ height="18"
+ initial_value="true"
+ label="Mono"
+ layout="topleft"
+ name="mono"
+ width="100" />
+ <check_box width="130"
+ height="21"
+ enabled="false"
+ left="9"
+ top_pad="10"
+ layout="topleft"
+ follows="bottom|left"
+ label="Use Experience:"
+ name="enable_xp"/>
+ <combo_box
+ label=""
+ top_pad="-21"
+ left="149"
+ right="467"
+ layout="topleft"
+ follows="left|bottom|right"
+ visible="false"
+ name="Experiences..."/>
+ <button label="&gt;"
+ name="view_profile"
+ height="23"
+ width="23"
+ right="496"
+ layout="topleft"
+ top_pad="-23"
+ follows="right"
+ visible="false"/>
</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index f253ed3e06..1cfe147b07 100755
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -53,6 +53,14 @@
parameter="" />
</menu_item_call>
<menu_item_call
+ label="Experiences..."
+ name="Experiences"
+ shortcut="control|E">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="experiences"/>
+ </menu_item_call>
+ <menu_item_call
label="Places..."
name="Places">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/panel_experience_info.xml b/indra/newview/skins/default/xui/en/panel_experience_info.xml
new file mode 100644
index 0000000000..268e7462c1
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_experience_info.xml
@@ -0,0 +1,377 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<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="true"
+ 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"
+ 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="true"
+ 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="true"
+ auto_resize="false"
+ name="marketplace panel"
+
+ >
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="Location"
+ width="290">
+ Marketplace store:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="18"
+ layout="topleft"
+ left="10"
+ valign="center"
+ name="LocationTextText"
+ 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"/>
+ <!--
+
+
+ <expandable_text
+ allow_scroll="false"
+ bg_visible="false"
+ follows="left|top|right"
+ h_pad="0"
+ height="35"
+ width="280"
+ layout="topleft"
+ font="SansSerifBig"
+ font.style="BOLD"
+ left="10"
+ top_pad="10"
+ name="pick_name"
+ read_only="false"
+ text_color="white"
+ v_pad="0"
+ use_ellipses="true"
+ value="It's an experience" />
+
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ top_pad="10"
+ value="Maturity level:"
+ width="130" />
+ <icon
+ follows="top|left"
+ height="16"
+ image_name="unknown"
+ layout="topleft"
+ left_pad="10"
+ name="maturity_icon"
+ top_pad="-18"
+ width="18" />
+ <text
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ name="maturity_value"
+ top_pad="-14"
+ value="unknown"
+ width="118" />
+ <panel
+ follows="left|top|right"
+ name="location_panel"
+ left="10"
+ width="280"
+ visible="false"
+ top_pad="10"
+ height="42">
+ <text
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left="00"
+ top="0"
+ value="Location:"
+ width="280" />
+
+ <text
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left="0"
+ top_pad="10"
+ value="Location:"
+ width="280" />
+ </panel>
+
+ <panel
+ follows="left|top|right"
+ name="location_panel"
+ left="10"
+ width="280"
+ top_pad="10"
+ height="42">
+ <text
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left="00"
+ top="0"
+ value="Location:"
+ width="280" />
+
+ <text
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left="0"
+ top_pad="10"
+ value="Location:"
+ width="280" />
+ </panel>
+
+-->
+ </layout_panel>
+ </layout_stack>
+ </panel>
+ </scroll_container>
+
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_experiences.xml b/indra/newview/skins/default/xui/en/panel_experiences.xml
new file mode 100644
index 0000000000..47a3005aae
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_experiences.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+
+<panel
+ layout="topleft"
+ top="3"
+ left="3"
+ right="-3"
+ bottom="-3"
+ label="Experiences"
+ follows="all">
+ <string
+ name="no_experiences"
+ value="No experiences."/>
+
+ <accordion
+ fit_parent="true"
+ layout="topleft"
+ top="0"
+ left="3"
+ right="-3"
+ bottom="-3"
+ single_expansion="true"
+ follows="all">
+ <accordion_tab
+ name="tab_experiences"
+ layout="topleft"
+ top="0"
+ left="0"
+ right="-3"
+ title="Experiences"
+ follows="all">
+ <flat_list_view
+ name="experiences_list"
+ layout="topleft"
+ top="0"
+ left="0"
+ follows="all"/>
+ </accordion_tab>
+ </accordion>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
index bcdef96138..469f6f036d 100755
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -1,211 +1,212 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
- bevel_style="none"
- border_style="line"
- follows="left|top|right|bottom"
- height="522"
- layout="topleft"
- left="0"
- name="script panel"
- width="497">
- <panel.string
- name="loading">
- Loading...
- </panel.string>
- <panel.string
- name="can_not_view">
- You can not view or edit this script, since it has been set as &quot;no copy&quot;. You need full permissions to view or edit a script inside an object.
- </panel.string>
- <panel.string
- name="public_objects_can_not_run">
- Public Objects cannot run scripts
- </panel.string>
- <panel.string
- name="script_running">
- Running
- </panel.string>
- <panel.string
- name="Title">
- Script: [NAME]
- </panel.string>
- <panel.string
- name="external_editor_not_set">
- Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting.
- </panel.string>
- <menu_bar
- bg_visible="false"
- follows="left|top"
- height="18"
- layout="topleft"
- left="0"
- mouse_opaque="false"
- name="script_menu"
- width="476">
- <menu
- top="0"
- height="62"
- label="File"
- layout="topleft"
- left="0"
- mouse_opaque="false"
- name="File"
- width="138">
- <menu_item_call
- label="Save"
- layout="topleft"
- name="Save" />
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Revert All Changes"
- layout="topleft"
- name="Revert All Changes" />
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Load from file..."
- layout="topleft"
- name="LoadFromFile" />
- <menu_item_call
- label="Save to file..."
- layout="topleft"
- name="SaveToFile" />
- </menu>
- <menu
- top="0"
- height="198"
- label="Edit"
- layout="topleft"
- mouse_opaque="false"
- name="Edit"
- width="139">
- <menu_item_call
- enabled="false"
- label="Undo"
- layout="topleft"
- name="Undo" />
- <menu_item_call
- enabled="false"
- label="Redo"
- layout="topleft"
- name="Redo" />
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- enabled="false"
- label="Cut"
- layout="topleft"
- name="Cut" />
- <menu_item_call
- enabled="false"
- label="Copy"
- layout="topleft"
- name="Copy" />
- <menu_item_call
- enabled="false"
- label="Paste"
- layout="topleft"
- name="Paste" />
- <menu_item_separator
- layout="topleft"
- name="separator2" />
- <menu_item_call
- label="Select All"
- layout="topleft"
- name="Select All" />
- <menu_item_call
- enabled="false"
- label="Deselect"
- layout="topleft"
- name="Deselect" />
- <menu_item_separator
- layout="topleft"
- name="separator3" />
- <menu_item_call
- label="Search / Replace..."
- layout="topleft"
- name="Search / Replace..." />
+ bevel_style="none"
+ border_style="line"
+ follows="left|top|right|bottom"
+ height="515"
+ layout="topleft"
+ left="0"
+ name="script panel"
+ width="497">
+ <panel.string
+ name="loading">
+ Loading...
+ </panel.string>
+ <panel.string
+ name="can_not_view">
+ You can not view or edit this script, since it has been set as &quot;no copy&quot;. You need full permissions to view or edit a script inside an object.
+ </panel.string>
+ <panel.string
+ name="public_objects_can_not_run">
+ Public Objects cannot run scripts
+ </panel.string>
+ <panel.string
+ name="script_running">
+ Running
+ </panel.string>
+ <panel.string
+ name="Title">
+ Script: [NAME]
+ </panel.string>
+ <panel.string
+ name="external_editor_not_set">
+ Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting.
+ </panel.string>
+ <menu_bar
+ bg_visible="false"
+ follows="left|top"
+ height="18"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="script_menu"
+ width="476">
+ <menu
+ top="0"
+ height="62"
+ label="File"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="File"
+ width="138">
+ <menu_item_call
+ label="Save"
+ layout="topleft"
+ name="Save" />
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Revert All Changes"
+ layout="topleft"
+ name="Revert All Changes" />
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Load from file..."
+ layout="topleft"
+ name="LoadFromFile" />
+ <menu_item_call
+ label="Save to file..."
+ layout="topleft"
+ name="SaveToFile" />
+ </menu>
+ <menu
+ top="0"
+ height="198"
+ label="Edit"
+ layout="topleft"
+ mouse_opaque="false"
+ name="Edit"
+ width="139">
+ <menu_item_call
+ enabled="false"
+ label="Undo"
+ layout="topleft"
+ name="Undo" />
+ <menu_item_call
+ enabled="false"
+ label="Redo"
+ layout="topleft"
+ name="Redo" />
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ enabled="false"
+ label="Cut"
+ layout="topleft"
+ name="Cut" />
+ <menu_item_call
+ enabled="false"
+ label="Copy"
+ layout="topleft"
+ name="Copy" />
+ <menu_item_call
+ enabled="false"
+ label="Paste"
+ layout="topleft"
+ name="Paste" />
+ <menu_item_separator
+ layout="topleft"
+ name="separator2" />
+ <menu_item_call
+ label="Select All"
+ layout="topleft"
+ name="Select All" />
+ <menu_item_call
+ enabled="false"
+ label="Deselect"
+ layout="topleft"
+ name="Deselect" />
+ <menu_item_separator
+ layout="topleft"
+ name="separator3" />
+ <menu_item_call
+ label="Search / Replace..."
+ layout="topleft"
+ name="Search / Replace..." />
<menu_item_call
label="Go to line..."
layout="topleft"
name="Go to line..." />
- </menu>
- <menu
- top="0"
- height="34"
- label="Help"
- layout="topleft"
- mouse_opaque="false"
- name="Help"
- width="112">
- <menu_item_call
- label="Help..."
- layout="topleft"
- name="Help..." />
- <menu_item_call
- label="Keyword Help..."
- layout="topleft"
- name="Keyword Help..." />
- </menu>
- </menu_bar>
- <text_editor
+ </menu>
+ <menu
+ top="0"
+ height="34"
+ label="Help"
+ layout="topleft"
+ mouse_opaque="false"
+ name="Help"
+ width="112">
+ <menu_item_call
+ label="Help..."
+ layout="topleft"
+ name="Help..." />
+ <menu_item_call
+ label="Keyword Help..."
+ layout="topleft"
+ name="Keyword Help..." />
+ </menu>
+ </menu_bar>
+ <text_editor
left="0"
- type="string"
- length="1"
- follows="left|top|right|bottom"
- font="Monospace"
- height="376"
- ignore_tab="false"
- layout="topleft"
- max_length="65536"
- name="Script Editor"
- text_readonly_color="DkGray"
- width="487"
- show_line_numbers="true"
- enable_tooltip_paste="true"
- word_wrap="true">
- Loading...
- </text_editor>
- <scroll_list
+ type="string"
+ length="1"
+ follows="left|top|right|bottom"
+ font="Monospace"
+ height="369"
+ ignore_tab="false"
+ layout="topleft"
+ max_length="65536"
+ name="Script Editor"
+ text_readonly_color="DkGray"
+ width="482"
+ show_line_numbers="true"
+ enable_tooltip_paste="true"
+ word_wrap="true">
+ Loading...
+ </text_editor>
+ <scroll_list
top_pad="10"
left="0"
- follows="left|right|bottom"
- height="60"
- layout="topleft"
- name="lsl errors"
- width="487" />
- <text
- follows="left|bottom"
- height="12"
- layout="topleft"
- left="0"
- name="line_col"
- width="128" />
- <combo_box
- follows="left|bottom"
- height="23"
- label="Insert..."
- layout="topleft"
- name="Insert..."
- width="128" />
- <button
- follows="right|bottom"
- height="23"
- label="Save"
- label_selected="Save"
- layout="topleft"
- top_pad="-35"
- right="487"
- name="Save_btn"
- width="81" />
- <button
- enabled="false"
- follows="right|bottom"
- height="23"
- label="Edit..."
- layout="topleft"
- top_pad="-23"
- right="400"
- name="Edit_btn"
- width="81" />
+ follows="left|right|bottom"
+ height="60"
+ layout="topleft"
+ name="lsl errors"
+ width="482" />
+ <text
+ follows="left|bottom"
+ height="12"
+ layout="topleft"
+ left="11"
+ name="line_col"
+ width="128" />
+ <combo_box
+ follows="left|bottom"
+ height="23"
+ label="Insert..."
+ layout="topleft"
+ name="Insert..."
+ width="128"
+ left="0"/>
+ <button
+ follows="right|bottom"
+ height="23"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ top_pad="-35"
+ right="482"
+ name="Save_btn"
+ width="81" />
+ <button
+ enabled="false"
+ follows="right|bottom"
+ height="23"
+ label="Edit..."
+ layout="topleft"
+ top_pad="-23"
+ right="396"
+ name="Edit_btn"
+ width="81" />
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_script_experience.xml b/indra/newview/skins/default/xui/en/panel_script_experience.xml
new file mode 100644
index 0000000000..e798638751
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_script_experience.xml
@@ -0,0 +1,97 @@
+<panel
+ name="script_experience"
+ title="EXPERIENCE"
+ width="400"
+ follows="top|left|right"
+ top="0"
+ left="0"
+ layout="topleft">
+ <!-- <floater.string name="EXPERIENCE">EXPERIENCE!!!!</floater.string>
+
+ <floater.string name="Script:">Script:</floater.string>
+ <floater.string name="Associated with:">Associated with:</floater.string>
+ <floater.string name="You can contribute:">You can contribute:</floater.string>
+ <floater.string name="Associate with:">Associate with:</floater.string>
+ <floater.string name="Yes">Yes</floater.string>
+ <floater.string name="No">No</floater.string>
+ <floater.string name="(none)"></floater.string>
+ <floater.string name="Choose Experience...">Choose Experience...</floater.string>
+ <floater.string name="You are not a contributor to any experiences.">You are not a contributor to any experiences.</floater.string>
+ -->
+
+ <button name="Expand Experience" width="200"
+ height="35"
+ is_toggle="true"
+ tab_stop="false"
+ pad_left="35"
+ top="0"
+ left="3"
+ label="Experience"
+ halign="left"
+ handle_right_mouse="false"
+ follows="top|left|right"
+ image_unselected="MarketplaceBtn_Off"
+ image_selected="MarketplaceBtn_Selected">
+ </button>
+ <check_box
+ follows="top|right" height="25" label="Uses Experience" left="215" width="0" top="0" name="enable_xp"
+ />
+ <layout_stack
+ follows="top|left|right"
+
+ width="384"
+ height="140"
+ name="xp_details"
+ left="4"
+ top="45"
+ orientation="horizontal"
+ layout="topleft"
+ visible="false">
+ <layout_panel width="120"
+ height="140">
+ <text >
+ Script:
+ </text>
+ <text bottom_delta="25">
+ Associated with:
+ </text>
+ <text bottom_delta="25">
+ You can contribute:
+ </text>
+ <text bottom_delta="25">
+ Associate with:
+ </text>
+ </layout_panel>
+
+ <layout_panel width="250"
+ height="140">
+ <text >
+ EasySit Animator 1.2.4
+ </text>
+ <text bottom_delta="25"
+ text_color="HTMLLinkColor" font.style="UNDERLINE">
+ Kyle's Superhero RPG
+ </text>
+ <text bottom_delta="25">
+ Yes
+ </text>
+ <combo_box left="0" bottom_delta="33"
+ label="Choose Experience..."
+ name="Experiences..."
+ follows="top|left|right"
+ />
+ </layout_panel>
+ </layout_stack>
+ <text
+ follows="top|left|right"
+ width="400"
+ height="15"
+ bottom_delta="-12"
+ left="0"
+ halign="center"
+ name="No Experiences"
+ visible="false"
+ text_color="AlertCautionTextColor">
+ You are not a contributor to any experiences.
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/role_actions.xml b/indra/newview/skins/default/xui/en/role_actions.xml
index 0eeccbeac5..9e429234d3 100755
--- a/indra/newview/skins/default/xui/en/role_actions.xml
+++ b/indra/newview/skins/default/xui/en/role_actions.xml
@@ -187,4 +187,16 @@
longdescription="Members in a Role with this Ability can control access and participation in group voice and text chat sessions."
name="moderate group chat" value="37" />
</action_set>
+ <action_set
+ description="These Abilities include power to modify experiences owned by this group."
+ name="experience_tools_experience">
+ <action description="Experience Admin"
+ longdescription="Members in a role with this ability can edit the meta-data for an experience."
+ name="experience admin"
+ value ="49" />
+ <action description="Experience Creator"
+ longdescription="Members in a role with this ability can create scripts for an experience."
+ name="experience creator"
+ value ="50" />
+ </action_set>
</role_actions>
diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
index c5dfb703e5..f1f8843a9d 100755
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -1,440 +1,477 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
- follows="all"
- height="570"
- layout="topleft"
- name="item properties"
- help_topic="item_properties"
- title="Item Profile"
- width="333">
- <panel.string
- name="unknown">
- (unknown)
- </panel.string>
- <panel.string
- name="unknown_multiple">
- (unknown / multiple)
- </panel.string>
- <panel.string
- name="public">
- (public)
- </panel.string>
- <panel.string
- name="you_can">
- You can:
- </panel.string>
- <panel.string
- name="owner_can">
- Owner can:
- </panel.string>
- <panel.string
- name="acquiredDate">
- [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
- </panel.string>
- <panel.string
- name="origin_inventory">
- (Inventory)
- </panel.string>
- <panel.string
- name="origin_inworld">
- (Inworld)
- </panel.string>
- <icon
- follows="top|right"
- height="18"
- image_name="Lock"
- layout="topleft"
- right="-15"
- mouse_opaque="true"
- name="IconLocked"
- top="8"
- width="18" />
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- left="12"
- name="back_btn"
- tab_stop="false"
- top="2"
- width="30"
- use_draw_context_alpha="false" />
- <text
- follows="top|left|right"
- font="SansSerifHugeBold"
- height="26"
- layout="topleft"
- left_pad="3"
- name="title"
- text_color="LtGray"
- top="2"
- use_ellipses="true"
- value="Item Profile"
- width="275" />
- <text
- follows="top|left|right"
- height="13"
- layout="topleft"
- left="45"
- name="origin"
- text_color="LtGray_50"
- use_ellipses="true"
- value="(Inventory)"
- width="275" />
- <scroll_container
- color="DkGray2"
- follows="all"
- layout="topleft"
- left="9"
- name="item_profile_scroll"
- opaque="true"
- height="493"
- width="313"
- top="45">
- <panel
- follows="left|top|right"
- height="390"
- help_topic=""
- label=""
- layout="topleft"
- left="0"
- name="item_profile"
- top="0"
- width="295">
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="5"
- name="LabelItemNameTitle"
- top="10"
- width="78">
- Name:
- </text>
- <line_editor
- border_style="line"
- border_thickness="1"
- follows="left|top|right"
- height="20"
- layout="topleft"
- left_delta="78"
- max_length_bytes="63"
- name="LabelItemName"
- top_delta="0"
- width="210" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="5"
- name="LabelItemDescTitle"
- top_pad="10"
- width="78">
- Description:
- </text>
- <line_editor
- border_style="line"
- border_thickness="1"
- follows="left|top|right"
- height="23"
- layout="topleft"
- left_delta="78"
- max_length_bytes="127"
- name="LabelItemDesc"
- top_delta="-5"
- width="210" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="23"
- layout="topleft"
- left="5"
- name="LabelCreatorTitle"
- top_pad="10"
- width="78">
- Creator:
- </text>
- <avatar_icon
- follows="top|left"
- height="20"
- default_icon_name="Generic_Person"
- layout="topleft"
- left_pad="0"
- top_delta="-6"
- mouse_opaque="true"
- width="20" />
- <text
- type="string"
- follows="left|right|top"
- font="SansSerifSmall"
- height="15"
- layout="topleft"
- left_pad="5"
- name="LabelCreatorName"
- top_delta="6"
- use_ellipses="true"
- width="165">
- </text>
- <button
- follows="top|right"
- height="16"
+ follows="all"
+ height="570"
+ layout="topleft"
+ name="item properties"
+ help_topic="item_properties"
+ title="Item Profile"
+ width="333">
+ <panel.string
+ name="no_experience">
+ (none)
+ </panel.string>
+ <panel.string
+ name="loading_experience">
+ (loading)
+ </panel.string>
+ <panel.string
+ name="unknown">
+ (unknown)
+ </panel.string>
+ <panel.string
+ name="unknown_multiple">
+ (unknown / multiple)
+ </panel.string>
+ <panel.string
+ name="public">
+ (public)
+ </panel.string>
+ <panel.string
+ name="you_can">
+ You can:
+ </panel.string>
+ <panel.string
+ name="owner_can">
+ Owner can:
+ </panel.string>
+ <panel.string
+ name="acquiredDate">
+ [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
+ </panel.string>
+ <panel.string
+ name="origin_inventory">
+ (Inventory)
+ </panel.string>
+ <panel.string
+ name="origin_inworld">
+ (Inworld)
+ </panel.string>
+ <icon
+ follows="top|right"
+ height="18"
+ image_name="Lock"
+ layout="topleft"
+ right="-15"
+ mouse_opaque="true"
+ name="IconLocked"
+ top="8"
+ width="18" />
+ <button
+ follows="top|left"
+ height="24"
+ image_hover_unselected="BackButton_Over"
+ image_pressed="BackButton_Press"
+ image_unselected="BackButton_Off"
+ layout="topleft"
+ left="12"
+ name="back_btn"
+ tab_stop="false"
+ top="2"
+ width="30"
+ use_draw_context_alpha="false" />
+ <text
+ follows="top|left|right"
+ font="SansSerifHugeBold"
+ height="26"
+ layout="topleft"
+ left_pad="3"
+ name="title"
+ text_color="LtGray"
+ top="2"
+ use_ellipses="true"
+ value="Item Profile"
+ width="275" />
+ <text
+ follows="top|left|right"
+ height="13"
+ layout="topleft"
+ left="45"
+ name="origin"
+ text_color="LtGray_50"
+ use_ellipses="true"
+ value="(Inventory)"
+ width="275" />
+ <scroll_container
+ color="DkGray2"
+ follows="all"
+ layout="topleft"
+ left="9"
+ name="item_profile_scroll"
+ opaque="true"
+ height="493"
+ width="313"
+ top="45">
+ <panel
+ follows="left|top|right"
+ height="390"
+ help_topic=""
+ label=""
+ layout="topleft"
+ left="0"
+ name="item_profile"
+ top="0"
+ width="295">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="5"
+ name="LabelItemNameTitle"
+ top="10"
+ width="78">
+ Name:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ height="20"
+ layout="topleft"
+ left_delta="78"
+ max_length_bytes="63"
+ name="LabelItemName"
+ top_delta="0"
+ width="210" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="5"
+ name="LabelItemDescTitle"
+ top_pad="10"
+ width="78">
+ Description:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ height="23"
+ layout="topleft"
+ left_delta="78"
+ max_length_bytes="127"
+ name="LabelItemDesc"
+ top_delta="-5"
+ width="210" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="23"
+ layout="topleft"
+ left="5"
+ name="LabelCreatorTitle"
+ top_pad="10"
+ width="78">
+ Creator:
+ </text>
+ <avatar_icon
+ follows="top|left"
+ height="20"
+ default_icon_name="Generic_Person"
+ layout="topleft"
+ left_pad="0"
+ top_delta="-6"
+ mouse_opaque="true"
+ width="20" />
+ <text
+ type="string"
+ follows="left|right|top"
+ font="SansSerifSmall"
+ height="15"
+ layout="topleft"
+ left_pad="5"
+ name="LabelCreatorName"
+ top_delta="6"
+ use_ellipses="true"
+ width="165">
+ </text>
+ <button
+ follows="top|right"
+ height="16"
+ image_selected="Inspector_I"
+ image_unselected="Inspector_I"
+ layout="topleft"
+ right="-5"
+ name="BtnCreator"
+ top_delta="-6"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="23"
+ layout="topleft"
+ left="5"
+ name="LabelOwnerTitle"
+ top_pad="10"
+ width="78">
+ Owner:
+ </text>
+ <avatar_icon
+ follows="top|left"
+ height="20"
+ default_icon_name="Generic_Person"
+ layout="topleft"
+ left_pad="0"
+ top_delta="-6"
+ mouse_opaque="true"
+ width="20" />
+ <text
+ type="string"
+ follows="left|right|top"
+ font="SansSerifSmall"
+ height="15"
+ layout="topleft"
+ left_pad="5"
+ name="LabelOwnerName"
+ top_delta="6"
+ use_ellipses="true"
+ width="165">
+ </text>
+ <button
+ follows="top|right"
+ height="16"
image_selected="Inspector_I"
image_unselected="Inspector_I"
+ layout="topleft"
+ right="-5"
+ name="BtnOwner"
+ top_delta="-3"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="23"
+ layout="topleft"
+ left="5"
+ name="LabelAcquiredTitle"
+ top_pad="10"
+ width="78">
+ Acquired:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="23"
+ layout="topleft"
+ left_delta="78"
+ name="LabelAcquiredDate"
+ top_delta="0"
+ width="210">
+ </text>
+ <panel
+ border="false"
+ follows="left|top|right"
+ layout="topleft"
+ mouse_opaque="false"
+ name="perms_inv"
+ left="0"
+ top_pad="25"
+ height="155"
+ width="313">
+ <text
+ type="string"
+ length="1"
+ left="10"
+ top_pad="13"
+ text_color="EmphasisColor"
+ height="15"
+ follows="left|top|right"
+ layout="topleft"
+ name="perm_modify"
+ width="200">
+ You can:
+ </text>
+ <check_box
+ height="18"
+ label="Modify"
+ layout="topleft"
+ left="20"
+ name="CheckOwnerModify"
+ top_pad="0"
+ width="90" />
+ <check_box
+ height="18"
+ label="Copy"
+ layout="topleft"
+ left_pad="0"
+ name="CheckOwnerCopy"
+ width="90" />
+ <check_box
+ height="18"
+ label="Transfer"
+ layout="topleft"
+ left_pad="0"
+ name="CheckOwnerTransfer"
+ width="106" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="AnyoneLabel"
+ top_pad="8"
+ width="100">
+ Anyone:
+ </text>
+ <check_box
+ height="18"
+ label="Copy"
layout="topleft"
- right="-5"
- name="BtnCreator"
- top_delta="-6"
- width="16" />
- <text
+ left_pad="0"
+ name="CheckEveryoneCopy"
+ top_delta="-2"
+ width="150" />
+ <text
type="string"
length="1"
follows="left|top"
- height="23"
+ height="16"
layout="topleft"
- left="5"
- name="LabelOwnerTitle"
- top_pad="10"
- width="78">
- Owner:
- </text>
- <avatar_icon
- follows="top|left"
- height="20"
- default_icon_name="Generic_Person"
- layout="topleft"
- left_pad="0"
- top_delta="-6"
- mouse_opaque="true"
- width="20" />
- <text
+ left="10"
+ name="GroupLabel"
+ top_pad="8"
+ width="100">
+ Group:
+ </text>
+ <check_box
+ height="18"
+ label="Share"
+ layout="topleft"
+ left_pad="0"
+ top_delta="-2"
+ name="CheckShareWithGroup"
+ tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."
+ width="150" />
+ <text
type="string"
- follows="left|right|top"
- font="SansSerifSmall"
- height="15"
- layout="topleft"
- left_pad="5"
- name="LabelOwnerName"
- top_delta="6"
- use_ellipses="true"
- width="165">
- </text>
- <button
- follows="top|right"
- height="16"
- image_selected="Inspector_I"
- image_unselected="Inspector_I"
- layout="topleft"
- right="-5"
- name="BtnOwner"
- top_delta="-3"
- width="16" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="23"
- layout="topleft"
- left="5"
- name="LabelAcquiredTitle"
- top_pad="10"
- width="78">
- Acquired:
- </text>
- <text
- type="string"
- length="1"
- follows="left|top|right"
- height="23"
- layout="topleft"
- left_delta="78"
- name="LabelAcquiredDate"
- top_delta="0"
- width="210">
- </text>
- <panel
- border="false"
- follows="left|top|right"
- layout="topleft"
- mouse_opaque="false"
- name="perms_inv"
- left="0"
- top_pad="25"
- height="155"
- width="313">
- <text
- type="string"
- length="1"
- left="10"
- top_pad="13"
- text_color="EmphasisColor"
- height="15"
- follows="left|top|right"
- layout="topleft"
- name="perm_modify"
- width="200">
- You can:
- </text>
- <check_box
- height="18"
- label="Modify"
- layout="topleft"
- left="20"
- name="CheckOwnerModify"
- top_pad="0"
- width="90" />
- <check_box
- height="18"
- label="Copy"
- layout="topleft"
- left_pad="0"
- name="CheckOwnerCopy"
- width="90" />
- <check_box
- height="18"
- label="Transfer"
- layout="topleft"
- left_pad="0"
- name="CheckOwnerTransfer"
- width="106" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- left="10"
- name="AnyoneLabel"
- top_pad="8"
- width="100">
- Anyone:
- </text>
- <check_box
- height="18"
- label="Copy"
- layout="topleft"
- left_pad="0"
- name="CheckEveryoneCopy"
- top_delta="-2"
- width="150" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- left="10"
- name="GroupLabel"
- top_pad="8"
- width="100">
- Group:
- </text>
- <check_box
- height="18"
- label="Share"
- layout="topleft"
- left_pad="0"
- top_delta="-2"
- name="CheckShareWithGroup"
- tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."
- width="150" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- left="10"
- name="NextOwnerLabel"
- top_pad="8"
- width="200"
- word_wrap="true">
- Next owner:
- </text>
- <check_box
- height="18"
- label="Modify"
- layout="topleft"
- left="20"
- top_pad="0"
- name="CheckNextOwnerModify"
- width="90" />
- <check_box
- height="18"
- label="Copy"
- layout="topleft"
- left_pad="0"
- name="CheckNextOwnerCopy"
- width="90" />
- <check_box
- height="18"
- label="Transfer"
- layout="topleft"
- left_pad="0"
- name="CheckNextOwnerTransfer"
- tool_tip="Next owner can give away or resell this object"
- width="106" />
- </panel>
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="NextOwnerLabel"
+ top_pad="8"
+ width="200"
+ word_wrap="true">
+ Next owner:
+ </text>
<check_box
- height="18"
- label="For Sale"
- layout="topleft"
- left="20"
- name="CheckPurchase"
- top_pad="20"
- width="100" />
- <combo_box
- height="23"
- left_pad="0"
- layout="topleft"
- follows="left|top"
- name="combobox sale copy"
- width="170">
- <combo_box.item
- label="Copy"
- name="Copy"
- value="Copy" />
- <combo_box.item
- label="Original"
- name="Original"
- value="Original" />
- </combo_box>
- <spinner
- follows="left|top"
- decimal_digits="0"
- increment="1"
- control_name="Edit Cost"
- name="Edit Cost"
- label="Price: L$"
- label_width="75"
- left="120"
- width="170"
- min_val="0"
- height="23"
- max_val="999999999"
- top_pad="10"/>
- </panel>
- </scroll_container>
- <panel
- height="30"
- layout="topleft"
- name="button_panel"
- left="5"
- top_pad="0"
- width="313">
- <button
- height="23"
- label="Cancel"
- layout="topleft"
- name="cancel_btn"
- right="-1"
- width="100" />
- </panel>
- </panel>
+ height="18"
+ label="Modify"
+ layout="topleft"
+ left="20"
+ top_pad="0"
+ name="CheckNextOwnerModify"
+ width="90" />
+ <check_box
+ height="18"
+ label="Copy"
+ layout="topleft"
+ left_pad="0"
+ name="CheckNextOwnerCopy"
+ width="90" />
+ <check_box
+ height="18"
+ label="Transfer"
+ layout="topleft"
+ left_pad="0"
+ name="CheckNextOwnerTransfer"
+ tool_tip="Next owner can give away or resell this object"
+ width="106" />
+ </panel>
+ <check_box
+ height="18"
+ label="For Sale"
+ layout="topleft"
+ left="20"
+ name="CheckPurchase"
+ top_pad="20"
+ width="100" />
+ <combo_box
+ height="23"
+ left_pad="0"
+ layout="topleft"
+ follows="left|top"
+ name="combobox sale copy"
+ width="170">
+ <combo_box.item
+ label="Copy"
+ name="Copy"
+ value="Copy" />
+ <combo_box.item
+ label="Original"
+ name="Original"
+ value="Original" />
+ </combo_box>
+ <spinner
+ follows="left|top"
+ decimal_digits="0"
+ increment="1"
+ control_name="Edit Cost"
+ name="Edit Cost"
+ label="Price: L$"
+ label_width="75"
+ left="120"
+ width="170"
+ min_val="0"
+ height="23"
+ max_val="999999999"
+ top_pad="10"/>
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="5"
+ name="LabelItemExperienceTitle"
+ top_pad="10"
+ width="78"
+ visible="false">
+ Experience:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="10"
+ layout="topleft"
+ left_delta="78"
+ name="LabelItemExperience"
+ top_delta="0"
+ width="210"
+ visible="false"
+ ></text>
+ </panel>
+
+ </scroll_container>
+ <panel
+ height="30"
+ layout="topleft"
+ name="button_panel"
+ left="5"
+ top_pad="0"
+ width="313"
+ follows="top|right|left">
+ <button
+ follows="top|right"
+ height="23"
+ label="Cancel"
+ layout="topleft"
+ name="cancel_btn"
+ right="-1"
+ width="100" />
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 73601ecb9f..b02d4e5d8f 100755
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3920,6 +3920,10 @@ Try enclosing path to the editor with double quotes.
<!-- Spell check settings floater -->
<string name="UserDictionary">[User]</string>
+ <!-- Experience Tools strings -->
+ <string name="experience_tools_experience">Experience</string>
+
+
<!-- Conversation log messages -->
<string name="logging_calls_disabled_log_empty">
Conversations are not being logged. To begin keeping a log, choose "Save: Log only" or "Save: Log and transcripts" under Preferences > Chat.