summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorTofu Linden <tofu.linden@lindenlab.com>2010-07-26 10:34:39 +0100
committerTofu Linden <tofu.linden@lindenlab.com>2010-07-26 10:34:39 +0100
commit44d0fd81ee3d26a80068713182ac19885ea40f95 (patch)
tree96577339efce5ccb30dc3968ebb3ee2bd9ea4155 /indra/newview
parentd6726e6e4b40efaee35b8df5ac9d1098f208bcac (diff)
parentfe91462d6277251dbcc6053bc8ecd54dd93a13f0 (diff)
(hairy) merge from viewer-release
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llagent.cpp4
-rw-r--r--indra/newview/llagentcamera.cpp2
-rw-r--r--indra/newview/llappearancemgr.cpp210
-rw-r--r--indra/newview/llappearancemgr.h186
-rw-r--r--indra/newview/llappviewer.cpp2
-rw-r--r--indra/newview/llavataractions.cpp5
-rw-r--r--indra/newview/llchathistory.cpp18
-rw-r--r--indra/newview/llcofwearables.cpp34
-rw-r--r--indra/newview/llcofwearables.h4
-rw-r--r--indra/newview/lldynamictexture.cpp4
-rw-r--r--indra/newview/llfloaterland.cpp3
-rw-r--r--indra/newview/llfolderview.h1
-rw-r--r--indra/newview/llgroupmgr.cpp10
-rw-r--r--indra/newview/llinventorylistitem.cpp7
-rw-r--r--indra/newview/lllogininstance.cpp21
-rw-r--r--indra/newview/llmoveview.cpp10
-rw-r--r--indra/newview/llmoveview.h2
-rw-r--r--indra/newview/lloutfitslist.cpp39
-rw-r--r--indra/newview/lloutfitslist.h5
-rw-r--r--indra/newview/llpaneleditwearable.cpp40
-rw-r--r--indra/newview/llpaneleditwearable.h5
-rw-r--r--indra/newview/llpanelgroup.cpp12
-rw-r--r--indra/newview/llpanelgroup.h3
-rw-r--r--indra/newview/llpanelgrouplandmoney.cpp8
-rw-r--r--indra/newview/llpanelgrouproles.cpp7
-rw-r--r--indra/newview/llpaneloutfitedit.cpp35
-rw-r--r--indra/newview/llpaneloutfitedit.h4
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp2
-rw-r--r--indra/newview/llpanelplaceinfo.cpp13
-rw-r--r--indra/newview/llpanelplaceprofile.cpp9
-rw-r--r--indra/newview/llpanelplaceprofile.h2
-rw-r--r--indra/newview/llsidepanelappearance.cpp21
-rw-r--r--indra/newview/lltexlayerparams.cpp2
-rw-r--r--indra/newview/lltexturectrl.cpp30
-rw-r--r--indra/newview/lltexturefetch.cpp23
-rw-r--r--indra/newview/llviewerinventory.cpp21
-rw-r--r--indra/newview/llviewermenu.cpp84
-rw-r--r--indra/newview/llviewermessage.cpp18
-rw-r--r--indra/newview/llviewertexteditor.cpp50
-rw-r--r--indra/newview/llviewertexteditor.h7
-rw-r--r--indra/newview/llviewerwindow.cpp2
-rw-r--r--indra/newview/llvoavatar.cpp42
-rw-r--r--indra/newview/llvoavatar.h3
-rw-r--r--indra/newview/llvoavatarself.cpp21
-rw-r--r--indra/newview/llwearable.cpp2
-rw-r--r--indra/newview/llwearableitemslist.cpp83
-rw-r--r--indra/newview/llwearableitemslist.h73
-rw-r--r--indra/newview/llworldmap.cpp9
-rw-r--r--indra/newview/llworldmap.h2
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml4
-rw-r--r--indra/newview/skins/default/xui/en/menu_attachment_self.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_notices.xml13
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_roles.xml4
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/floater_water.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_windlight_options.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_nearby_media.xml2
-rw-r--r--indra/newview/tests/lllogininstance_test.cpp10
59 files changed, 867 insertions, 379 deletions
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 53b7febba7..e85d108bb2 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -3079,7 +3079,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
return;
}
- if (gAgentCamera.cameraCustomizeAvatar())
+ if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
{
// ignore baked textures when in customize mode
return;
@@ -3548,7 +3548,7 @@ void LLAgent::sendAgentSetAppearance()
{
if (!isAgentAvatarValid()) return;
- if (gAgentQueryManager.mNumPendingQueries > 0 && !gAgentCamera.cameraCustomizeAvatar())
+ if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && gAgentAvatarp->isUsingBakedTextures()))
{
return;
}
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 1ef9e34f87..4dc78e9a1d 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -941,7 +941,7 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction)
*/
}
- if( cameraCustomizeAvatar() )
+ if(cameraCustomizeAvatar())
{
new_distance = llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM );
}
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index d2449abf08..b64007aa75 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1801,9 +1801,9 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool
llinfos << "wearInventoryCategory( " << category->getName()
<< " )" << llendl;
- callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal,
- &LLAppearanceMgr::instance(),
- category->getUUID(), copy, append));
+ callAfterCategoryFetch(category->getUUID(), boost::bind(&LLAppearanceMgr::wearCategoryFinal,
+ &LLAppearanceMgr::instance(),
+ category->getUUID(), copy, append));
}
void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append)
@@ -2699,6 +2699,21 @@ BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const
return gInventory.isObjectDescendentOf(obj_id, getCOF());
}
+// static
+bool LLAppearanceMgr::isLinkInCOF(const LLUUID& obj_id)
+{
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ LLLinkedItemIDMatches find_links(gInventory.getLinkedItemID(obj_id));
+ gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(),
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ find_links);
+
+ return !items.empty();
+}
+
BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const
{
if (!getIsInCOF(obj_id)) return FALSE;
@@ -2726,3 +2741,192 @@ BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const
return FALSE;
*/
}
+
+// Shim class to allow arbitrary boost::bind
+// expressions to be run as one-time idle callbacks.
+//
+// TODO: rework idle function spec to take a boost::function in the first place.
+class OnIdleCallbackOneTime
+{
+public:
+ OnIdleCallbackOneTime(nullary_func_t callable):
+ mCallable(callable)
+ {
+ }
+ static void onIdle(void *data)
+ {
+ gIdleCallbacks.deleteFunction(onIdle, data);
+ OnIdleCallbackOneTime* self = reinterpret_cast<OnIdleCallbackOneTime*>(data);
+ self->call();
+ delete self;
+ }
+ void call()
+ {
+ mCallable();
+ }
+private:
+ nullary_func_t mCallable;
+};
+
+void doOnIdleOneTime(nullary_func_t callable)
+{
+ OnIdleCallbackOneTime* cb_functor = new OnIdleCallbackOneTime(callable);
+ gIdleCallbacks.addFunction(&OnIdleCallbackOneTime::onIdle,cb_functor);
+}
+
+// Shim class to allow generic boost functions to be run as
+// recurring idle callbacks. Callable should return true when done,
+// false to continue getting called.
+//
+// TODO: rework idle function spec to take a boost::function in the first place.
+class OnIdleCallbackRepeating
+{
+public:
+ OnIdleCallbackRepeating(bool_func_t callable):
+ mCallable(callable)
+ {
+ }
+ // Will keep getting called until the callable returns true.
+ static void onIdle(void *data)
+ {
+ OnIdleCallbackRepeating* self = reinterpret_cast<OnIdleCallbackRepeating*>(data);
+ bool done = self->call();
+ if (done)
+ {
+ gIdleCallbacks.deleteFunction(onIdle, data);
+ delete self;
+ }
+ }
+ bool call()
+ {
+ return mCallable();
+ }
+private:
+ bool_func_t mCallable;
+};
+
+void doOnIdleRepeating(bool_func_t callable)
+{
+ OnIdleCallbackRepeating* cb_functor = new OnIdleCallbackRepeating(callable);
+ gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor);
+}
+
+class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver
+{
+public:
+ CallAfterCategoryFetchStage2(const uuid_vec_t& ids,
+ nullary_func_t callable) :
+ LLInventoryFetchItemsObserver(ids),
+ mCallable(callable)
+ {
+ }
+ ~CallAfterCategoryFetchStage2()
+ {
+ }
+ virtual void done()
+ {
+ llinfos << this << " done with incomplete " << mIncomplete.size()
+ << " complete " << mComplete.size() << " calling callable" << llendl;
+
+ gInventory.removeObserver(this);
+ doOnIdleOneTime(mCallable);
+ delete this;
+ }
+protected:
+ nullary_func_t mCallable;
+};
+
+class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver
+{
+public:
+ CallAfterCategoryFetchStage1(const LLUUID& cat_id, nullary_func_t callable) :
+ LLInventoryFetchDescendentsObserver(cat_id),
+ mCallable(callable)
+ {
+ }
+ ~CallAfterCategoryFetchStage1()
+ {
+ }
+ virtual void done()
+ {
+ // What we do here is get the complete information on the items in
+ // the library, and set up an observer that will wait for that to
+ // happen.
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+ gInventory.collectDescendents(mComplete.front(),
+ cat_array,
+ item_array,
+ LLInventoryModel::EXCLUDE_TRASH);
+ S32 count = item_array.count();
+ if(!count)
+ {
+ llwarns << "Nothing fetched in category " << mComplete.front()
+ << llendl;
+ //dec_busy_count();
+ gInventory.removeObserver(this);
+
+ // lets notify observers that loading is finished.
+ gAgentWearables.notifyLoadingFinished();
+ delete this;
+ return;
+ }
+
+ llinfos << "stage1 got " << item_array.count() << " items, passing to stage2 " << llendl;
+ uuid_vec_t ids;
+ for(S32 i = 0; i < count; ++i)
+ {
+ ids.push_back(item_array.get(i)->getUUID());
+ }
+
+ gInventory.removeObserver(this);
+
+ // do the fetch
+ CallAfterCategoryFetchStage2 *stage2 = new CallAfterCategoryFetchStage2(ids, mCallable);
+ stage2->startFetch();
+ if(stage2->isFinished())
+ {
+ // everything is already here - call done.
+ stage2->done();
+ }
+ else
+ {
+ // it's all on it's way - add an observer, and the inventory
+ // will call done for us when everything is here.
+ gInventory.addObserver(stage2);
+ }
+ delete this;
+ }
+protected:
+ nullary_func_t mCallable;
+};
+
+void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb)
+{
+ CallAfterCategoryFetchStage1 *stage1 = new CallAfterCategoryFetchStage1(cat_id, cb);
+ stage1->startFetch();
+ if (stage1->isFinished())
+ {
+ stage1->done();
+ }
+ else
+ {
+ gInventory.addObserver(stage1);
+ }
+}
+
+void wear_multiple(const uuid_vec_t& ids, bool replace)
+{
+ LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
+
+ bool first = true;
+ uuid_vec_t::const_iterator it;
+ for (it = ids.begin(); it != ids.end(); ++it)
+ {
+ // if replace is requested, the first item worn will replace the current top
+ // item, and others will be added.
+ LLAppearanceMgr::instance().wearItemOnAvatar(*it,false,first && replace,cb);
+ first = false;
+ }
+}
+
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 84c911c038..9f554dbdef 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -223,6 +223,11 @@ public:
BOOL getIsInCOF(const LLUUID& obj_id) const;
// Is this in the COF and can the user delete it from the COF?
BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const;
+
+ /**
+ * Checks if COF contains link to specified object.
+ */
+ static bool isLinkInCOF(const LLUUID& obj_id);
};
class LLUpdateAppearanceOnDestroy: public LLInventoryCallback
@@ -242,180 +247,19 @@ private:
LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name);
-// Shim class and template function to allow arbitrary boost::bind
-// expressions to be run as one-time idle callbacks.
-template <typename T>
-class OnIdleCallbackOneTime
-{
-public:
- OnIdleCallbackOneTime(T callable):
- mCallable(callable)
- {
- }
- static void onIdle(void *data)
- {
- gIdleCallbacks.deleteFunction(onIdle, data);
- OnIdleCallbackOneTime<T>* self = reinterpret_cast<OnIdleCallbackOneTime<T>*>(data);
- self->call();
- delete self;
- }
- void call()
- {
- mCallable();
- }
-private:
- T mCallable;
-};
+typedef boost::function<void ()> nullary_func_t;
+typedef boost::function<bool ()> bool_func_t;
-template <typename T>
-void doOnIdleOneTime(T callable)
-{
- OnIdleCallbackOneTime<T>* cb_functor = new OnIdleCallbackOneTime<T>(callable);
- gIdleCallbacks.addFunction(&OnIdleCallbackOneTime<T>::onIdle,cb_functor);
-}
-
-// Shim class and template function to allow arbitrary boost::bind
-// expressions to be run as recurring idle callbacks.
-// Callable should return true when done, false to continue getting called.
-template <typename T>
-class OnIdleCallbackRepeating
-{
-public:
- OnIdleCallbackRepeating(T callable):
- mCallable(callable)
- {
- }
- // Will keep getting called until the callable returns true.
- static void onIdle(void *data)
- {
- OnIdleCallbackRepeating<T>* self = reinterpret_cast<OnIdleCallbackRepeating<T>*>(data);
- bool done = self->call();
- if (done)
- {
- gIdleCallbacks.deleteFunction(onIdle, data);
- delete self;
- }
- }
- bool call()
- {
- return mCallable();
- }
-private:
- T mCallable;
-};
+// Call a given callable once in idle loop.
+void doOnIdleOneTime(nullary_func_t callable);
-template <typename T>
-void doOnIdleRepeating(T callable)
-{
- OnIdleCallbackRepeating<T>* cb_functor = new OnIdleCallbackRepeating<T>(callable);
- gIdleCallbacks.addFunction(&OnIdleCallbackRepeating<T>::onIdle,cb_functor);
-}
+// Repeatedly call a callable in idle loop until it returns true.
+void doOnIdleRepeating(bool_func_t callable);
-template <class T>
-class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver
-{
-public:
- CallAfterCategoryFetchStage2(const uuid_vec_t& ids,
- T callable) :
- LLInventoryFetchItemsObserver(ids),
- mCallable(callable)
- {
- }
- ~CallAfterCategoryFetchStage2()
- {
- }
- virtual void done()
- {
- llinfos << this << " done with incomplete " << mIncomplete.size()
- << " complete " << mComplete.size() << " calling callable" << llendl;
-
- gInventory.removeObserver(this);
- doOnIdleOneTime(mCallable);
- delete this;
- }
-protected:
- T mCallable;
-};
+// Invoke a given callable after category contents are fully fetched.
+void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb);
-template <class T>
-class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver
-{
-public:
- CallAfterCategoryFetchStage1(const LLUUID& cat_id, T callable) :
- LLInventoryFetchDescendentsObserver(cat_id),
- mCallable(callable)
- {
- }
- ~CallAfterCategoryFetchStage1()
- {
- }
- virtual void done()
- {
- // What we do here is get the complete information on the items in
- // the library, and set up an observer that will wait for that to
- // happen.
- LLInventoryModel::cat_array_t cat_array;
- LLInventoryModel::item_array_t item_array;
- gInventory.collectDescendents(mComplete.front(),
- cat_array,
- item_array,
- LLInventoryModel::EXCLUDE_TRASH);
- S32 count = item_array.count();
- if(!count)
- {
- llwarns << "Nothing fetched in category " << mComplete.front()
- << llendl;
- //dec_busy_count();
- gInventory.removeObserver(this);
-
- // lets notify observers that loading is finished.
- gAgentWearables.notifyLoadingFinished();
- delete this;
- return;
- }
-
- llinfos << "stage1 got " << item_array.count() << " items, passing to stage2 " << llendl;
- uuid_vec_t ids;
- for(S32 i = 0; i < count; ++i)
- {
- ids.push_back(item_array.get(i)->getUUID());
- }
-
- gInventory.removeObserver(this);
-
- // do the fetch
- CallAfterCategoryFetchStage2<T> *stage2 = new CallAfterCategoryFetchStage2<T>(ids, mCallable);
- stage2->startFetch();
- if(stage2->isFinished())
- {
- // everything is already here - call done.
- stage2->done();
- }
- else
- {
- // it's all on it's way - add an observer, and the inventory
- // will call done for us when everything is here.
- gInventory.addObserver(stage2);
- }
- delete this;
- }
-protected:
- T mCallable;
-};
-
-template <class T>
-void callAfterCategoryFetch(const LLUUID& cat_id, T callable)
-{
- CallAfterCategoryFetchStage1<T> *stage1 = new CallAfterCategoryFetchStage1<T>(cat_id, callable);
- stage1->startFetch();
- if (stage1->isFinished())
- {
- stage1->done();
- }
- else
- {
- gInventory.addObserver(stage1);
- }
-}
+// Wear all items in a uuid vector.
+void wear_multiple(const uuid_vec_t& ids, bool replace);
#endif
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 21766a731d..d222d94ec6 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -357,7 +357,7 @@ static void ui_audio_callback(const LLUUID& uuid)
bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
{
- if(!match || !base)
+ if(!match || !base || base->getPlainText())
return false;
LLUUID match_id = match->getID();
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 752a2e7504..1e59e5b805 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -550,9 +550,10 @@ namespace action_give_inventory
}
LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
- if (NULL == active_panel)
+ if (!active_panel)
{
- return;
+ active_panel = get_outfit_editor_inventory_panel();
+ if (!active_panel) return;
}
const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index c0fa910f86..7c33923f04 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -111,6 +111,12 @@ public:
return pInstance;
}
+ ~LLChatHistoryHeader()
+ {
+ // Detach the info button so that it doesn't get destroyed (EXT-8463).
+ hideInfoCtrl();
+ }
+
BOOL handleMouseUp(S32 x, S32 y, MASK mask)
{
return LLPanel::handleMouseUp(x,y,mask);
@@ -382,8 +388,18 @@ protected:
if (!sInfoCtrl)
{
+ // *TODO: Delete the button at exit.
sInfoCtrl = LLUICtrlFactory::createFromFile<LLUICtrl>("inspector_info_ctrl.xml", NULL, LLPanel::child_registry_t::instance());
- sInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, sInfoCtrl));
+ if (sInfoCtrl)
+ {
+ sInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, sInfoCtrl));
+ }
+ }
+
+ if (!sInfoCtrl)
+ {
+ llassert(sInfoCtrl != NULL);
+ return;
}
LLTextBase* name = getChild<LLTextBase>("user_name");
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index 35a1ad747b..01932949e4 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -284,7 +284,8 @@ LLCOFWearables::LLCOFWearables() : LLPanel(),
mAttachmentsTab(NULL),
mBodyPartsTab(NULL),
mLastSelectedTab(NULL),
- mCOFVersion(-1)
+ mCOFVersion(-1),
+ mAccordionCtrl(NULL)
{
mClothingMenu = new CofClothingContextMenu(this);
mAttachmentMenu = new CofAttachmentContextMenu(this);
@@ -336,6 +337,8 @@ BOOL LLCOFWearables::postBuild()
mTab2AssetType[mAttachmentsTab] = LLAssetType::AT_OBJECT;
mTab2AssetType[mBodyPartsTab] = LLAssetType::AT_BODYPART;
+ mAccordionCtrl = getChild<LLAccordionCtrl>("cof_wearables_accordion");
+
return LLPanel::postBuild();
}
@@ -652,18 +655,35 @@ LLAssetType::EType LLCOFWearables::getExpandedAccordionAssetType()
typedef std::map<std::string, LLAssetType::EType> type_map_t;
static type_map_t type_map;
- static LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("cof_wearables_accordion");
- const LLAccordionCtrlTab* expanded_tab = accordion_ctrl->getExpandedTab();
- return get_if_there(mTab2AssetType, expanded_tab, LLAssetType::AT_NONE);
+ if (mAccordionCtrl != NULL)
+ {
+ const LLAccordionCtrlTab* expanded_tab = mAccordionCtrl->getExpandedTab();
+
+ return get_if_there(mTab2AssetType, expanded_tab, LLAssetType::AT_NONE);
}
+ return LLAssetType::AT_NONE;
+}
+
LLAssetType::EType LLCOFWearables::getSelectedAccordionAssetType()
+{
+ if (mAccordionCtrl != NULL)
{
- static LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("cof_wearables_accordion");
- const LLAccordionCtrlTab* selected_tab = accordion_ctrl->getSelectedTab();
+ const LLAccordionCtrlTab* selected_tab = mAccordionCtrl->getSelectedTab();
- return get_if_there(mTab2AssetType, selected_tab, LLAssetType::AT_NONE);
+ return get_if_there(mTab2AssetType, selected_tab, LLAssetType::AT_NONE);
+ }
+
+ return LLAssetType::AT_NONE;
+}
+
+void LLCOFWearables::expandDefaultAccordionTab()
+{
+ if (mAccordionCtrl != NULL)
+ {
+ mAccordionCtrl->expandDefaultTab();
+ }
}
void LLCOFWearables::onListRightClick(LLUICtrl* ctrl, S32 x, S32 y, LLListContextMenu* menu)
diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h
index d005b75eaa..cd7cc060e5 100644
--- a/indra/newview/llcofwearables.h
+++ b/indra/newview/llcofwearables.h
@@ -40,6 +40,7 @@
#include "llappearancemgr.h"
#include "llinventorymodel.h"
+class LLAccordionCtrl;
class LLAccordionCtrlTab;
class LLListContextMenu;
class LLPanelClothingListItem;
@@ -87,6 +88,7 @@ public:
LLAssetType::EType getExpandedAccordionAssetType();
LLAssetType::EType getSelectedAccordionAssetType();
+ void expandDefaultAccordionTab();
LLCOFCallbacks& getCOFCallbacks() { return mCOFCallbacks; }
@@ -125,6 +127,8 @@ protected:
LLListContextMenu* mAttachmentMenu;
LLListContextMenu* mBodyPartMenu;
+ LLAccordionCtrl* mAccordionCtrl;
+
/* COF category version since last refresh */
S32 mCOFVersion;
};
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index c423473740..bb4e6c7a3e 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -167,6 +167,10 @@ void LLViewerDynamicTexture::postRender(BOOL success)
{
generateGLTexture() ;
}
+ if(!mGLTexturep->getHasGLTexture())
+ {
+ generateGLTexture() ;
+ }
llcallstacks << "class type: " << (S32)getType() << llcallstacksendl ;
success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 913bb676b0..f0ed659f5a 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -2088,7 +2088,8 @@ void LLPanelLandOptions::refresh()
LLStyle::Params style;
style.image(LLUI::getUIImage(gFloaterView->getParentFloater(this)->getString("maturity_icon_moderate")));
LLCheckBoxWithTBAcess* fullaccess_mature_ctrl = (LLCheckBoxWithTBAcess*)mMatureCtrl;
- fullaccess_mature_ctrl->getTextBox()->setText(std::string("icon"),style);
+ fullaccess_mature_ctrl->getTextBox()->setText(LLStringExplicit(""));
+ fullaccess_mature_ctrl->getTextBox()->appendImageSegment(style);
fullaccess_mature_ctrl->getTextBox()->appendText(getString("mature_check_mature"), false);
fullaccess_mature_ctrl->setToolTip(getString("mature_check_mature_tooltip"));
fullaccess_mature_ctrl->reshape(fullaccess_mature_ctrl->getRect().getWidth(), fullaccess_mature_ctrl->getRect().getHeight(), FALSE);
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 3944fa53c9..03e1bb9eee 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -263,6 +263,7 @@ public:
BOOL needsAutoRename() { return mNeedsAutoRename; }
void setNeedsAutoRename(BOOL val) { mNeedsAutoRename = val; }
void setAutoSelectOverride(BOOL val) { mAutoSelectOverride = val; }
+ void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }
void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 996553ccf7..d464b67105 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -903,7 +903,15 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
if (member_id.notNull())
{
- formatDateString(online_status); // reformat for sorting, e.g. 12/25/2008 -> 2008/12/25
+ if (online_status == "Online")
+ {
+ static std::string localized_online(LLTrans::getString("group_member_status_online"));
+ online_status = localized_online;
+ }
+ else
+ {
+ formatDateString(online_status); // reformat for sorting, e.g. 12/25/2008 -> 2008/12/25
+ }
//llinfos << "Member " << member_id << " has powers " << std::hex << agent_powers << std::dec << llendl;
LLGroupMemberData* newdata = new LLGroupMemberData(member_id,
diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp
index ea57d36c06..b1f5b3be2f 100644
--- a/indra/newview/llinventorylistitem.cpp
+++ b/indra/newview/llinventorylistitem.cpp
@@ -96,9 +96,12 @@ void LLPanelInventoryListItemBase::draw()
if (mSeparatorVisible && mSeparatorImage)
{
- // stretch along bottom of listitem, using image height
+ // place under bottom of listitem, using image height
+ // item_pad in list using the item should be >= image height
+ // to avoid cropping of top of the next item.
LLRect separator_rect = getLocalRect();
- separator_rect.mTop = mSeparatorImage->getHeight();
+ separator_rect.mTop = separator_rect.mBottom;
+ separator_rect.mBottom -= mSeparatorImage->getHeight();
mSeparatorImage->draw(separator_rect);
}
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 06f490e8e3..ae8efc01a3 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -58,6 +58,7 @@
#endif
#include "llsecapi.h"
#include "llstartup.h"
+#include "llmachineid.h"
static const char * const TOS_REPLY_PUMP = "lllogininstance_tos_callback";
static const char * const TOS_LISTENER_NAME = "lllogininstance_tos";
@@ -165,22 +166,24 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
// (re)initialize the request params with creds.
LLSD request_params = user_credential->getLoginParams();
- char hashed_mac_string[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */
- LLMD5 hashed_mac;
- unsigned char MACAddress[MAC_ADDRESS_BYTES];
- if(LLUUID::getNodeID(MACAddress) == 0) {
- llerrs << "Failed to get node id; cannot uniquely identify this machine." << llendl;
+ char hashed_unique_id_string[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */
+ LLMD5 hashed_unique_id;
+ unsigned char unique_id[MAC_ADDRESS_BYTES];
+ if(LLUUID::getNodeID(unique_id) == 0) {
+ if(LLMachineID::getUniqueID(unique_id, sizeof(unique_id)) == 0) {
+ llerrs << "Failed to get an id; cannot uniquely identify this machine." << llendl;
+ }
}
- hashed_mac.update( MACAddress, MAC_ADDRESS_BYTES );
- hashed_mac.finalize();
- hashed_mac.hex_digest(hashed_mac_string);
+ hashed_unique_id.update(unique_id, MAC_ADDRESS_BYTES);
+ hashed_unique_id.finalize();
+ hashed_unique_id.hex_digest(hashed_unique_id_string);
request_params["start"] = construct_start_string();
request_params["skipoptional"] = mSkipOptionalUpdate;
request_params["agree_to_tos"] = false; // Always false here. Set true in
request_params["read_critical"] = false; // handleTOSResponse
request_params["last_exec_event"] = mLastExecEvent;
- request_params["mac"] = hashed_mac_string;
+ request_params["mac"] = hashed_unique_id_string;
request_params["version"] = gCurrentVersion; // Includes channel name
request_params["channel"] = gSavedSettings.getString("VersionChannelName");
request_params["id0"] = mSerialNumber;
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 6ae4a5e5e4..fc41137686 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -83,6 +83,16 @@ LLFloaterMove::LLFloaterMove(const LLSD& key)
{
}
+LLFloaterMove::~LLFloaterMove()
+{
+ // Ensure LLPanelStandStopFlying panel is not among floater's children. See EXT-8458.
+ setVisible(FALSE);
+
+ // Otherwise it can be destroyed and static pointer in LLPanelStandStopFlying::getInstance() will become invalid.
+ // Such situation was possible when LLFloaterReg returns "dead" instance of floater.
+ // Should not happen after LLFloater::destroy was modified to remove "dead" instances from LLFloaterReg.
+}
+
// virtual
BOOL LLFloaterMove::postBuild()
{
diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h
index d463861188..43b0342744 100644
--- a/indra/newview/llmoveview.h
+++ b/indra/newview/llmoveview.h
@@ -51,7 +51,7 @@ class LLFloaterMove
private:
LLFloaterMove(const LLSD& key);
- ~LLFloaterMove() {}
+ ~LLFloaterMove();
public:
/*virtual*/ BOOL postBuild();
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 63ffb80ff2..c3eee1d1ad 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -665,7 +665,18 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata)
}
if (command_name == "wear")
{
- return !gAgentWearables.isCOFChangeInProgress();
+ if (gAgentWearables.isCOFChangeInProgress())
+ {
+ return false;
+ }
+
+ if (hasItemSelected())
+ {
+ return canWearSelected();
+ }
+
+ // outfit selected
+ return LLAppearanceMgr::getCanAddToCOF(mSelectedOutfitUUID);
}
if (command_name == "take_off")
{
@@ -677,6 +688,7 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata)
if (command_name == "wear_add")
{
+ // *TODO: do we ever get here?
if (gAgentWearables.isCOFChangeInProgress())
{
return false;
@@ -984,6 +996,31 @@ bool LLOutfitsList::canTakeOffSelected()
return false;
}
+bool LLOutfitsList::canWearSelected()
+{
+ uuid_vec_t selected_items;
+ getSelectedItemsUUIDs(selected_items);
+
+ for (uuid_vec_t::const_iterator it = selected_items.begin(); it != selected_items.end(); ++it)
+ {
+ const LLUUID& id = *it;
+
+ if (LLAppearanceMgr::isLinkInCOF(id))
+ {
+ return false;
+ }
+
+ // Check whether the item is worn.
+ if (!get_can_item_be_worn(id))
+ {
+ return false;
+ }
+ }
+
+ // All selected items can be worn.
+ return true;
+}
+
void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id)
{
LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl);
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index d7cf8a8c08..206854b232 100644
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -183,6 +183,11 @@ private:
*/
bool canTakeOffSelected();
+ /**
+ * Returns true if all selected items can be worn.
+ */
+ bool canWearSelected();
+
void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
void onCOFChanged();
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index 094769b8f5..ac71069621 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -47,6 +47,7 @@
#include "llvoavatarself.h"
#include "lltexteditor.h"
#include "lltextbox.h"
+#include "llaccordionctrl.h"
#include "llaccordionctrltab.h"
#include "llagentwearables.h"
#include "llscrollingpanelparam.h"
@@ -666,6 +667,35 @@ void LLPanelEditWearable::updateAvatarHeightLabel()
mTxtAvatarHeight->appendText(this->mReplacementMetricUrl, false, param);
}
+void LLPanelEditWearable::onWearablePanelVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl)
+{
+ if (in_visible_chain.asBoolean() && accordion_ctrl != NULL)
+ {
+ accordion_ctrl->expandDefaultTab();
+ }
+}
+
+void LLPanelEditWearable::setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel)
+{
+ if (bodypart_panel != NULL)
+ {
+ LLAccordionCtrl* accordion_ctrl = bodypart_panel->getChild<LLAccordionCtrl>("wearable_accordion");
+
+ if (accordion_ctrl != NULL)
+ {
+ bodypart_panel->setVisibleCallback(
+ boost::bind(&LLPanelEditWearable::onWearablePanelVisibilityChange, this, _2, accordion_ctrl));
+ }
+ else
+ {
+ llwarns << "accordion_ctrl is NULL" << llendl;
+ }
+ }
+ else
+ {
+ llwarns << "bodypart_panel is NULL" << llendl;
+ }
+}
// virtual
BOOL LLPanelEditWearable::postBuild()
@@ -695,6 +725,14 @@ BOOL LLPanelEditWearable::postBuild()
mPanelEyes = getChild<LLPanel>("edit_eyes_panel");
mPanelHair = getChild<LLPanel>("edit_hair_panel");
+ // Setting the visibility callback is applied only to the bodyparts panel
+ // because currently they are the only ones whose 'wearable_accordion' has
+ // multiple accordion tabs (see EXT-8164 for details).
+ setWearablePanelVisibilityChangeCallback(mPanelShape);
+ setWearablePanelVisibilityChangeCallback(mPanelSkin);
+ setWearablePanelVisibilityChangeCallback(mPanelEyes);
+ setWearablePanelVisibilityChangeCallback(mPanelHair);
+
//clothes
mPanelShirt = getChild<LLPanel>("edit_shirt_panel");
mPanelPants = getChild<LLPanel>("edit_pants_panel");
@@ -905,7 +943,7 @@ void LLPanelEditWearable::onTexturePickerCommit(const LLUICtrl* ctrl)
{
// Set the new version
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_ctrl->getImageAssetID());
- if( image->getID().isNull() )
+ if( image->getID() == IMG_DEFAULT )
{
image = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
}
diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h
index 1c980c207e..03b2cb7932 100644
--- a/indra/newview/llpaneleditwearable.h
+++ b/indra/newview/llpaneleditwearable.h
@@ -39,6 +39,7 @@
#include "llvoavatardefines.h"
#include "llwearabletype.h"
+class LLAccordionCtrl;
class LLCheckBoxCtrl;
class LLWearable;
class LLTextBox;
@@ -115,6 +116,10 @@ private:
// updates avatar height label
void updateAvatarHeightLabel();
+ void onWearablePanelVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl);
+
+ void setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel);
+
// the pointer to the wearable we're editing. NULL means we're not editing a wearable.
LLWearable *mWearablePtr;
LLViewerInventoryItem* mWearableItem;
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index 2112c8c026..2fc74e138b 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -182,6 +182,11 @@ BOOL LLPanelGroup::postBuild()
LLPanelGroupTab* panel_notices = findChild<LLPanelGroupTab>("group_notices_tab_panel");
LLPanelGroupTab* panel_land = findChild<LLPanelGroupTab>("group_land_tab_panel");
+ if (LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("groups_accordion"))
+ {
+ setVisibleCallback(boost::bind(&LLPanelGroup::onVisibilityChange, this, _2, accordion_ctrl));
+ }
+
if(panel_general) mTabs.push_back(panel_general);
if(panel_roles) mTabs.push_back(panel_roles);
if(panel_notices) mTabs.push_back(panel_notices);
@@ -305,6 +310,13 @@ void LLPanelGroup::onBtnCancel()
onBackBtnClick();
}
+void LLPanelGroup::onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl)
+{
+ if (in_visible_chain.asBoolean() && accordion_ctrl != NULL)
+ {
+ accordion_ctrl->expandDefaultTab();
+ }
+}
void LLPanelGroup::changed(LLGroupChange gc)
{
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index 13a03b0713..2b21e9895a 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -42,6 +42,7 @@ class LLOfferInfo;
const S32 UPDATE_MEMBERS_PER_FRAME = 500;
// Forward declares
+class LLAccordionCtrl;
class LLPanelGroupTab;
class LLTabContainer;
class LLAgent;
@@ -102,6 +103,7 @@ protected:
void onBackBtnClick();
void onBtnJoin();
void onBtnCancel();
+ void onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl);
static void onBtnApply(void*);
static void onBtnRefresh(void*);
@@ -126,7 +128,6 @@ protected:
LLButton* mButtonJoin;
LLUICtrl* mJoinText;
-
};
class LLPanelGroupTab : public LLPanel
diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp
index 65fe7165c2..b7d6b65ce5 100644
--- a/indra/newview/llpanelgrouplandmoney.cpp
+++ b/indra/newview/llpanelgrouplandmoney.cpp
@@ -1432,10 +1432,10 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,
// text.append(llformat( "%-24s %6d %6d \n", LLTrans::getString("GroupMoneyDebits").c_str(), total_debits, (S32)floor((F32)total_debits/(F32)non_exempt_members)));
// text.append(llformat( "%-24s %6d %6d \n", LLTrans::getString("GroupMoneyTotal").c_str(), total_credits + total_debits, (S32)floor((F32)(total_credits + total_debits)/(F32)non_exempt_members)));
- text.append( " Group\n");
- text.append(llformat( "%-24s %6d\n", "Credits", total_credits));
- text.append(llformat( "%-24s %6d\n", "Debits", total_debits));
- text.append(llformat( "%-24s %6d\n", "Total", total_credits + total_debits));
+ text.append(llformat( "%s\n", LLTrans::getString("GroupColumn").c_str()));
+ text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyCredits").c_str(), total_credits));
+ text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyDebits").c_str(), total_debits));
+ text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyTotal").c_str(), total_credits + total_debits));
if ( mImplementationp->mTextEditorp )
{
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 26e8a932aa..445cfe64f7 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1593,6 +1593,7 @@ void LLPanelGroupMembersSubTab::updateMembers()
LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end();
+ LLUIString donated = getString("donation_area");
S32 i = 0;
for( ; mMemberProgress != end && i<UPDATE_MEMBERS_PER_FRAME;
@@ -1614,9 +1615,7 @@ void LLPanelGroupMembersSubTab::updateMembers()
if (add_member)
{
- // Build the donated tier string.
- std::ostringstream donated;
- donated << mMemberProgress->second->getContribution() << " sq. m.";
+ donated.setArg("[AREA]", llformat("%d", mMemberProgress->second->getContribution()));
LLSD row;
row["id"] = (*mMemberProgress).first;
@@ -1625,7 +1624,7 @@ void LLPanelGroupMembersSubTab::updateMembers()
// value is filled in by name list control
row["columns"][1]["column"] = "donated";
- row["columns"][1]["value"] = donated.str();
+ row["columns"][1]["value"] = donated.getString();
row["columns"][2]["column"] = "online";
row["columns"][2]["value"] = mMemberProgress->second->getOnlineStatus();
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 6ab7fd6a2b..6c6f830000 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -421,6 +421,8 @@ LLPanelOutfitEdit::~LLPanelOutfitEdit()
delete mCOFDragAndDropObserver;
+ delete mWearableListViewItemsComparator;
+
while (!mListViewItemTypes.empty()) {
delete mListViewItemTypes.back();
mListViewItemTypes.pop_back();
@@ -526,12 +528,25 @@ BOOL LLPanelOutfitEdit::postBuild()
childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance()));
+ /*
+ * By default AT_CLOTHING are sorted by (in in MY OUTFITS):
+ * - by type (types order determined in LLWearableType::EType)
+ * - each LLWearableType::EType by outer layer on top
+ *
+ * In Add More panel AT_CLOTHING should be sorted in a such way:
+ * - by type (types order determined in LLWearableType::EType)
+ * - each LLWearableType::EType by name (EXT-8205)
+ */
+ mWearableListViewItemsComparator = new LLWearableItemTypeNameComparator();
+ mWearableListViewItemsComparator->setOrder(LLAssetType::AT_CLOTHING, LLWearableItemTypeNameComparator::ORDER_RANK_1, false, true);
+
mWearablesListViewPanel = getChild<LLPanel>("filtered_wearables_panel");
mWearableItemsList = getChild<LLWearableItemsList>("list_view");
mWearableItemsList->setCommitOnSelectionChange(true);
mWearableItemsList->setCommitCallback(boost::bind(&LLPanelOutfitEdit::updatePlusButton, this));
mWearableItemsList->setDoubleClickCallback(boost::bind(&LLPanelOutfitEdit::onPlusBtnClicked, this));
- mWearableItemsList->setSortOrder((LLWearableItemsList::ESortOrder)gSavedSettings.getU32("AddWearableSortOrder"));
+ mWearableItemsList->setComparator(mWearableListViewItemsComparator);
+ mWearableItemsList->setSortOrder((LLWearableItemsList::ESortOrder)gSavedSettings.getU32("AddWearableSortOrder"));
mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));
return TRUE;
@@ -901,7 +916,9 @@ void LLPanelOutfitEdit::updatePlusButton()
}
// If any of the selected items are not wearable (due to already being worn OR being of the wrong type), disable the add button.
- uuid_vec_t::iterator unwearable_item = std::find_if(selected_items.begin(), selected_items.end(), !boost::bind(& get_can_item_be_worn, _1));
+ uuid_vec_t::iterator unwearable_item = std::find_if(selected_items.begin(), selected_items.end(), !boost::bind(& get_can_item_be_worn, _1)
+ // since item can be not worn but in wearing process at that time - we need to check is link to item presents in COF
+ || boost::bind(&LLAppearanceMgr::isLinkInCOF, _1));
bool can_add = ( unwearable_item == selected_items.end() );
mPlusBtn->setEnabled(can_add);
@@ -1149,16 +1166,18 @@ bool LLPanelOutfitEdit::switchPanels(LLPanel* switch_from_panel, LLPanel* switch
return false;
}
-void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button)
+void LLPanelOutfitEdit::resetAccordionState()
{
- LLMenuGL* menu = NULL;
+ if (mCOFWearables != NULL)
if (mAddWearablesPanel->getVisible())
{
- if (!mAddWearablesGearMenu)
- {
- mAddWearablesGearMenu = LLAddWearablesGearMenu::create(mWearableItemsList, mInventoryItemsPanel);
- }
+ mCOFWearables->expandDefaultAccordionTab();
+ }
+ else
+ {
+ llwarns << "mCOFWearables is NULL" << llendl;
+ }
menu = mAddWearablesGearMenu;
}
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index 93215c5920..fa3c48c3e7 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -64,6 +64,7 @@ class LLMenuGL;
class LLFindNonLinksByMask;
class LLFindWearablesOfType;
class LLSaveOutfitComboBtn;
+class LLWearableItemTypeNameComparator;
class LLPanelOutfitEdit : public LLPanel
{
@@ -188,6 +189,8 @@ public:
*/
bool switchPanels(LLPanel* switch_from_panel, LLPanel* switch_to_panel);
+ void resetAccordionState();
+
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
@@ -228,6 +231,7 @@ private:
LLFilteredWearableListManager* mWearableListManager;
LLWearableItemsList* mWearableItemsList;
LLPanel* mWearablesListViewPanel;
+ LLWearableItemTypeNameComparator* mWearableListViewItemsComparator;
LLCOFDragAndDropObserver* mCOFDragAndDropObserver;
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index ca5679d5b0..16ef7998b3 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -337,7 +337,7 @@ bool LLPanelOutfitsInventory::isCOFPanelActive() const
void LLPanelOutfitsInventory::setWearablesLoading(bool val)
{
- mListCommands->childSetEnabled("wear_btn", !val);
+ updateVerbs();
}
void LLPanelOutfitsInventory::onWearablesLoaded()
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 8c1f5d0915..99e48cca6d 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -60,7 +60,8 @@ LLPanelPlaceInfo::LLPanelPlaceInfo()
mScrollingPanelWidth(0),
mInfoType(UNKNOWN),
mScrollingPanel(NULL),
- mScrollContainer(NULL)
+ mScrollContainer(NULL),
+ mDescEditor(NULL)
{}
//virtual
@@ -248,6 +249,16 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
// virtual
void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
{
+
+ // This if was added to force collapsing description textbox on Windows at the beginning of reshape
+ // (the only case when reshape is skipped here is when it's caused by this textbox, so called_from_parent is FALSE)
+ // This way it is consistent with Linux where topLost collapses textbox at the beginning of reshape.
+ // On windows it collapsed only after reshape which caused EXT-8342.
+ if(called_from_parent)
+ {
+ if(mDescEditor) mDescEditor->onTopLost();
+ }
+
LLPanel::reshape(width, height, called_from_parent);
if (!mScrollContainer || !mScrollingPanel)
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index 1f979b0ef1..08835dc2b8 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -79,7 +79,8 @@ LLPanelPlaceProfile::LLPanelPlaceProfile()
: LLPanelPlaceInfo(),
mForSalePanel(NULL),
mYouAreHerePanel(NULL),
- mSelectedParcelID(-1)
+ mSelectedParcelID(-1),
+ mAccordionCtrl(NULL)
{}
// virtual
@@ -139,6 +140,7 @@ BOOL LLPanelPlaceProfile::postBuild()
mSubdivideText = getChild<LLTextEditor>("subdivide");
mResaleText = getChild<LLTextEditor>("resale");
mSaleToText = getChild<LLTextBox>("sale_to");
+ mAccordionCtrl = getChild<LLAccordionCtrl>("advanced_info_accordion");
icon_pg = getString("icon_PG");
icon_m = getString("icon_M");
@@ -278,6 +280,11 @@ void LLPanelPlaceProfile::handleVisibilityChange(BOOL new_visibility)
parcel_mgr->deselectUnused();
}
}
+
+ if (mAccordionCtrl != NULL)
+ {
+ mAccordionCtrl->expandDefaultTab();
+ }
}
void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h
index e77b441567..49c13ff5e3 100644
--- a/indra/newview/llpanelplaceprofile.h
+++ b/indra/newview/llpanelplaceprofile.h
@@ -35,6 +35,7 @@
#include "llpanelplaceinfo.h"
+class LLAccordionCtrl;
class LLIconCtrl;
class LLTextEditor;
@@ -118,6 +119,7 @@ private:
LLTextEditor* mSubdivideText;
LLTextEditor* mResaleText;
LLTextBox* mSaleToText;
+ LLAccordionCtrl* mAccordionCtrl;
};
#endif // LL_LLPANELPLACEPROFILE_H
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 7a7ffb9983..98cd0b88eb 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -190,13 +190,16 @@ void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility)
{
if (new_visibility.asBoolean())
{
- if ((mOutfitEdit && mOutfitEdit->getVisible()) || (mEditWearable && mEditWearable->getVisible()))
+ bool is_outfit_edit_visible = mOutfitEdit && mOutfitEdit->getVisible();
+ bool is_wearable_edit_visible = mEditWearable && mEditWearable->getVisible();
+
+ if (is_outfit_edit_visible || is_wearable_edit_visible)
{
if (!gAgentCamera.cameraCustomizeAvatar() && gSavedSettings.getBOOL("AppearanceCameraMovement"))
{
gAgentCamera.changeCameraToCustomizeAvatar();
}
- if (mEditWearable && mEditWearable->getVisible())
+ if (is_wearable_edit_visible)
{
LLWearable *wearable_ptr = mEditWearable->getWearable();
if (gAgentWearables.getWearableIndex(wearable_ptr) == LLAgentWearables::MAX_CLOTHING_PER_TYPE)
@@ -205,6 +208,11 @@ void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility)
showOutfitEditPanel();
}
}
+
+ if (is_outfit_edit_visible)
+ {
+ mOutfitEdit->resetAccordionState();
+ }
}
}
else
@@ -283,6 +291,15 @@ void LLSidepanelAppearance::showOutfitsInventoryPanel()
void LLSidepanelAppearance::showOutfitEditPanel()
{
+ // Accordion's state must be reset in all cases except the one when user
+ // is returning back to the mOutfitEdit panel from the mEditWearable panel.
+ // The simplest way to control this is to check the visibility state of the mEditWearable
+ // BEFORE it is changed by the call to the toggleWearableEditPanel(FALSE, NULL, TRUE).
+ if (mEditWearable != NULL && !mEditWearable->getVisible() && mOutfitEdit != NULL)
+ {
+ mOutfitEdit->resetAccordionState();
+ }
+
togglMyOutfitsPanel(FALSE);
toggleWearableEditPanel(FALSE, NULL, TRUE); // don't switch out of edit appearance mode
toggleOutfitEditPanel(TRUE);
diff --git a/indra/newview/lltexlayerparams.cpp b/indra/newview/lltexlayerparams.cpp
index f2d1b5d032..dc97c4b673 100644
--- a/indra/newview/lltexlayerparams.cpp
+++ b/indra/newview/lltexlayerparams.cpp
@@ -180,7 +180,7 @@ void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL upload_bake)
if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
{
- if (gAgentCamera.cameraCustomizeAvatar())
+ if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
{
upload_bake = FALSE;
}
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 0b02861b75..c0518b705b 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -175,6 +175,8 @@ protected:
BOOL mNoCopyTextureSelected;
F32 mContextConeOpacity;
LLSaveFolderState mSavedFolderState;
+
+ BOOL mSelectedItemPinned;
};
LLFloaterTexturePicker::LLFloaterTexturePicker(
@@ -197,7 +199,8 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
mFilterEdit(NULL),
mImmediateFilterPermMask(immediate_filter_perm_mask),
mNonImmediateFilterPermMask(non_immediate_filter_perm_mask),
- mContextConeOpacity(0.f)
+ mContextConeOpacity(0.f),
+ mSelectedItemPinned( FALSE )
{
mCanApplyImmediately = can_apply_immediately;
LLUICtrlFactory::getInstance()->buildFloater(this,"floater_texture_ctrl.xml",NULL);
@@ -597,6 +600,31 @@ void LLFloaterTexturePicker::draw()
mTentativeLabel->setVisible( TRUE );
drawChild(mTentativeLabel);
}
+
+ if (mSelectedItemPinned) return;
+
+ LLFolderView* folder_view = mInventoryPanel->getRootFolder();
+ if (!folder_view) return;
+
+ LLInventoryFilter* filter = folder_view->getFilter();
+ if (!filter) return;
+
+ bool is_filter_active = folder_view->getCompletedFilterGeneration() < filter->getCurrentGeneration() &&
+ filter->isNotDefault();
+
+ // After inventory panel filter is applied we have to update
+ // constraint rect for the selected item because of folder view
+ // AutoSelectOverride set to TRUE. We force PinningSelectedItem
+ // flag to FALSE state and setting filter "dirty" to update
+ // scroll container to show selected item (see LLFolderView::doIdle()).
+ if (!is_filter_active && !mSelectedItemPinned)
+ {
+ folder_view->setPinningSelectedItem(mSelectedItemPinned);
+ folder_view->dirtyFilter();
+ folder_view->arrangeFromRoot();
+
+ mSelectedItemPinned = TRUE;
+ }
}
}
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index ceed90e210..dddfed097d 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -290,8 +290,8 @@ class HTTPGetResponder : public LLCurl::Responder
{
LOG_CLASS(HTTPGetResponder);
public:
- HTTPGetResponder(LLTextureFetch* fetcher, const LLUUID& id, U64 startTime, S32 requestedSize, U32 offset)
- : mFetcher(fetcher), mID(id), mStartTime(startTime), mRequestedSize(requestedSize), mOffset(offset)
+ HTTPGetResponder(LLTextureFetch* fetcher, const LLUUID& id, U64 startTime, S32 requestedSize, U32 offset, bool redir)
+ : mFetcher(fetcher), mID(id), mStartTime(startTime), mRequestedSize(requestedSize), mOffset(offset), mFollowRedir(redir)
{
}
~HTTPGetResponder()
@@ -344,6 +344,11 @@ public:
llwarns << "Worker not found: " << mID << llendl;
}
}
+
+ virtual bool followRedir()
+ {
+ return mFollowRedir;
+ }
private:
LLTextureFetch* mFetcher;
@@ -351,6 +356,7 @@ private:
U64 mStartTime;
S32 mRequestedSize;
U32 mOffset;
+ bool mFollowRedir;
};
//////////////////////////////////////////////////////////////////////////////
@@ -897,7 +903,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
std::vector<std::string> headers;
headers.push_back("Accept: image/x-j2c");
res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize,
- new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset));
+ new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true));
}
if (!res)
{
@@ -945,17 +951,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
max_attempts = mHTTPFailCount+1; // Keep retrying
LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL;
}
- else if(mGetStatus >= HTTP_MULTIPLE_CHOICES && mGetStatus < HTTP_BAD_REQUEST) //http re-direct
- {
- ++mHTTPFailCount;
- max_attempts = 5 ; //try at most 5 times to avoid infinite redirection loop.
-
- llwarns << "HTTP GET failed because of redirection: " << mUrl
- << " Status: " << mGetStatus << " Reason: '" << mGetReason << llendl ;
-
- //assign to the new url
- mUrl = mGetReason ;
- }
else
{
const S32 HTTP_MAX_RETRY_COUNT = 3;
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 2d57c16889..9926c8d15f 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -96,6 +96,7 @@ public:
mInventoryItemsDict["New Gesture"] = LLTrans::getString("New Gesture");
mInventoryItemsDict["New Script"] = LLTrans::getString("New Script");
mInventoryItemsDict["New Folder"] = LLTrans::getString("New Folder");
+ mInventoryItemsDict["New Note"] = LLTrans::getString("New Note");
mInventoryItemsDict["Contents"] = LLTrans::getString("Contents");
mInventoryItemsDict["Gesture"] = LLTrans::getString("Gesture");
@@ -935,7 +936,7 @@ void ModifiedCOFCallback::fire(const LLUUID& inv_item)
gAgentWearables.editWearableIfRequested(inv_item);
// TODO: camera mode may not be changed if a debug setting is tweaked
- if( gAgentCamera.cameraCustomizeAvatar() )
+ if(gAgentCamera.cameraCustomizeAvatar())
{
// If we're in appearance editing mode, the current tab may need to be refreshed
LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLSideTray::getInstance()->getPanel("sidepanel_appearance"));
@@ -1172,6 +1173,14 @@ void move_inventory_item(
void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecard_inv_id, const LLInventoryItem *src, U32 callback_id)
{
+ if (NULL == src)
+ {
+ LL_WARNS("copy_inventory_from_notecard") << "Null pointer to item was passed for object_id "
+ << object_id << " and notecard_inv_id "
+ << notecard_inv_id << LL_ENDL;
+ return;
+ }
+
LLViewerRegion* viewer_region = NULL;
LLViewerObject* vo = NULL;
if (object_id.notNull() && (vo = gObjectList.findObject(object_id)) != NULL)
@@ -1194,6 +1203,16 @@ void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecar
return;
}
+ // check capability to prevent a crash while LL_ERRS in LLCapabilityListener::capListener. See EXT-8459.
+ std::string url = viewer_region->getCapability("CopyInventoryFromNotecard");
+ if (url.empty())
+ {
+ LL_WARNS("copy_inventory_from_notecard") << "There is no 'CopyInventoryFromNotecard' capability"
+ << " for region: " << viewer_region->getName()
+ << LL_ENDL;
+ return;
+ }
+
LLSD request, body;
body["notecard-id"] = notecard_inv_id;
body["object-id"] = object_id;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index b3fc0df1bf..090b7bba90 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -108,9 +108,12 @@
#include "llappearancemgr.h"
#include "lltrans.h"
#include "lleconomy.h"
+#include "boost/unordered_map.hpp"
using namespace LLVOAvatarDefines;
+static boost::unordered_map<std::string, LLStringExplicit> sDefaultItemLabels;
+
BOOL enable_land_build(void*);
BOOL enable_object_build(void*);
@@ -2403,31 +2406,53 @@ void handle_object_touch()
msg->sendMessage(object->getRegion()->getHost());
}
-// One object must have touch sensor
-class LLObjectEnableTouch : public view_listener_t
+static void init_default_item_label(const std::string& item_name)
{
- bool handleEvent(const LLSD& userdata)
+ boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
+ if (it == sDefaultItemLabels.end())
{
- LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
-
- bool new_value = obj && obj->flagHandleTouch();
-
- // Update label based on the node touch name if available.
- std::string touch_text;
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
- if (node && node->mValid && !node->mTouchName.empty())
- {
- touch_text = node->mTouchName;
- }
- else
+ LLStringExplicit default_label = gMenuHolder->childGetValue(item_name).asString();
+ if (!default_label.empty())
{
- touch_text = userdata.asString();
+ sDefaultItemLabels.insert(std::pair<std::string, LLStringExplicit>(item_name, default_label));
}
- gMenuHolder->childSetText("Object Touch", touch_text);
- gMenuHolder->childSetText("Attachment Object Touch", touch_text);
+ }
+}
- return new_value;
+static LLStringExplicit get_default_item_label(const std::string& item_name)
+{
+ LLStringExplicit res("");
+ boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
+ if (it != sDefaultItemLabels.end())
+ {
+ res = it->second;
+ }
+
+ return res;
+}
+
+
+bool enable_object_touch(LLUICtrl* ctrl)
+{
+ LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+
+ bool new_value = obj && obj->flagHandleTouch();
+
+ std::string item_name = ctrl->getName();
+ init_default_item_label(item_name);
+
+ // Update label based on the node touch name if available.
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
+ if (node && node->mValid && !node->mTouchName.empty())
+ {
+ gMenuHolder->childSetText(item_name, node->mTouchName);
+ }
+ else
+ {
+ gMenuHolder->childSetText(item_name, get_default_item_label(item_name));
}
+
+ return new_value;
};
//void label_touch(std::string& label, void*)
@@ -5519,27 +5544,27 @@ bool enable_object_stand_up()
return sitting_on_selection();
}
-bool enable_object_sit()
+bool enable_object_sit(LLUICtrl* ctrl)
{
// 'Object Sit' menu item is enabled when agent is not sitting on selection
bool sitting_on_sel = sitting_on_selection();
if (!sitting_on_sel)
{
- LLMenuItemGL* sit_menu_item = gMenuHolder->getChild<LLMenuItemGL>("Object Sit");
- // Init default 'Object Sit' menu item label
- static const LLStringExplicit sit_text(sit_menu_item->getLabel());
+ std::string item_name = ctrl->getName();
+
+ // init default labels
+ init_default_item_label(item_name);
+
// Update label
- std::string label;
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
if (node && node->mValid && !node->mSitName.empty())
{
- label.assign(node->mSitName);
+ gMenuHolder->childSetText(item_name, node->mSitName);
}
else
{
- label = sit_text;
+ gMenuHolder->childSetText(item_name, get_default_item_label(item_name));
}
- sit_menu_item->setLabel(label);
}
return !sitting_on_sel && is_object_sittable();
}
@@ -8087,7 +8112,6 @@ void initialize_menus()
view_listener_t::addMenu(new LLObjectBuild(), "Object.Build");
commit.add("Object.Touch", boost::bind(&handle_object_touch));
commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand));
- enable.add("Object.EnableGearSit", boost::bind(&is_object_sittable));
commit.add("Object.Delete", boost::bind(&handle_object_delete));
view_listener_t::addMenu(new LLObjectAttachToAvatar(), "Object.AttachToAvatar");
view_listener_t::addMenu(new LLObjectReturn(), "Object.Return");
@@ -8103,12 +8127,12 @@ void initialize_menus()
commit.add("Object.Open", boost::bind(&handle_object_open));
commit.add("Object.Take", boost::bind(&handle_take));
enable.add("Object.EnableOpen", boost::bind(&enable_object_open));
- view_listener_t::addMenu(new LLObjectEnableTouch(), "Object.EnableTouch");
+ enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1));
enable.add("Object.EnableDelete", boost::bind(&enable_object_delete));
enable.add("Object.EnableWear", boost::bind(&object_selected_and_point_valid));
enable.add("Object.EnableStandUp", boost::bind(&enable_object_stand_up));
- enable.add("Object.EnableSit", boost::bind(&enable_object_sit));
+ enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1));
view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");
view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 2b6eadcc04..401433e6e1 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1138,10 +1138,26 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam
}
else if(from_name.empty())
{
+ std::string folder_name;
+ if (parent_folder)
+ {
+ // Localize folder name.
+ // *TODO: share this code?
+ folder_name = parent_folder->getName();
+ if (LLFolderType::lookupIsProtectedType(parent_folder->getPreferredType()))
+ {
+ LLTrans::findString(folder_name, "InvFolder " + folder_name);
+ }
+ }
+ else
+ {
+ folder_name = LLTrans::getString("Unknown");
+ }
+
// we receive a message from LLOpenTaskOffer, it mean that new landmark has been added.
LLSD args;
args["LANDMARK_NAME"] = item->getName();
- args["FOLDER_NAME"] = std::string(parent_folder ? parent_folder->getName() : "unknown");
+ args["FOLDER_NAME"] = folder_name;
LLNotificationsUtil::add("LandmarkCreated", args);
}
}
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 59efae4cb2..8bd43bb30c 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -90,7 +90,7 @@ public:
}
static void processForeignLandmark(LLLandmark* landmark,
const LLUUID& object_id, const LLUUID& notecard_inventory_id,
- LLInventoryItem* item)
+ LLPointer<LLInventoryItem> item_ptr)
{
LLVector3d global_pos;
landmark->getGlobalPos(global_pos);
@@ -103,8 +103,16 @@ public:
}
else
{
- LLPointer<LLEmbeddedLandmarkCopied> cb = new LLEmbeddedLandmarkCopied();
- copy_inventory_from_notecard(object_id, notecard_inventory_id, item, gInventoryCallbacks.registerCB(cb));
+ if (item_ptr.isNull())
+ {
+ // check to prevent a crash. See EXT-8459.
+ llwarns << "Passed handle contains a dead inventory item. Most likely notecard has been closed and embedded item was destroyed." << llendl;
+ }
+ else
+ {
+ LLPointer<LLEmbeddedLandmarkCopied> cb = new LLEmbeddedLandmarkCopied();
+ copy_inventory_from_notecard(object_id, notecard_inventory_id, item_ptr.get(), gInventoryCallbacks.registerCB(cb));
+ }
}
}
};
@@ -300,14 +308,14 @@ public:
void markSaved();
- static LLInventoryItem* getEmbeddedItem(llwchar ext_char); // returns item from static list
+ static LLPointer<LLInventoryItem> getEmbeddedItemPtr(llwchar ext_char); // returns pointer to item from static list
static BOOL getEmbeddedItemSaved(llwchar ext_char); // returns whether item from static list is saved
private:
struct embedded_info_t
{
- LLPointer<LLInventoryItem> mItem;
+ LLPointer<LLInventoryItem> mItemPtr;
BOOL mSaved;
};
typedef std::map<llwchar, embedded_info_t > item_map_t;
@@ -378,7 +386,7 @@ BOOL LLEmbeddedItems::insertEmbeddedItem( LLInventoryItem* item, llwchar* ext_ch
++wc_emb;
}
- sEntries[wc_emb].mItem = item;
+ sEntries[wc_emb].mItemPtr = item;
sEntries[wc_emb].mSaved = is_new ? FALSE : TRUE;
*ext_char = wc_emb;
mEmbeddedUsedChars.insert(wc_emb);
@@ -400,14 +408,14 @@ BOOL LLEmbeddedItems::removeEmbeddedItem( llwchar ext_char )
}
// static
-LLInventoryItem* LLEmbeddedItems::getEmbeddedItem(llwchar ext_char)
+LLPointer<LLInventoryItem> LLEmbeddedItems::getEmbeddedItemPtr(llwchar ext_char)
{
if( ext_char >= LLTextEditor::FIRST_EMBEDDED_CHAR && ext_char <= LLTextEditor::LAST_EMBEDDED_CHAR )
{
item_map_t::iterator iter = sEntries.find(ext_char);
if (iter != sEntries.end())
{
- return iter->second.mItem;
+ return iter->second.mItemPtr;
}
}
return NULL;
@@ -505,7 +513,7 @@ BOOL LLEmbeddedItems::hasEmbeddedItem(llwchar ext_char)
LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const
{
- LLInventoryItem* item = getEmbeddedItem(ext_char);
+ LLInventoryItem* item = getEmbeddedItemPtr(ext_char);
if (item)
{
const char* img_name = "";
@@ -567,7 +575,7 @@ void LLEmbeddedItems::getEmbeddedItemList( std::vector<LLPointer<LLInventoryItem
for (std::set<llwchar>::iterator iter = mEmbeddedUsedChars.begin(); iter != mEmbeddedUsedChars.end(); ++iter)
{
llwchar wc = *iter;
- LLPointer<LLInventoryItem> item = getEmbeddedItem(wc);
+ LLPointer<LLInventoryItem> item = getEmbeddedItemPtr(wc);
if (item)
{
items.push_back(item);
@@ -698,7 +706,7 @@ BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
{
wc = getWText()[mCursorPos];
}
- LLInventoryItem* item_at_pos = LLEmbeddedItems::getEmbeddedItem(wc);
+ LLPointer<LLInventoryItem> item_at_pos = LLEmbeddedItems::getEmbeddedItemPtr(wc);
if (item_at_pos)
{
mDragItem = item_at_pos;
@@ -1019,7 +1027,7 @@ llwchar LLViewerTextEditor::pasteEmbeddedItem(llwchar ext_char)
{
return ext_char; // already exists in my list
}
- LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItem(ext_char);
+ LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItemPtr(ext_char);
if (item)
{
// Add item to my list and return new llwchar associated with it
@@ -1053,7 +1061,7 @@ void LLViewerTextEditor::findEmbeddedItemSegments(S32 start, S32 end)
&& embedded_char <= LAST_EMBEDDED_CHAR
&& mEmbeddedItemList->hasEmbeddedItem(embedded_char) )
{
- LLInventoryItem* itemp = mEmbeddedItemList->getEmbeddedItem(embedded_char);
+ LLInventoryItem* itemp = mEmbeddedItemList->getEmbeddedItemPtr(embedded_char);
LLUIImagePtr image = mEmbeddedItemList->getItemImage(embedded_char);
insertSegment(new LLEmbeddedItemSegment(idx, image, itemp, *this));
}
@@ -1065,7 +1073,7 @@ BOOL LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos)
if( pos < getLength())
{
llwchar wc = getWText()[pos];
- LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItem( wc );
+ LLPointer<LLInventoryItem> item = LLEmbeddedItems::getEmbeddedItemPtr( wc );
if( item )
{
BOOL saved = LLEmbeddedItems::getEmbeddedItemSaved( wc );
@@ -1083,7 +1091,7 @@ BOOL LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos)
}
-BOOL LLViewerTextEditor::openEmbeddedItem(LLInventoryItem* item, llwchar wc)
+BOOL LLViewerTextEditor::openEmbeddedItem(LLPointer<LLInventoryItem> item, llwchar wc)
{
switch( item->getType() )
@@ -1151,17 +1159,17 @@ void LLViewerTextEditor::openEmbeddedSound( LLInventoryItem* item, llwchar wc )
}
-void LLViewerTextEditor::openEmbeddedLandmark( LLInventoryItem* item, llwchar wc )
+void LLViewerTextEditor::openEmbeddedLandmark( LLPointer<LLInventoryItem> item_ptr, llwchar wc )
{
- if (!item)
+ if (item_ptr.isNull())
return;
- LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID(),
- boost::bind(&LLEmbeddedLandmarkCopied::processForeignLandmark, _1, mObjectID, mNotecardInventoryID, item));
+ LLLandmark* landmark = gLandmarkList.getAsset(item_ptr->getAssetUUID(),
+ boost::bind(&LLEmbeddedLandmarkCopied::processForeignLandmark, _1, mObjectID, mNotecardInventoryID, item_ptr));
if (landmark)
{
LLEmbeddedLandmarkCopied::processForeignLandmark(landmark, mObjectID,
- mNotecardInventoryID, item);
+ mNotecardInventoryID, item_ptr);
}
}
@@ -1220,7 +1228,7 @@ bool LLViewerTextEditor::onCopyToInvDialog(const LLSD& notification, const LLSD&
{
LLUUID item_id = notification["payload"]["item_id"].asUUID();
llwchar wc = llwchar(notification["payload"]["item_wc"].asInteger());
- LLInventoryItem* itemp = LLEmbeddedItems::getEmbeddedItem(wc);
+ LLInventoryItem* itemp = LLEmbeddedItems::getEmbeddedItemPtr(wc);
if (itemp)
copyInventory(itemp);
}
diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h
index ba0c40cb2e..74b6d70640 100644
--- a/indra/newview/llviewertexteditor.h
+++ b/indra/newview/llviewertexteditor.h
@@ -104,13 +104,16 @@ private:
virtual llwchar pasteEmbeddedItem(llwchar ext_char);
BOOL openEmbeddedItemAtPos( S32 pos );
- BOOL openEmbeddedItem(LLInventoryItem* item, llwchar wc);
+ BOOL openEmbeddedItem(LLPointer<LLInventoryItem> item, llwchar wc);
S32 insertEmbeddedItem(S32 pos, LLInventoryItem* item);
+ // *NOTE: most of openEmbeddedXXX methods except openEmbeddedLandmark take pointer to LLInventoryItem.
+ // Be sure they don't bind it to callback function to avoid situation when it gets invalid when
+ // callback is trigged after text editor is closed. See EXT-8459.
void openEmbeddedTexture( LLInventoryItem* item, llwchar wc );
void openEmbeddedSound( LLInventoryItem* item, llwchar wc );
- void openEmbeddedLandmark( LLInventoryItem* item, llwchar wc );
+ void openEmbeddedLandmark( LLPointer<LLInventoryItem> item_ptr, llwchar wc );
void openEmbeddedNotecard( LLInventoryItem* item, llwchar wc);
void openEmbeddedCallingcard( LLInventoryItem* item, llwchar wc);
void showCopyToInvDialog( LLInventoryItem* item, llwchar wc );
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 2f63e7ef01..00873a797c 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -4390,7 +4390,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
gResizeScreenTexture = TRUE;
- if (gAgentCamera.cameraCustomizeAvatar())
+ if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
{
LLVisualParamHint::requestHintUpdates();
}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 9353c6daef..68085b1baf 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -4095,9 +4095,13 @@ void LLVOAvatar::updateTextures()
}
else
{
- render_avatar = isVisible() && !mCulled;
+ if(!isVisible())
+ {
+ return ;//do not update for invisible avatar.
+ }
+
+ render_avatar = !mCulled; //visible and not culled.
}
- checkTextureLoading() ;
std::vector<BOOL> layer_baked;
// GL NOT ACTIVE HERE - *TODO
@@ -4138,7 +4142,7 @@ void LLVOAvatar::updateTextures()
}
}
}
- if (isIndexBakedTexture((ETextureIndex) texture_index) && render_avatar)
+ if (isIndexBakedTexture((ETextureIndex) texture_index))
{
const S32 boost_level = getAvatarBakedBoostLevel();
imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE);
@@ -4172,10 +4176,11 @@ void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture
return;
}
-
+const S32 MAX_TEXTURE_UPDATE_INTERVAL = 64 ; //need to call updateTextures() at least every 32 frames.
+const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = S32_MAX ; //frames
void LLVOAvatar::checkTextureLoading()
{
- static const F32 MAX_INVISIBLE_WAITING_TIME = 30.f ; //seconds
+ static const F32 MAX_INVISIBLE_WAITING_TIME = 15.f ; //seconds
BOOL pause = !isVisible() ;
if(!pause)
@@ -4195,9 +4200,9 @@ void LLVOAvatar::checkTextureLoading()
if(pause && mInvisibleTimer.getElapsedTimeF32() < MAX_INVISIBLE_WAITING_TIME)
{
- return ;
+ return ; //have not been invisible for enough time.
}
-
+
for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = mCallbackTextureList.begin();
iter != mCallbackTextureList.end(); ++iter)
{
@@ -4207,17 +4212,22 @@ void LLVOAvatar::checkTextureLoading()
if(pause)//pause texture fetching.
{
tex->pauseLoadedCallbacks(&mCallbackTextureList) ;
+
+ //set to terminate texture fetching after MAX_TEXTURE_UPDATE_INTERVAL frames.
+ tex->setMaxVirtualSizeResetInterval(MAX_TEXTURE_UPDATE_INTERVAL);
+ tex->resetMaxVirtualSizeResetCounter() ;
}
else//unpause
{
- static const F32 START_AREA = 100.f ;
-
- tex->unpauseLoadedCallbacks(&mCallbackTextureList) ;
- tex->addTextureStats(START_AREA); //jump start the fetching again
+ tex->unpauseLoadedCallbacks(&mCallbackTextureList) ;
}
}
}
+ if(!pause)
+ {
+ updateTextures() ; //refresh texture stats.
+ }
mLoadedCallbacksPaused = pause ;
return ;
}
@@ -4226,12 +4236,14 @@ const F32 SELF_ADDITIONAL_PRI = 0.75f ;
const F32 ADDITIONAL_PRI = 0.5f;
void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level)
{
- //if this function is not called for the last 512 frames, the texture pipeline will stop fetching this texture.
- static const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = 512 ; //frames
-
+ //Note:
+ //if this function is not called for the last MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL frames,
+ //the texture pipeline will stop fetching this texture.
+
imagep->resetTextureStats();
imagep->setCanUseHTTP(false) ; //turn off http fetching for baked textures.
imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
+ imagep->resetMaxVirtualSizeResetCounter() ;
mMaxPixelArea = llmax(pixel_area, mMaxPixelArea);
mMinPixelArea = llmin(pixel_area, mMinPixelArea);
@@ -6051,7 +6063,7 @@ void LLVOAvatar::updateMeshTextures()
}
}
- const BOOL self_customizing = isSelf() && gAgentCamera.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures
+ const BOOL self_customizing = isSelf() && !gAgentAvatarp->isUsingBakedTextures(); // During face edit mode, we don't use baked textures
const BOOL other_culled = !isSelf() && mCulled;
LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ;
BOOL paused = FALSE;
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 83ca299da1..4163810d6c 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -1049,6 +1049,7 @@ protected: // Shared with LLVOAvatarSelf
*******************************************************************************/
}; // LLVOAvatar
-extern const F32 SELF_ADDITIONAL_PRI;
+extern const F32 SELF_ADDITIONAL_PRI;
+extern const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL;
#endif // LL_VO_AVATAR_H
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 8961d2c285..3a283e7aa6 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1148,11 +1148,11 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr
discard_level < local_tex_obj->getDiscard())
{
local_tex_obj->setDiscard(discard_level);
- if (!gAgentCamera.cameraCustomizeAvatar())
+ if (isUsingBakedTextures())
{
requestLayerSetUpdate(index);
}
- else if (gAgentCamera.cameraCustomizeAvatar())
+ else
{
LLVisualParamHint::requestHintUpdates();
}
@@ -1622,13 +1622,16 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
if (tex_discard >= 0 && tex_discard <= desired_discard)
{
local_tex_obj->setDiscard(tex_discard);
- if (isSelf() && !gAgentCamera.cameraCustomizeAvatar())
- {
- requestLayerSetUpdate(type);
- }
- else if (isSelf() && gAgentCamera.cameraCustomizeAvatar())
+ if (isSelf())
{
- LLVisualParamHint::requestHintUpdates();
+ if (gAgentAvatarp->isUsingBakedTextures())
+ {
+ requestLayerSetUpdate(type);
+ }
+ else
+ {
+ LLVisualParamHint::requestHintUpdates();
+ }
}
}
else
@@ -2032,7 +2035,7 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe
imagep->setBoostLevel(getAvatarBoostLevel());
imagep->resetTextureStats();
- imagep->setMaxVirtualSizeResetInterval(16);
+ imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
imagep->addTextureStats( desired_pixels / texel_area_ratio );
imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
imagep->forceUpdateBindStats() ;
diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp
index dfa7ca7136..c5042ca016 100644
--- a/indra/newview/llwearable.cpp
+++ b/indra/newview/llwearable.cpp
@@ -698,7 +698,7 @@ void LLWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake
}
}
- if( gAgentCamera.cameraCustomizeAvatar() )
+ if(gAgentCamera.cameraCustomizeAvatar())
{
LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "edit_outfit"));
}
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index b614860b74..d9b2dfbec0 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -465,6 +465,29 @@ std::string LLPanelDummyClothingListItem::wearableTypeToString(LLWearableType::E
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
+LLWearableItemTypeNameComparator::LLWearableTypeOrder::LLWearableTypeOrder(LLWearableItemTypeNameComparator::ETypeListOrder order_priority, bool sort_asset_by_name, bool sort_wearable_by_name):
+ mOrderPriority(order_priority),
+ mSortAssetTypeByName(sort_asset_by_name),
+ mSortWearableTypeByName(sort_wearable_by_name)
+{
+}
+
+LLWearableItemTypeNameComparator::LLWearableItemTypeNameComparator()
+{
+ // By default the sort order conforms the order by spec of MY OUTFITS items list:
+ // 1. CLOTHING - sorted by name
+ // 2. OBJECT - sorted by type
+ // 3. BODYPART - sorted by name
+ mWearableOrder[LLAssetType::AT_CLOTHING] = LLWearableTypeOrder(ORDER_RANK_1, false, false);
+ mWearableOrder[LLAssetType::AT_OBJECT] = LLWearableTypeOrder(ORDER_RANK_2, true, true);
+ mWearableOrder[LLAssetType::AT_BODYPART] = LLWearableTypeOrder(ORDER_RANK_3, false, true);
+}
+
+void LLWearableItemTypeNameComparator::setOrder(LLAssetType::EType items_of_type, LLWearableItemTypeNameComparator::ETypeListOrder order_priority, bool sort_asset_items_by_name, bool sort_wearable_items_by_name)
+{
+ mWearableOrder[items_of_type] = LLWearableTypeOrder(order_priority, sort_asset_items_by_name, sort_wearable_items_by_name);
+}
+
/*virtual*/
bool LLWearableItemNameComparator::doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const
{
@@ -493,7 +516,7 @@ bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemB
return item_type_order1 < item_type_order2;
}
- if (item_type_order1 & TLO_SORTABLE_BY_NAME)
+ if (sortAssetTypeByName(item_type1))
{
// If both items are of the same asset type except AT_CLOTHING and AT_BODYPART
// we can compare them by name.
@@ -505,50 +528,62 @@ bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemB
if (item_wearable_type1 != item_wearable_type2)
{
- // If items are of different clothing types they are compared
- // by clothing types order determined in LLWearableType::EType.
+ // If items are of different LLWearableType::EType types they are compared
+ // by LLWearableType::EType. types order determined in LLWearableType::EType.
return item_wearable_type1 < item_wearable_type2;
}
else
{
// If both items are of the same clothing type they are compared
- // by description and place in reverse order i.e. outer layer item
- // on top.
+ // by description and place in reverse order (i.e. outer layer item
+ // on top) OR by name
+ if(sortWearableTypeByName(item_type1))
+ {
+ return LLWearableItemNameComparator::doCompare(wearable_item1, wearable_item2);
+ }
return wearable_item1->getDescription() > wearable_item2->getDescription();
}
}
-// static
-LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparator::getTypeListOrder(LLAssetType::EType item_type)
+LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparator::getTypeListOrder(LLAssetType::EType item_type) const
{
- switch (item_type)
+ wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
+
+ if(const_it == mWearableOrder.end())
{
- case LLAssetType::AT_OBJECT:
- return TLO_ATTACHMENT;
+ llwarns<<"Absent information about order rang of items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
+ return ORDER_RANK_UNKNOWN;
+ }
- case LLAssetType::AT_CLOTHING:
- return TLO_CLOTHING;
+ return const_it->second.mOrderPriority;
+}
- case LLAssetType::AT_BODYPART:
- return TLO_BODYPART;
+bool LLWearableItemTypeNameComparator::sortAssetTypeByName(LLAssetType::EType item_type) const
+{
+ wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
- default:
- return TLO_UNKNOWN;
+ if(const_it == mWearableOrder.end())
+ {
+ llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
+ return true;
}
+
+ return const_it->second.mSortAssetTypeByName;
}
-/*virtual*/
+bool LLWearableItemTypeNameComparator::sortWearableTypeByName(LLAssetType::EType item_type) const
bool LLWearableItemCreationDateComparator::doCompare(const LLPanelInventoryListItemBase* item1, const LLPanelInventoryListItemBase* item2) const
{
- time_t date1 = item1->getCreationDate();
+ wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
time_t date2 = item2->getCreationDate();
- if (date1 == date2)
+ if(const_it == mWearableOrder.end())
{
- return LLWearableItemNameComparator::doCompare(item1, item2);
+ llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
+ return true;
}
- return date1 > date2;
+ return const_it->second.mSortWearableTypeByName;
}
//////////////////////////////////////////////////////////////////////////
@@ -718,13 +753,11 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()
const uuid_vec_t& ids = mUUIDs; // selected items IDs
LLUUID selected_id = ids.front(); // ID of the first selected item
- functor_t wear = boost::bind(&LLAppearanceMgr::wearItemOnAvatar, LLAppearanceMgr::getInstance(), _1, true, true, LLPointer<LLInventoryCallback>(NULL));
- functor_t add = boost::bind(&LLAppearanceMgr::wearItemOnAvatar, LLAppearanceMgr::getInstance(), _1, true, false, LLPointer<LLInventoryCallback>(NULL));
functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
// Register handlers common for all wearable types.
- registrar.add("Wearable.Wear", boost::bind(handleMultiple, wear, ids));
- registrar.add("Wearable.Add", boost::bind(handleMultiple, add, ids));
+ registrar.add("Wearable.Wear", boost::bind(wear_multiple, ids, true));
+ registrar.add("Wearable.Add", boost::bind(wear_multiple, ids, false));
registrar.add("Wearable.Edit", boost::bind(handleMultiple, LLAgentWearables::editWearable, ids));
registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id));
registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id));
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index 55f8996140..84e999cd57 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -307,33 +307,76 @@ class LLWearableItemTypeNameComparator : public LLWearableItemNameComparator
LOG_CLASS(LLWearableItemTypeNameComparator);
public:
- LLWearableItemTypeNameComparator() {};
+
+ LLWearableItemTypeNameComparator();
virtual ~LLWearableItemTypeNameComparator() {};
+ enum ETypeListOrder
+ {
+ ORDER_RANK_1 = 1,
+ ORDER_RANK_2,
+ ORDER_RANK_3,
+ ORDER_RANK_UNKNOWN
+ };
+
+ void setOrder(LLAssetType::EType items_of_type, ETypeListOrder order_priority, bool sort_items_by_name, bool sort_wearable_items_by_name);
+
protected:
/**
- * Returns "true" if wearable_item1 is placed before wearable_item2 sorted by the following:
- * - Attachments (abc order)
- * - Clothing
- * - by type (types order determined in LLWearableType::EType)
- * - outer layer on top
- * - Body Parts (abc order),
- * "false" otherwise.
+ * All information about sort order is stored in mWearableOrder map
+ *
+ * mWearableOrder : KYES VALUES
+ * [LLAssetType] [struct LLWearableTypeOrder]
+ *
+ *---------------------------------------------------------------------------------------------
+ * I. Determines order (ORDER_RANK) in which items of LLAssetType should be displayed in list.
+ * For example by spec in MY OUTFITS the order is:
+ * 1. AT_CLOTHING (ORDER_RANK_1)
+ * 2. AT_OBJECT (ORDER_RANK_2)
+ * 3. AT_BODYPART (ORDER_RANK_3)
+ *
+ * II.Items of each type(LLAssetType) are sorted by name or type(LLWearableType)
+ * For example by spec in MY OUTFITS the order within each items type(LLAssetType) is:
+ * 1. AT_OBJECTS (abc order)
+ * 2. AT_CLOTHINGS
+ * - by type (types order determined in LLWearableType::EType)
+ * - outer layer on top
+ * 3. AT_BODYPARTS (abc order)
+ *---------------------------------------------------------------------------------------------
+ *
+ * For each LLAssetType (KEYS in mWearableOrder) the information about:
+ *
+ * I. ORDER_RANK (the flag is LLWearableTypeOrder::mOrderPriority)
+ *
+ * II. whether items of this LLAssetType type should be ordered
+ * by name or by LLWearableType::EType (the flag is LLWearableTypeOrder::mSortAssetTypeByName)
+ *
+ * III.whether items of LLWearableType type within this LLAssetType
+ * should be ordered by name (the flag is LLWearableTypeOrder::mSortWearableTypeByName)
+ *
+ * holds in mWearableOrder map as VALUES (struct LLWearableTypeOrder).
*/
/*virtual*/ bool doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const;
private:
- enum ETypeListOrder
+
+ struct LLWearableTypeOrder
{
- TLO_CLOTHING = 0x01,
- TLO_ATTACHMENT = 0x02,
- TLO_BODYPART = 0x04,
- TLO_UNKNOWN = 0x08,
+ ETypeListOrder mOrderPriority;
+ bool mSortAssetTypeByName;
+ bool mSortWearableTypeByName;
- TLO_SORTABLE_BY_NAME = TLO_ATTACHMENT | TLO_UNKNOWN
+ LLWearableTypeOrder(ETypeListOrder order_priority, bool sort_asset_by_name, bool sort_wearable_by_name);
+ LLWearableTypeOrder(){};
};
- static LLWearableItemTypeNameComparator::ETypeListOrder getTypeListOrder(LLAssetType::EType item_type);
+ ETypeListOrder getTypeListOrder(LLAssetType::EType item_type) const;
+
+ bool sortAssetTypeByName(LLAssetType::EType item_type) const;
+ bool sortWearableTypeByName(LLAssetType::EType item_type) const;
+
+ typedef std::map<LLAssetType::EType,LLWearableTypeOrder> wearable_type_order_map_t;
+ wearable_type_order_map_t mWearableOrder;
};
/**
diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp
index 66cb02ce99..9bbe005de8 100644
--- a/indra/newview/llworldmap.cpp
+++ b/indra/newview/llworldmap.cpp
@@ -37,6 +37,7 @@
#include "llworldmapmessage.h"
#include "message.h"
#include "lltracker.h"
+#include "lluistring.h"
#include "llviewertexturelist.h"
#include "lltrans.h"
@@ -522,8 +523,12 @@ bool LLWorldMap::insertItem(U32 x_world, U32 y_world, std::string& name, LLUUID&
case MAP_ITEM_LAND_FOR_SALE: // land for sale
case MAP_ITEM_LAND_FOR_SALE_ADULT: // adult land for sale
{
- std::string tooltip = llformat("%d sq. m. L$%d", extra, extra2);
- new_item.setTooltip(tooltip);
+ static LLUIString tooltip_fmt = LLTrans::getString("worldmap_item_tooltip_format");
+
+ tooltip_fmt.setArg("[AREA]", llformat("%d", extra));
+ tooltip_fmt.setArg("[PRICE]", llformat("%d", extra2));
+ new_item.setTooltip(tooltip_fmt.getString());
+
if (type == MAP_ITEM_LAND_FOR_SALE)
{
siminfo->insertLandForSale(new_item);
diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h
index e4e677eb64..b97e5249e1 100644
--- a/indra/newview/llworldmap.h
+++ b/indra/newview/llworldmap.h
@@ -52,7 +52,7 @@ public:
LLItemInfo(F32 global_x, F32 global_y, const std::string& name, LLUUID id);
// Setters
- void setTooltip(std::string& tooltip) { mToolTip = tooltip; }
+ void setTooltip(const std::string& tooltip) { mToolTip = tooltip; }
void setElevation(F64 z) { mPosGlobal.mdV[VZ] = z; }
void setCount(S32 count) { mCount = count; }
// void setSelected(bool selected) { mSelected = selected; }
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index 68e36ff0b3..99bf3e6bc1 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1472,8 +1472,10 @@ Only large parcels can be listed in search.
left="14"
name="MatureCheck"
top="177"
+ label_text.valign="center"
+ label_text.v_pad="-5"
tool_tip=" "
- width="107" />
+ width="200" />
<text
type="string"
length="1"
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
index 7239b13466..e2348375d5 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -11,8 +11,7 @@
function="Object.Touch" />
<menu_item_call.on_enable
function="Object.EnableTouch"
- name="EnableTouch"
- parameter="Touch" />
+ name="EnableTouch"/>
</menu_item_call>
<!--menu_item_call
label="Stand Up"
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
index b6f00ef6d1..8ec7689819 100644
--- a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
@@ -22,7 +22,7 @@
<menu_item_call.on_click
function="InspectObject.Sit"/>
<menu_item_call.on_visible
- function="Object.EnableGearSit" />
+ function="Object.EnableSit"/>
</menu_item_call>
<menu_item_call
label="Pay"
diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
index 6523b0d491..41f2b28004 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -76,19 +76,22 @@ Maximum 200 per group daily
follows="top|left"
height="23"
image_overlay="AddItem_Off"
+ image_overlay_alignment="left"
+ imgoverlay_label_space="-10"
+ label="New Notice"
layout="topleft"
left="5"
name="create_new_notice"
tool_tip="Create a new notice"
- top_delta="-3"
- width="23" />
+ top_delta="0"
+ width="93" />
<button
follows="top|left"
height="23"
image_overlay="Refresh_Off"
layout="topleft"
name="refresh_notices"
- left_pad="230"
+ left="260"
tool_tip="Refresh list of notices"
top_delta="0"
width="23" />
@@ -113,7 +116,7 @@ Maximum 200 per group daily
mouse_opaque="false"
name="lbl"
text_color="EmphasisColor"
- top="0"
+ top="5"
width="200">
Create a Notice
</text>
@@ -270,7 +273,7 @@ Maximum 200 per group daily
mouse_opaque="false"
name="lbl"
text_color="EmphasisColor"
- top_pad="0"
+ top_pad="5"
width="265">
Archived Notice
</text>
diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
index 0eb5c47f85..18a2f37ba2 100644
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -50,6 +50,10 @@ Select multiple Members by holding the Ctrl key and
clicking on their names.
</panel.string>
<panel.string
+ name="donation_area">
+ [AREA] m²
+ </panel.string>
+ <panel.string
name="power_folder_icon" translate="false">
Inv_FolderClosed
</panel.string>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index e5bd549036..a0c67e3612 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -278,6 +278,7 @@
<!-- world map -->
<string name="texture_loading">Loading...</string>
<string name="worldmap_offline">Offline</string>
+ <string name="worldmap_item_tooltip_format">[AREA] m² L$[PRICE]</string>
<string name="worldmap_results_none_found">None found.</string>
<!-- animations uploading status codes -->
@@ -2102,6 +2103,7 @@ Clears (deletes) the media and all params from the given face.
<string name="SummaryForTheWeek" value="Summary for this week, beginning on " />
<string name="NextStipendDay" value="The next stipend day is " />
<string name="GroupIndividualShare" value=" Group Individual Share" />
+ <string name="GroupColumn" value=" Group" />
<string name="Balance">Balance</string>
<string name="Credits">Credits</string>
<string name="Debits">Debits</string>
@@ -3141,6 +3143,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="group_role_everyone">Everyone</string>
<string name="group_role_officers">Officers</string>
<string name="group_role_owners">Owners</string>
+ <string name="group_member_status_online">Online</string>
<string name="uploading_abuse_report">Uploading...
@@ -3165,6 +3168,7 @@ Abuse Report</string>
<string name="Invalid Wearable">Invalid Wearable</string>
<string name="New Gesture">New Gesture</string>
<string name="New Script">New Script</string>
+ <string name="New Note">New Note</string>
<string name="New Folder">New Folder</string>
<string name="Contents">Contents</string>
<string name="Gesture">Gesture</string>
diff --git a/indra/newview/skins/default/xui/fr/floater_water.xml b/indra/newview/skins/default/xui/fr/floater_water.xml
index 96723b0fe6..7d1e3cd65c 100644
--- a/indra/newview/skins/default/xui/fr/floater_water.xml
+++ b/indra/newview/skins/default/xui/fr/floater_water.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="Water Floater" title="ÉDITEUR D&apos;EAU AVANCÉ">
<floater.string name="WLDefaultWaterNames">
- Default:Glassy:Pond:Murky:Second Plague:SNAKE!!!:Valdez
+ Valeur par défaut:Transparente:Bassin:Trouble:Première plaie:SERPENT !!!:Valdez
</floater.string>
<text name="KeyFramePresetsText" width="120">
Préréglages :
diff --git a/indra/newview/skins/default/xui/fr/floater_windlight_options.xml b/indra/newview/skins/default/xui/fr/floater_windlight_options.xml
index 74f1697449..657e5f5051 100644
--- a/indra/newview/skins/default/xui/fr/floater_windlight_options.xml
+++ b/indra/newview/skins/default/xui/fr/floater_windlight_options.xml
@@ -184,6 +184,6 @@
</panel>
</tab_container>
<string name="WLDefaultSkyNames">
- A-12AM:A-12PM:A-3AM:A-3PM:A-4.30PM:A-6AM:A-6PM:A-9AM:A-9PM:Barcelona:Blizzard:Blue Midday:Coastal Afternoon:Coastal Sunset:Default:Desert Sunset:Fine Day:Fluffy Big Clouds:Foggy:Funky Funky:Funky Funky Funky:Gelatto:Ghost:Incongruent Truths:Midday 1:Midday 2:Midday 3:Midday 4:Night:Pirate:Purple:Sailor&apos;s Delight:Sheer Sensuality
+ A-Minuit:A-Midi:A-3h:A-15h:A-16h30:A-6h:A-18h:A-9h:A-21h:Barcelone:Blizzard:Bleu mi-journée:Après-midi sur la côte:Coucher de soleil (côte):Valeur par défaut:Coucher de soleil (désert):Belle journée:Gros nuages floconneux:Brumeux:Funky Funky:Funky Funky Funky:Gelatto:Fantôme:Vérités incohérentes:Mi-journée 1:Mi-journée 2:Mi-journée 3:Mi-journée 4:Nuit:Pirate:Mauve:Rêve de navigateur:Sensualité pure
</string>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/panel_nearby_media.xml b/indra/newview/skins/default/xui/fr/panel_nearby_media.xml
index 978ca86d62..1a6101830b 100644
--- a/indra/newview/skins/default/xui/fr/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/fr/panel_nearby_media.xml
@@ -27,7 +27,7 @@
Médias proches
</text>
<text name="show_text">
- Afficher :
+ Voir :
</text>
<combo_box name="show_combo">
<combo_box.item label="Tout" name="All"/>
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index 1c29feec5f..347a5e8ab8 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -226,6 +226,16 @@ S32 LLNotification::getSelectedOption(const LLSD& notification, const LLSD& resp
return response.asInteger();
}
+//-----------------------------------------------------------------------------
+#include "../llmachineid.h"
+unsigned char gMACAddress[MAC_ADDRESS_BYTES] = {77,21,46,31,89,2};
+
+S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
+{
+ memcpy(unique_id, gMACAddress, len);
+ return 1;
+}
+//-----------------------------------------------------------------------------
// misc
std::string xml_escape_string(const std::string& in)
{