summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llrender/llrendertarget.cpp26
-rw-r--r--indra/llrender/llrendertarget.h7
-rw-r--r--indra/llui/llconsole.cpp5
-rw-r--r--indra/llui/llflatlistview.h2
-rw-r--r--indra/llui/llfloater.h1
-rw-r--r--indra/llui/lltextbase.cpp6
-rw-r--r--indra/llui/llurlentry.cpp33
-rw-r--r--indra/llui/llurlentry.h13
-rw-r--r--indra/llui/llurlregistry.cpp1
-rw-r--r--indra/newview/CMakeLists.txt4
-rw-r--r--indra/newview/llagent.cpp6
-rw-r--r--indra/newview/llagent.h2
-rw-r--r--indra/newview/llagentwearables.cpp107
-rw-r--r--indra/newview/llagentwearables.h1
-rw-r--r--indra/newview/llappearancemgr.cpp11
-rw-r--r--indra/newview/llappviewer.cpp9
-rw-r--r--indra/newview/llavataractions.cpp23
-rw-r--r--indra/newview/llavataractions.h5
-rw-r--r--indra/newview/llbottomtray.cpp146
-rw-r--r--indra/newview/llchathistory.cpp27
-rw-r--r--indra/newview/llfloatertools.cpp10
-rw-r--r--indra/newview/llfolderview.cpp10
-rw-r--r--indra/newview/llfolderview.h38
-rw-r--r--indra/newview/llfolderviewitem.cpp54
-rw-r--r--indra/newview/llfolderviewitem.h3
-rw-r--r--indra/newview/llimfloater.cpp6
-rw-r--r--indra/newview/llimview.cpp7
-rw-r--r--indra/newview/llinventorybridge.cpp301
-rw-r--r--indra/newview/llinventorybridge.h4
-rw-r--r--indra/newview/llinventorymodel.cpp27
-rw-r--r--indra/newview/llinventorymodel.h9
-rw-r--r--indra/newview/llinventoryobserver.cpp18
-rw-r--r--indra/newview/llinventoryobserver.h5
-rw-r--r--indra/newview/llinventorypanel.cpp117
-rw-r--r--indra/newview/llinventorypanel.h43
-rwxr-xr-xindra/newview/llmediadataclient.cpp58
-rwxr-xr-xindra/newview/llmediadataclient.h31
-rw-r--r--indra/newview/llpanelavatar.cpp58
-rw-r--r--indra/newview/llpanelavatar.h17
-rw-r--r--indra/newview/llpanelimcontrolpanel.cpp8
-rw-r--r--indra/newview/llpanellogin.cpp6
-rw-r--r--indra/newview/llpanelme.cpp272
-rw-r--r--indra/newview/llpanelme.h111
-rw-r--r--indra/newview/llpanelmediasettingsgeneral.cpp22
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp87
-rw-r--r--indra/newview/llpaneloutfitsinventory.h23
-rw-r--r--indra/newview/llpanelpeople.cpp31
-rw-r--r--indra/newview/llpanelpeople.h4
-rw-r--r--indra/newview/llpanelpicks.h2
-rw-r--r--indra/newview/llpanelprimmediacontrols.cpp2
-rw-r--r--indra/newview/llpanelprofile.cpp18
-rw-r--r--indra/newview/llpanelprofile.h4
-rw-r--r--indra/newview/llpanelprofileview.cpp4
-rw-r--r--indra/newview/llpanelprofileview.h2
-rw-r--r--indra/newview/llpanelteleporthistory.cpp7
-rw-r--r--indra/newview/llpanelteleporthistory.h1
-rw-r--r--indra/newview/llscreenchannel.cpp24
-rw-r--r--indra/newview/llscrollingpanelparam.cpp5
-rw-r--r--indra/newview/llsidepanelappearance.cpp24
-rw-r--r--indra/newview/llsidetray.cpp39
-rw-r--r--indra/newview/llstartup.cpp2
-rw-r--r--indra/newview/lltexlayer.cpp102
-rw-r--r--indra/newview/lltexlayer.h6
-rw-r--r--indra/newview/lltoast.cpp2
-rw-r--r--indra/newview/llviewerinventory.cpp32
-rw-r--r--indra/newview/llviewermedia.cpp6
-rw-r--r--indra/newview/llviewermessage.cpp416
-rw-r--r--indra/newview/llviewermessage.h6
-rw-r--r--indra/newview/llviewerwindow.cpp28
-rw-r--r--indra/newview/llviewerwindow.h1
-rw-r--r--indra/newview/llvoavatar.cpp24
-rw-r--r--indra/newview/llvoavatarself.cpp17
-rw-r--r--indra/newview/llvoavatarself.h1
-rw-r--r--indra/newview/llvovolume.cpp12
-rw-r--r--indra/newview/llvovolume.h2
-rw-r--r--indra/newview/llwearable.cpp12
-rw-r--r--indra/newview/llwearable.h2
-rw-r--r--indra/newview/pipeline.cpp118
-rw-r--r--indra/newview/pipeline.h6
-rw-r--r--indra/newview/skins/default/textures/icons/Stop_Off.pngbin0 -> 148 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/UnZoom_Off.pngbin0 -> 423 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml12
-rw-r--r--indra/newview/skins/default/xui/de/panel_me.xml7
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml15
-rw-r--r--indra/newview/skins/default/xui/en/menu_profile_overflow.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_url_inventory.xml28
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml2
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml36
-rw-r--r--indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_chat_header.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_control_panel.xml7
-rw-r--r--indra/newview/skins/default/xui/en/panel_im_control_panel.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_me.xml52
-rw-r--r--indra/newview/skins/default/xui/en/panel_media_settings_general.xml12
-rw-r--r--indra/newview/skins/default/xui/en/panel_my_profile.xml429
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfits_inventory.xml33
-rw-r--r--indra/newview/skins/default/xui/en/panel_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_prim_media_controls.xml89
-rw-r--r--indra/newview/skins/default/xui/en/panel_side_tray.xml6
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_inventory.xml10
-rw-r--r--indra/newview/skins/default/xui/fr/panel_me.xml7
-rw-r--r--indra/newview/skins/default/xui/ja/panel_me.xml7
-rw-r--r--indra/newview/tests/llmediadataclient_test.cpp93
103 files changed, 2629 insertions, 981 deletions
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index bab5cfd56e..d9520b3bf6 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -61,11 +61,8 @@ BOOL LLRenderTarget::sUseFBO = FALSE;
LLRenderTarget::LLRenderTarget() :
mResX(0),
mResY(0),
- mViewportWidth(0),
- mViewportHeight(0),
mTex(0),
mFBO(0),
- mColorFmt(0),
mDepth(0),
mStencil(0),
mUseDepth(FALSE),
@@ -92,15 +89,10 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOO
stop_glerror();
mResX = resx;
mResY = resy;
- // default viewport to entire texture
- mViewportWidth = mResX;
- mViewportHeight = mResY;
mStencil = stencil;
mUsage = usage;
mUseDepth = depth;
- mFBO = 0;
- mColorFmt = color_fmt;
release();
@@ -320,7 +312,7 @@ void LLRenderTarget::bindTarget()
}
}
- glViewport(0, 0, mViewportWidth, mViewportHeight);
+ glViewport(0, 0, mResX, mResY);
sBoundTarget = this;
}
@@ -523,18 +515,12 @@ BOOL LLRenderTarget::isComplete() const
return (!mTex.empty() || mDepth) ? TRUE : FALSE;
}
-void LLRenderTarget::setViewport(U32 width, U32 height)
-{
- mViewportWidth = llmin(width, mResX);
- mViewportHeight = llmin(height, mResY);
-}
-
void LLRenderTarget::getViewport(S32* viewport)
{
viewport[0] = 0;
viewport[1] = 0;
- viewport[2] = mViewportWidth;
- viewport[3] = mViewportHeight;
+ viewport[2] = mResX;
+ viewport[3] = mResY;
}
//==================================================
@@ -595,7 +581,7 @@ void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref)
check_framebuffer_status();
- glViewport(0, 0, mViewportWidth, mViewportHeight);
+ glViewport(0, 0, mResX, mResY);
sBoundTarget = this;
}
@@ -610,14 +596,10 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth
stop_glerror();
mResX = resx;
mResY = resy;
- mViewportWidth = mResX;
- mViewportHeight = mResY;
mUsage = usage;
mUseDepth = depth;
mStencil = stencil;
- mFBO = 0;
- mColorFmt = color_fmt;
releaseSampleBuffer();
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 125747424c..b7ebfc8f7f 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -107,9 +107,6 @@ public:
//uses scissor rect if in copy-to-texture mode
void clear(U32 mask = 0xFFFFFFFF);
- // override default viewport to a smaller size
- void setViewport(U32 width, U32 height);
-
//get applied viewport
void getViewport(S32* viewport);
@@ -153,16 +150,12 @@ protected:
friend class LLMultisampleBuffer;
U32 mResX;
U32 mResY;
- U32 mViewportWidth;
- U32 mViewportHeight;
std::vector<U32> mTex;
U32 mFBO;
- U32 mColorFmt;
U32 mDepth;
BOOL mStencil;
BOOL mUseDepth;
BOOL mRenderDepth;
-
LLTexUnit::eTextureType mUsage;
U32 mSamples;
LLMultisampleBuffer* mSampleBuffer;
diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp
index 48c76cf105..fa0abd55d0 100644
--- a/indra/llui/llconsole.cpp
+++ b/indra/llui/llconsole.cpp
@@ -392,9 +392,4 @@ void LLConsole::addLine(const LLWString& wline, F32 size, const LLColor4 &color)
Paragraph paragraph(wline, color, mTimer.getElapsedTimeF32(), mFont, (F32)getRect().getWidth() );
mParagraphs.push_back ( paragraph );
-
-#if LL_WINDOWS && LL_LCD_COMPILE
- // add to LCD screen
- AddNewDebugConsoleToLCD(wline);
-#endif
}
diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h
index eac947a0d7..3867e910c0 100644
--- a/indra/llui/llflatlistview.h
+++ b/indra/llui/llflatlistview.h
@@ -50,7 +50,7 @@ class LLTextBox;
* is ignored. The option "keep_one_selected" forces at least one item to be selected at any time (only for mouse events on items)
* since any item of the list was selected.
*
- * Examples of using this control are presented in Picks panel (Me Profile and Profile View), where this control is used to
+ * Examples of using this control are presented in Picks panel (My Profile and Profile View), where this control is used to
* manage the list of pick items.
*
* ASSUMPTIONS AND STUFF
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 42d3240c0a..d7ec0aac00 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -197,6 +197,7 @@ public:
/// The static isShown() can accept a NULL pointer (which of course
/// returns false). When non-NULL, it calls the non-static isShown().
static bool isShown(const LLFloater* floater);
+ BOOL isFirstLook() { return mFirstLook; } // EXT-2653: This function is necessary to prevent overlapping for secondary showed toasts
BOOL isFrontmost();
BOOL isDependent() { return !mDependeeHandle.isDead(); }
void setCanMinimize(BOOL can_minimize);
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 3619b36c0d..7bf10d774c 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -2065,16 +2065,16 @@ void LLTextBase::updateRects()
mContentsRect.unionWith(line_iter->mRect);
}
- mContentsRect.mLeft = 0;
+ S32 delta_pos_x = -mContentsRect.mLeft;
mContentsRect.mTop += mVPad;
S32 delta_pos = -mContentsRect.mBottom;
// move line segments to fit new document rect
for (line_list_t::iterator it = mLineInfoList.begin(); it != mLineInfoList.end(); ++it)
{
- it->mRect.translate(0, delta_pos);
+ it->mRect.translate(delta_pos_x, delta_pos);
}
- mContentsRect.translate(0, delta_pos);
+ mContentsRect.translate(delta_pos_x, delta_pos);
}
// update document container dimensions according to text contents
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 219fae84be..b51709e208 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -34,6 +34,7 @@
#include "linden_common.h"
#include "llurlentry.h"
#include "lluri.h"
+
#include "llcachename.h"
#include "lltrans.h"
#include "lluicolortable.h"
@@ -383,6 +384,38 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa
}
}
+//
+// LLUrlEntryInventory Describes a Second Life inventory Url, e.g.,
+// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select
+//
+LLUrlEntryInventory::LLUrlEntryInventory()
+{
+ mPattern = boost::regex("secondlife:///app/inventory/[\\da-f-]+/\\w+",
+ boost::regex::perl|boost::regex::icase);
+ mMenuName = "menu_url_inventory.xml";
+}
+
+std::string LLUrlEntryInventory::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+ return unescapeUrl(url);
+ // TODO: Figure out if we can somehow access the inventory from here to get the actual item name
+ /*
+ std::string inventory_id_string = getIDStringFromUrl(url);
+ if (inventory_id_string.empty())
+ {
+ // something went wrong, give raw url
+ return unescapeUrl(url);
+ }
+ LLUUID inventory_id(inventory_id_string);
+ LLInventoryItem* item = gInventory.getItem(inventory_id);
+ if(!item)
+ {
+ return unescapeUrl(url);
+ }
+ return item->getName(); */
+}
+
+
///
/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 7970b48eb5..b3fb333fdd 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -174,6 +174,19 @@ private:
};
///
+/// LLUrlEntryInventory Describes a Second Life inventory Url, e.g.,
+/// secondlife:///app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select
+///
+class LLUrlEntryInventory : public LLUrlEntryBase
+{
+public:
+ LLUrlEntryInventory();
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+private:
+};
+
+
+///
/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
///
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index a6922b019b..b2f084e5ac 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -55,6 +55,7 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(new LLUrlEntryPlace());
registerUrl(new LLUrlEntrySL());
registerUrl(new LLUrlEntrySLLabel());
+ registerUrl(new LLUrlEntryInventory());
}
LLUrlRegistry::~LLUrlRegistry()
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 611875a1e2..e632cbaaf2 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -325,7 +325,7 @@ set(viewer_SOURCE_FILES
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
llpanelmediasettingssecurity.cpp
- llpanelmeprofile.cpp
+ llpanelme.cpp
llpanelobject.cpp
llpanelobjectinventory.cpp
llpaneloutfitsinventory.cpp
@@ -821,7 +821,7 @@ set(viewer_HEADER_FILES
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
llpanelmediasettingssecurity.h
- llpanelmeprofile.h
+ llpanelme.h
llpanelobject.h
llpanelobjectinventory.h
llpaneloutfitsinventory.h
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 7034066669..2b582c90f0 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -735,6 +735,10 @@ BOOL LLAgent::canFly()
return parcel->getAllowFly();
}
+BOOL LLAgent::getFlying() const
+{
+ return mControlFlags & AGENT_CONTROL_FLY;
+}
//-----------------------------------------------------------------------------
// setFlying()
@@ -792,7 +796,7 @@ void LLAgent::setFlying(BOOL fly)
// static
void LLAgent::toggleFlying()
{
- BOOL fly = !(gAgent.mControlFlags & AGENT_CONTROL_FLY);
+ BOOL fly = !gAgent.getFlying();
gAgent.setFlying( fly );
gAgent.resetView();
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 4162dfce1e..2e95dc72be 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -310,7 +310,7 @@ private:
// Fly
//--------------------------------------------------------------------
public:
- BOOL getFlying() const { return mControlFlags & AGENT_CONTROL_FLY; }
+ BOOL getFlying() const;
void setFlying(BOOL fly);
static void toggleFlying();
static bool enableFlying();
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index f6cdc9ac02..18a8396451 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -676,7 +676,7 @@ void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearab
{
wearable_vec[index] = wearable;
old_wearable->setLabelUpdated();
- mAvatarObject->wearableUpdated(wearable->getType());
+ wearableUpdated(wearable);
}
}
@@ -691,13 +691,32 @@ U32 LLAgentWearables::pushWearable(const EWearableType type, LLWearable *wearabl
if (type < WT_COUNT || mWearableDatas[type].size() < MAX_WEARABLES_PER_TYPE)
{
mWearableDatas[type].push_back(wearable);
- mAvatarObject->wearableUpdated(wearable->getType());
- wearable->setLabelUpdated();
+ wearableUpdated(wearable);
return mWearableDatas[type].size()-1;
}
return MAX_WEARABLES_PER_TYPE;
}
+void LLAgentWearables::wearableUpdated(LLWearable *wearable)
+{
+ mAvatarObject->wearableUpdated(wearable->getType());
+ wearable->setLabelUpdated();
+
+ // Hack pt 2. If the wearable we just loaded has definition version 24,
+ // then force a re-save of this wearable after slamming the version number to 22.
+ // This number was incorrectly incremented for internal builds before release, and
+ // this fix will ensure that the affected wearables are re-saved with the right version number.
+ // the versions themselves are compatible. This code can be removed before release.
+ if( wearable->getDefinitionVersion() == 24 )
+ {
+ wearable->setDefinitionVersion(22);
+ U32 index = getWearableIndex(wearable);
+ llinfos << "forcing werable type " << wearable->getType() << " to version 22 from 24" << llendl;
+ saveWearable(wearable->getType(),index,TRUE);
+ }
+
+}
+
void LLAgentWearables::popWearable(LLWearable *wearable)
{
if (wearable == NULL)
@@ -1529,7 +1548,6 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
gInventory.notifyObservers();
- queryWearableCache();
std::vector<LLWearable*>::iterator wearable_iter;
@@ -1552,6 +1570,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
// Start rendering & update the server
mWearablesLoaded = TRUE;
checkWearablesLoaded();
+ queryWearableCache();
updateServer();
lldebugs << "setWearableOutfit() end" << llendl;
@@ -2156,7 +2175,6 @@ void LLLibraryOutfitsFetch::contentsDone(void)
LLInitialWearablesFetch::~LLInitialWearablesFetch()
{
- llinfos << "~LLInitialWearablesFetch" << llendl;
}
// virtual
@@ -2186,17 +2204,50 @@ void LLInitialWearablesFetch::processContents()
else
{
processWearablesMessage();
- // Create links for attachments that may have arrived before the COF existed.
- LLAppearanceManager::instance().linkRegisteredAttachments();
}
delete this;
}
+class LLFetchAndLinkObserver: public LLInventoryFetchObserver
+{
+public:
+ LLFetchAndLinkObserver(LLInventoryFetchObserver::item_ref_t& ids):
+ m_ids(ids),
+ LLInventoryFetchObserver(true)
+ {
+ }
+ ~LLFetchAndLinkObserver()
+ {
+ }
+ virtual void done()
+ {
+ gInventory.removeObserver(this);
+ // Link to all fetched items in COF.
+ for (LLInventoryFetchObserver::item_ref_t::iterator it = m_ids.begin();
+ it != m_ids.end();
+ ++it)
+ {
+ LLUUID id = *it;
+ LLViewerInventoryItem *item = gInventory.getItem(*it);
+ if (!item)
+ {
+ llwarns << "fetch failed!" << llendl;
+ continue;
+ }
+ link_inventory_item(gAgent.getID(), item->getLinkedUUID(), LLAppearanceManager::instance().getCOF(), item->getName(),
+ LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
+ }
+ }
+private:
+ LLInventoryFetchObserver::item_ref_t m_ids;
+};
+
void LLInitialWearablesFetch::processWearablesMessage()
{
if (!mAgentInitialWearables.empty()) // We have an empty current outfit folder, use the message data instead.
{
- const LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+ const LLUUID current_outfit_id = LLAppearanceManager::instance().getCOF();
+ LLInventoryFetchObserver::item_ref_t ids;
for (U8 i = 0; i < mAgentInitialWearables.size(); ++i)
{
// Populate the current outfit folder with links to the wearables passed in the message
@@ -2205,9 +2256,7 @@ void LLInitialWearablesFetch::processWearablesMessage()
if (wearable_data->mAssetID.notNull())
{
#ifdef USE_CURRENT_OUTFIT_FOLDER
- const std::string link_name = "WearableLink"; // Unimportant what this is named, it isn't exposed.
- link_inventory_item(gAgent.getID(), wearable_data->mItemID, current_outfit_id, link_name,
- LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
+ ids.push_back(wearable_data->mItemID);
#endif
// Fetch the wearables
LLWearableList::instance().getAsset(wearable_data->mAssetID,
@@ -2221,6 +2270,42 @@ void LLInitialWearablesFetch::processWearablesMessage()
<< wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl;
}
}
+
+ // Add all current attachments to the requested items as well.
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
+ if( avatar )
+ {
+ for (LLVOAvatar::attachment_map_t::const_iterator iter = avatar->mAttachmentPoints.begin();
+ iter != avatar->mAttachmentPoints.end(); ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (!attachment) continue;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = (*attachment_iter);
+ if (!attached_object) continue;
+ const LLUUID& item_id = attached_object->getItemID();
+ if (item_id.isNull()) continue;
+ ids.push_back(item_id);
+ }
+ }
+ }
+
+ // Need to fetch the inventory items for ids, then create links to them after they arrive.
+ LLFetchAndLinkObserver *fetcher = new LLFetchAndLinkObserver(ids);
+ fetcher->fetchItems(ids);
+ // If no items to be fetched, done will never be triggered.
+ // TODO: Change LLInventoryFetchObserver::fetchItems to trigger done() on this condition.
+ if (fetcher->isEverythingComplete())
+ {
+ fetcher->done();
+ }
+ else
+ {
+ gInventory.addObserver(fetcher);
+ }
}
else
{
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 8f3a16501e..b4f58674af 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -107,6 +107,7 @@ private:
// Low-level data structure setter - public access is via setWearableItem, etc.
void setWearable(const EWearableType type, U32 index, LLWearable *wearable);
U32 pushWearable(const EWearableType type, LLWearable *wearable);
+ void wearableUpdated(LLWearable *wearable);
void popWearable(LLWearable *wearable);
void popWearable(const EWearableType type, U32 index);
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 8964c20c1c..c7f05d99f7 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -559,10 +559,9 @@ void LLAppearanceManager::updateCOF(const LLUUID& category, bool append)
linkAll(cof, obj_items, link_waiter);
linkAll(cof, gest_items, link_waiter);
- // Add link to outfit if category is an outfit.
- const LLViewerInventoryCategory* catp = gInventory.getCategory(category);
LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance *>(LLSideTray::getInstance()->getPanel("sidepanel_appearance"));
-
+ // Add link to outfit if category is an outfit.
+ LLViewerInventoryCategory* catp = gInventory.getCategory(category);
if (!append && catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
{
link_inventory_item(gAgent.getID(), category, cof, catp->getName(),
@@ -576,10 +575,9 @@ void LLAppearanceManager::updateCOF(const LLUUID& category, bool append)
}
else
{
- // Update the current outfit name of the appearance sidepanel.
if (panel_appearance)
{
- panel_appearance->refreshCurrentOutfitName();
+ panel_appearance->refreshCurrentOutfitName("");
}
}
}
@@ -858,7 +856,7 @@ bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventor
void LLAppearanceManager::addCOFItemLink(const LLUUID &item_id, bool do_update )
{
const LLInventoryItem *item = gInventory.getItem(item_id);
- addCOFItemLink(item);
+ addCOFItemLink(item, do_update);
}
void LLAppearanceManager::addCOFItemLink(const LLInventoryItem *item, bool do_update )
@@ -1029,7 +1027,6 @@ void LLAppearanceManager::registerAttachment(const LLUUID& item_id)
if (mAttachmentInvLinkEnabled)
{
- //LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Adding attachment link:");
LLAppearanceManager::addCOFItemLink(item_id, false); // Add COF link for item.
}
else
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 799a09540e..f196ebbf93 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -801,13 +801,6 @@ bool LLAppViewer::init()
// call all self-registered classes
LLInitClassList::instance().fireCallbacks();
- #if LL_LCD_COMPILE
- // start up an LCD window on a logitech keyboard, if there is one
- HINSTANCE hInstance = GetModuleHandle(NULL);
- gLcdScreen = new LLLCD(hInstance);
- CreateLCDDebugWindows();
-#endif
-
LLFolderViewItem::initClass(); // SJB: Needs to happen after initWindow(), not sure why but related to fonts
gGLManager.getGLInfo(gDebugInfo);
@@ -3555,7 +3548,7 @@ void LLAppViewer::idle()
gEventNotifier.update();
gIdleCallbacks.callFunctions();
- gInventory.notifyObservers();
+ gInventory.idleNotifyObservers();
}
if (gDisconnected)
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 43b8fd8adb..a7a6da3ac2 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -298,7 +298,7 @@ void LLAvatarActions::showProfile(const LLUUID& id)
//Show own profile
if(gAgent.getID() == id)
{
- LLSideTray::getInstance()->showPanel("panel_me_profile", params);
+ LLSideTray::getInstance()->showPanel("panel_me", params);
}
//Show other user profile
else
@@ -325,6 +325,27 @@ void LLAvatarActions::pay(const LLUUID& id)
}
}
+//static
+void LLAvatarActions::share(const LLUUID& id)
+{
+ LLSD key;
+ LLSideTray::getInstance()->showPanel("sidepanel_inventory", key);
+
+
+ LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL,id);
+
+ if (!gIMMgr->hasSession(session_id))
+ {
+ startIM(id);
+ }
+
+ if (gIMMgr->hasSession(session_id))
+ {
+ // we should always get here, but check to verify anyways
+ LLIMModel::getInstance()->addMessage(session_id, SYSTEM_FROM, LLUUID::null, LLTrans::getString("share_alert"), false);
+ }
+}
+
// static
void LLAvatarActions::toggleBlock(const LLUUID& id)
{
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index d9dab95a77..4c9851a48d 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -104,6 +104,11 @@ public:
static void pay(const LLUUID& id);
/**
+ * Share items with the avatar.
+ */
+ static void share(const LLUUID& id);
+
+ /**
* Block/unblock the avatar.
*/
static void toggleBlock(const LLUUID& id);
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 9cc7b8c785..cbf7107b7e 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -331,31 +331,31 @@ BOOL LLBottomTray::postBuild()
void LLBottomTray::log(LLView* panel, const std::string& descr)
{
if (NULL == panel) return;
- LLView* layout = panel->getParent();
- lldebugs << descr << ": "
- << "panel: " << panel->getName()
- << ", rect: " << panel->getRect()
-
-
- << "layout: " << layout->getName()
- << ", rect: " << layout->getRect()
- << llendl
- ;
+ //LLView* layout = panel->getParent();
+ //lldebugs << descr << ": "
+ // << "panel: " << panel->getName()
+ // << ", rect: " << panel->getRect()
+ //
+ //
+ // << "layout: " << layout->getName()
+ // << ", rect: " << layout->getRect()
+ // << llendl
+ // ;
}
void LLBottomTray::reshape(S32 width, S32 height, BOOL called_from_parent)
{
static S32 debug_calling_number = 0;
- lldebugs << "**************************************** " << ++debug_calling_number << llendl;
+ //lldebugs << "**************************************** " << ++debug_calling_number << llendl;
S32 current_width = getRect().getWidth();
S32 delta_width = width - current_width;
- lldebugs << "Reshaping: "
- << ", width: " << width
- << ", cur width: " << current_width
- << ", delta_width: " << delta_width
- << ", called_from_parent: " << called_from_parent
- << llendl;
+ //lldebugs << "Reshaping: "
+ // << ", width: " << width
+ // << ", cur width: " << current_width
+ // << ", delta_width: " << delta_width
+ // << ", called_from_parent: " << called_from_parent
+ // << llendl;
if (mNearbyChatBar) log(mNearbyChatBar, "before");
if (mChicletPanel) log(mChicletPanel, "before");
@@ -412,7 +412,7 @@ void LLBottomTray::reshape(S32 width, S32 height, BOOL called_from_parent)
if (should_be_reshaped)
{
- lldebugs << "Reshape all children with width: " << width << llendl;
+ //lldebugs << "Reshape all children with width: " << width << llendl;
LLPanel::reshape(width, height, called_from_parent);
}
@@ -434,10 +434,10 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width)
S32 delta_panel = llmin(-delta_width, panel_delta_min);
- lldebugs << "delta_width: " << delta_width
- << ", panel_delta_min: " << panel_delta_min
- << ", delta_panel: " << delta_panel
- << llendl;
+ //lldebugs << "delta_width: " << delta_width
+ // << ", panel_delta_min: " << panel_delta_min
+ // << ", delta_panel: " << delta_panel
+ // << llendl;
// is chiclet panel width enough to process resizing?
delta_width += panel_delta_min;
@@ -447,9 +447,9 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width)
mChicletPanel->getParent()->reshape(mChicletPanel->getParent()->getRect().getWidth() - delta_panel, mChicletPanel->getParent()->getRect().getHeight());
log(mChicletPanel, "after processing panel decreasing via chiclet panel");
- lldebugs << "RS_CHICLET_PANEL"
- << ", delta_width: " << delta_width
- << llendl;
+ //lldebugs << "RS_CHICLET_PANEL"
+ // << ", delta_width: " << delta_width
+ // << llendl;
}
const S32 chatbar_panel_width = mNearbyChatBar->getRect().getWidth();
@@ -470,10 +470,10 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width)
log(mChicletPanel, "after processing panel decreasing via nearby chatbar panel");
- lldebugs << "RS_CHATBAR_INPUT"
- << ", delta_panel: " << delta_panel
- << ", delta_width: " << delta_width
- << llendl;
+ //lldebugs << "RS_CHATBAR_INPUT"
+ // << ", delta_panel: " << delta_panel
+ // << ", delta_width: " << delta_width
+ // << llendl;
}
S32 extra_shrink_width = 0;
@@ -514,7 +514,7 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width)
log(mNearbyChatBar, "before applying compensative width");
mNearbyChatBar->reshape(mNearbyChatBar->getRect().getWidth() + buttons_freed_width, mNearbyChatBar->getRect().getHeight() );
log(mNearbyChatBar, "after applying compensative width");
- lldebugs << buttons_freed_width << llendl;
+ //lldebugs << buttons_freed_width << llendl;
}
}
@@ -538,11 +538,11 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
// how many room we have to show hidden buttons
S32 total_available_width = delta_width + chatbar_available_shrink_width + available_width_chiclet;
- lldebugs << "Processing extending, available width:"
- << ", chatbar - " << chatbar_available_shrink_width
- << ", chiclets - " << available_width_chiclet
- << ", total - " << total_available_width
- << llendl;
+ //lldebugs << "Processing extending, available width:"
+ // << ", chatbar - " << chatbar_available_shrink_width
+ // << ", chiclets - " << available_width_chiclet
+ // << ", total - " << total_available_width
+ // << llendl;
S32 available_width = total_available_width;
if (available_width > 0)
@@ -587,7 +587,7 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
log(mNearbyChatBar, "increase width: before applying compensative width");
mNearbyChatBar->reshape(mNearbyChatBar->getRect().getWidth() - chatbar_shrink_width, mNearbyChatBar->getRect().getHeight() );
if (mNearbyChatBar) log(mNearbyChatBar, "after applying compensative width");
- lldebugs << chatbar_shrink_width << llendl;
+ //lldebugs << chatbar_shrink_width << llendl;
// 3. use width available via decreasing of chiclet panel
required_to_process_width -= chatbar_shrink_width;
@@ -596,7 +596,7 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
{
mChicletPanel->getParent()->reshape(mChicletPanel->getParent()->getRect().getWidth() - required_to_process_width, mChicletPanel->getParent()->getRect().getHeight());
log(mChicletPanel, "after applying compensative width for chiclets: ");
- lldebugs << required_to_process_width << llendl;
+ //lldebugs << required_to_process_width << llendl;
}
}
@@ -611,10 +611,10 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
{
S32 delta_panel_max = chatbar_panel_max_width - chatbar_panel_width_;
S32 delta_panel = llmin(delta_width, delta_panel_max);
- lldebugs << "Unprocesed delta width: " << delta_width
- << ", can be applied to chatbar: " << delta_panel_max
- << ", will be applied: " << delta_panel
- << llendl;
+ //lldebugs << "Unprocesed delta width: " << delta_width
+ // << ", can be applied to chatbar: " << delta_panel_max
+ // << ", will be applied: " << delta_panel
+ // << llendl;
delta_width -= delta_panel_max;
mNearbyChatBar->reshape(chatbar_panel_width_ + delta_panel, mNearbyChatBar->getRect().getHeight());
@@ -624,12 +624,12 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32* available_width)
{
- lldebugs << "Trying to show object type: " << shown_object_type << llendl;
+ //lldebugs << "Trying to show object type: " << shown_object_type << llendl;
LLPanel* panel = mStateProcessedObjectMap[shown_object_type];
if (NULL == panel)
{
- lldebugs << "There is no object to process for state: " << shown_object_type << llendl;
+ //lldebugs << "There is no object to process for state: " << shown_object_type << llendl;
return false;
}
bool can_be_shown = canButtonBeShown(shown_object_type);
@@ -644,9 +644,9 @@ bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32* availa
setTrayButtonVisible(shown_object_type, true);
- lldebugs << "processed object type: " << shown_object_type
- << ", rest available width: " << *available_width
- << llendl;
+ //lldebugs << "processed object type: " << shown_object_type
+ //<< ", rest available width: " << *available_width
+ //<< llendl;
mResizeState &= ~shown_object_type;
}
}
@@ -655,12 +655,12 @@ bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32* availa
void LLBottomTray::processHideButton(EResizeState processed_object_type, S32* required_width, S32* buttons_freed_width)
{
- lldebugs << "Trying to hide object type: " << processed_object_type << llendl;
+ //lldebugs << "Trying to hide object type: " << processed_object_type << llendl;
LLPanel* panel = mStateProcessedObjectMap[processed_object_type];
if (NULL == panel)
{
- lldebugs << "There is no object to process for state: " << processed_object_type << llendl;
+ //lldebugs << "There is no object to process for state: " << processed_object_type << llendl;
return;
}
@@ -677,9 +677,9 @@ void LLBottomTray::processHideButton(EResizeState processed_object_type, S32* re
mResizeState |= processed_object_type;
- lldebugs << "processing object type: " << processed_object_type
- << ", buttons_freed_width: " << *buttons_freed_width
- << llendl;
+ //lldebugs << "processing object type: " << processed_object_type
+ // << ", buttons_freed_width: " << *buttons_freed_width
+ // << llendl;
}
}
@@ -703,7 +703,7 @@ void LLBottomTray::processShrinkButtons(S32* required_width, S32* buttons_freed_
bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width, NULL);
if (!success)
{
- lldebugs << "Panel was not found to get its min width: " << panel_name << llendl;
+ //lldebugs << "Panel was not found to get its min width: " << panel_name << llendl;
}
else
{
@@ -723,10 +723,10 @@ void LLBottomTray::processShrinkButtons(S32* required_width, S32* buttons_freed_
*buttons_freed_width += *required_width;
}
- lldebugs << "Shrunk panel: " << panel_name
- << ", shrunk width: " << possible_shrink_width
- << ", rest width to process: " << *required_width
- << llendl;
+ //lldebugs << "Shrunk panel: " << panel_name
+ // << ", shrunk width: " << possible_shrink_width
+ // << ", rest width to process: " << *required_width
+ // << llendl;
}
}
}
@@ -737,7 +737,7 @@ void LLBottomTray::processShrinkButton(EResizeState processed_object_type, S32*
LLPanel* panel = mStateProcessedObjectMap[processed_object_type];
if (NULL == panel)
{
- lldebugs << "There is no object to process for type: " << processed_object_type << llendl;
+// lldebugs << "There is no object to process for type: " << processed_object_type << llendl;
return;
}
@@ -751,7 +751,7 @@ void LLBottomTray::processShrinkButton(EResizeState processed_object_type, S32*
if (!success)
{
- lldebugs << "Panel was not found to get its min width: " << panel_name << llendl;
+ //lldebugs << "Panel was not found to get its min width: " << panel_name << llendl;
}
// we have some space to free by shrinking the button
else if (possible_shrink_width > 0)
@@ -770,10 +770,10 @@ void LLBottomTray::processShrinkButton(EResizeState processed_object_type, S32*
}
panel->reshape(panel_width - possible_shrink_width, panel->getRect().getHeight());
- lldebugs << "Shrunk panel: " << panel_name
- << ", shrunk width: " << possible_shrink_width
- << ", rest width to process: " << *required_width
- << llendl;
+ //lldebugs << "Shrunk panel: " << panel_name
+ // << ", shrunk width: " << possible_shrink_width
+ // << ", rest width to process: " << *required_width
+ // << llendl;
}
}
}
@@ -807,10 +807,10 @@ void LLBottomTray::processExtendButtons(S32* available_width)
*available_width -= possible_extend_width;
- lldebugs << "Extending panel: " << mSpeakPanel->getName()
- << ", extended width: " << possible_extend_width
- << ", rest width to process: " << *available_width
- << llendl;
+ //lldebugs << "Extending panel: " << mSpeakPanel->getName()
+ // << ", extended width: " << possible_extend_width
+ // << ", rest width to process: " << *available_width
+ // << llendl;
}
}
}
@@ -820,7 +820,7 @@ void LLBottomTray::processExtendButton(EResizeState processed_object_type, S32*
LLPanel* panel = mStateProcessedObjectMap[processed_object_type];
if (NULL == panel)
{
- lldebugs << "There is no object to process for type: " << processed_object_type << llendl;
+ //lldebugs << "There is no object to process for type: " << processed_object_type << llendl;
return;
}
@@ -846,10 +846,10 @@ void LLBottomTray::processExtendButton(EResizeState processed_object_type, S32*
}
panel->reshape(panel_width + possible_extend_width, panel->getRect().getHeight());
- lldebugs << "Extending panel: " << panel->getName()
- << ", extended width: " << possible_extend_width
- << ", rest width to process: " << *available_width
- << llendl;
+ //lldebugs << "Extending panel: " << panel->getName()
+ // << ", extended width: " << possible_extend_width
+ // << ", rest width to process: " << *available_width
+ // << llendl;
}
}
@@ -895,7 +895,7 @@ void LLBottomTray::setTrayButtonVisible(EResizeState shown_object_type, bool vis
LLPanel* panel = mStateProcessedObjectMap[shown_object_type];
if (NULL == panel)
{
- lldebugs << "There is no object to show for state: " << shown_object_type << llendl;
+ //lldebugs << "There is no object to show for state: " << shown_object_type << llendl;
return;
}
@@ -911,7 +911,7 @@ void LLBottomTray::setTrayButtonVisibleIfPossible(EResizeState shown_object_type
LLPanel* panel = mStateProcessedObjectMap[shown_object_type];
if (NULL == panel)
{
- lldebugs << "There is no object to process for state: " << shown_object_type << llendl;
+ //lldebugs << "There is no object to process for state: " << shown_object_type << llendl;
return;
}
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index cd0456b308..2c9b38b82a 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -199,10 +199,8 @@ public:
userName->setValue(SL);
}
+ setTimeField(chat.mTimeStr);
- LLUICtrl* timeBox = getChild<LLUICtrl>("time_box");
- timeBox->setValue(chat.mTimeStr);
-
LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon");
if(mSourceType != CHAT_SOURCE_AGENT)
@@ -268,7 +266,28 @@ protected:
}
}
-
+private:
+ void setTimeField(const std::string& time_value)
+ {
+ LLTextBox* time_box = getChild<LLTextBox>("time_box");
+
+ LLRect rect_before = time_box->getRect();
+ time_box->setValue(time_value);
+
+ // set necessary textbox width to fit all text
+ time_box->reshapeToFitText();
+ LLRect rect_after = time_box->getRect();
+
+ // move rect to the left to correct position...
+ S32 delta_pos_x = rect_before.getWidth() - rect_after.getWidth();
+ S32 delta_pos_y = rect_before.getHeight() - rect_after.getHeight();
+ time_box->translate(delta_pos_x, delta_pos_y);
+
+ //... & change width of the name control
+ LLTextBox* user_name = getChild<LLTextBox>("user_name");
+ const LLRect& user_rect = user_name->getRect();
+ user_name->reshape(user_rect.getWidth() + delta_pos_x, user_rect.getHeight());
+ }
protected:
LLHandle<LLView> mPopupMenuHandleAvatar;
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index d683c697f4..6ba032c152 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -565,7 +565,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
mBtnEdit ->setToggleState( edit_visible );
mRadioGroupEdit->setVisible( edit_visible );
- childSetVisible("RenderingCost", edit_visible || focus_visible || move_visible);
+ bool linked_parts = gSavedSettings.getBOOL("EditLinkedParts");
+ childSetVisible("RenderingCost", !linked_parts && (edit_visible || focus_visible || move_visible));
if (mCheckSelectIndividual)
{
@@ -977,6 +978,8 @@ void LLFloaterTools::onClickGridOptions()
S32 LLFloaterTools::calcRenderCost()
{
S32 cost = 0;
+ std::set<LLUUID> textures;
+
for (LLObjectSelection::iterator selection_iter = LLSelectMgr::getInstance()->getSelection()->begin();
selection_iter != LLSelectMgr::getInstance()->getSelection()->end();
++selection_iter)
@@ -987,11 +990,14 @@ S32 LLFloaterTools::calcRenderCost()
LLVOVolume *viewer_volume = (LLVOVolume*)select_node->getObject();
if (viewer_volume)
{
- cost += viewer_volume->getRenderCost();
+ cost += viewer_volume->getRenderCost(textures);
+ cost += textures.size() * 5;
+ textures.clear();
}
}
}
+
return cost;
}
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 955bc64e05..ab49739d58 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -39,11 +39,13 @@
#include "llinventoryclipboard.h" // *TODO: remove this once hack below gone.
#include "llinventoryfilter.h"
#include "llinventoryfunctions.h"
+#include "llinventorypanel.h"
#include "llfoldertype.h"
#include "llfloaterinventory.h"// hacked in for the bonus context menu items.
#include "llkeyboard.h"
#include "lllineeditor.h"
#include "llmenugl.h"
+#include "llpanel.h"
#include "llpreview.h"
#include "llscrollcontainer.h" // hack to allow scrolling
#include "lltooldraganddrop.h"
@@ -2014,6 +2016,14 @@ static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory");
// Main idle routine
void LLFolderView::doIdle()
{
+ // If this is associated with the user's inventory, don't do anything
+ // until that inventory is loaded up.
+ const LLInventoryPanel *inventory_panel = dynamic_cast<LLInventoryPanel*>(mParentPanel);
+ if (inventory_panel && !inventory_panel->getIsViewsInitialized())
+ {
+ return;
+ }
+
LLFastTimer t2(FTM_INVENTORY);
BOOL debug_filters = gSavedSettings.getBOOL("DebugInventoryFilters");
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 0bd65b5f90..a0e252ae88 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -41,25 +41,27 @@
#ifndef LL_LLFOLDERVIEW_H
#define LL_LLFOLDERVIEW_H
-// JAMESDEBUG - trim this list
-#include <vector>
-#include <map>
-#include <deque>
-#include <boost/function.hpp>
-#include <boost/signals2.hpp>
+#include "llfolderviewitem.h" // because LLFolderView is-a LLFolderViewFolder
#include "lluictrl.h"
#include "v4color.h"
#include "lldarray.h"
-//#include "llviewermenu.h"
#include "stdenums.h"
-#include "llfontgl.h"
-#include "lleditmenuhandler.h"
-#include "llviewertexture.h"
#include "lldepthstack.h"
+#include "lleditmenuhandler.h"
+#include "llfontgl.h"
#include "lltooldraganddrop.h"
-// JAMESDEBUG - move this up
-#include "llfolderviewitem.h" // because LLFolderView is-a LLFolderViewFolder
+#include "llviewertexture.h"
+
+class LLFolderViewEventListener;
+class LLFolderViewFolder;
+class LLFolderViewItem;
+class LLInventoryModel;
+class LLPanel;
+class LLLineEditor;
+class LLMenuGL;
+class LLScrollContainer;
+class LLUICtrl;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFolderViewFunctor
@@ -70,8 +72,7 @@
// that later when it's determined to be too slow.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLFolderViewItem;
-class LLFolderViewFolder;
+
class LLFolderViewFunctor
{
@@ -89,13 +90,6 @@ public:
// manages the screen region of the folder view.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLFolderViewEventListener;
-class LLInventoryModel;
-class LLLineEditor;
-class LLMenuGL;
-class LLScrollContainer;
-class LLUICtrl;
-
class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
{
public:
@@ -330,7 +324,7 @@ protected:
LLUUID mSelectThisID; // if non null, select this item
- LLPanel* mParentPanel;
+ LLPanel* mParentPanel;
/**
* Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll.
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index a1260d1156..63511301b3 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -38,12 +38,12 @@
#include "llfoldervieweventlistener.h"
#include "llinventorybridge.h" // for LLItemBridge in LLInventorySort::operator()
#include "llinventoryfilter.h"
+#include "llpanel.h"
#include "llviewercontrol.h" // gSavedSettings
#include "llviewerwindow.h" // Argh, only for setCursor()
// linden library includes
#include "llfocusmgr.h" // gFocusMgr
-#include "llpanel.h" // panel->hasFocus()
#include "lltrans.h"
///----------------------------------------------------------------------------
@@ -1290,9 +1290,10 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
// now query children
for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
+ iter != mFolders.end();
+ ++iter)
{
- folders_t::iterator fit = iter++;
+ LLFolderViewFolder* folder = (*iter);
// have we run out of iterations this frame?
if (filter.getFilterCount() < 0)
{
@@ -1302,15 +1303,15 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
// mMostFilteredDescendantGeneration might have been reset
// in which case we need to update it even for folders that
// don't need to be filtered anymore
- if ((*fit)->getCompletedFilterGeneration() >= filter_generation)
+ if (folder->getCompletedFilterGeneration() >= filter_generation)
{
// track latest generation to pass any child items
- if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter.getMinRequiredGeneration()))
+ if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getMinRequiredGeneration()))
{
mMostFilteredDescendantGeneration = filter_generation;
if (getRoot()->needsAutoSelect() && autoopen_folders)
{
- (*fit)->setOpenArrangeRecursively(TRUE);
+ folder->setOpenArrangeRecursively(TRUE);
}
}
// just skip it, it has already been filtered
@@ -1318,48 +1319,49 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
}
// update this folders filter status (and children)
- (*fit)->filter( filter );
+ folder->filter( filter );
// track latest generation to pass any child items
- if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter_generation))
+ if (folder->getFiltered() || folder->hasFilteredDescendants(filter_generation))
{
mMostFilteredDescendantGeneration = filter_generation;
if (getRoot()->needsAutoSelect() && autoopen_folders)
{
- (*fit)->setOpenArrangeRecursively(TRUE);
+ folder->setOpenArrangeRecursively(TRUE);
}
}
}
for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
+ iter != mItems.end();
+ ++iter)
{
- items_t::iterator iit = iter++;
+ LLFolderViewItem* item = (*iter);
if (filter.getFilterCount() < 0)
{
break;
}
- if ((*iit)->getLastFilterGeneration() >= filter_generation)
+ if (item->getLastFilterGeneration() >= filter_generation)
{
- if ((*iit)->getFiltered())
+ if (item->getFiltered())
{
mMostFilteredDescendantGeneration = filter_generation;
}
continue;
}
- if ((*iit)->getLastFilterGeneration() >= must_pass_generation &&
- !(*iit)->getFiltered(must_pass_generation))
+ if (item->getLastFilterGeneration() >= must_pass_generation &&
+ !item->getFiltered(must_pass_generation))
{
// failed to pass an earlier filter that was a subset of the current one
// go ahead and flag this item as done
- (*iit)->setFiltered(FALSE, filter_generation);
+ item->setFiltered(FALSE, filter_generation);
continue;
}
- (*iit)->filter( filter );
+ item->filter( filter );
- if ((*iit)->getFiltered(filter.getMinRequiredGeneration()))
+ if (item->getFiltered(filter.getMinRequiredGeneration()))
{
mMostFilteredDescendantGeneration = filter_generation;
}
@@ -2028,6 +2030,22 @@ void LLFolderViewFolder::openItem( void )
toggleOpen();
}
+void LLFolderViewFolder::applyFunctorToChildren(LLFolderViewFunctor& functor)
+{
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ functor.doItem((*fit));
+ }
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ functor.doItem((*iit));
+ }
+}
+
void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor)
{
functor.doFolder(this);
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index 30387812a6..f6264ec968 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -501,6 +501,9 @@ public:
void applyFunctorRecursively(LLFolderViewFunctor& functor);
virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
+ // Just apply this functor to the folder's immediate children.
+ void applyFunctorToChildren(LLFolderViewFunctor& functor);
+
virtual void openItem( void );
virtual BOOL addItem(LLFolderViewItem* item);
virtual BOOL addFolder( LLFolderViewFolder* folder);
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 795770d3db..ee93a9349a 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -110,10 +110,10 @@ void LLIMFloater::onFocusReceived()
// virtual
void LLIMFloater::onClose(bool app_quitting)
{
- if (!gIMMgr->hasSession(mSessionID)) return;
-
setTyping(false);
- gIMMgr->leaveSession(mSessionID);
+ // SJB: We want the close button to hide the session window, not end it
+ // *NOTE: Yhis is functional, but not ideal - it's still closing the floater; we really want to change the behavior of the X button instead.
+ //gIMMgr->leaveSession(mSessionID);
}
/* static */
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 4999a495c9..c096b5220a 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -73,6 +73,7 @@
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llnotify.h"
+#include "llnearbychat.h"
#include "llviewerregion.h"
#include "llvoicechannel.h"
#include "lltrans.h"
@@ -1613,6 +1614,12 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
LLChat chat(message);
chat.mSourceType = CHAT_SOURCE_SYSTEM;
LLFloaterChat::addChatHistory(chat);
+
+ LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
+ if(nearby_chat)
+ {
+ nearby_chat->addMessage(chat);
+ }
}
else // going to IM session
{
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index d682f94286..d216872363 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -64,6 +64,7 @@
#include "llviewerwindow.h"
#include "llvoavatarself.h"
#include "llwearablelist.h"
+#include "llpaneloutfitsinventory.h"
using namespace LLOldEvents;
@@ -173,16 +174,33 @@ time_t LLInvFVBridge::getCreationDate() const
return 0;
}
-// Can be destoryed (or moved to trash)
+// Can be destroyed (or moved to trash)
BOOL LLInvFVBridge::isItemRemovable()
{
- LLInventoryModel* model = getInventoryModel();
- if(!model) return FALSE;
- if(model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()))
+ const LLInventoryModel* model = getInventoryModel();
+ if(!model)
+ {
+ return FALSE;
+ }
+ if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()))
+ {
+ return FALSE;
+ }
+ const LLInventoryObject *obj = model->getItem(mUUID);
+ if (obj && obj->getIsLinkType())
{
return TRUE;
}
- return FALSE;
+ if (gAgentWearables.isWearingItem(mUUID))
+ {
+ return FALSE;
+ }
+ const LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
+ if (avatar && avatar->isWearingAttachment(mUUID))
+ {
+ return FALSE;
+ }
+ return TRUE;
}
// Can be moved to another folder
@@ -477,6 +495,7 @@ void hide_context_entries(LLMenuGL& menu,
}
else
{
+ (*itor)->setVisible(TRUE);
for (itor2 = disabled_entries.begin(); itor2 != disabled_entries.end(); ++itor2)
{
if (*itor2 == name)
@@ -493,28 +512,39 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
std::vector<std::string> &items,
std::vector<std::string> &disabled_items, U32 flags)
{
- items.push_back(std::string("Rename"));
- if (!isItemRenameable() || (flags & FIRST_SELECTED_ITEM) == 0)
- {
- disabled_items.push_back(std::string("Rename"));
- }
-
- if (show_asset_id)
+ const LLInventoryObject *obj = getInventoryObject();
+ if (obj && obj->getIsLinkType())
{
- items.push_back(std::string("Copy Asset UUID"));
- if ( (! ( isItemPermissive() || gAgent.isGodlike() ) )
- || (flags & FIRST_SELECTED_ITEM) == 0)
+ items.push_back(std::string("Find Original"));
+ if (LLAssetType::lookupIsLinkType(obj->getType()))
{
- disabled_items.push_back(std::string("Copy Asset UUID"));
+ disabled_items.push_back(std::string("Find Original"));
}
}
-
- items.push_back(std::string("Copy Separator"));
-
- items.push_back(std::string("Copy"));
- if (!isItemCopyable())
+ else
{
- disabled_items.push_back(std::string("Copy"));
+ items.push_back(std::string("Rename"));
+ if (!isItemRenameable() || (flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ disabled_items.push_back(std::string("Rename"));
+ }
+
+ if (show_asset_id)
+ {
+ items.push_back(std::string("Copy Asset UUID"));
+ if ( (! ( isItemPermissive() || gAgent.isGodlike() ) )
+ || (flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ disabled_items.push_back(std::string("Copy Asset UUID"));
+ }
+ }
+ items.push_back(std::string("Copy Separator"));
+
+ items.push_back(std::string("Copy"));
+ if (!isItemCopyable())
+ {
+ disabled_items.push_back(std::string("Copy"));
+ }
}
items.push_back(std::string("Paste"));
@@ -1305,6 +1335,23 @@ void LLFolderBridge::selectItem()
}
+// Iterate through a folder's children to determine if
+// all the children are removable.
+class LLIsItemRemovable : public LLFolderViewFunctor
+{
+public:
+ LLIsItemRemovable() : mPassed(TRUE) {}
+ virtual void doFolder(LLFolderViewFolder* folder)
+ {
+ mPassed &= folder->getListener()->isItemRemovable();
+ }
+ virtual void doItem(LLFolderViewItem* item)
+ {
+ mPassed &= item->getListener()->isItemRemovable();
+ }
+ BOOL mPassed;
+};
+
// Can be destroyed (or moved to trash)
BOOL LLFolderBridge::isItemRemovable()
{
@@ -1330,47 +1377,25 @@ BOOL LLFolderBridge::isItemRemovable()
{
return FALSE;
}
-
+ // Allow protected types to be removed, but issue a warning.
+ /*
if(LLFolderType::lookupIsProtectedType(category->getPreferredType()))
{
return FALSE;
}
+ */
- LLInventoryModel::cat_array_t descendent_categories;
- LLInventoryModel::item_array_t descendent_items;
- gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE );
-
- S32 i;
- for( i = 0; i < descendent_categories.count(); i++ )
+ LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
+ LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL);
+ if (folderp)
{
- LLInventoryCategory* category = descendent_categories[i];
- if(LLFolderType::lookupIsProtectedType(category->getPreferredType()))
+ LLIsItemRemovable folder_test;
+ folderp->applyFunctorToChildren(folder_test);
+ if (!folder_test.mPassed)
{
return FALSE;
}
}
-
- for( i = 0; i < descendent_items.count(); i++ )
- {
- LLInventoryItem* item = descendent_items[i];
- if( (item->getType() == LLAssetType::AT_CLOTHING) ||
- (item->getType() == LLAssetType::AT_BODYPART) )
- {
- if(gAgentWearables.isWearingItem(item->getUUID()))
- {
- return FALSE;
- }
- }
- else
- if( item->getType() == LLAssetType::AT_OBJECT )
- {
- if(avatar->isWearingAttachment(item->getUUID()))
- {
- return FALSE;
- }
- }
- }
-
return TRUE;
}
@@ -2182,38 +2207,70 @@ BOOL LLFolderBridge::removeItem()
{
return FALSE;
}
- // move it to the trash
- LLPreview::hide(mUUID);
- LLInventoryModel* model = getInventoryModel();
- if(!model) return FALSE;
+ const LLViewerInventoryCategory *cat = getCategory();
+
+ LLSD payload;
+ LLSD args;
+ args["FOLDERNAME"] = cat->getName();
- const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ LLNotification::Params params("ConfirmDeleteProtectedCategory");
+ params.payload(payload).substitutions(args).functor.function(boost::bind(&LLFolderBridge::removeItemResponse, this, _1, _2));
+ //params.functor.function(boost::bind(&LLFolderBridge::removeItemResponse, this, _1, _2));
+ /*
+ LLNotification::Params params("ChangeLindenEstate");
+ params.functor.function(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2));
+ */
+ if (LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
+ {
+ LLNotifications::instance().add(params);
+ }
+ else
+ {
+ LLNotifications::instance().forceResponse(params, 0);
+ }
+ return TRUE;
+}
- // Look for any gestures and deactivate them
- LLInventoryModel::cat_array_t descendent_categories;
- LLInventoryModel::item_array_t descendent_items;
- gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE );
+bool LLFolderBridge::removeItemResponse(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
- S32 i;
- for (i = 0; i < descendent_items.count(); i++)
+ // if they choose delete, do it. Otherwise, don't do anything
+ if(option == 0)
{
- LLInventoryItem* item = descendent_items[i];
- if (item->getType() == LLAssetType::AT_GESTURE
- && LLGestureManager::instance().isGestureActive(item->getUUID()))
+ // move it to the trash
+ LLPreview::hide(mUUID);
+ LLInventoryModel* model = getInventoryModel();
+ if(!model) return FALSE;
+
+ const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
+
+ // Look for any gestures and deactivate them
+ LLInventoryModel::cat_array_t descendent_categories;
+ LLInventoryModel::item_array_t descendent_items;
+ gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE );
+
+ S32 i;
+ for (i = 0; i < descendent_items.count(); i++)
{
- LLGestureManager::instance().deactivateGesture(item->getUUID());
+ LLInventoryItem* item = descendent_items[i];
+ if (item->getType() == LLAssetType::AT_GESTURE
+ && LLGestureManager::instance().isGestureActive(item->getUUID()))
+ {
+ LLGestureManager::instance().deactivateGesture(item->getUUID());
+ }
}
+
+ // go ahead and do the normal remove if no 'last calling
+ // cards' are being removed.
+ LLViewerInventoryCategory* cat = getCategory();
+ if(cat)
+ {
+ LLInvFVBridge::changeCategoryParent(model, cat, trash_id, TRUE);
+ }
+ return TRUE;
}
-
- // go ahead and do the normal remove if no 'last calling
- // cards' are being removed.
- LLViewerInventoryCategory* cat = getCategory();
- if(cat)
- {
- LLInvFVBridge::changeCategoryParent(model, cat, trash_id, TRUE);
- }
-
- return TRUE;
+ return FALSE;
}
void LLFolderBridge::pasteFromClipboard()
@@ -2297,6 +2354,19 @@ void LLFolderBridge::staticFolderOptionsMenu()
sSelf->folderOptionsMenu();
}
+bool isInOutfitsSidePanel(LLPanel *panel)
+{
+ LLInventoryPanel *my_panel = dynamic_cast<LLInventoryPanel*>(panel);
+ LLPanelOutfitsInventory *outfit_panel =
+ dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));
+ if (!outfit_panel)
+ return false;
+ return outfit_panel->isAccordionPanel(my_panel);
+
+ //LLInventoryPanel *outfit_inv_panel = outfit_panel ? outfit_panel->getActivePanel(): NULL;
+ //return (my_panel && (my_panel == outfit_inv_panel));
+}
+
void LLFolderBridge::folderOptionsMenu()
{
std::vector<std::string> disabled_items;
@@ -2310,11 +2380,17 @@ void LLFolderBridge::folderOptionsMenu()
// BAP change once we're no longer treating regular categories as ensembles.
const bool is_ensemble = category && (type == LLFolderType::FT_NONE ||
LLFolderType::lookupIsEnsembleType(type));
+ const bool is_sidepanel = isInOutfitsSidePanel(mInventoryPanel.get());
// calling card related functionality for folders.
+ if (is_sidepanel)
+ {
+ mItems.clear();
+ }
+
// Only enable calling-card related options for non-default folders.
- if (!is_default_folder)
+ if (!is_sidepanel && !is_default_folder)
{
LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))
@@ -2351,6 +2427,10 @@ void LLFolderBridge::folderOptionsMenu()
mItems.push_back(std::string("Remove From Outfit"));
}
hide_context_entries(*mMenu, mItems, disabled_items);
+
+ // Reposition the menu, in case we're adding items to an existing menu.
+ mMenu->needsArrange();
+ mMenu->arrangeAndClear();
}
BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& is_type)
@@ -2771,7 +2851,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
BOOL drop)
{
LLInventoryModel* model = getInventoryModel();
- if(!model) return FALSE;
+ if(!model || !inv_item) return FALSE;
// cannot drag into library
if(!isAgentInventory())
@@ -3660,11 +3740,6 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
- LLInventoryItem* item = getItem();
- if (item && item->getIsLinkType())
- {
- items.push_back(std::string("Find Original"));
- }
items.push_back(std::string("Open"));
items.push_back(std::string("Properties"));
@@ -3774,14 +3849,6 @@ LLItemBridge(inventory, uuid), mInvType(type)
mIsMultiObject = ( flags & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS ) ? TRUE: FALSE;
}
-BOOL LLObjectBridge::isItemRemovable()
-{
- LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
- if(!avatar) return FALSE;
- if(avatar->isWearingAttachment(mUUID)) return FALSE;
- return LLInvFVBridge::isItemRemovable();
-}
-
LLUIImagePtr LLObjectBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_OBJECT, mInvType, mAttachPt, mIsMultiObject );
@@ -3992,14 +4059,9 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
- LLInventoryItem* item = getItem();
- if (item && item->getIsLinkType())
- {
- items.push_back(std::string("Find Original"));
- }
-
items.push_back(std::string("Properties"));
+ LLInventoryItem *item = getItem();
getClipboardEntries(true, items, disabled_items, flags);
LLObjectBridge::sContextMenuItemID = mUUID;
@@ -4237,32 +4299,37 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_
{
for(i = 0; i < wearable_count; ++i)
{
- if( gAgentWearables.isWearingItem (item_array.get(i)->getUUID()) )
+ LLViewerInventoryItem *item = item_array.get(i);
+ if (item->getType() == LLAssetType::AT_BODYPART)
+ continue;
+ if (gAgent.isTeen() && item->isWearableType() &&
+ (item->getWearableType() == WT_UNDERPANTS || item->getWearableType() == WT_UNDERSHIRT))
+ continue;
+ if( gAgentWearables.isWearingItem (item->getLinkedUUID()) )
{
- LLWearableList::instance().getAsset(item_array.get(i)->getAssetUUID(),
- item_array.get(i)->getName(),
- item_array.get(i)->getType(),
+ LLWearableList::instance().getAsset(item->getAssetUUID(),
+ item->getName(),
+ item->getType(),
LLWearableBridge::onRemoveFromAvatarArrived,
- new OnRemoveStruct(item_array.get(i)->getUUID()));
-
+ new OnRemoveStruct(item->getLinkedUUID()));
}
}
}
-
if (obj_count > 0)
{
for(i = 0; i < obj_count; ++i)
{
+ LLViewerInventoryItem *obj_item = obj_item_array.get(i);
gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
gMessageSystem->nextBlockFast(_PREHASH_ObjectData );
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_ItemID, obj_item_array.get(i)->getUUID() );
+ gMessageSystem->addUUIDFast(_PREHASH_ItemID, obj_item->getLinkedUUID() );
gMessageSystem->sendReliable( gAgent.getRegion()->getHost() );
// this object might have been selected, so let the selection manager know it's gone now
- LLViewerObject *found_obj = gObjectList.findObject( obj_item_array.get(i)->getUUID());
+ LLViewerObject *found_obj = gObjectList.findObject( obj_item->getLinkedUUID());
if (found_obj)
{
LLSelectMgr::getInstance()->remove(found_obj);
@@ -4274,10 +4341,11 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_
{
for(i = 0; i < gest_count; ++i)
{
- if ( LLGestureManager::instance().isGestureActive( gest_item_array.get(i)->getUUID()) )
+ LLViewerInventoryItem *gest_item = gest_item_array.get(i);
+ if ( LLGestureManager::instance().isGestureActive( gest_item->getLinkedUUID()) )
{
- LLGestureManager::instance().deactivateGesture( gest_item_array.get(i)->getUUID() );
- gInventory.updateItem( gest_item_array.get(i) );
+ LLGestureManager::instance().deactivateGesture( gest_item->getLinkedUUID() );
+ gInventory.updateItem( gest_item );
gInventory.notifyObservers();
}
@@ -4295,12 +4363,6 @@ BOOL LLWearableBridge::renameItem(const std::string& new_name)
return LLItemBridge::renameItem(new_name);
}
-BOOL LLWearableBridge::isItemRemovable()
-{
- if (gAgentWearables.isWearingItem(mUUID)) return FALSE;
- return LLInvFVBridge::isItemRemovable();
-}
-
std::string LLWearableBridge::getLabelSuffix() const
{
if( gAgentWearables.isWearingItem( mUUID ) )
@@ -4430,11 +4492,6 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Open"));
}
- if (item && item->getIsLinkType())
- {
- items.push_back(std::string("Find Original"));
- }
-
items.push_back(std::string("Properties"));
getClipboardEntries(true, items, disabled_items, flags);
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 49e64ebdde..6a284e0550 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -288,6 +288,8 @@ public:
virtual BOOL renameItem(const std::string& new_name);
virtual BOOL removeItem();
+ bool removeItemResponse(const LLSD& notification, const LLSD& response);
+
virtual void pasteFromClipboard();
virtual void pasteLinkFromClipboard();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
@@ -508,7 +510,6 @@ public:
virtual LLFontGL::StyleFlags getLabelStyle() const;
virtual std::string getLabelSuffix() const;
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
- virtual BOOL isItemRemovable();
virtual BOOL renameItem(const std::string& new_name);
LLInventoryObject* getObject() const;
@@ -546,7 +547,6 @@ public:
virtual void openItem();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
virtual std::string getLabelSuffix() const;
- virtual BOOL isItemRemovable();
virtual BOOL renameItem(const std::string& new_name);
static void onWearOnAvatar( void* userdata ); // Access to wearOnAvatar() from menu
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 4ece876192..9f96ebc366 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1119,9 +1119,16 @@ BOOL LLInventoryModel::containsObserver(LLInventoryObserver* observer) const
return mObservers.find(observer) != mObservers.end();
}
-// Call this method when it's time to update everyone on a new state,
-// by default, the inventory model will not update observers
-// automatically.
+void LLInventoryModel::idleNotifyObservers()
+{
+ if (mModifyMask == LLInventoryObserver::NONE && (mChangedItemIDs.size() == 0))
+ {
+ return;
+ }
+ notifyObservers("");
+}
+
+// Call this method when it's time to update everyone on a new state.
// The optional argument 'service_name' is used by Agent Inventory Service [DEV-20328]
void LLInventoryModel::notifyObservers(const std::string service_name)
{
@@ -1134,13 +1141,6 @@ void LLInventoryModel::notifyObservers(const std::string service_name)
return;
}
- if ((mModifyMask == LLInventoryObserver::NONE) && (service_name == ""))
- {
- mModifyMask = LLInventoryObserver::NONE;
- mChangedItemIDs.clear();
- return;
- }
-
mIsNotifyObservers = TRUE;
for (observer_list_t::iterator iter = mObservers.begin();
iter != mObservers.end(); )
@@ -3309,8 +3309,7 @@ void LLInventoryModel::processInventoryDescendents(LLMessageSystem* msg,void**)
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
if(agent_id != gAgent.getID())
{
- llwarns << "Got a UpdateInventoryItem for the wrong agent."
- << llendl;
+ llwarns << "Got a UpdateInventoryItem for the wrong agent." << llendl;
return;
}
LLUUID parent_id;
@@ -3321,6 +3320,7 @@ void LLInventoryModel::processInventoryDescendents(LLMessageSystem* msg,void**)
msg->getS32("AgentData", "Version", version);
S32 descendents;
msg->getS32("AgentData", "Descendents", descendents);
+
S32 i;
S32 count = msg->getNumberOfBlocksFast(_PREHASH_FolderData);
LLPointer<LLViewerInventoryCategory> tcategory = new LLViewerInventoryCategory(owner_id);
@@ -3350,6 +3350,9 @@ void LLInventoryModel::processInventoryDescendents(LLMessageSystem* msg,void**)
{
cat->setVersion(version);
cat->setDescendentCount(descendents);
+ // Get this UUID on the changed list so that whatever's listening for it
+ // will get triggered.
+ gInventory.addChangedMask(LLInventoryObserver::INTERNAL, cat->getUUID());
}
gInventory.notifyObservers();
}
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index da12dbdf7f..50f54cb842 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -252,9 +252,12 @@ public:
// multiple trash can bug.
const LLUUID findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder = true, bool find_in_library = false);
- // Call this method when it's time to update everyone on a new
- // state, by default, the inventory model will not update
- // observers automatically.
+ // This gets called by the idle loop. It only updates if new
+ // state is detected. Call notifyObservers() manually to update
+ // regardless of whether state change has been indicated.
+ void idleNotifyObservers();
+
+ // Call this method to explicitly update everyone on a new state.
// The optional argument 'service_name' is used by Agent Inventory Service [DEV-20328]
void notifyObservers(const std::string service_name="");
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index ae46e4d1b1..944676ad7a 100644
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -112,10 +112,20 @@ void LLInventoryFetchObserver::changed(U32 mask)
LLViewerInventoryItem* item = gInventory.getItem(*it);
if(!item)
{
- // BUG: This can cause done() to get called prematurely below.
- // This happens with the LLGestureInventoryFetchObserver that
- // loads gestures at startup. JC
- it = mIncomplete.erase(it);
+ if (mRetryIfMissing)
+ {
+ // BAP changed to skip these items, so we should keep retrying until they arrive.
+ // Did not make this the default behavior because of uncertainty about impact -
+ // could cause some observers that currently complete to wait forever.
+ ++it;
+ }
+ else
+ {
+ // BUG: This can cause done() to get called prematurely below.
+ // This happens with the LLGestureInventoryFetchObserver that
+ // loads gestures at startup. JC
+ it = mIncomplete.erase(it);
+ }
continue;
}
if(item->isComplete())
diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h
index 384e6292e8..73b25a8ed0 100644
--- a/indra/newview/llinventoryobserver.h
+++ b/indra/newview/llinventoryobserver.h
@@ -106,16 +106,17 @@ protected:
class LLInventoryFetchObserver : public LLInventoryObserver
{
public:
- LLInventoryFetchObserver() {}
+ LLInventoryFetchObserver(bool retry_if_missing = false): mRetryIfMissing(retry_if_missing) {}
virtual void changed(U32 mask);
typedef std::vector<LLUUID> item_ref_t;
bool isEverythingComplete() const;
void fetchItems(const item_ref_t& ids);
- virtual void done() = 0;
+ virtual void done() {};
protected:
+ bool mRetryIfMissing;
item_ref_t mComplete;
item_ref_t mIncomplete;
};
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 327a735f78..0c893dddd6 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -78,7 +78,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mSortOrderSetting(p.sort_order_setting),
mInventory(p.inventory),
mAllowMultiSelect(p.allow_multi_select),
- mHasInventoryConnection(false),
+ mViewsInitialized(false),
mStartFolderString(p.start_folder),
mBuildDefaultHierarchy(true),
mInvFVBridgeBuilder(NULL)
@@ -96,6 +96,11 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
setBackgroundColor(LLUIColorTable::instance().getColor("InventoryBackgroundColor"));
setBackgroundVisible(TRUE);
setBackgroundOpaque(TRUE);
+
+ if (mStartFolderString != "")
+ {
+ mBuildDefaultHierarchy = false;
+ }
}
BOOL LLInventoryPanel::postBuild()
@@ -146,13 +151,13 @@ BOOL LLInventoryPanel::postBuild()
mInventory->addObserver(mInventoryObserver);
// build view of inventory if we need default full hierarchy and inventory ready, otherwise wait for modelChanged() callback
- if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mHasInventoryConnection)
+ if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mViewsInitialized)
{
- rebuildViews();
- mHasInventoryConnection = true;
- defaultOpenInventory();
+ initializeViews();
}
+ gIdleCallbacks.addFunction(onIdle, (void*)this);
+
if (mSortOrderSetting != INHERIT_SORT_ORDER)
{
setSortOrder(gSavedSettings.getU32(mSortOrderSetting));
@@ -252,15 +257,11 @@ void LLInventoryPanel::modelChanged(U32 mask)
bool handled = false;
- // inventory just initialized, do complete build
- if ((mask & LLInventoryObserver::ADD) && gInventory.getChangedIDs().empty() && !mHasInventoryConnection)
+ if (!mViewsInitialized)
{
- rebuildViews();
- mHasInventoryConnection = true;
- defaultOpenInventory();
return;
}
-
+
if (mask & LLInventoryObserver::LABEL)
{
handled = true;
@@ -327,22 +328,26 @@ void LLInventoryPanel::modelChanged(U32 mask)
// around in the panel's directory structure (i.e. reparented).
if (model_item && view_item)
{
- LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolders->getItemByID(model_item->getParentUUID());
-
- // Item has been moved.
- if (view_item->getParentFolder() != new_parent)
+ // Don't process the item if it's hanging from the root, since its
+ // model_item's parent will be NULL.
+ if (view_item->getRoot() != view_item->getParent())
{
- if (new_parent != NULL)
+ LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolders->getItemByID(model_item->getParentUUID());
+ // Item has been moved.
+ if (view_item->getParentFolder() != new_parent)
{
- // Item is to be moved and we found its new parent in the panel's directory, so move the item's UI.
- view_item->getParentFolder()->extractItem(view_item);
- view_item->addToFolder(new_parent, mFolders);
- }
- else
- {
- // Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that
- // doesn't include trash). Just remove the item's UI.
- view_item->destroyView();
+ if (new_parent != NULL)
+ {
+ // Item is to be moved and we found its new parent in the panel's directory, so move the item's UI.
+ view_item->getParentFolder()->extractItem(view_item);
+ view_item->addToFolder(new_parent, mFolders);
+ }
+ else
+ {
+ // Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that
+ // doesn't include trash). Just remove the item's UI.
+ view_item->destroyView();
+ }
}
}
}
@@ -366,11 +371,28 @@ void LLInventoryPanel::modelChanged(U32 mask)
}
}
+// static
+void LLInventoryPanel::onIdle(void *userdata)
+{
+ LLInventoryPanel *self = (LLInventoryPanel*)userdata;
+ // inventory just initialized, do complete build
+ if (!self->mViewsInitialized && gInventory.isInventoryUsable())
+ {
+ self->initializeViews();
+ }
+ if (self->mViewsInitialized)
+ {
+ gIdleCallbacks.deleteFunction(onIdle, (void*)self);
+ }
+}
-void LLInventoryPanel::rebuildViews()
+void LLInventoryPanel::initializeViews()
{
- // Determine the root folder and rebuild the views starting
- // at that folder.
+ if (!gInventory.isInventoryUsable())
+ return;
+
+ // Determine the root folder in case specified, and
+ // build the views starting with that folder.
const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString);
if ("LIBRARY" == mStartFolderString)
@@ -381,16 +403,17 @@ void LLInventoryPanel::rebuildViews()
{
mStartFolderID = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
}
-
+ llinfos << this << " Generating views for start folder " << mStartFolderString << llendl;
rebuildViewsFor(mStartFolderID);
+
+ mViewsInitialized = true;
+ defaultOpenInventory();
}
void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
{
- LLFolderViewItem* old_view = NULL;
-
- // get old LLFolderViewItem
- old_view = mFolders->getItemByID(id);
+ // Destroy the old view for this ID so we can rebuild it
+ LLFolderViewItem* old_view = mFolders->getItemByID(id);
if (old_view && id.notNull())
{
old_view->destroyView();
@@ -409,11 +432,13 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
const LLUUID &parent_id = objectp->getParentUUID();
LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolders->getItemByID(parent_id);
if (id == mStartFolderID)
+ {
parent_folder = mFolders;
-
- if (!parent_folder)
+ }
+ else if ((mStartFolderID != LLUUID::null) && (!gInventory.isObjectDescendentOf(id, mStartFolderID)))
{
- // This item exists outside the inventory's hierarchy, so don't add it.
+ // This item exists outside the inventory's hierarchy,
+ // so don't add it.
return;
}
@@ -520,19 +545,20 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
// bit of a hack to make sure the inventory is open.
void LLInventoryPanel::defaultOpenInventory()
{
- const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString);
- if (preferred_type != LLFolderType::FT_NONE)
+ if (mStartFolderString != "")
{
- const std::string& top_level_folder_name = LLViewerFolderType::lookupNewCategoryName(preferred_type);
- mFolders->openFolder(top_level_folder_name);
+ mFolders->openFolder(mStartFolderString);
}
else
{
// Get the first child (it should be "My Inventory") and
// open it up by name (just to make sure the first child is actually a folder).
LLView* first_child = mFolders->getFirstChild();
- const std::string& first_child_name = first_child->getName();
- mFolders->openFolder(first_child_name);
+ if (first_child)
+ {
+ const std::string& first_child_name = first_child->getName();
+ mFolders->openFolder(first_child_name);
+ }
}
}
@@ -640,13 +666,6 @@ void LLInventoryPanel::openAllFolders()
mFolders->arrangeAll();
}
-void LLInventoryPanel::openDefaultFolderForType(LLFolderType::EType type)
-{
- LLUUID category_id = mInventory->findCategoryUUIDForType(type);
- LLOpenFolderByID opener(category_id);
- mFolders->applyFunctorRecursively(opener);
-}
-
void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus)
{
// Don't select objects in COF (e.g. to prevent refocus when items are worn).
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 0ccee337c9..fd23b375fa 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -122,7 +122,6 @@ public:
// Call this method to set the selection.
void openAllFolders();
- void openDefaultFolderForType(LLFolderType::EType);
void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);
void setSelectCallback(const LLFolderView::signal_t::slot_type& cb) { if (mFolders) mFolders->setSelectCallback(cb); }
void clearSelection();
@@ -161,40 +160,23 @@ public:
void openSelected();
void unSelectAll() { mFolders->setSelection(NULL, FALSE, FALSE); }
-protected:
- // Destroys the old views, and regenerates them based on the
- // start folder ID.
- void rebuildViews();
+ static void onIdle(void* user_data);
+
+private:
// Given the id and the parent, build all of the folder views.
void rebuildViewsFor(const LLUUID& id);
virtual void buildNewViews(const LLUUID& id); // made virtual to support derived classes. EXT-719
- void defaultOpenInventory(); // open the first level of inventory
protected:
+ void defaultOpenInventory(); // open the first level of inventory
+
LLInventoryModel* mInventory;
LLInventoryObserver* mInventoryObserver;
BOOL mAllowMultiSelect;
std::string mSortOrderSetting;
-//private: // Can not make these private - needed by llinventorysubtreepanel
LLFolderView* mFolders;
- std::string mStartFolderString;
-
- /**
- * Contains UUID of Inventory item from which hierarchy should be built.
- * Can be set with the "start_folder" xml property.
- * Default is LLUUID::null that means total Inventory hierarchy.
- */
- LLUUID mStartFolderID;
LLScrollContainer* mScroller;
- bool mHasInventoryConnection;
-
- /**
- * Flag specified if default inventory hierarchy should be created in postBuild()
- */
- bool mBuildDefaultHierarchy;
-
- LLUUID mRootInventoryItemUUID;
/**
* Pointer to LLInventoryFVBridgeBuilder.
@@ -205,6 +187,21 @@ protected:
*/
const LLInventoryFVBridgeBuilder* mInvFVBridgeBuilder;
+ //--------------------------------------------------------------------
+ // Initialization routines for building up the UI ("views")
+ //--------------------------------------------------------------------
+public:
+ BOOL getIsViewsInitialized() const { return mViewsInitialized; }
+private:
+ // Builds the UI. Call this once the inventory is usable.
+ void initializeViews();
+ BOOL mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
+ BOOL mViewsInitialized; // Views have been generated
+
+ // UUID of category from which hierarchy should be built. Set with the
+ // "start_folder" xml property. Default is LLUUID::null that means total Inventory hierarchy.
+ std::string mStartFolderString;
+ LLUUID mStartFolderID;
};
#endif // LL_LLINVENTORYPANEL_H
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index badef4c7ae..3c337961e1 100755
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -260,7 +260,8 @@ void LLMediaDataClient::Responder::result(const LLSD& content)
//
//////////////////////////////////////////////////////////////////////////////////////
-bool LLMediaDataClient::Comparator::operator() (const request_ptr_t &o1, const request_ptr_t &o2) const
+// static
+bool LLMediaDataClient::compareRequests(const request_ptr_t &o1, const request_ptr_t &o2)
{
if (o2.isNull()) return true;
if (o1.isNull()) return false;
@@ -277,20 +278,13 @@ bool LLMediaDataClient::Comparator::operator() (const request_ptr_t &o1, const r
// 3: One item with an impl, another without: item with impl wins
// (XXX is that what we want?)
// Calculate the scores for each.
- F64 o1_score = Comparator::getObjectScore(o1->getObject());
- F64 o2_score = Comparator::getObjectScore(o2->getObject());
-
- // XXX Weird: a higher score should go earlier, but by observation I notice
- // that this causes further-away objects load first. This is counterintuitive
- // to the priority_queue Comparator, which states that this function should
- // return 'true' if o1 should be *before* o2.
- // In other words, I'd have expected that the following should return
- // ( o1_score > o2_score).
- return ( o1_score < o2_score );
+ F64 o1_score = getObjectScore(o1->getObject());
+ F64 o2_score = getObjectScore(o2->getObject());
+ return ( o1_score > o2_score );
}
-
+
// static
-F64 LLMediaDataClient::Comparator::getObjectScore(const LLMediaDataClientObject::ptr_t &obj)
+F64 LLMediaDataClient::getObjectScore(const LLMediaDataClientObject::ptr_t &obj)
{
// *TODO: make this less expensive?
F64 dist = obj->getDistanceFromAvatar() + 0.1; // avoids div by 0
@@ -310,12 +304,12 @@ F64 LLMediaDataClient::Comparator::getObjectScore(const LLMediaDataClientObject:
//////////////////////////////////////////////////////////////////////////////////////
// dump the queue
-std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::PriorityQueue &q)
+std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::request_queue_t &q)
{
int i = 0;
- std::vector<LLMediaDataClient::request_ptr_t>::const_iterator iter = q.c.begin();
- std::vector<LLMediaDataClient::request_ptr_t>::const_iterator end = q.c.end();
- while (iter < end)
+ LLMediaDataClient::request_queue_t::const_iterator iter = q.begin();
+ LLMediaDataClient::request_queue_t::const_iterator end = q.end();
+ while (iter != end)
{
s << "\t" << i << "]: " << (*iter)->getObject()->getID().asString();
iter++;
@@ -325,11 +319,11 @@ std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::PriorityQueue
}
// find the given object in the queue.
-bool LLMediaDataClient::PriorityQueue::find(const LLMediaDataClientObject::ptr_t &obj) const
+bool LLMediaDataClient::find(const LLMediaDataClientObject::ptr_t &obj) const
{
- std::vector<LLMediaDataClient::request_ptr_t>::const_iterator iter = c.begin();
- std::vector<LLMediaDataClient::request_ptr_t>::const_iterator end = c.end();
- while (iter < end)
+ request_queue_t::const_iterator iter = pRequestQueue->begin();
+ request_queue_t::const_iterator end = pRequestQueue->end();
+ while (iter != end)
{
if (obj->getID() == (*iter)->getObject()->getID())
{
@@ -370,13 +364,17 @@ BOOL LLMediaDataClient::QueueTimer::tick()
return TRUE;
}
- LLMediaDataClient::PriorityQueue &queue = *(mMDC->pRequestQueue);
+ request_queue_t &queue = *(mMDC->pRequestQueue);
if(!queue.empty())
{
LL_INFOS("LLMediaDataClient") << "QueueTimer::tick() started, queue is: " << queue << LL_ENDL;
- }
+ // Re-sort the list every time...
+ // XXX Is this really what we want?
+ queue.sort(LLMediaDataClient::compareRequests);
+ }
+
// quick retry loop for cases where we shouldn't wait for the next timer tick
while(true)
{
@@ -387,7 +385,7 @@ BOOL LLMediaDataClient::QueueTimer::tick()
}
// Peel one off of the items from the queue, and execute request
- request_ptr_t request = queue.top();
+ request_ptr_t request = queue.front();
llassert(!request.isNull());
const LLMediaDataClientObject *object = (request.isNull()) ? NULL : request->getObject();
bool performed_request = false;
@@ -398,7 +396,7 @@ BOOL LLMediaDataClient::QueueTimer::tick()
{
// This object has been marked dead. Pop it and move on to the next item in the queue immediately.
LL_INFOS("LLMediaDataClient") << "Skipping " << *request << ": object is dead!" << LL_ENDL;
- queue.pop();
+ queue.pop_front();
continue; // jump back to the start of the quick retry loop
}
@@ -442,7 +440,7 @@ BOOL LLMediaDataClient::QueueTimer::tick()
<< mMDC->mMaxNumRetries << " tries...popping object id " << object->getID() << LL_ENDL;
// XXX Should we bring up a warning dialog??
}
- queue.pop();
+ queue.pop_front();
}
else {
request->incRetryCount();
@@ -451,7 +449,7 @@ BOOL LLMediaDataClient::QueueTimer::tick()
// end of quick retry loop -- any cases where we want to loop will use 'continue' to jump back to the start.
break;
}
-
+
LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() finished, queue is now: " << (*(mMDC->pRequestQueue)) << LL_ENDL;
return queue.empty();
@@ -488,7 +486,7 @@ void LLMediaDataClient::enqueue(const Request *request)
LL_INFOS("LLMediaDataClient") << "Queuing request for " << *request << LL_ENDL;
// Push the request on the priority queue
// Sadly, we have to const-cast because items put into the queue are not const
- pRequestQueue->push(const_cast<LLMediaDataClient::Request*>(request));
+ pRequestQueue->push_back(const_cast<LLMediaDataClient::Request*>(request));
LL_DEBUGS("LLMediaDataClient") << "Queue:" << (*pRequestQueue) << LL_ENDL;
// Start the timer if not already running
startQueueTimer();
@@ -508,7 +506,7 @@ LLMediaDataClient::LLMediaDataClient(F32 queue_timer_delay,
mMaxNumRetries(max_retries),
mQueueTimerIsRunning(false)
{
- pRequestQueue = new PriorityQueue();
+ pRequestQueue = new request_queue_t();
}
LLMediaDataClient::~LLMediaDataClient()
@@ -529,7 +527,7 @@ bool LLMediaDataClient::isEmpty() const
bool LLMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &object) const
{
- return (NULL == pRequestQueue) ? false : pRequestQueue->find(object);
+ return (NULL == pRequestQueue) ? false : find(object);
}
//////////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h
index d5dd050111..812e9cbdec 100755
--- a/indra/newview/llmediadataclient.h
+++ b/indra/newview/llmediadataclient.h
@@ -195,30 +195,14 @@ protected:
private:
- // Comparator for PriorityQueue
- class Comparator
- {
- public:
- bool operator() (const request_ptr_t &o1, const request_ptr_t &o2) const;
- private:
- static F64 getObjectScore(const LLMediaDataClientObject::ptr_t &obj);
- };
+ typedef std::list<request_ptr_t> request_queue_t;
- // PriorityQueue
- class PriorityQueue : public std::priority_queue<
- request_ptr_t,
- std::vector<request_ptr_t>,
- Comparator >
- {
- public:
- // Return whether the given object is in the queue
- bool find(const LLMediaDataClientObject::ptr_t &obj) const;
-
- friend std::ostream& operator<<(std::ostream &s, const PriorityQueue &q);
- };
+ // Comparator for sorting
+ static bool compareRequests(const request_ptr_t &o1, const request_ptr_t &o2);
+ static F64 getObjectScore(const LLMediaDataClientObject::ptr_t &obj);
friend std::ostream& operator<<(std::ostream &s, const Request &q);
- friend std::ostream& operator<<(std::ostream &s, const PriorityQueue &q);
+ friend std::ostream& operator<<(std::ostream &s, const request_queue_t &q);
class QueueTimer : public LLEventTimer
{
@@ -232,6 +216,9 @@ private:
LLPointer<LLMediaDataClient> mMDC;
};
+ // Return whether the given object is in the queue
+ bool find(const LLMediaDataClientObject::ptr_t &obj) const;
+
void startQueueTimer();
void stopQueueTimer();
void setIsRunning(bool val) { mQueueTimerIsRunning = val; }
@@ -242,7 +229,7 @@ private:
bool mQueueTimerIsRunning;
- PriorityQueue *pRequestQueue;
+ request_queue_t *pRequestQueue;
};
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 4c55e3d7ac..6f753b6176 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -121,7 +121,7 @@ BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
static LLDefaultChildRegistry::Register<LLDropTarget> r("drop_target");
static LLRegisterPanelClassWrapper<LLPanelAvatarProfile> t_panel_profile("panel_profile");
-static LLRegisterPanelClassWrapper<LLPanelAvatarMeProfile> t_panel_me_profile("panel_me_profile");
+static LLRegisterPanelClassWrapper<LLPanelMyProfile> t_panel_my_profile("panel_my_profile");
static LLRegisterPanelClassWrapper<LLPanelAvatarNotes> t_panel_notes("panel_notes");
//-----------------------------------------------------------------------------
@@ -341,6 +341,7 @@ BOOL LLPanelAvatarProfile::postBuild()
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("Profile.Pay", boost::bind(&LLPanelAvatarProfile::pay, this));
+ registrar.add("Profile.Share", boost::bind(&LLPanelAvatarProfile::share, this));
mProfileMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_profile_overflow.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
@@ -360,7 +361,7 @@ void LLPanelAvatarProfile::onOpen(const LLSD& key)
{
LLPanelProfileTab::onOpen(key);
- mGroups.erase();
+ mGroups.clear();
//Disable "Add Friend" button for friends.
childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId()));
@@ -392,7 +393,7 @@ void LLPanelAvatarProfile::resetControls()
void LLPanelAvatarProfile::resetData()
{
- mGroups.erase();
+ mGroups.clear();
childSetValue("2nd_life_pic",LLUUID::null);
childSetValue("real_world_pic",LLUUID::null);
childSetValue("online_status",LLStringUtil::null);
@@ -444,23 +445,29 @@ void LLPanelAvatarProfile::processGroupProperties(const LLAvatarGroups* avatar_g
// Group properties may arrive in two callbacks, we need to save them across
// different calls. We can't do that in textbox as textbox may change the text.
- std::string groups = mGroups;
LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin();
const LLAvatarGroups::group_list_t::const_iterator it_end = avatar_groups->group_list.end();
- if(groups.empty() && it_end != it)
- {
- groups = (*it).group_name;
- ++it;
- }
for(; it_end != it; ++it)
{
LLAvatarGroups::LLGroupData group_data = *it;
- groups += ", ";
- groups += group_data.group_name;
+
+ // Check if there is no duplicates for this group
+ if (std::find(mGroups.begin(), mGroups.end(), group_data.group_name) == mGroups.end())
+ mGroups.push_back(group_data.group_name);
}
- mGroups = groups;
- childSetValue("sl_groups",mGroups);
+
+ // Creating string, containing group list
+ std::string groups = "";
+ for (group_list_t::const_iterator it = mGroups.begin(); it != mGroups.end(); ++it)
+ {
+ if (it != mGroups.begin())
+ groups += ", ";
+
+ groups += *it;
+ }
+
+ childSetValue("sl_groups", groups);
}
void LLPanelAvatarProfile::fillCommonData(const LLAvatarData* avatar_data)
@@ -530,6 +537,11 @@ void LLPanelAvatarProfile::pay()
LLAvatarActions::pay(getAvatarId());
}
+void LLPanelAvatarProfile::share()
+{
+ LLAvatarActions::share(getAvatarId());
+}
+
void LLPanelAvatarProfile::onUrlTextboxClicked(const std::string& url)
{
LLWeb::loadURL(url);
@@ -590,19 +602,19 @@ void LLPanelAvatarProfile::onOverflowButtonClicked()
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-LLPanelAvatarMeProfile::LLPanelAvatarMeProfile()
+LLPanelMyProfile::LLPanelMyProfile()
: LLPanelAvatarProfile()
{
}
-BOOL LLPanelAvatarMeProfile::postBuild()
+BOOL LLPanelMyProfile::postBuild()
{
LLPanelAvatarProfile::postBuild();
mStatusCombobox = getChild<LLComboBox>("status_combo");
- childSetCommitCallback("status_combo", boost::bind(&LLPanelAvatarMeProfile::onStatusChanged, this), NULL);
- childSetCommitCallback("status_me_message_text", boost::bind(&LLPanelAvatarMeProfile::onStatusMessageChanged, this), NULL);
+ childSetCommitCallback("status_combo", boost::bind(&LLPanelMyProfile::onStatusChanged, this), NULL);
+ childSetCommitCallback("status_me_message_text", boost::bind(&LLPanelMyProfile::onStatusMessageChanged, this), NULL);
resetControls();
resetData();
@@ -610,12 +622,12 @@ BOOL LLPanelAvatarMeProfile::postBuild()
return TRUE;
}
-void LLPanelAvatarMeProfile::onOpen(const LLSD& key)
+void LLPanelMyProfile::onOpen(const LLSD& key)
{
LLPanelProfileTab::onOpen(key);
}
-void LLPanelAvatarMeProfile::processProfileProperties(const LLAvatarData* avatar_data)
+void LLPanelMyProfile::processProfileProperties(const LLAvatarData* avatar_data)
{
fillCommonData(avatar_data);
@@ -626,7 +638,7 @@ void LLPanelAvatarMeProfile::processProfileProperties(const LLAvatarData* avatar
fillAccountStatus(avatar_data);
}
-void LLPanelAvatarMeProfile::fillStatusData(const LLAvatarData* avatar_data)
+void LLPanelMyProfile::fillStatusData(const LLAvatarData* avatar_data)
{
std::string status;
if (gAgent.getAFK())
@@ -645,7 +657,7 @@ void LLPanelAvatarMeProfile::fillStatusData(const LLAvatarData* avatar_data)
mStatusCombobox->setValue(status);
}
-void LLPanelAvatarMeProfile::resetControls()
+void LLPanelMyProfile::resetControls()
{
childSetVisible("status_panel", false);
childSetVisible("profile_buttons_panel", false);
@@ -655,7 +667,7 @@ void LLPanelAvatarMeProfile::resetControls()
childSetVisible("profile_me_buttons_panel", true);
}
-void LLPanelAvatarMeProfile::onStatusChanged()
+void LLPanelMyProfile::onStatusChanged()
{
LLSD::String status = mStatusCombobox->getValue().asString();
@@ -677,7 +689,7 @@ void LLPanelAvatarMeProfile::onStatusChanged()
}
}
-void LLPanelAvatarMeProfile::onStatusMessageChanged()
+void LLPanelMyProfile::onStatusMessageChanged()
{
updateData();
}
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index a0caf0c915..527e1c0d34 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -47,7 +47,7 @@ enum EOnlineStatus
};
/**
-* Base class for any Profile View or Me Profile Panel.
+* Base class for any Profile View or My Profile Panel.
*/
class LLPanelProfileTab
: public LLPanel
@@ -148,7 +148,7 @@ protected:
virtual void processGroupProperties(const LLAvatarGroups* avatar_groups);
/**
- * Fills common for Avatar profile and Me Profile fields.
+ * Fills common for Avatar profile and My Profile fields.
*/
virtual void fillCommonData(const LLAvatarData* avatar_data);
@@ -172,6 +172,11 @@ protected:
*/
void pay();
+ /**
+ * opens inventory and IM for sharing items
+ */
+ void share();
+
void onUrlTextboxClicked(const std::string& url);
void onHomepageTextboxClicked();
void onAddFriendButtonClick();
@@ -183,18 +188,20 @@ protected:
private:
- std::string mGroups;
+ typedef std::list<std::string> group_list_t;
+ group_list_t mGroups;
+
LLToggleableMenu* mProfileMenu;
};
/**
* Panel for displaying own first and second life related info.
*/
-class LLPanelAvatarMeProfile
+class LLPanelMyProfile
: public LLPanelAvatarProfile
{
public:
- LLPanelAvatarMeProfile();
+ LLPanelMyProfile();
/*virtual*/ BOOL postBuild();
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index 40319d949d..fa6d16cfb1 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -160,13 +160,7 @@ void LLPanelIMControlPanel::onAddFriendButtonClicked()
void LLPanelIMControlPanel::onShareButtonClicked()
{
- LLSD key;
- LLSideTray::getInstance()->showPanel("sidepanel_inventory", key);
-
- if (gIMMgr->hasSession(getSessionId()))
- {
- LLIMModel::getInstance()->addMessage(getSessionId(), SYSTEM_FROM, LLUUID::null, LLTrans::getString("share_alert"), false);
- }
+ LLAvatarActions::share(mAvatarID);
}
void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id)
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index ce5d682ddc..bde34302ed 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -392,6 +392,10 @@ LLPanelLogin::~LLPanelLogin()
//// We know we're done with the image, so be rid of it.
//gTextureList.deleteImage( mLogoImage );
+
+ // Controls having keyboard focus by default
+ // must reset it on destroy. (EXT-2748)
+ gFocusMgr.setDefaultKeyboardFocus(NULL);
}
// virtual
@@ -683,8 +687,6 @@ void LLPanelLogin::closePanel()
if (sInstance)
{
gViewerWindow->getRootView()->removeChild( LLPanelLogin::sInstance );
-
- gFocusMgr.setDefaultKeyboardFocus(NULL);
delete sInstance;
sInstance = NULL;
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
new file mode 100644
index 0000000000..046118cf75
--- /dev/null
+++ b/indra/newview/llpanelme.cpp
@@ -0,0 +1,272 @@
+/**
+ * @file llpanelme.cpp
+ * @brief Side tray "Me" (My Profile) panel
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelprofile.h"
+#include "llavatarconstants.h"
+#include "llpanelme.h"
+#include "llagent.h"
+#include "llagentwearables.h"
+#include "lliconctrl.h"
+#include "llsidetray.h"
+#include "lltabcontainer.h"
+#include "lltexturectrl.h"
+
+#define PICKER_SECOND_LIFE "2nd_life_pic"
+#define PICKER_FIRST_LIFE "real_world_pic"
+#define PANEL_PROFILE "panel_profile"
+
+static LLRegisterPanelClassWrapper<LLPanelMyProfileEdit> t_panel_me_profile_edit("edit_profile_panel");
+static LLRegisterPanelClassWrapper<LLPanelMe> t_panel_me_profile("panel_me");
+
+LLPanelMe::LLPanelMe(void)
+ : LLPanelProfile()
+ , mEditPanel(NULL)
+{
+ setAvatarId(gAgent.getID());
+}
+
+BOOL LLPanelMe::postBuild()
+{
+ LLPanelProfile::postBuild();
+
+ getTabContainer()[PANEL_PROFILE]->childSetAction("edit_profile_btn", boost::bind(&LLPanelMe::onEditProfileClicked, this), this);
+ getTabContainer()[PANEL_PROFILE]->childSetAction("edit_appearance_btn", boost::bind(&LLPanelMe::onEditAppearanceClicked, this), this);
+
+ return TRUE;
+}
+
+void LLPanelMe::onOpen(const LLSD& key)
+{
+ LLPanelProfile::onOpen(key);
+}
+
+void LLPanelMe::notifyChildren(const LLSD& info)
+{
+ if (info.has("task-panel-action") && info["task-panel-action"].asString() == "handle-tri-state")
+ {
+ // Implement task panel tri-state behavior.
+ //
+ // When the button of an active open task panel is clicked, side tray
+ // calls notifyChildren() on the panel, passing task-panel-action=>handle-tri-state as an argument.
+ // The task panel is supposed to handle this by reverting to the default view,
+ // i.e. closing any dependent panels like "pick info" or "profile edit".
+
+ bool on_default_view = true;
+
+ const LLRect& task_panel_rect = getRect();
+ for (LLView* child = getFirstChild(); child; child = findNextSibling(child))
+ {
+ LLPanel* panel = dynamic_cast<LLPanel*>(child);
+ if (!panel)
+ continue;
+
+ // *HACK: implement panel stack instead (e.g. me->pick_info->pick_edit).
+ if (panel->getRect().getWidth() == task_panel_rect.getWidth() &&
+ panel->getRect().getHeight() == task_panel_rect.getHeight() &&
+ panel->getVisible())
+ {
+ panel->setVisible(FALSE);
+ on_default_view = false;
+ }
+ }
+
+ if (on_default_view)
+ LLSideTray::getInstance()->collapseSideBar();
+
+ return; // this notification is only supposed to be handled by task panels
+ }
+
+ LLPanel::notifyChildren(info);
+}
+
+void LLPanelMe::buildEditPanel()
+{
+ if (NULL == mEditPanel)
+ {
+ mEditPanel = new LLPanelMyProfileEdit();
+ mEditPanel->childSetAction("save_btn", boost::bind(&LLPanelMe::onSaveChangesClicked, this), this);
+ mEditPanel->childSetAction("cancel_btn", boost::bind(&LLPanelMe::onCancelClicked, this), this);
+ }
+}
+
+
+void LLPanelMe::onEditProfileClicked()
+{
+ buildEditPanel();
+ togglePanel(mEditPanel, getAvatarId()); // open
+}
+
+void LLPanelMe::onEditAppearanceClicked()
+{
+ if (gAgentWearables.areWearablesLoaded())
+ {
+ gAgent.changeCameraToCustomizeAvatar();
+ }
+}
+
+void LLPanelMe::onSaveChangesClicked()
+{
+ LLAvatarData data = LLAvatarData();
+ data.avatar_id = gAgent.getID();
+ data.image_id = mEditPanel->getChild<LLTextureCtrl>(PICKER_SECOND_LIFE)->getImageAssetID();
+ data.fl_image_id = mEditPanel->getChild<LLTextureCtrl>(PICKER_FIRST_LIFE)->getImageAssetID();
+ data.about_text = mEditPanel->childGetValue("sl_description_edit").asString();
+ data.fl_about_text = mEditPanel->childGetValue("fl_description_edit").asString();
+ data.profile_url = mEditPanel->childGetValue("homepage_edit").asString();
+ data.allow_publish = mEditPanel->childGetValue("show_in_search_checkbox");
+
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate(&data);
+ togglePanel(mEditPanel); // close
+ onOpen(getAvatarId());
+}
+
+void LLPanelMe::onCancelClicked()
+{
+ togglePanel(mEditPanel); // close
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLPanelMyProfileEdit::LLPanelMyProfileEdit()
+ : LLPanelMyProfile()
+{
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_edit_profile.xml");
+
+ setAvatarId(gAgent.getID());
+}
+
+void LLPanelMyProfileEdit::onOpen(const LLSD& key)
+{
+ resetData();
+
+ // Disable editing until data is loaded, or edited fields will be overwritten when data
+ // is loaded.
+ enableEditing(false);
+ LLPanelMyProfile::onOpen(getAvatarId());
+}
+
+void LLPanelMyProfileEdit::processProperties(void* data, EAvatarProcessorType type)
+{
+ if(APT_PROPERTIES == type)
+ {
+ const LLAvatarData* avatar_data = static_cast<const LLAvatarData*>(data);
+ if(avatar_data && getAvatarId() == avatar_data->avatar_id)
+ {
+ // *TODO dzaporozhan
+ // Workaround for ticket EXT-1099, waiting for fix for ticket EXT-1128
+ enableEditing(true);
+ processProfileProperties(avatar_data);
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
+ }
+ }
+}
+
+void LLPanelMyProfileEdit::processProfileProperties(const LLAvatarData* avatar_data)
+{
+ fillCommonData(avatar_data);
+
+ fillOnlineStatus(avatar_data);
+
+ fillPartnerData(avatar_data);
+
+ fillAccountStatus(avatar_data);
+
+ childSetValue("show_in_search_checkbox", (BOOL)(avatar_data->flags & AVATAR_ALLOW_PUBLISH));
+
+ std::string first, last;
+ BOOL found = gCacheName->getName(avatar_data->avatar_id, first, last);
+ if (found)
+ {
+ childSetTextArg("name_text", "[FIRST]", first);
+ childSetTextArg("name_text", "[LAST]", last);
+ }
+}
+
+BOOL LLPanelMyProfileEdit::postBuild()
+{
+ initTexturePickerMouseEvents();
+
+ childSetTextArg("partner_edit_link", "[URL]", getString("partner_edit_link_url"));
+
+ return LLPanelAvatarProfile::postBuild();
+}
+/**
+ * Inits map with texture picker and appropriate edit icon.
+ * Sets callbacks of Mouse Enter and Mouse Leave signals of Texture Pickers
+ */
+void LLPanelMyProfileEdit::initTexturePickerMouseEvents()
+{
+ LLTextureCtrl* text_pic = getChild<LLTextureCtrl>(PICKER_SECOND_LIFE);
+ LLIconCtrl* text_icon = getChild<LLIconCtrl>("2nd_life_edit_icon");
+ mTextureEditIconMap[text_pic->getName()] = text_icon;
+ text_pic->setMouseEnterCallback(boost::bind(&LLPanelMyProfileEdit::onTexturePickerMouseEnter, this, _1));
+ text_pic->setMouseLeaveCallback(boost::bind(&LLPanelMyProfileEdit::onTexturePickerMouseLeave, this, _1));
+ text_icon->setVisible(FALSE);
+
+ text_pic = getChild<LLTextureCtrl>(PICKER_FIRST_LIFE);
+ text_icon = getChild<LLIconCtrl>("real_world_edit_icon");
+ mTextureEditIconMap[text_pic->getName()] = text_icon;
+ text_pic->setMouseEnterCallback(boost::bind(&LLPanelMyProfileEdit::onTexturePickerMouseEnter, this, _1));
+ text_pic->setMouseLeaveCallback(boost::bind(&LLPanelMyProfileEdit::onTexturePickerMouseLeave, this, _1));
+ text_icon->setVisible(FALSE);
+}
+
+void LLPanelMyProfileEdit::resetData()
+{
+ LLPanelMyProfile::resetData();
+
+ childSetTextArg("name_text", "[FIRST]", LLStringUtil::null);
+ childSetTextArg("name_text", "[LAST]", LLStringUtil::null);
+}
+
+void LLPanelMyProfileEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
+{
+ mTextureEditIconMap[ctrl->getName()]->setVisible(TRUE);
+}
+void LLPanelMyProfileEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
+{
+ mTextureEditIconMap[ctrl->getName()]->setVisible(FALSE);
+}
+
+void LLPanelMyProfileEdit::enableEditing(bool enable)
+{
+ childSetEnabled("2nd_life_pic", enable);
+ childSetEnabled("real_world_pic", enable);
+ childSetEnabled("sl_description_edit", enable);
+ childSetEnabled("fl_description_edit", enable);
+ childSetEnabled("homepage_edit", enable);
+ childSetEnabled("show_in_search_checkbox", enable);
+}
diff --git a/indra/newview/llpanelme.h b/indra/newview/llpanelme.h
new file mode 100644
index 0000000000..17d367132e
--- /dev/null
+++ b/indra/newview/llpanelme.h
@@ -0,0 +1,111 @@
+/**
+ * @file llpanelme.h
+ * @brief Side tray "Me" (My Profile) panel
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELMEPROFILE_H
+#define LL_LLPANELMEPROFILE_H
+
+#include "llpanel.h"
+#include "llpanelavatar.h"
+
+class LLPanelMyProfileEdit;
+class LLPanelProfile;
+class LLIconCtrl;
+
+/**
+* Panel for displaying Agent's profile, it consists of two sub panels - Profile
+* and Picks.
+* LLPanelMe allows user to edit his profile and picks.
+*/
+class LLPanelMe : public LLPanelProfile
+{
+ LOG_CLASS(LLPanelMe);
+
+public:
+
+ LLPanelMe();
+
+ /*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ void notifyChildren(const LLSD& info);
+
+ /*virtual*/ BOOL postBuild();
+
+private:
+
+ void buildEditPanel();
+
+ void onEditProfileClicked();
+ void onEditAppearanceClicked();
+ void onSaveChangesClicked();
+ void onCancelClicked();
+
+ LLPanelMyProfileEdit * mEditPanel;
+
+};
+
+class LLPanelMyProfileEdit : public LLPanelMyProfile
+{
+ LOG_CLASS(LLPanelMyProfileEdit);
+
+public:
+
+ LLPanelMyProfileEdit();
+
+ /*virtual*/void processProperties(void* data, EAvatarProcessorType type);
+
+ /*virtual*/BOOL postBuild();
+
+ /*virtual*/ void onOpen(const LLSD& key);
+
+protected:
+
+ /*virtual*/void resetData();
+
+ void processProfileProperties(const LLAvatarData* avatar_data);
+
+private:
+ void initTexturePickerMouseEvents();
+ void onTexturePickerMouseEnter(LLUICtrl* ctrl);
+ void onTexturePickerMouseLeave(LLUICtrl* ctrl);
+
+ /**
+ * Enabled/disables controls to prevent overwriting edited data upon receiving
+ * current data from server.
+ */
+ void enableEditing(bool enable);
+
+private:
+ // map TexturePicker name => Edit Icon pointer should be visible while hovering Texture Picker
+ typedef std::map<std::string, LLIconCtrl*> texture_edit_icon_map_t;
+ texture_edit_icon_map_t mTextureEditIconMap;
+};
+
+#endif // LL_LLPANELMEPROFILE_H
diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp
index 1a90e85abb..5bb266a01d 100644
--- a/indra/newview/llpanelmediasettingsgeneral.cpp
+++ b/indra/newview/llpanelmediasettingsgeneral.cpp
@@ -392,17 +392,19 @@ void LLPanelMediaSettingsGeneral::preApply()
//
void LLPanelMediaSettingsGeneral::getValues( LLSD &fill_me_in )
{
- fill_me_in[LLMediaEntry::AUTO_LOOP_KEY] = mAutoLoop->getValue();
- fill_me_in[LLMediaEntry::AUTO_PLAY_KEY] = mAutoPlay->getValue();
- fill_me_in[LLMediaEntry::AUTO_SCALE_KEY] = mAutoScale->getValue();
- fill_me_in[LLMediaEntry::AUTO_ZOOM_KEY] = mAutoZoom->getValue();
- fill_me_in[LLMediaEntry::CONTROLS_KEY] = mControls->getCurrentIndex();
- //Don't fill in current URL: this is only supposed to get changed via navigate
+ fill_me_in[LLMediaEntry::AUTO_LOOP_KEY] = mAutoLoop->getValue();
+ fill_me_in[LLMediaEntry::AUTO_PLAY_KEY] = mAutoPlay->getValue();
+ fill_me_in[LLMediaEntry::AUTO_SCALE_KEY] = mAutoScale->getValue();
+ fill_me_in[LLMediaEntry::AUTO_ZOOM_KEY] = mAutoZoom->getValue();
+ fill_me_in[LLMediaEntry::CONTROLS_KEY] = mControls->getCurrentIndex();
+ //Don't fill in current URL: this is only supposed to get changed via navigate
// fill_me_in[LLMediaEntry::CURRENT_URL_KEY] = mCurrentURL->getValue();
- fill_me_in[LLMediaEntry::HEIGHT_PIXELS_KEY] = mHeightPixels->getValue();
- fill_me_in[LLMediaEntry::HOME_URL_KEY] = mHomeURL->getValue();
- fill_me_in[LLMediaEntry::FIRST_CLICK_INTERACT_KEY] = mFirstClick->getValue();
- fill_me_in[LLMediaEntry::WIDTH_PIXELS_KEY] = mWidthPixels->getValue();
+ fill_me_in[LLMediaEntry::HEIGHT_PIXELS_KEY] = mHeightPixels->getValue();
+ // Don't fill in the home URL if it is the special "Multiple Media" string!
+ if (LLTrans::getString("Multiple Media") != mHomeURL->getValue())
+ fill_me_in[LLMediaEntry::HOME_URL_KEY] = mHomeURL->getValue();
+ fill_me_in[LLMediaEntry::FIRST_CLICK_INTERACT_KEY] = mFirstClick->getValue();
+ fill_me_in[LLMediaEntry::WIDTH_PIXELS_KEY] = mWidthPixels->getValue();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index 5ad9bf056e..5af26c1ad9 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -59,7 +59,7 @@
static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
- mInventoryPanel(NULL),
+ mActivePanel(NULL),
mParent(NULL)
{
mSavedFolderState = new LLSaveFolderState();
@@ -74,12 +74,8 @@ LLPanelOutfitsInventory::~LLPanelOutfitsInventory()
// virtual
BOOL LLPanelOutfitsInventory::postBuild()
{
- mInventoryPanel = getChild<LLInventoryPanel>("outfits_list");
- mInventoryPanel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, TRUE);
- mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
- mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_MY_OUTFITS);
- mInventoryPanel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onSelectionChange, this, _1, _2));
+ initAccordionPanels();
initListCommandsHandlers();
return TRUE;
}
@@ -102,7 +98,7 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
{
if (string == "")
{
- mInventoryPanel->setFilterSubString(LLStringUtil::null);
+ mActivePanel->setFilterSubString(LLStringUtil::null);
// re-open folders that were initially open
mSavedFolderState->setApply(TRUE);
@@ -114,7 +110,7 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
gInventory.startBackgroundFetch();
- if (mInventoryPanel->getFilterSubString().empty() && string.empty())
+ if (mActivePanel->getFilterSubString().empty() && string.empty())
{
// current filter and new filter empty, do nothing
return;
@@ -128,7 +124,7 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
}
// set new filter string
- mInventoryPanel->setFilterSubString(string);
+ mActivePanel->setFilterSubString(string);
}
void LLPanelOutfitsInventory::onWear()
@@ -148,13 +144,20 @@ void LLPanelOutfitsInventory::onNew()
{
const std::string& outfit_name = LLViewerFolderType::lookupNewCategoryName(LLFolderType::FT_OUTFIT);
LLUUID outfit_folder = gAgentWearables.makeNewOutfitLinks(outfit_name);
+
getRootFolder()->setSelectionByID(outfit_folder, TRUE);
getRootFolder()->setNeedsAutoRename(TRUE);
}
void LLPanelOutfitsInventory::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)
{
+ updateListCommands();
updateParent();
+ if (getRootFolder()->needsAutoRename())
+ {
+ getRootFolder()->startRenamingSelectedItem();
+ getRootFolder()->setNeedsAutoRename(FALSE);
+ }
}
void LLPanelOutfitsInventory::onSelectorButtonClicked()
@@ -203,7 +206,7 @@ bool LLPanelOutfitsInventory::getIsCorrectType(const LLFolderViewEventListener *
LLFolderView *LLPanelOutfitsInventory::getRootFolder()
{
- return mInventoryPanel->getRootFolder();
+ return mActivePanel->getRootFolder();
}
//////////////////////////////////////////////////////////////////////////////////
@@ -345,3 +348,67 @@ bool LLPanelOutfitsInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropTy
// List Commands //
////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
+// Accordion //
+
+void LLPanelOutfitsInventory::initAccordionPanels()
+{
+ mAccordionPanels.resize(2);
+
+ LLInventoryPanel *myoutfits_panel = getChild<LLInventoryPanel>("outfitslist_accordionpanel");
+ myoutfits_panel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, TRUE);
+ myoutfits_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ mAccordionPanels[0] = myoutfits_panel;
+ mActivePanel = myoutfits_panel;
+
+ LLInventoryPanel *cof_panel = getChild<LLInventoryPanel>("cof_accordionpanel");
+ cof_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ mAccordionPanels[1] = cof_panel;
+
+ for (accordionpanels_vec_t::iterator iter = mAccordionPanels.begin();
+ iter != mAccordionPanels.end();
+ ++iter)
+ {
+ LLInventoryPanel *panel = (*iter);
+ panel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onAccordionSelectionChange, this, panel, _1, _2));
+ }
+}
+
+void LLPanelOutfitsInventory::onAccordionSelectionChange(LLInventoryPanel* accordion_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action)
+{
+ if (user_action && items.size() > 0)
+ {
+ for (accordionpanels_vec_t::iterator iter = mAccordionPanels.begin();
+ iter != mAccordionPanels.end();
+ ++iter)
+ {
+ LLInventoryPanel *panel = (*iter);
+ if (panel == accordion_panel)
+ {
+ mActivePanel = panel;
+ }
+ else
+ {
+ panel->getRootFolder()->clearSelection();
+ }
+ }
+ }
+ onSelectionChange(items, user_action);
+}
+
+LLInventoryPanel* LLPanelOutfitsInventory::getActivePanel()
+{
+ return mActivePanel;
+}
+
+bool LLPanelOutfitsInventory::isAccordionPanel(LLInventoryPanel *panel)
+{
+ for(accordionpanels_vec_t::iterator it = mAccordionPanels.begin();
+ it != mAccordionPanels.end();
+ ++it)
+ {
+ if (*it == panel)
+ return true;
+ }
+ return false;
+}
diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h
index 4d903a389b..7769a7d172 100644
--- a/indra/newview/llpaneloutfitsinventory.h
+++ b/indra/newview/llpaneloutfitsinventory.h
@@ -61,8 +61,6 @@ public:
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
void onSelectorButtonClicked();
- LLInventoryPanel* getActivePanel() { return mInventoryPanel; }
-
// If a compatible listener type is selected, then return a pointer to that.
// Otherwise, return NULL.
LLFolderViewEventListener* getCorrectListenerForAction();
@@ -74,9 +72,26 @@ protected:
private:
LLSidepanelAppearance* mParent;
- LLInventoryPanel* mInventoryPanel;
LLSaveFolderState* mSavedFolderState;
+public:
+ //////////////////////////////////////////////////////////////////////////////////
+ // Accordion //
+ LLInventoryPanel* getActivePanel();
+ bool isAccordionPanel(LLInventoryPanel *panel);
+
+protected:
+ void initAccordionPanels();
+ void onAccordionSelectionChange(LLInventoryPanel* accordion_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action);
+
+private:
+ LLInventoryPanel* mActivePanel;
+ typedef std::vector<LLInventoryPanel *> accordionpanels_vec_t;
+ accordionpanels_vec_t mAccordionPanels;
+
+ // Accordion //
+ ////////////////////////////////////////////////////////////////////////////////
+
//////////////////////////////////////////////////////////////////////////////////
// List Commands //
@@ -95,7 +110,7 @@ private:
LLPanel* mListCommands;
LLMenuGL* mMenuGearDefault;
LLMenuGL* mMenuAdd;
- // //
+ // List Commands //
////////////////////////////////////////////////////////////////////////////////
};
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 0c832defd7..e6b6ec64bd 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -56,6 +56,8 @@
#include "llgrouplist.h"
#include "llinventoryobserver.h"
#include "llpanelpeoplemenus.h"
+#include "llsidetray.h"
+#include "llsidetraypanelcontainer.h"
#include "llrecentpeople.h"
#include "llviewercontrol.h" // for gSavedSettings
#include "llviewermenu.h" // for gMenuHolder
@@ -765,7 +767,7 @@ void LLPanelPeople::updateButtons()
buttonSetEnabled("view_profile_btn", item_selected);
buttonSetEnabled("im_btn", multiple_selected); // allow starting the friends conference for multiple selection
buttonSetEnabled("call_btn", multiple_selected);
- buttonSetEnabled("share_btn", item_selected && false); // not implemented yet
+ buttonSetEnabled("share_btn", item_selected); // not implemented yet
bool none_group_selected = item_selected && selected_id.isNull();
buttonSetEnabled("group_info_btn", !none_group_selected);
@@ -1218,7 +1220,7 @@ void LLPanelPeople::onTeleportButtonClicked()
void LLPanelPeople::onShareButtonClicked()
{
- // *TODO: not implemented yet
+ LLAvatarActions::share(getCurrentItemID());
}
void LLPanelPeople::onMoreButtonClicked()
@@ -1270,6 +1272,31 @@ void LLPanelPeople::onOpen(const LLSD& key)
reSelectedCurrentTab();
}
+void LLPanelPeople::notifyChildren(const LLSD& info)
+{
+ if (info.has("task-panel-action") && info["task-panel-action"].asString() == "handle-tri-state")
+ {
+ LLSideTrayPanelContainer* container = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
+ if (!container)
+ {
+ llwarns << "Cannot find People panel container" << llendl;
+ return;
+ }
+
+ if (container->getCurrentPanelIndex() > 0)
+ {
+ // if not on the default panel, switch to it
+ container->onOpen(LLSD().insert(LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME, getName()));
+ }
+ else
+ LLSideTray::getInstance()->collapseSideBar();
+
+ return; // this notification is only supposed to be handled by task panels
+ }
+
+ LLPanel::notifyChildren(info);
+}
+
void LLPanelPeople::showAccordion(const std::string name, bool show)
{
if(name.empty())
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index a369bcd3e2..d9dd76f3ac 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -50,8 +50,8 @@ public:
virtual ~LLPanelPeople();
/*virtual*/ BOOL postBuild();
-
- virtual void onOpen(const LLSD& key);
+ /*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ void notifyChildren(const LLSD& info);
// internals
class Updater;
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
index 4b90ea5048..b17b6d6fe9 100644
--- a/indra/newview/llpanelpicks.h
+++ b/indra/newview/llpanelpicks.h
@@ -83,7 +83,7 @@ public:
LLClassifiedItem* getSelectedClassifiedItem();
//*NOTE top down approch when panel toggling is done only by
- // parent panels failed to work (picks related code was in me profile panel)
+ // parent panels failed to work (picks related code was in my profile panel)
void setProfilePanel(LLPanelProfile* profile_panel);
private:
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
index 529912929d..71c1b0cbb9 100644
--- a/indra/newview/llpanelprimmediacontrols.cpp
+++ b/indra/newview/llpanelprimmediacontrols.cpp
@@ -510,7 +510,7 @@ void LLPanelPrimMediaControls::updateShape()
mMediaProgressBar->setPercent(media_plugin->getProgressPercent());
gFocusMgr.setTopCtrl(mMediaProgressPanel);
}
- else
+ else if (mMediaProgressPanel->getVisible())
{
mMediaProgressPanel->setVisible(false);
gFocusMgr.setTopCtrl(NULL);
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 02f45c1b48..4d152a13f3 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -158,28 +158,14 @@ void LLPanelProfile::onOpen(const LLSD& key)
}
//*TODO redo panel toggling
-void LLPanelProfile::togglePanel(LLPanel* panel)
+void LLPanelProfile::togglePanel(LLPanel* panel, const LLSD& key)
{
// TRUE - we need to open/expand "panel"
bool expand = getChildList()->front() != panel; // mTabCtrl->getVisible();
if (expand)
{
- if (panel->getParent() != this)
- {
- addChild(panel);
- }
- else
- {
- sendChildToFront(panel);
- }
-
- panel->setVisible(TRUE);
-
- LLRect new_rect = getRect();
- panel->reshape(new_rect.getWidth(), new_rect.getHeight());
- new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight());
- panel->setRect(new_rect);
+ openPanel(panel, key);
}
else
{
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
index e0b827c986..067beb248b 100644
--- a/indra/newview/llpanelprofile.h
+++ b/indra/newview/llpanelprofile.h
@@ -40,7 +40,7 @@
class LLTabContainer;
/**
-* Base class for Profile View and Me Profile.
+* Base class for Profile View and My Profile.
*/
class LLPanelProfile : public LLPanel
{
@@ -51,7 +51,7 @@ public:
/*virtual*/ void onOpen(const LLSD& key);
- virtual void togglePanel(LLPanel*);
+ virtual void togglePanel(LLPanel*, const LLSD& key = LLSD());
virtual void openPanel(LLPanel* panel, const LLSD& params);
diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp
index bcf5b16aa6..7832f63e6a 100644
--- a/indra/newview/llpanelprofileview.cpp
+++ b/indra/newview/llpanelprofileview.cpp
@@ -193,8 +193,10 @@ void LLPanelProfileView::onAvatarNameCached(const LLUUID& id, const std::string&
getChild<LLUICtrl>("user_name", FALSE)->setValue(first_name + " " + last_name);
}
-void LLPanelProfileView::togglePanel(LLPanel* panel)
+void LLPanelProfileView::togglePanel(LLPanel* panel, const LLSD& key)
{
+ // *TODO: unused method?
+
LLPanelProfile::togglePanel(panel);
if(FALSE == panel->getVisible())
{
diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h
index 45c2fc116e..5dc617d4a0 100644
--- a/indra/newview/llpanelprofileview.h
+++ b/indra/newview/llpanelprofileview.h
@@ -64,7 +64,7 @@ public:
/*virtual*/ BOOL postBuild();
- /*virtual*/ void togglePanel(LLPanel* panel);
+ /*virtual*/ void togglePanel(LLPanel* panel, const LLSD& key = LLSD());
BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop, EDragAndDropType cargo_type,
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index 0652ac5a4a..b82b994540 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -263,6 +263,7 @@ BOOL LLTeleportHistoryPanel::postBuild()
fl->setCommitOnSelectionChange(true);
fl->setDoubleClickCallback(boost::bind(&LLTeleportHistoryPanel::onDoubleClickItem, this));
fl->setCommitCallback(boost::bind(&LLTeleportHistoryPanel::handleItemSelect, this, fl));
+ fl->setReturnCallback(boost::bind(&LLTeleportHistoryPanel::onReturnKeyPressed, this));
}
}
}
@@ -637,6 +638,12 @@ void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected)
updateVerbs();
}
+void LLTeleportHistoryPanel::onReturnKeyPressed()
+{
+ // Teleport to selected region as default action on return key pressed
+ onTeleport();
+}
+
void LLTeleportHistoryPanel::onDoubleClickItem()
{
// If item got doubleclick, then that item is already selected
diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h
index b34d9e876c..a31ff34cb6 100644
--- a/indra/newview/llpanelteleporthistory.h
+++ b/indra/newview/llpanelteleporthistory.h
@@ -80,6 +80,7 @@ public:
private:
void onDoubleClickItem();
+ void onReturnKeyPressed();
void onAccordionTabRightClick(LLView *view, S32 x, S32 y, MASK mask);
void onAccordionTabOpen(LLAccordionCtrlTab *tab);
void onAccordionTabClose(LLAccordionCtrlTab *tab);
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index fb9db42cf6..24ba288c49 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -115,7 +115,9 @@ void LLScreenChannelBase::init(S32 channel_left, S32 channel_right)
// LLScreenChannel
//////////////////////
//--------------------------------------------------------------------------
-LLScreenChannel::LLScreenChannel(LLUUID& id): LLScreenChannelBase(id)
+LLScreenChannel::LLScreenChannel(LLUUID& id):
+LLScreenChannelBase(id)
+,mStartUpToastPanel(NULL)
{
}
@@ -358,8 +360,6 @@ void LLScreenChannel::redrawToasts()
if(mToastList.size() == 0 || isHovering())
return;
- hideToastsFromScreen();
-
switch(mToastAlignment)
{
case NA_TOP :
@@ -383,6 +383,8 @@ void LLScreenChannel::showToastsBottom()
S32 toast_margin = 0;
std::vector<ToastElem>::reverse_iterator it;
+ closeOverflowToastPanel();
+
for(it = mToastList.rbegin(); it != mToastList.rend(); ++it)
{
if(it != mToastList.rbegin())
@@ -408,7 +410,20 @@ void LLScreenChannel::showToastsBottom()
if(stop_showing_toasts)
break;
- (*it).toast->setVisible(TRUE);
+ if( !(*it).toast->getVisible() )
+ {
+ if((*it).toast->isFirstLook())
+ {
+ (*it).toast->setVisible(TRUE);
+ }
+ else
+ {
+ // HACK
+ // EXT-2653: it is necessary to prevent overlapping for secondary showed toasts
+ (*it).toast->setVisible(TRUE);
+ gFloaterView->sendChildToBack((*it).toast);
+ }
+ }
}
if(it != mToastList.rend() && !mOverflowToastHidden)
@@ -417,6 +432,7 @@ void LLScreenChannel::showToastsBottom()
for(; it != mToastList.rend(); it++)
{
(*it).toast->stopTimer();
+ (*it).toast->setVisible(FALSE);
mHiddenToastsNum++;
}
createOverflowToast(bottom, gSavedSettings.getS32("NotificationTipToastLifeTime"));
diff --git a/indra/newview/llscrollingpanelparam.cpp b/indra/newview/llscrollingpanelparam.cpp
index b5e55df1f5..32a915608e 100644
--- a/indra/newview/llscrollingpanelparam.cpp
+++ b/indra/newview/llscrollingpanelparam.cpp
@@ -86,9 +86,8 @@ LLScrollingPanelParam::LLScrollingPanelParam( const LLPanel::Params& panel_param
childSetEnabled("param slider", mAllowModify);
childSetCommitCallback("param slider", LLScrollingPanelParam::onSliderMoved, this);
- // *TODO: Translate
- std::string min_name = param->getMinDisplayName();
- std::string max_name = param->getMaxDisplayName();
+ std::string min_name = LLTrans::getString(param->getMinDisplayName());
+ std::string max_name = LLTrans::getString(param->getMaxDisplayName());
childSetValue("min param text", min_name);
childSetValue("max param text", max_name);
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 0f8e86cb3c..d5f01418c6 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -32,6 +32,7 @@
#include "llviewerprecompiledheaders.h"
#include "llsidepanelappearance.h"
+#include "llaccordionctrltab.h"
#include "llagent.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
@@ -142,6 +143,7 @@ void LLSidepanelAppearance::onOpen(const LLSD& key)
{
fetchInventory();
refreshCurrentOutfitName();
+ updateVerbs();
if(key.size() == 0)
return;
@@ -188,16 +190,22 @@ void LLSidepanelAppearance::onOpenOutfitButtonClicked()
return;
if (!outfit_link->getIsLinkType())
return;
- LLInventoryPanel *inventory_panel = mPanelOutfitsInventory->getActivePanel();
- if (inventory_panel)
+
+ LLAccordionCtrlTab* tab_outfits = mPanelOutfitsInventory->findChild<LLAccordionCtrlTab>("tab_outfits");
+ if (tab_outfits)
{
- LLFolderView *folder = inventory_panel->getRootFolder();
- LLFolderViewItem *outfit_folder = folder->getItemByID(outfit_link->getLinkedUUID());
- if (outfit_folder)
+ tab_outfits->changeOpenClose(FALSE);
+ LLInventoryPanel *inventory_panel = tab_outfits->findChild<LLInventoryPanel>("outfitslist_accordionpanel");
+ if (inventory_panel)
{
- outfit_folder->setOpen(!outfit_folder->isOpen());
- folder->setSelectionFromRoot(outfit_folder,TRUE);
- folder->scrollToShowSelection();
+ LLFolderView *folder = inventory_panel->getRootFolder();
+ LLFolderViewItem *outfit_folder = folder->getItemByID(outfit_link->getLinkedUUID());
+ if (outfit_folder)
+ {
+ outfit_folder->setOpen(!outfit_folder->isOpen());
+ folder->setSelectionFromRoot(outfit_folder,TRUE);
+ folder->scrollToShowSelection();
+ }
}
}
}
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 2f98435b83..ee5fa46c9c 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -436,35 +436,16 @@ void LLSideTray::processTriState ()
expandSideBar();
else
{
- //!!!!!!!!!!!!!!!!!
- //** HARDCODED!!!!!
- //!!!!!!!!!!!!!!!!!
-
- //there is no common way to determine "default" panel for tab
- //so default panels for now will be hardcoded
-
- //hardcoded for people tab and profile tab
-
- /*if(mActiveTab == getTab("sidebar_people"))
- {
- LLSideTrayPanelContainer* container = findChild<LLSideTrayPanelContainer>("panel_container");
- if(container && container->getCurrentPanelIndex()>0)
- {
- container->onOpen(LLSD().insert("sub_panel_name","panel_people"));
- }
- else
- collapseSideBar();
- }
- else if(mActiveTab == getTab("sidebar_me"))
- {
- LLTabContainer* tab_container = findChild<LLTabContainer>("tabs");
- if(tab_container && tab_container->getCurrentPanelIndex()>0)
- tab_container->selectFirstTab();
- else
- collapseSideBar();
- }
- else*/
- collapseSideBar();
+#if 0 // *TODO: EXT-2092
+
+ // Tell the active task panel to switch to its default view
+ // or collapse side tray if already on the default view.
+ LLSD info;
+ info["task-panel-action"] = "handle-tri-state";
+ mActiveTab->notifyChildren(info);
+#else
+ collapseSideBar();
+#endif
}
}
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 22282d8a2e..e7fe85bdf0 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2155,7 +2155,7 @@ void login_callback(S32 option, void *userdata)
LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
return;
}
- else if (QUIT_OPTION == option)
+ else if (QUIT_OPTION == option) // *TODO: THIS CODE SEEMS TO BE UNREACHABLE!!!!! login_callback is never called with option equal to QUIT_OPTION
{
// Make sure we don't save the password if the user is trying to clear it.
std::string first, last, password;
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index 25e0ca46e4..a90f3ee181 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -223,7 +223,16 @@ BOOL LLTexLayerSetBuffer::render()
}
else
{
- readBackAndUpload();
+ if (mTexLayerSet->isVisible())
+ {
+ readBackAndUpload();
+ }
+ else
+ {
+ mUploadPending = FALSE;
+ mNeedsUpload = FALSE;
+ mTexLayerSet->getAvatar()->setNewBakedTexture(mTexLayerSet->getBakedTexIndex(),IMG_INVISIBLE);
+ }
}
}
@@ -551,6 +560,7 @@ LLTexLayerSet::LLTexLayerSet(LLVOAvatarSelf* const avatar) :
mComposite( NULL ),
mAvatar( avatar ),
mUpdatesEnabled( FALSE ),
+ mIsVisible( TRUE ),
mInfo( NULL )
{
}
@@ -665,38 +675,54 @@ BOOL LLTexLayerSet::isLocalTextureDataFinal() const
BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
{
BOOL success = TRUE;
+ mIsVisible = TRUE;
- LLGLSUIDefault gls_ui;
- LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE);
- gGL.setColorMask(true, true);
-
- // clear buffer area to ensure we don't pick up UI elements
+ if (mMaskLayerList.size() > 0)
{
- gGL.flush();
- LLGLDisable no_alpha(GL_ALPHA_TEST);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4f( 0.f, 0.f, 0.f, 1.f );
-
- gl_rect_2d_simple( width, height );
-
- gGL.flush();
+ for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++)
+ {
+ LLTexLayerInterface* layer = *iter;
+ if (layer->isInvisibleAlphaMask())
+ {
+ mIsVisible = FALSE;
+ }
+ }
}
- // composite color layers
- for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
+ if (mIsVisible)
{
- LLTexLayerInterface* layer = *iter;
- if (layer->getRenderPass() == LLTexLayer::RP_COLOR)
+ LLGLSUIDefault gls_ui;
+ LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE);
+ gGL.setColorMask(true, true);
+
+ // clear buffer area to ensure we don't pick up UI elements
{
gGL.flush();
- success &= layer->render(x, y, width, height);
+ LLGLDisable no_alpha(GL_ALPHA_TEST);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.color4f( 0.f, 0.f, 0.f, 1.f );
+
+ gl_rect_2d_simple( width, height );
+
gGL.flush();
}
- }
- renderAlphaMaskTextures(x, y, width, height, false);
-
- stop_glerror();
+ // composite color layers
+ for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
+ {
+ LLTexLayerInterface* layer = *iter;
+ if (layer->getRenderPass() == LLTexLayer::RP_COLOR)
+ {
+ gGL.flush();
+ success &= layer->render(x, y, width, height);
+ gGL.flush();
+ }
+ }
+
+ renderAlphaMaskTextures(x, y, width, height, false);
+
+ stop_glerror();
+ }
return success;
}
@@ -1709,6 +1735,19 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32
}
}
+/*virtual*/ BOOL LLTexLayer::isInvisibleAlphaMask()
+{
+ if (mLocalTextureObject)
+ {
+ if (mLocalTextureObject->getID() == IMG_INVISIBLE)
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
// private helper function
LLUUID LLTexLayer::getUUID()
{
@@ -1898,6 +1937,23 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i)
}
}
+/*virtual*/ BOOL LLTexLayerTemplate::isInvisibleAlphaMask()
+{
+ U32 num_wearables = updateWearableCache();
+ for (U32 i = 0; i < num_wearables; i++)
+ {
+ LLTexLayer *layer = getLayer(i);
+ if (layer)
+ {
+ if (layer->isInvisibleAlphaMask())
+ {
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
//-----------------------------------------------------------------------------
diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h
index cd8f27a96b..5be58f64a9 100644
--- a/indra/newview/lltexlayer.h
+++ b/indra/newview/lltexlayer.h
@@ -99,6 +99,7 @@ public:
virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) = 0;
BOOL hasAlphaParams() const { return !mParamAlphaList.empty(); }
BOOL isVisibilityMask() const;
+ virtual BOOL isInvisibleAlphaMask() = 0;
LLTexLayerSet* getLayerSet() {return mTexLayerSet;}
@@ -141,6 +142,8 @@ public:
/*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
/*virtual*/ void setHasMorph(BOOL newval);
/*virtual*/ void deleteCaches();
+ /*virtual*/ BOOL isInvisibleAlphaMask();
+
private:
U32 updateWearableCache();
LLTexLayer* getLayer(U32 i);
@@ -173,6 +176,7 @@ public:
/*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
BOOL renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color);
void addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
+ /*virtual*/ BOOL isInvisibleAlphaMask();
void setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; }
LLLocalTextureObject* getLTO() { return mLocalTextureObject; }
@@ -272,6 +276,7 @@ public:
BOOL hasComposite() const { return (mComposite.notNull()); }
LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; }
void setBakedTexIndex( LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
+ BOOL isVisible() const { return mIsVisible; }
public:
static BOOL sHasCaches;
@@ -284,6 +289,7 @@ private:
LLPointer<LLTexLayerSetBuffer> mComposite;
LLVOAvatarSelf* const mAvatar; // Backlink only; don't make this an LLPointer.
BOOL mUpdatesEnabled;
+ BOOL mIsVisible;
LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex;
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index f7240326fc..bf485b7e65 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -228,7 +228,7 @@ void LLToast::setVisible(BOOL show)
}
LLModalDialog::setFrontmost(FALSE);
}
- LLPanel::setVisible(show);
+ LLFloater::setVisible(show);
if(mPanel)
{
if(!mPanel->isDead())
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index d99d2f0870..d0ae5d1e38 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -57,11 +57,43 @@
#include "lltrans.h"
#include "llappearancemgr.h"
#include "llfloatercustomize.h"
+#include "llcommandhandler.h"
+#include "llviewermessage.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
///----------------------------------------------------------------------------
+class LLInventoryHandler : public LLCommandHandler
+{
+public:
+ // requires trusted browser to trigger
+ LLInventoryHandler() : LLCommandHandler("inventory", UNTRUSTED_THROTTLE) { }
+
+ bool handle(const LLSD& params, const LLSD& query_map,
+ LLMediaCtrl* web)
+ {
+ if (params.size() < 2) return false;
+ LLUUID inventory_id;
+ if (!inventory_id.set(params[0], FALSE))
+ {
+ return false;
+ }
+
+ const std::string verb = params[1].asString();
+ if (verb == "select")
+ {
+ std::vector<LLUUID> items_to_open;
+ items_to_open.push_back(inventory_id);
+ open_inventory_offer(items_to_open, "");
+ return true;
+ }
+
+ return false;
+ }
+};
+LLInventoryHandler gInventoryHandler;
+
///----------------------------------------------------------------------------
/// Class LLViewerInventoryItem
///----------------------------------------------------------------------------
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index fc469f5e51..f2ddb0b1f1 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -169,6 +169,12 @@ public:
completeAny(status, "text/html");
}
else
+ if(status == 404)
+ {
+ // Treat 404s like an html page.
+ completeAny(status, "text/html");
+ }
+ else
{
llwarns << "responder failed with status " << status << ", reason " << reason << llendl;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 8dd9b3df22..9fc818e1ff 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -171,7 +171,6 @@ static const F32 LLREQUEST_PERMISSION_THROTTLE_INTERVAL = 10.0f; // seconds
extern BOOL gDebugClicks;
// function prototypes
-void open_offer(const std::vector<LLUUID>& items, const std::string& from_name);
bool check_offer_throttle(const std::string& from_name, bool check_only);
//inventory offer throttle globals
@@ -728,7 +727,7 @@ public:
LLOpenAgentOffer(const std::string& from_name) : mFromName(from_name) {}
/*virtual*/ void done()
{
- open_offer(mComplete, mFromName);
+ open_inventory_offer(mComplete, mFromName);
gInventory.removeObserver(this);
delete this;
}
@@ -746,7 +745,7 @@ class LLOpenTaskOffer : public LLInventoryAddedObserver
protected:
/*virtual*/ void done()
{
- open_offer(mAdded, "");
+ open_inventory_offer(mAdded, "");
mAdded.clear();
}
};
@@ -877,7 +876,7 @@ bool check_offer_throttle(const std::string& from_name, bool check_only)
}
}
-void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)
+void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& from_name)
{
std::vector<LLUUID>::const_iterator it = items.begin();
std::vector<LLUUID>::const_iterator end = items.end();
@@ -1067,12 +1066,60 @@ LLSD LLOfferInfo::asLLSD()
return sd;
}
+void LLOfferInfo::send_auto_receive_response(void)
+{
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_MessageBlock);
+ msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
+ msg->addUUIDFast(_PREHASH_ToAgentID, mFromID);
+ msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
+ msg->addUUIDFast(_PREHASH_ID, mTransactionID);
+ msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
+ std::string name;
+ LLAgentUI::buildFullname(name);
+ msg->addStringFast(_PREHASH_FromAgentName, name);
+ msg->addStringFast(_PREHASH_Message, "");
+ msg->addU32Fast(_PREHASH_ParentEstateID, 0);
+ msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
+ msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
+
+ // Auto Receive Message. The math for the dialog works, because the accept
+ // for inventory_offered, task_inventory_offer or
+ // group_notice_inventory is 1 greater than the offer integer value.
+ // Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED,
+ // or IM_GROUP_NOTICE_INVENTORY_ACCEPTED
+ msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1));
+ msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData),
+ sizeof(mFolderID.mData));
+ // send the message
+ msg->sendReliable(mHost);
+
+ if(IM_INVENTORY_OFFERED == mIM)
+ {
+ // add buddy to recent people list
+ LLRecentPeople::instance().add(mFromID);
+ }
+}
+
bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& response)
- {
+{
LLChat chat;
std::string log_message;
S32 button = LLNotificationsUtil::getSelectedOption(notification, response);
-
+
+ LLInventoryObserver* opener = NULL;
+ LLViewerInventoryCategory* catp = NULL;
+ catp = (LLViewerInventoryCategory*)gInventory.getCategory(mObjectID);
+ LLViewerInventoryItem* itemp = NULL;
+ if(!catp)
+ {
+ itemp = (LLViewerInventoryItem*)gInventory.getItem(mObjectID);
+ }
+
// For muting, we need to add the mute, then decline the offer.
// This must be done here because:
// * callback may be called immediately,
@@ -1083,6 +1130,136 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
gCacheName->get(mFromID, mFromGroup, &inventory_offer_mute_callback);
}
+ std::string from_string; // Used in the pop-up.
+ std::string chatHistory_string; // Used in chat history.
+
+ // TODO: when task inventory offers can also be handled the new way, migrate the code that sets these strings here:
+ from_string = chatHistory_string = mFromName;
+
+ bool busy=FALSE;
+
+ switch(button)
+ {
+ case IOR_SHOW:
+ // we will want to open this item when it comes back.
+ LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << mTransactionID
+ << LL_ENDL;
+ switch (mIM)
+ {
+ case IM_INVENTORY_OFFERED:
+ {
+ // This is an offer from an agent. In this case, the back
+ // end has already copied the items into your inventory,
+ // so we can fetch it out of our inventory.
+ LLInventoryFetchObserver::item_ref_t items;
+ items.push_back(mObjectID);
+ LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(from_string);
+ open_agent_offer->fetchItems(items);
+ if(catp || (itemp && itemp->isComplete()))
+ {
+ open_agent_offer->done();
+ }
+ else
+ {
+ opener = open_agent_offer;
+ }
+ }
+ break;
+ case IM_TASK_INVENTORY_OFFERED:
+ case IM_GROUP_NOTICE:
+ case IM_GROUP_NOTICE_REQUESTED:
+ // This is an offer from a task or group.
+ // We don't use a new instance of an opener
+ // We instead use the singular observer gOpenTaskOffer
+ // Since it already exists, we don't need to actually do anything
+ break;
+ default:
+ LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
+ break;
+ } // end switch (mIM)
+
+ // Show falls through to accept.
+
+ case IOR_ACCEPT:
+ //don't spam them if they are getting flooded
+ if (check_offer_throttle(mFromName, true))
+ {
+ log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString(".");
+ chat.mText = log_message;
+ LLFloaterChat::addChatHistory(chat);
+ }
+ break;
+
+ case IOR_BUSY:
+ //Busy falls through to decline. Says to make busy message.
+ busy=TRUE;
+ case IOR_MUTE:
+ // MUTE falls through to decline
+ case IOR_DECLINE:
+ {
+ log_message = LLTrans::getString("InvOfferYouDecline") + " " + mDesc + " " + LLTrans::getString("InvOfferFrom") + " " + mFromName +".";
+ chat.mText = log_message;
+ if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::getInstance()->isLinden(mFromName) ) // muting for SL-42269
+ {
+ chat.mMuted = TRUE;
+ }
+ LLFloaterChat::addChatHistory(chat);
+
+ LLInventoryFetchComboObserver::folder_ref_t folders;
+ LLInventoryFetchComboObserver::item_ref_t items;
+ items.push_back(mObjectID);
+ LLDiscardAgentOffer* discard_agent_offer;
+ discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID);
+ discard_agent_offer->fetch(folders, items);
+ if(catp || (itemp && itemp->isComplete()))
+ {
+ discard_agent_offer->done();
+ }
+ else
+ {
+ opener = discard_agent_offer;
+ }
+
+
+ if (busy && (!mFromGroup && !mFromObject))
+ {
+ busy_message(gMessageSystem, mFromID);
+ }
+ break;
+ }
+ default:
+ // close button probably
+ // The item has already been fetched and is in your inventory, we simply won't highlight it
+ // OR delete it if the notification gets killed, since we don't want that to be a vector for
+ // losing inventory offers.
+ break;
+ }
+
+ if(opener)
+ {
+ gInventory.addObserver(opener);
+ }
+
+ delete this;
+ return false;
+}
+
+bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const LLSD& response)
+{
+ LLChat chat;
+ std::string log_message;
+ S32 button = LLNotification::getSelectedOption(notification, response);
+
+ // For muting, we need to add the mute, then decline the offer.
+ // This must be done here because:
+ // * callback may be called immediately,
+ // * adding the mute sends a message,
+ // * we can't build two messages at once.
+ if (2 == button)
+ {
+ gCacheName->get(mFromID, mFromGroup, &inventory_offer_mute_callback);
+ }
+
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -1109,7 +1286,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
{
itemp = (LLViewerInventoryItem*)gInventory.getItem(mObjectID);
}
-
+
std::string from_string; // Used in the pop-up.
std::string chatHistory_string; // Used in chat history.
if (mFromObject == TRUE)
@@ -1120,16 +1297,16 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
if (gCacheName->getGroupName(mFromID, group_name))
{
from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+"'"
- + mFromName + LLTrans::getString("'") +" " + LLTrans::getString("InvOfferOwnedByGroup")
- + " "+ "'" + group_name + "'";
+ + mFromName + LLTrans::getString("'") +" " + LLTrans::getString("InvOfferOwnedByGroup")
+ + " "+ "'" + group_name + "'";
chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedByGroup")
- + " " + group_name + "'";
+ + " " + group_name + "'";
}
else
{
from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+"'"
- + mFromName +"'"+ " " + LLTrans::getString("InvOfferOwnedByUnknownGroup");
+ + mFromName +"'"+ " " + LLTrans::getString("InvOfferOwnedByUnknownGroup");
chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedByUnknownGroup");
}
}
@@ -1139,13 +1316,13 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
if (gCacheName->getName(mFromID, first_name, last_name))
{
from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+ LLTrans::getString("'") + mFromName
- + LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedBy") + first_name + " " + last_name;
+ + LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedBy") + first_name + " " + last_name;
chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedBy") + " " + first_name + " " + last_name;
}
else
{
from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+LLTrans::getString("'")
- + mFromName + LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedByUnknownUser");
+ + mFromName + LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedByUnknownUser");
chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedByUnknownUser");
}
}
@@ -1159,137 +1336,90 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
switch(button)
{
- case IOR_ACCEPT:
- // ACCEPT. The math for the dialog works, because the accept
- // for inventory_offered, task_inventory_offer or
- // group_notice_inventory is 1 greater than the offer integer value.
- // Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED,
- // or IM_GROUP_NOTICE_INVENTORY_ACCEPTED
- msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1));
- msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData),
- sizeof(mFolderID.mData));
- // send the message
- msg->sendReliable(mHost);
-
- //don't spam them if they are getting flooded
- if (check_offer_throttle(mFromName, true))
- {
- log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString(".");
- chat.mText = log_message;
- LLFloaterChat::addChatHistory(chat);
- }
-
- // we will want to open this item when it comes back.
- LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << mTransactionID
- << LL_ENDL;
- switch (mIM)
- {
- case IM_INVENTORY_OFFERED:
- {
- // This is an offer from an agent. In this case, the back
- // end has already copied the items into your inventory,
- // so we can fetch it out of our inventory.
- LLInventoryFetchObserver::item_ref_t items;
- items.push_back(mObjectID);
- LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(from_string);
- open_agent_offer->fetchItems(items);
- if(catp || (itemp && itemp->isComplete()))
+ case IOR_ACCEPT:
+ // ACCEPT. The math for the dialog works, because the accept
+ // for inventory_offered, task_inventory_offer or
+ // group_notice_inventory is 1 greater than the offer integer value.
+ // Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED,
+ // or IM_GROUP_NOTICE_INVENTORY_ACCEPTED
+ msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1));
+ msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData),
+ sizeof(mFolderID.mData));
+ // send the message
+ msg->sendReliable(mHost);
+
+ //don't spam them if they are getting flooded
+ if (check_offer_throttle(mFromName, true))
{
- open_agent_offer->done();
+ log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString(".");
+ chat.mText = log_message;
+ LLFloaterChat::addChatHistory(chat);
}
- else
+
+ // we will want to open this item when it comes back.
+ LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << mTransactionID
+ << LL_ENDL;
+ switch (mIM)
+ {
+ case IM_TASK_INVENTORY_OFFERED:
+ case IM_GROUP_NOTICE:
+ case IM_GROUP_NOTICE_REQUESTED:
{
- opener = open_agent_offer;
+ // This is an offer from a task or group.
+ // We don't use a new instance of an opener
+ // We instead use the singular observer gOpenTaskOffer
+ // Since it already exists, we don't need to actually do anything
}
- }
+ break;
+ default:
+ LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
+ break;
+ } // end switch (mIM)
break;
- case IM_TASK_INVENTORY_OFFERED:
- case IM_GROUP_NOTICE:
- case IM_GROUP_NOTICE_REQUESTED:
- {
- // This is an offer from a task or group.
- // We don't use a new instance of an opener
- // We instead use the singular observer gOpenTaskOffer
- // Since it already exists, we don't need to actually do anything
- }
- break;
+
+ case IOR_BUSY:
+ //Busy falls through to decline. Says to make busy message.
+ busy=TRUE;
+ case IOR_MUTE:
+ // MUTE falls through to decline
+ case IOR_DECLINE:
+ // DECLINE. The math for the dialog works, because the decline
+ // for inventory_offered, task_inventory_offer or
+ // group_notice_inventory is 2 greater than the offer integer value.
+ // Generates IM_INVENTORY_DECLINED, IM_TASK_INVENTORY_DECLINED,
+ // or IM_GROUP_NOTICE_INVENTORY_DECLINED
default:
- LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
- break;
- } // end switch (mIM)
- break;
-
- case IOR_BUSY:
- //Busy falls through to decline. Says to make busy message.
- busy=TRUE;
- case IOR_MUTE:
- // MUTE falls through to decline
- case IOR_DECLINE:
- // DECLINE. The math for the dialog works, because the decline
- // for inventory_offered, task_inventory_offer or
- // group_notice_inventory is 2 greater than the offer integer value.
- // Generates IM_INVENTORY_DECLINED, IM_TASK_INVENTORY_DECLINED,
- // or IM_GROUP_NOTICE_INVENTORY_DECLINED
- default:
- // close button probably (or any of the fall-throughs from above)
- msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 2));
- msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE);
- // send the message
- msg->sendReliable(mHost);
-
- log_message = LLTrans::getString("InvOfferYouDecline") + " " + mDesc + " " + LLTrans::getString("InvOfferFrom") + " " + mFromName +".";
- chat.mText = log_message;
- if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::getInstance()->isLinden(mFromName) ) // muting for SL-42269
- {
- chat.mMuted = TRUE;
- }
- LLFloaterChat::addChatHistory(chat);
-
- // If it's from an agent, we have to fetch the item to throw
- // it away. If it's from a task or group, just denying the
- // request will suffice to discard the item.
- if(IM_INVENTORY_OFFERED == mIM)
- {
- LLInventoryFetchComboObserver::folder_ref_t folders;
- LLInventoryFetchComboObserver::item_ref_t items;
- items.push_back(mObjectID);
- LLDiscardAgentOffer* discard_agent_offer;
- discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID);
- discard_agent_offer->fetch(folders, items);
- if(catp || (itemp && itemp->isComplete()))
+ // close button probably (or any of the fall-throughs from above)
+ msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 2));
+ msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE);
+ // send the message
+ msg->sendReliable(mHost);
+
+ log_message = LLTrans::getString("InvOfferYouDecline") + " " + mDesc + " " + LLTrans::getString("InvOfferFrom") + " " + mFromName +".";
+ chat.mText = log_message;
+ if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::getInstance()->isLinden(mFromName) ) // muting for SL-42269
{
- discard_agent_offer->done();
+ chat.mMuted = TRUE;
}
- else
+ LLFloaterChat::addChatHistory(chat);
+
+ if (busy && (!mFromGroup && !mFromObject))
{
- opener = discard_agent_offer;
+ busy_message(msg,mFromID);
}
-
- }
- if (busy && (!mFromGroup && !mFromObject))
- {
- busy_message(msg,mFromID);
- }
- break;
- }
-
- if(IM_INVENTORY_OFFERED == mIM)
- {
- // add buddy to recent people list
- LLRecentPeople::instance().add(mFromID);
+ break;
}
-
+
if(opener)
{
gInventory.addObserver(opener);
}
-
+
delete this;
return false;
}
-
-void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
+void inventory_offer_handler(LLOfferInfo* info)
{
//Until throttling is implmented, busy mode should reject inventory instead of silently
//accepting it. SEE SL-39554
@@ -1376,21 +1506,45 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
args["OBJECTFROMNAME"] = info->mFromName;
args["NAME"] = info->mFromName;
args["NAME_SLURL"] = LLSLURL::buildCommand("agent", info->mFromID, "about");
- std::string verb = "highlight?name=" + msg;
+ std::string verb = "select?name=" + msg;
args["ITEM_SLURL"] = LLSLURL::buildCommand("inventory", info->mObjectID, verb.c_str());
LLNotification::Params p("ObjectGiveItem");
- p.substitutions(args).payload(payload).functor.function(boost::bind(&LLOfferInfo::inventory_offer_callback, info, _1, _2));
- if (from_task)
+ // Object -> Agent Inventory Offer
+ if (info->mFromObject)
{
+ // Inventory Slurls don't currently work for non agent transfers, so only display the object name.
+ args["ITEM_SLURL"] = msg;
+ // Note: sets inventory_task_offer_callback as the callback
+ p.substitutions(args).payload(payload).functor.function(boost::bind(&LLOfferInfo::inventory_task_offer_callback, info, _1, _2));
p.name = name_found ? "ObjectGiveItem" : "ObjectGiveItemUnknownUser";
}
- else
+ else // Agent -> Agent Inventory Offer
{
+ // Note: sets inventory_offer_callback as the callback
+ p.substitutions(args).payload(payload).functor.function(boost::bind(&LLOfferInfo::inventory_offer_callback, info, _1, _2));
p.name = "UserGiveItem";
+
+ // Prefetch the item into your local inventory.
+ LLInventoryFetchObserver::item_ref_t items;
+ items.push_back(info->mObjectID);
+ LLInventoryFetchObserver* fetch_item = new LLInventoryFetchObserver();
+ fetch_item->fetchItems(items);
+ if(fetch_item->isEverythingComplete())
+ {
+ fetch_item->done();
+ }
+ else
+ {
+ gInventory.addObserver(fetch_item);
+ }
+
+ // In viewer 2 we're now auto receiving inventory offers and messaging as such (not sending reject messages).
+ info->send_auto_receive_response();
}
-
+
+ // Pop up inv offer notification and let the user accept (keep), or reject (and silently delete) the inventory.
LLNotifications::instance().add(p);
}
@@ -1886,7 +2040,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
}
else
{
- inventory_offer_handler(info, dialog == IM_TASK_INVENTORY_OFFERED);
+ inventory_offer_handler(info);
}
}
break;
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index e24da2013d..1a98828010 100644
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -59,7 +59,8 @@ enum InventoryOfferResponse
IOR_ACCEPT,
IOR_DECLINE,
IOR_MUTE,
- IOR_BUSY
+ IOR_BUSY,
+ IOR_SHOW
};
BOOL can_afford_transaction(S32 cost);
@@ -197,6 +198,7 @@ void invalid_message_callback(LLMessageSystem*, void*, EMessageException);
void process_initiate_download(LLMessageSystem* msg, void**);
void start_new_inventory_observer();
+void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& from_name);
struct LLOfferInfo
{
@@ -218,7 +220,9 @@ struct LLOfferInfo
LLHost mHost;
LLSD asLLSD();
+ void send_auto_receive_response(void);
bool inventory_offer_callback(const LLSD& notification, const LLSD& response);
+ bool inventory_task_offer_callback(const LLSD& notification, const LLSD& response);
};
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index ccf3822876..f12937194d 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1349,6 +1349,7 @@ LLViewerWindow::LLViewerWindow(
mDebugText = new LLDebugText(this);
+ mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);
}
void LLViewerWindow::initGLDefaults()
@@ -2870,19 +2871,17 @@ void LLViewerWindow::updateWorldViewRect(bool use_full_window)
if (mWorldViewRectRaw != new_world_rect)
{
- // sending a signal with a new WorldView rect
- mOnWorldViewRectUpdated(mWorldViewRectRaw, new_world_rect);
-
+ LLRect old_world_rect = mWorldViewRectRaw;
mWorldViewRectRaw = new_world_rect;
gResizeScreenTexture = TRUE;
LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
- mWorldViewRectScaled = mWorldViewRectRaw;
- mWorldViewRectScaled.mLeft = llround((F32)mWorldViewRectScaled.mLeft / mDisplayScale.mV[VX]);
- mWorldViewRectScaled.mRight = llround((F32)mWorldViewRectScaled.mRight / mDisplayScale.mV[VX]);
- mWorldViewRectScaled.mBottom = llround((F32)mWorldViewRectScaled.mBottom / mDisplayScale.mV[VY]);
- mWorldViewRectScaled.mTop = llround((F32)mWorldViewRectScaled.mTop / mDisplayScale.mV[VY]);
+ mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);
+
+ // sending a signal with a new WorldView rect
+ old_world_rect = calcScaledRect(old_world_rect, mDisplayScale);
+ mOnWorldViewRectUpdated(old_world_rect, mWorldViewRectScaled);
}
}
@@ -4755,7 +4754,6 @@ F32 LLViewerWindow::getWorldViewAspectRatio() const
}
else
{
- llinfos << "World aspect ratio: " << world_aspect << llendl;
return world_aspect;
}
}
@@ -4797,6 +4795,18 @@ void LLViewerWindow::calcDisplayScale()
}
}
+//static
+LLRect LLViewerWindow::calcScaledRect(const LLRect & rect, const LLVector2& display_scale)
+{
+ LLRect res = rect;
+ res.mLeft = llround((F32)res.mLeft / display_scale.mV[VX]);
+ res.mRight = llround((F32)res.mRight / display_scale.mV[VX]);
+ res.mBottom = llround((F32)res.mBottom / display_scale.mV[VY]);
+ res.mTop = llround((F32)res.mTop / display_scale.mV[VY]);
+
+ return res;
+}
+
S32 LLViewerWindow::getChatConsoleBottomPad()
{
S32 offset = 0;
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 517993182b..747fd3b253 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -391,6 +391,7 @@ public:
F32 getWorldViewAspectRatio() const;
const LLVector2& getDisplayScale() const { return mDisplayScale; }
void calcDisplayScale();
+ static LLRect calcScaledRect(const LLRect & rect, const LLVector2& display_scale);
private:
bool shouldShowToolTipFor(LLMouseHandler *mh);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 75e35e5221..9882dcd6af 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -3868,7 +3868,7 @@ U32 LLVOAvatar::renderRigid()
return 0;
}
- if (isTextureVisible(TEX_EYES_BAKED) || mIsDummy)
+ if (isTextureVisible(TEX_EYES_BAKED) || mIsDummy)
{
num_indices += mMeshLOD[MESH_ID_EYEBALL_LEFT]->render(mAdjustedPixelArea, TRUE, mIsDummy);
num_indices += mMeshLOD[MESH_ID_EYEBALL_RIGHT]->render(mAdjustedPixelArea, TRUE, mIsDummy);
@@ -7636,15 +7636,19 @@ void LLVOAvatar::idleUpdateRenderCost()
return;
}
- U32 shame = 0;
+ U32 cost = 0;
+ std::set<LLUUID> textures;
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
ETextureIndex tex_index = baked_dict->mTextureIndex;
- if (isTextureVisible(tex_index))
+ if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(WT_SKIRT)))
{
- shame +=20;
+ if (isTextureVisible(tex_index))
+ {
+ cost +=20;
+ }
}
}
@@ -7663,20 +7667,22 @@ void LLVOAvatar::idleUpdateRenderCost()
const LLDrawable* drawable = attached_object->mDrawable;
if (drawable)
{
- shame += 10;
+ cost += 10;
const LLVOVolume* volume = drawable->getVOVolume();
if (volume)
{
- shame += volume->getRenderCost();
+ cost += volume->getRenderCost(textures);
}
}
}
}
}
- setDebugText(llformat("%d", shame));
- F32 green = 1.f-llclamp(((F32) shame-1024.f)/1024.f, 0.f, 1.f);
- F32 red = llmin((F32) shame/1024.f, 1.f);
+ cost += textures.size() * 5;
+
+ setDebugText(llformat("%d", cost));
+ F32 green = 1.f-llclamp(((F32) cost-1024.f)/1024.f, 0.f, 1.f);
+ F32 red = llmin((F32) cost/1024.f, 1.f);
mText->setColor(LLColor4(red,green,0,1));
}
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index d9c5e932a2..f3e787ae7e 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -318,11 +318,6 @@ BOOL LLVOAvatarSelf::buildMenus()
}
}
-
- if (!attachment_found)
- {
- gAttachPieMenu->addSeparator();
- }
}
if (gDetachBodyPartPieMenus[i])
@@ -362,11 +357,6 @@ BOOL LLVOAvatarSelf::buildMenus()
break;
}
}
-
- if (!attachment_found)
- {
- gDetachPieMenu->addSeparator();
- }
}
}
@@ -1849,6 +1839,13 @@ ETextureIndex LLVOAvatarSelf::getBakedTE( const LLTexLayerSet* layerset ) const
}
+void LLVOAvatarSelf::setNewBakedTexture(LLVOAvatarDefines::EBakedTextureIndex i, const LLUUID &uuid)
+{
+ ETextureIndex index = LLVOAvatarDictionary::bakedToLocalTextureIndex(i);
+ setNewBakedTexture(index, uuid);
+}
+
+
//-----------------------------------------------------------------------------
// setNewBakedTexture()
// A new baked texture has been successfully uploaded and we can start using it now.
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index a1cad82eff..e376e5e9ef 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -209,6 +209,7 @@ private:
//--------------------------------------------------------------------
public:
LLVOAvatarDefines::ETextureIndex getBakedTE(const LLTexLayerSet* layerset ) const;
+ void setNewBakedTexture(LLVOAvatarDefines::EBakedTextureIndex i, const LLUUID &uuid);
void setNewBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid);
void setCachedBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid);
void forceBakeAllTextures(bool slam_for_debug = false);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 428af5380c..48bd387022 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -2566,7 +2566,11 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const
return mDrawable->getWorldMatrix();
}
-U32 LLVOVolume::getRenderCost() const
+// Returns a base cost and adds textures to passed in set.
+// total cost is returned value + 5 * size of the resulting set.
+// Cannot include cost of textures, as they may be re-used in linked
+// children, and cost should only be increased for unique textures -Nyx
+U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const
{
U32 shame = 0;
@@ -2599,7 +2603,7 @@ U32 LLVOVolume::getRenderCost() const
{
const LLSculptParams *sculpt_params = (LLSculptParams *) getParameterEntry(LLNetworkData::PARAMS_SCULPT);
LLUUID sculpt_id = sculpt_params->getSculptTexture();
- shame += 5;
+ textures.insert(sculpt_id);
}
for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
@@ -2608,7 +2612,7 @@ U32 LLVOVolume::getRenderCost() const
const LLTextureEntry* te = face->getTextureEntry();
const LLViewerTexture* img = face->getTexture();
- shame += 5;
+ textures.insert(img->getID());
if (face->getPoolType() == LLDrawPool::POOL_ALPHA)
{
@@ -2658,7 +2662,7 @@ U32 LLVOVolume::getRenderCost() const
const LLVOVolume* child_volumep = child_drawablep->getVOVolume();
if (child_volumep)
{
- shame += child_volumep->getRenderCost();
+ shame += child_volumep->getRenderCost(textures);
}
}
}
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 70d203daf2..06e214b41e 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -121,7 +121,7 @@ public:
const LLMatrix4& getRelativeXform() const { return mRelativeXform; }
const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; }
/*virtual*/ const LLMatrix4 getRenderMatrix() const;
- U32 getRenderCost() const;
+ U32 getRenderCost(std::set<LLUUID> &textures) const;
/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp
index 0c15e80f9b..807434c397 100644
--- a/indra/newview/llwearable.cpp
+++ b/indra/newview/llwearable.cpp
@@ -422,18 +422,6 @@ BOOL LLWearable::importFile( LLFILE* file )
// copy all saved param values to working params
revertValues();
- // Hack pt 2. If the wearable we just loaded has definition version 24,
- // then force a re-save of this wearable after slamming the version number to 22.
- // This number was incorrectly incremented for internal builds before release, and
- // this fix will ensure that the affected wearables are re-saved with the right version number.
- // the versions themselves are compatible. This code can be removed before release.
- if( mDefinitionVersion == 24 )
- {
- mDefinitionVersion = 22;
- U32 index = gAgentWearables.getWearableIndex(this);
- gAgentWearables.saveWearable(mType,index,TRUE);
- }
-
return TRUE;
}
diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h
index 0863adb7f5..43ffa12420 100644
--- a/indra/newview/llwearable.h
+++ b/indra/newview/llwearable.h
@@ -82,6 +82,8 @@ public:
const std::string& getTypeName() const;
LLAssetType::EType getAssetType() const;
LLLocalTextureObject* getLocalTextureObject(S32 index) const;
+ S32 getDefinitionVersion() const { return mDefinitionVersion; }
+ void setDefinitionVersion( S32 new_version ) { mDefinitionVersion = new_version; }
public:
typedef std::vector<LLVisualParam*> visual_param_vec_t;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 5aad87630d..f908a015df 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -346,10 +346,7 @@ LLPipeline::LLPipeline() :
mLightMovingMask(0),
mLightingDetail(0),
mScreenWidth(0),
- mScreenHeight(0),
- mViewportWidth(0),
- mViewportHeight(0)
-
+ mScreenHeight(0)
{
mNoiseMap = 0;
mTrueNoiseMap = 0;
@@ -517,46 +514,29 @@ void LLPipeline::resizeScreenTexture()
LLFastTimer ft(FTM_RESIZE_SCREEN_TEXTURE);
if (gPipeline.canUseVertexShaders() && assertInitialized())
{
- GLuint resX = gViewerWindow->getWindowWidthRaw();
- GLuint resY = gViewerWindow->getWindowHeightRaw();
- GLuint view_width = gViewerWindow->getWorldViewWidthRaw();
- GLuint view_height = gViewerWindow->getWorldViewHeightRaw();
+ GLuint resX = gViewerWindow->getWorldViewWidthRaw();
+ GLuint resY = gViewerWindow->getWorldViewHeightRaw();
- allocateScreenBuffer(resX, resY, view_width, view_height);
+ allocateScreenBuffer(resX,resY);
}
}
-void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 viewport_width, U32 viewport_height)
+void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
{
- bool screen_size_changed = resX != mScreenWidth || resY != mScreenHeight;
- bool viewport_size_changed = viewport_width != mViewportWidth || viewport_height != mViewportHeight;
-
- if (!screen_size_changed
- && !viewport_size_changed)
- {
- // nothing to do
- return;
- }
-
// remember these dimensions
mScreenWidth = resX;
mScreenHeight = resY;
- mViewportWidth = viewport_width;
- mViewportHeight = viewport_height;
-
- llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl;
-
+
U32 samples = gSavedSettings.getU32("RenderFSAASamples");
-
U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor");
+
if (res_mod > 1 && res_mod < resX && res_mod < resY)
{
resX /= res_mod;
resY /= res_mod;
}
- if (gSavedSettings.getBOOL("RenderUIBuffer")
- && screen_size_changed)
+ if (gSavedSettings.getBOOL("RenderUIBuffer"))
{
mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
}
@@ -564,51 +544,30 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 viewport_width, U3
if (LLPipeline::sRenderDeferred)
{
//allocate deferred rendering color buffers
- if (screen_size_changed)
- {
- mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
- mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
- addDeferredAttachments(mDeferredScreen);
- }
+ mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
+ mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
+ addDeferredAttachments(mDeferredScreen);
+
// always set viewport to desired size, since allocate resets the viewport
- mDeferredScreen.setViewport(viewport_width, viewport_height);
- mDeferredDepth.setViewport(viewport_width, viewport_height);
- if (screen_size_changed)
- {
- mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
- mEdgeMap.allocate(resX, resY, GL_ALPHA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
- }
- mScreen.setViewport(viewport_width, viewport_height);
- mEdgeMap.setViewport(viewport_width, viewport_height);
+ mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
+ mEdgeMap.allocate(resX, resY, GL_ALPHA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
for (U32 i = 0; i < 3; i++)
{
- if (screen_size_changed)
- {
- mDeferredLight[i].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
- }
- mDeferredLight[i].setViewport(viewport_width, viewport_height);
+ mDeferredLight[i].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
}
for (U32 i = 0; i < 2; i++)
{
- if (screen_size_changed)
- {
- mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
- }
- mGIMapPost[i].setViewport(viewport_width, viewport_height);
+ mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
}
F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale");
for (U32 i = 0; i < 4; i++)
{
- if (screen_size_changed)
- {
- mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
- }
- mShadow[i].setViewport(viewport_width, viewport_height);
+ mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
}
@@ -617,52 +576,36 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 viewport_width, U3
for (U32 i = 4; i < 6; i++)
{
- if (screen_size_changed)
- {
- mShadow[i].allocate(width, height, 0, TRUE, FALSE);
- }
- mShadow[i].setViewport(viewport_width, viewport_height);
+ mShadow[i].allocate(width, height, 0, TRUE, FALSE);
}
width = nhpo2(resX)/2;
height = nhpo2(resY)/2;
- if (screen_size_changed)
- {
- mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE);
- }
- mLuminanceMap.setViewport(viewport_width, viewport_height);
+ mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE);
}
else
{
- if (screen_size_changed)
- {
- mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
- }
- mScreen.setViewport(viewport_width, viewport_height);
+ mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
}
if (gGLManager.mHasFramebufferMultisample && samples > 1)
{
- if (screen_size_changed)
+ mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples);
+ if (LLPipeline::sRenderDeferred)
{
- mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples);
- if (LLPipeline::sRenderDeferred)
- {
- addDeferredAttachments(mSampleBuffer);
- mDeferredScreen.setSampleBuffer(&mSampleBuffer);
- }
+ addDeferredAttachments(mSampleBuffer);
+ mDeferredScreen.setSampleBuffer(&mSampleBuffer);
}
- mSampleBuffer.setViewport(viewport_width, viewport_height);
+
mScreen.setSampleBuffer(&mSampleBuffer);
stop_glerror();
}
- if (LLPipeline::sRenderDeferred
- && screen_size_changed)
+ if (LLPipeline::sRenderDeferred)
{ //share depth buffer between deferred targets
mDeferredScreen.shareDepthBuffer(mScreen);
for (U32 i = 0; i < 3; i++)
@@ -762,10 +705,8 @@ void LLPipeline::createGLBuffers()
stop_glerror();
- GLuint resX = gViewerWindow->getWindowWidthRaw();
- GLuint resY = gViewerWindow->getWindowHeightRaw();
- GLuint viewport_width = gViewerWindow->getWorldViewWidthRaw();
- GLuint viewport_height = gViewerWindow->getWorldViewHeightRaw();
+ GLuint resX = gViewerWindow->getWorldViewWidthRaw();
+ GLuint resY = gViewerWindow->getWorldViewHeightRaw();
if (LLPipeline::sRenderGlow)
{ //screen space glow buffers
@@ -777,11 +718,10 @@ void LLPipeline::createGLBuffers()
mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE);
}
- // force reallocation of buffers by clearing known dimensions
+ allocateScreenBuffer(resX,resY);
mScreenWidth = 0;
mScreenHeight = 0;
- allocateScreenBuffer(resX,resY, viewport_width, viewport_height);
}
if (sRenderDeferred)
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 11b7b55f20..67004a5f2d 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -111,7 +111,7 @@ public:
void resizeScreenTexture();
void releaseGLBuffers();
void createGLBuffers();
- void allocateScreenBuffer(U32 resX, U32 resY, U32 viewport_width, U32 viewport_height);
+ void allocateScreenBuffer(U32 resX, U32 resY);
void resetVertexBuffers(LLDrawable* drawable);
void setUseVBO(BOOL use_vbo);
@@ -469,9 +469,7 @@ public:
//screen texture
U32 mScreenWidth;
U32 mScreenHeight;
- U32 mViewportWidth;
- U32 mViewportHeight;
-
+
LLRenderTarget mScreen;
LLRenderTarget mUIScreen;
LLRenderTarget mDeferredScreen;
diff --git a/indra/newview/skins/default/textures/icons/Stop_Off.png b/indra/newview/skins/default/textures/icons/Stop_Off.png
new file mode 100644
index 0000000000..3ee215d36f
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Stop_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/UnZoom_Off.png b/indra/newview/skins/default/textures/icons/UnZoom_Off.png
new file mode 100644
index 0000000000..c794113755
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/UnZoom_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 99f6fc5cb3..3576b6ed77 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -490,6 +490,9 @@ with the same filename but different name
<texture name="Stepper_Up_Off" file_name="widgets/Stepper_Up_Off.png" preload="true" />
<texture name="Stepper_Up_Press" file_name="widgets/Stepper_Up_Press.png" preload="true" />
+ <texture name="Stop_Off" file_name="icons/Stop_Off.png" preload="false" />
+ <texture name="Stop_Over" file_name="icons/Stop_Over.png" preload="false" />
+ <texture name="Stop_Press" file_name="icons/Stop_Press.png" preload="false" />
<texture name="StopReload_Off" file_name="icons/StopReload_Off.png" preload="false" />
<texture name="StopReload_Over" file_name="icons/StopReload_Over.png" preload="false" />
<texture name="StopReload_Press" file_name="icons/StopReload_Press.png" preload="false" />
@@ -607,6 +610,15 @@ with the same filename but different name
<texture name="Zoom_Off" file_name="icons/Zoom_Off.png" preload="false" />
<texture name="Zoom_Over" file_name="icons/Zoom_Over.png" preload="false" />
<texture name="Zoom_Press" file_name="icons/Zoom_Press.png" preload="false" />
+ <texture name="UnZoom_Off" file_name="icons/UnZoom_Off.png" preload="false" />
+ <texture name="UnZoom_Over" file_name="icons/UnZoom_Over.png" preload="false" />
+ <texture name="UnZoom_Press" file_name="icons/UnZoom_Press.png" preload="false" />
+ <texture name="PowerOn_Off" file_name="icons/PowerOn_Off.png" preload="false" />
+ <texture name="PowerOn_Over" file_name="icons/PowerOn_Over.png" preload="false" />
+ <texture name="PowerOn_Press" file_name="icons/PowerOn_Press.png" preload="false" />
+ <texture name="PowerOff_Off" file_name="icons/PowerOff_Off.png" preload="false" />
+ <texture name="PowerOff_Over" file_name="icons/PowerOff_Over.png" preload="false" />
+ <texture name="PowerOff_Press" file_name="icons/PowerOff_Press.png" preload="false" />
<!--WARNING OLD ART *do not use*-->
diff --git a/indra/newview/skins/default/xui/de/panel_me.xml b/indra/newview/skins/default/xui/de/panel_me.xml
new file mode 100644
index 0000000000..a685a430f0
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_me.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Ich" name="panel_me">
+ <tab_container name="tabs">
+ <panel label="Mein Profil" name="panel_profile"/>
+ <panel label="Auswahl" name="panel_picks"/>
+ </tab_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 7f2f37409c..645c2973d8 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -18,7 +18,7 @@
min_height="350">
<layout_stack
follows="all"
- height="350"
+ height="320"
width="300"
layout="topleft"
orientation="horizontal"
@@ -35,7 +35,8 @@
<layout_panel
left="0"
top="0"
- width="180"
+ height="200"
+ width="185"
user_resize="false">
<button
height="20"
@@ -55,10 +56,9 @@
width="25"
name="slide_right_btn" />
<chat_history
- length="1"
font="SansSerifSmall"
- follows="left|right|top"
- height="280"
+ follows="left|right|top|bottom"
+ height="150"
name="chat_history"
parse_highlights="true"
allow_html="true"
@@ -66,12 +66,13 @@
width="180">
</chat_history>
<line_editor
- follows="left|right|top"
+ bottom="0"
+ follows="left|right|bottom"
font="SansSerifSmall"
height="20"
label="To"
+ layout="bottomleft"
name="chat_editor"
- top_pad="1"
width="180">
</line_editor>
</layout_panel>
diff --git a/indra/newview/skins/default/xui/en/menu_profile_overflow.xml b/indra/newview/skins/default/xui/en/menu_profile_overflow.xml
index 7b52fecef7..d0128d1c9a 100644
--- a/indra/newview/skins/default/xui/en/menu_profile_overflow.xml
+++ b/indra/newview/skins/default/xui/en/menu_profile_overflow.xml
@@ -12,4 +12,11 @@
<menu_item_call.on_click
function="Profile.Pay" />
</menu_item_call>
+ <menu_item_call
+ label="Share"
+ layout="topleft"
+ name="share">
+ <menu_item_call.on_click
+ function="Profile.Share" />
+ </menu_item_call>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_url_inventory.xml b/indra/newview/skins/default/xui/en/menu_url_inventory.xml
new file mode 100644
index 0000000000..cf9d1d5881
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_url_inventory.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Url Popup">
+ <menu_item_call
+ label="Show Inventory Item"
+ layout="topleft"
+ name="show_item">
+ <menu_item_call.on_click
+ function="Url.Execute" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Copy Name to clipboard"
+ layout="topleft"
+ name="url_copy_label">
+ <menu_item_call.on_click
+ function="Url.CopyLabel" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy SLurl to clipboard"
+ layout="topleft"
+ name="url_copy">
+ <menu_item_call.on_click
+ function="Url.CopyUrl" />
+ </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 75d8ea6697..ae8a1599a9 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1718,6 +1718,8 @@
layout="topleft"
name="Fly"
shortcut="Home">
+ <menu_item_check.on_check
+ function="Agent.getFlying" />
<menu_item_check.on_click
function="Agent.toggleFlying" />
<menu_item_check.on_enable
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index ca749406d4..6e178ad570 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3939,6 +3939,18 @@ Would you like to leave Busy Mode before completing this transaction?
<notification
icon="alertmodal.tga"
+ name="ConfirmDeleteProtectedCategory"
+ type="alertmodal">
+The folder &apos;[FOLDERNAME]&apos; is a system folder. Deleting system folders can cause instability. Are you sure you want to delete it?
+ <usetemplate
+ ignoretext="Confirm before I delete a system folder"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="ConfirmEmptyTrash"
type="alertmodal">
Are you sure you want to permanently delete the contents of your Trash?
@@ -4494,7 +4506,7 @@ You don&apos;t have permission to copy this.
icon="notifytip.tga"
name="InventoryAccepted"
type="notifytip">
-[NAME] accepted your inventory offer.
+[NAME] received your inventory offer.
</notification>
<notification
@@ -4966,17 +4978,17 @@ No valid parcel could be found.
icon="notify.tga"
name="ObjectGiveItem"
type="offer">
-An object named [OBJECTFROMNAME] owned by [NAME_SLURL] has offered you [OBJECTTYPE]:
+An object named [OBJECTFROMNAME] owned by [NAME_SLURL] has given you [OBJECTTYPE]:
[ITEM_SLURL]
<form name="form">
<button
index="0"
name="Keep"
- text="OK"/>
+ text="Keep"/>
<button
index="1"
name="Discard"
- text="Cancel"/>
+ text="Discard"/>
<button
index="2"
name="Mute"
@@ -4988,17 +5000,17 @@ An object named [OBJECTFROMNAME] owned by [NAME_SLURL] has offered you [OBJECTTY
icon="notify.tga"
name="ObjectGiveItemUnknownUser"
type="offer">
-An object named [OBJECTFROMNAME] owned by (an unknown Resident) has offered you [OBJECTTYPE]:
+An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you [OBJECTTYPE]:
[ITEM_SLURL]
<form name="form">
<button
index="0"
name="Keep"
- text="OK"/>
+ text="Keep"/>
<button
index="1"
name="Discard"
- text="Cancel"/>
+ text="Discard"/>
<button
index="2"
name="Mute"
@@ -5010,17 +5022,21 @@ An object named [OBJECTFROMNAME] owned by (an unknown Resident) has offered you
icon="notify.tga"
name="UserGiveItem"
type="offer">
-[NAME_SLURL] has offered you [OBJECTTYPE]:
+[NAME_SLURL] has given you [OBJECTTYPE]:
[ITEM_SLURL]
<form name="form">
<button
index="0"
name="Keep"
- text="Accept"/>
+ text="Keep"/>
+ <button
+ index="4"
+ name="Show"
+ text="Show"/>
<button
index="1"
name="Discard"
- text="No, thanks"/>
+ text="Discard"/>
</form>
</notification>
diff --git a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml
index a283cff5b3..368ab17689 100644
--- a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml
+++ b/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
border="false"
+ follows="all"
height="215"
name="panel_im_control_panel"
width="180">
@@ -23,7 +24,7 @@
bg_alpha_color="DkGray2"
border="false"
bottom="1"
- follows="left|bottom"
+ follows="left|right|bottom"
height="70"
left="0"
left_pad="0"
@@ -32,6 +33,7 @@
width="180">
<button
bottom="10"
+ follows="all"
height="20"
label="Call"
left_delta="40"
@@ -39,6 +41,7 @@
width="100" />
<button
bottom="40"
+ follows="all"
height="20"
label="Leave Call"
name="end_call_btn"
@@ -46,6 +49,7 @@
width="100" />
<button
enabled="false"
+ follows="all"
bottom="10"
height="20"
label="Voice Controls"
diff --git a/indra/newview/skins/default/xui/en/panel_chat_header.xml b/indra/newview/skins/default/xui/en/panel_chat_header.xml
index 692461b1a2..c1090a1686 100644
--- a/indra/newview/skins/default/xui/en/panel_chat_header.xml
+++ b/indra/newview/skins/default/xui/en/panel_chat_header.xml
@@ -27,7 +27,7 @@
height="12"
layout="topleft"
left_pad="5"
- right="-50"
+ right="-60"
name="user_name"
text_color="white"
top="8"
@@ -41,7 +41,7 @@
layout="topleft"
left_pad="5"
name="time_box"
- right="-10"
+ right="-5"
top="8"
value="23:30"
width="50" />
diff --git a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
index 2fee2033f6..41b210557e 100644
--- a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
border="false"
+ follows="left|top|right|bottom"
height="238"
name="panel_im_control_panel"
width="180">
@@ -22,6 +23,7 @@
<button
bottom_pad="0"
+ follows="left|right|bottom"
height="20"
label="Group Info"
left_delta="28"
@@ -32,7 +34,7 @@
background_visible="true"
bg_alpha_color="0.2 0.2 0.2 1"
border="false"
- follows="left|bottom"
+ follows="left|right|bottom"
height="70"
left="0"
left_pad="0"
@@ -42,6 +44,7 @@
<button
bottom="10"
+ follows="all"
height="20"
label="Call Group"
left_delta="28"
@@ -50,6 +53,7 @@
<button
bottom="40"
+ follows="all"
height="20"
label="Leave Call"
name="end_call_btn"
@@ -59,6 +63,7 @@
<button
enabled="false"
bottom="10"
+ follows="all"
height="20"
label="Open Voice Controls"
name="voice_ctrls_btn"
diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
index 73d843e6dd..0a5812882d 100644
--- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
+++ b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
@@ -38,12 +38,12 @@
label="Teleport"
name="teleport_btn"
width="100" />
- <!-- <button
+ <button
follows="left|top"
height="20"
label="Share"
name="share_btn"
- width="100" />-->
+ width="100" />
<!--Removing pay button to save space - will update spec - verified by Erica/Steve -->
<!-- <button
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_me.xml b/indra/newview/skins/default/xui/en/panel_me.xml
new file mode 100644
index 0000000000..a99777848b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_me.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ border="false"
+ follows="all"
+ height="570"
+ label="My Profile"
+ layout="topleft"
+ left="0"
+ name="panel_me"
+ top="0"
+ width="333">
+ <!--<text
+ type="string"
+ follows="top|left|right"
+ font="SansSerifHugeBold"
+ height="20"
+ layout="topleft"
+ left="15"
+ name="user_name"
+ text_color="white"
+ top="0"
+ mouse_opaque="true"
+ width="280">
+ (Loading...)
+ </text> -->
+ <tab_container
+ follows="all"
+ height="575"
+ halign="center"
+ layout="topleft"
+ left="10"
+ name="tabs"
+ tab_min_width="95"
+ tab_height="30"
+ tab_position="top"
+ top_pad="10"
+ width="313">
+ <panel
+ class="panel_my_profile"
+ filename="panel_my_profile.xml"
+ label="PROFILE"
+ help_topic="panel_my_profile_tab"
+ name="panel_profile" />
+ <panel
+ class="panel_picks"
+ filename="panel_picks.xml"
+ label="PICKS"
+ help_topic="panel_my_picks_tab"
+ name="panel_picks" />
+ </tab_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
index 686f4ac1d5..e00f654750 100644
--- a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
@@ -93,27 +93,19 @@
</text>
<combo_box
allow_text_entry="false"
- bottom_delta="-20"
- enabled="true"
+ bottom_delta="-20"
follows="left|top"
height="18"
left="10"
- max_chars="20"
- mouse_opaque="true"
+ max_chars="20"
name="controls"
width="120">
<combo_item
- type="string"
- length="1"
- enabled="true"
name="Standard"
value="Standard">
Standard
</combo_item>
<combo_item
- type="string"
- length="1"
- enabled="true"
name="Mini"
value="Mini">
Mini
diff --git a/indra/newview/skins/default/xui/en/panel_my_profile.xml b/indra/newview/skins/default/xui/en/panel_my_profile.xml
new file mode 100644
index 0000000000..fe3e010cf9
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_my_profile.xml
@@ -0,0 +1,429 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="all"
+ height="535"
+ label="Profile"
+ layout="topleft"
+ left="0"
+ name="panel_profile"
+ top="0"
+ width="313">
+ <string
+ name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string
+ name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string
+ name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string
+ name="my_account_link_url"
+ value="http://secondlife.com/account" />
+ <string
+ name="no_partner_text"
+ value="None" />
+ <string
+ name="RegisterDateFormat">
+ [REG_DATE] ([AGE])
+ </string>
+ <scroll_container
+ color="DkGray2"
+ follows="all"
+ height="485"
+ layout="topleft"
+ name="profile_scroll"
+ reserve_scroll_corner="true"
+ opaque="true"
+ top="0"
+ width="313">
+ <panel
+ name="scroll_content_panel"
+ follows="left|top|right"
+ height="485"
+ layout="topleft"
+ top="0"
+ left="0"
+ width="313">
+ <panel
+ follows="left|top"
+ height="117"
+ layout="topleft"
+ left="10"
+ name="second_life_image_panel"
+ top="0"
+ width="280">
+ <texture_picker
+ allow_no_texture="true"
+ default_image_name="None"
+ enabled="false"
+ follows="top|left"
+ height="117"
+ layout="topleft"
+ left="0"
+ name="2nd_life_pic"
+ top="10"
+ width="102" />
+ <icon
+ height="102"
+ image_name="Blank"
+ layout="topleft"
+ name="2nd_life_edit_icon"
+ label=""
+ left="0"
+ tool_tip="Click the Edit Profile button below to change image"
+ top="10"
+ width="102" />
+ <text
+ follows="left|top|right"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left_pad="10"
+ name="title_sl_descr_text"
+ text_color="white"
+ top_delta="0"
+ value="[SECOND_LIFE]:"
+ width="165" />
+ <expandable_text
+ follows="left|top|right"
+ height="95"
+ layout="topleft"
+ left="107"
+ textbox.max_length="512"
+ name="sl_description_edit"
+ top_pad="-3"
+ width="173"
+ expanded_bg_visible="true"
+ expanded_bg_color="DkGray">
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum.
+ </expandable_text>
+ </panel>
+ <panel
+ follows="left|top"
+ height="117"
+ layout="topleft"
+ top_pad="10"
+ left="10"
+ name="first_life_image_panel"
+ width="280">
+ <texture_picker
+ allow_no_texture="true"
+ default_image_name="None"
+ enabled="false"
+ follows="top|left"
+ height="117"
+ layout="topleft"
+ left="0"
+ name="real_world_pic"
+ width="102" />
+ <icon
+ height="102"
+ image_name="Blank"
+ layout="topleft"
+ name="real_world_edit_icon"
+ label=""
+ left="0"
+ tool_tip="Click the Edit Profile button below to change image"
+ top="4"
+ width="102" />
+ <text
+ follows="left|top|right"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left_pad="10"
+ name="title_rw_descr_text"
+ text_color="white"
+ top_delta="0"
+ value="Real World:"
+ width="165" />
+ <expandable_text
+ follows="left|top|right"
+ height="95"
+ layout="topleft"
+ left="107"
+ textbox.max_length="512"
+ name="fl_description_edit"
+ top_pad="-3"
+ width="173"
+ expanded_bg_visible="true"
+ expanded_bg_color="DkGray">
+ Lorem ipsum dolor sit amet, consectetur adlkjpiscing elit moose moose. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet. adipiscing elit. Aenean rigviverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet sorbet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum.
+ </expandable_text>
+ </panel>
+
+
+ <!-- <panel
+ name="lifes_images_panel"
+ follows="left|top|right"
+ height="244"
+ layout="topleft"
+ top="0"
+ left="0"
+ width="285">
+ <panel
+ follows="left|top"
+ height="117"
+ layout="topleft"
+ left="10"
+ name="second_life_image_panel"
+ top="0"
+ width="285">
+ <text
+ follows="left|top|right"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="0"
+ name="second_life_photo_title_text"
+ text_color="white"
+ value="[SECOND_LIFE]:"
+ width="170" />
+ <texture_picker
+ allow_no_texture="true"
+ default_image_name="None"
+ enabled="false"
+ follows="top|left"
+ height="117"
+ layout="topleft"
+ left="0"
+ name="2nd_life_pic"
+ top_pad="0"
+ width="102" />
+ </panel>
+ <icon
+ height="18"
+ image_name="AddItem_Off"
+ layout="topleft"
+ name="2nd_life_edit_icon"
+ label=""
+ left="87"
+ tool_tip="Click to select an image"
+ top="25"
+ width="18" />
+ </panel> -->
+
+
+
+
+ <text
+ type="string"
+ follows="left|top"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="me_homepage_text"
+ text_color="white"
+ top_pad="0"
+ width="280">
+ Homepage:
+ </text>
+ <text
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="homepage_edit"
+ top_pad="0"
+ value="http://librarianavengers.org"
+ width="280"
+ word_wrap="false"
+ use_ellipses="true"
+ />
+ <text
+ follows="left|top"
+ font.style="BOLD"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="title_member_text"
+ text_color="white"
+ top_pad="10"
+ value="Member Since:"
+ width="280" />
+ <text
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="register_date"
+ value="05/31/1976"
+ width="280"
+ word_wrap="true" />
+ <text
+ follows="left|top"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="title_acc_status_text"
+ text_color="white"
+ top_pad="10"
+ value="Account Status:"
+ width="280" />
+ <!-- <text
+ type="string"
+ follows="left|top"
+ font="SansSerifSmall"
+ height="15"
+ layout="topleft"
+ left_pad="10"
+ name="my_account_link"
+ top_delta="0"
+ value="Go to Dashboard"
+ width="100"/> -->
+ <text
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="acc_status_text"
+ top_pad="0"
+ value="Resident. No payment info on file."
+ width="280"
+ word_wrap="true" />
+ <text
+ follows="left|top"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="title_partner_text"
+ text_color="white"
+ top_pad="5"
+ value="Partner:"
+ width="280" />
+ <panel
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="partner_data_panel"
+ top_pad="0"
+ width="280">
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="0"
+ name="partner_text"
+ top="0"
+ value="[FIRST] [LAST]"
+ width="280"
+ word_wrap="true" />
+ </panel>
+ <text
+ follows="left|top"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="title_groups_text"
+ text_color="white"
+ top_pad="8"
+ value="Groups:"
+ width="280" />
+ <expandable_text
+ follows="left|top|bottom"
+ height="60"
+ layout="topleft"
+ left="10"
+ name="sl_groups"
+ top_pad="0"
+ width="280"
+ expanded_bg_visible="true"
+ expanded_bg_color="DkGray">
+ Lorem ipsum dolor sit amet, consectetur adlkjpiscing elit moose moose. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet. adipiscing elit. Aenean rigviverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet sorbet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum.
+ </expandable_text>
+ </panel>
+ </scroll_container>
+ <panel
+ follows="bottom|left"
+ layout="topleft"
+ left="0"
+ name="profile_buttons_panel"
+ top_pad="2"
+ bottom="10"
+ height="19"
+ width="303">
+ <button
+ follows="bottom|left"
+ height="19"
+ label="Add Friend"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="add_friend"
+ top="5"
+ width="75" />
+ <button
+ follows="bottom|left"
+ height="19"
+ label="IM"
+ layout="topleft"
+ name="im"
+ top="5"
+ left_pad="5"
+ width="45" />
+ <button
+ follows="bottom|left"
+ height="19"
+ label="Call"
+ layout="topleft"
+ name="call"
+ left_pad="5"
+ top="5"
+ width="45" />
+ <button
+ enabled="false"
+ follows="bottom|left"
+ height="19"
+ label="Map"
+ layout="topleft"
+ name="show_on_map_btn"
+ top="5"
+ left_pad="5"
+ width="45" />
+ <button
+ follows="bottom|left"
+ height="19"
+ label="Teleport"
+ layout="topleft"
+ name="teleport"
+ left_pad="5"
+ top="5"
+ width="80" />
+ </panel>
+ <panel
+ follows="bottom|left"
+ layout="topleft"
+ left="0"
+ top_pad="-17"
+ name="profile_me_buttons_panel"
+ visible="false"
+ height="19"
+ width="303">
+ <button
+ follows="bottom|right"
+ height="19"
+ left="10"
+ label="Edit Profile"
+ name="edit_profile_btn"
+ width="130" />
+ <button
+ follows="bottom|right"
+ height="19"
+ label="Edit Appearance"
+ left_pad="10"
+ name="edit_appearance_btn"
+ right="-10"
+ width="130" />
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
index f511ec0d6f..d805209bf5 100644
--- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
@@ -6,6 +6,18 @@
width="310"
border="true"
follows="left|top|right|bottom">
+ <accordion
+ follows="left|top|right|bottom"
+ height="315"
+ layout="topleft"
+ left="0"
+ name="outfits_accordion"
+ top="2"
+ width="310">
+ <accordion_tab
+ layout="topleft"
+ name="tab_outfits"
+ title="Outfits bar">
<inventory_panel
allow_multi_select="true"
border="true"
@@ -14,9 +26,28 @@
height="326"
left="0"
mouse_opaque="true"
- name="outfits_list"
+ name="outfitslist_accordionpanel"
width="310"
start_folder="My Outfits"/>
+ </accordion_tab>
+ <accordion_tab
+ layout="topleft"
+ name="tab_cof"
+ title="Current Outfit bar">
+ <inventory_panel
+ allow_multi_select="true"
+ border="true"
+ bottom="0"
+ follows="left|top|right|bottom"
+ height="326"
+ left="0"
+ mouse_opaque="true"
+ name="cof_accordionpanel"
+ width="310"
+ start_folder="Current Outfit"/>
+ </accordion_tab>
+ </accordion>
+
<button bottom="0"
halign="center"
height="16"
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
index 69a81adecd..ca84c9147b 100644
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ b/indra/newview/skins/default/xui/en/panel_picks.xml
@@ -24,7 +24,7 @@
top="10"
visible="false"
width="313">
- There are no any picks/classifieds here
+ There are no picks/classifieds here
</text>
<accordion
follows="all"
diff --git a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml
index 88049fe7d1..af4c01185a 100644
--- a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml
@@ -3,7 +3,7 @@
follows="left|right|top|bottom"
name="MediaControls"
background_visible="false"
- height="160"
+ height="192"
layout="topleft"
mouse_opaque="false"
width="800">
@@ -17,44 +17,6 @@
mouse_opaque="false"
top="20" />
<layout_stack
- follows="left|right|bottom"
- height="32"
- layout="topleft"
- animate="false"
- left="0"
- orientation="horizontal"
- top="96">
- <!-- outer layout_panels center the inner one -->
- <layout_panel
- width="0"
- layout="topleft"
- user_resize="false" />
- <panel
- name="media_progress_indicator"
- height="22"
- layout="topleft"
- visible="false"
- left="0"
- top="0"
- auto_resize="false"
- user_resize="false"
- min_width="100"
- width="200">
- <progress_bar
- name="media_progress_bar"
- color_bar="1 1 1 0.96"
- follows="left|right|top"
- height="16"
- layout="topleft"
- left="0"
- tool_tip="Media is Loading"/>
- </panel>
- <layout_panel
- width="0"
- layout="topleft"
- user_resize="false" />
- </layout_stack>
- <layout_stack
name="media_controls"
follows="left|right"
animate="false"
@@ -152,9 +114,8 @@
top="2"
min_width="22"
width="22">
- <!-- The stop button here is temporary artwork -->
<button
- image_overlay="media_btn_stoploading.png"
+ image_overlay="Stop_Off"
image_disabled="PushButton_Disabled"
image_disabled_selected="PushButton_Disabled"
image_selected="PushButton_Selected"
@@ -417,8 +378,8 @@ function="MediaCtrl.CommitURL" />
height="22"
min_width="22"
width="22">
- <!-- Note: this isn't quite right either...the mute button is not the -->
- <!-- same as the others because it can't have the "image_overlay" be -->
+ <!-- Note: this is not quite right either...the mute button is not the -->
+ <!-- same as the others because it cannot have the "image_overlay" be -->
<!-- two different images. -->
<button
image_disabled="PushButton_Disabled"
@@ -439,7 +400,7 @@ function="MediaCtrl.CommitURL" />
function="MediaCtrl.ToggleMute" />
</button>
</layout_panel>
- <!-- We don't have a design yet for "volume", so this is a temporary -->
+ <!-- We do not have a design yet for "volume", so this is a temporary -->
<!-- solution. See DEV-42827. -->
<layout_panel
name="volume_up"
@@ -609,9 +570,8 @@ function="MediaCtrl.CommitURL" />
layout="topleft"
min_width="21"
width="21" >
- <!-- There is no "Zoom out" icon, so we use this temporarily -->
<button
- image_overlay="ForwardArrow_Off"
+ image_overlay="UnZoom_Off"
image_disabled="PushButton_Disabled"
image_disabled_selected="PushButton_Disabled"
image_selected="PushButton_Selected"
@@ -657,4 +617,41 @@ function="MediaCtrl.CommitURL" />
layout="topleft"
user_resize="false" />
</layout_stack>
+ <layout_stack
+ follows="left|right|bottom"
+ height="32"
+ layout="topleft"
+ animate="false"
+ left="0"
+ orientation="horizontal"
+ top="150">
+ <!-- outer layout_panels center the inner one -->
+ <layout_panel
+ width="0"
+ layout="topleft"
+ user_resize="false" />
+ <panel
+ name="media_progress_indicator"
+ height="22"
+ layout="topleft"
+ left="0"
+ top="0"
+ auto_resize="false"
+ user_resize="false"
+ min_width="100"
+ width="200">
+ <progress_bar
+ name="media_progress_bar"
+ color_bar="1 1 1 0.96"
+ follows="left|right|top"
+ height="8"
+ layout="topleft"
+ left="0"
+ tool_tip="Media is Loading"/>
+ </panel>
+ <layout_panel
+ width="0"
+ layout="topleft"
+ user_resize="false" />
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml
index d02354a647..95242a9639 100644
--- a/indra/newview/skins/default/xui/en/panel_side_tray.xml
+++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml
@@ -102,9 +102,9 @@
background_visible="true"
>
<panel
- class="panel_me_profile_view"
- name="panel_me_profile"
- filename="panel_me_profile.xml"
+ class="panel_me"
+ name="panel_me"
+ filename="panel_me.xml"
label="Me"
/>
</sidetray_tab>
diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
index 51b74307c8..33a6a52f5c 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
@@ -49,16 +49,6 @@
top="0"
width="60" />
<button
- enabled="true"
- follows="bottom|left"
- height="25"
- label="Share"
- layout="topleft"
- left_pad="5"
- name="share_btn"
- top="0"
- width="60" />
- <button
enabled="false"
follows="bottom|left"
height="25"
diff --git a/indra/newview/skins/default/xui/fr/panel_me.xml b/indra/newview/skins/default/xui/fr/panel_me.xml
new file mode 100644
index 0000000000..5bedee4616
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_me.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Moi" name="panel_me">
+ <tab_container name="tabs">
+ <panel label="Mon Profil" name="panel_profile"/>
+ <panel label="Préférences" name="panel_picks"/>
+ </tab_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_me.xml b/indra/newview/skins/default/xui/ja/panel_me.xml
new file mode 100644
index 0000000000..84151f43cf
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_me.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="ミー" name="panel_me">
+ <tab_container name="tabs">
+ <panel label="プロフィール" name="panel_profile"/>
+ <panel label="ピック" name="panel_picks"/>
+ </tab_container>
+</panel>
diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp
index 217889c390..6ff2c9446e 100644
--- a/indra/newview/tests/llmediadataclient_test.cpp
+++ b/indra/newview/tests/llmediadataclient_test.cpp
@@ -191,6 +191,12 @@ public:
virtual bool isDead() const
{ return mDead; }
+ void setDistanceFromAvatar(F64 val)
+ { mRep["distance"] = val; }
+
+ void setTotalMediaInterest(F64 val)
+ { mRep["interest"] = val; }
+
int getNumBounceBacks() const
{ return mNumBounceBacks; }
@@ -593,6 +599,91 @@ namespace tut
ensure("queue empty", mdc->isEmpty());
}
-
+ ensure("refcount of o1", o1->getNumRefs(), 1);
+ ensure("refcount of o2", o2->getNumRefs(), 1);
+ ensure("refcount of o3", o3->getNumRefs(), 1);
+ ensure("refcount of o4", o4->getNumRefs(), 1);
+
}
+
+ //////////////////////////////////////////////////////////////////////////////////////////
+
+ template<> template<>
+ void mediadataclient_object_t::test<9>()
+ {
+ //
+ // Test queue re-ordering
+ //
+ LOG_TEST(9);
+
+ LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"10.0","1.0"));
+ LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"20.0","1.0"));
+ LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"30.0","1.0"));
+ LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"40.0","1.0"));
+ {
+ LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);
+
+ // queue up all 4 objects. They should now be in the queue in
+ // order 1 through 4, with 4 being at the front of the queue
+ mdc->fetchMedia(o1);
+ mdc->fetchMedia(o2);
+ mdc->fetchMedia(o3);
+ mdc->fetchMedia(o4);
+
+ int test_num = 0;
+
+ ensure(STR(test_num) + ". is in queue 1", mdc->isInQueue(o1));
+ ensure(STR(test_num) + ". is in queue 2", mdc->isInQueue(o2));
+ ensure(STR(test_num) + ". is in queue 3", mdc->isInQueue(o3));
+ ensure(STR(test_num) + ". is in queue 4", mdc->isInQueue(o4));
+ ensure(STR(test_num) + ". post records", gPostRecords->size(), 0);
+
+ ::pump_timers();
+ ++test_num;
+
+ // The first tick should remove the first one
+ ensure(STR(test_num) + ". is not in queue 1", !mdc->isInQueue(o1));
+ ensure(STR(test_num) + ". is in queue 2", mdc->isInQueue(o2));
+ ensure(STR(test_num) + ". is in queue 3", mdc->isInQueue(o3));
+ ensure(STR(test_num) + ". is in queue 4", mdc->isInQueue(o4));
+ ensure(STR(test_num) + ". post records", gPostRecords->size(), 1);
+
+ // Now, pretend that object 4 moved relative to the avatar such
+ // that it is now closest
+ static_cast<LLMediaDataClientObjectTest*>(
+ static_cast<LLMediaDataClientObject*>(o4))->setDistanceFromAvatar(5.0);
+
+ ::pump_timers();
+ ++test_num;
+
+ // The second tick should still pick off item 2, but then re-sort
+ // have picked off object 4
+ ensure(STR(test_num) + ". is in queue 2", mdc->isInQueue(o2));
+ ensure(STR(test_num) + ". is in queue 3", mdc->isInQueue(o3));
+ ensure(STR(test_num) + ". is not in queue 4", !mdc->isInQueue(o4));
+ ensure(STR(test_num) + ". post records", gPostRecords->size(), 2);
+
+ ::pump_timers();
+ ++test_num;
+
+ // The third tick should pick off object 2
+ ensure(STR(test_num) + ". is not in queue 2", !mdc->isInQueue(o2));
+ ensure(STR(test_num) + ". is in queue 3", mdc->isInQueue(o3));
+ ensure(STR(test_num) + ". post records", gPostRecords->size(), 3);
+
+ // The fourth tick should pick off object 3
+ ::pump_timers();
+ ++test_num;
+
+ ensure(STR(test_num) + ". is not in queue 3", !mdc->isInQueue(o3));
+ ensure(STR(test_num) + ". post records", gPostRecords->size(), 4);
+
+ ensure("queue empty", mdc->isEmpty());
+ }
+ ensure("refcount of o1", o1->getNumRefs(), 1);
+ ensure("refcount of o2", o2->getNumRefs(), 1);
+ ensure("refcount of o3", o3->getNumRefs(), 1);
+ ensure("refcount of o4", o4->getNumRefs(), 1);
+ }
+
}