summaryrefslogtreecommitdiff
path: root/indra/newview/llviewermenu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llviewermenu.cpp')
-rw-r--r--indra/newview/llviewermenu.cpp93
1 files changed, 71 insertions, 22 deletions
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 2cf341f87f..2604c7f8d6 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -289,6 +289,7 @@ void handle_disconnect_viewer(void *);
void force_error_breakpoint(void *);
void force_error_llerror(void *);
+void force_error_llerror_msg(void*);
void force_error_bad_memory_access(void *);
void force_error_infinite_loop(void *);
void force_error_software_exception(void *);
@@ -2400,6 +2401,15 @@ class LLAdvancedForceErrorLlerror : public view_listener_t
}
};
+class LLAdvancedForceErrorLlerrorMsg: public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_llerror_msg(NULL);
+ return true;
+ }
+};
+
class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -7279,37 +7289,70 @@ class LLAttachmentDetach : public view_listener_t
{
// Called when the user clicked on an object attached to them
// and selected "Detach".
- LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ LLViewerObject *object = selection->getPrimaryObject();
if (!object)
{
LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL;
return true;
}
- LLViewerObject *parent = (LLViewerObject*)object->getParent();
- while (parent)
- {
- if(parent->isAvatar())
- {
- break;
- }
- object = parent;
- parent = (LLViewerObject*)parent->getParent();
- }
+ struct f: public LLSelectedObjectFunctor
+ {
+ f() : mAvatarsInSelection(false) {}
+ virtual bool apply(LLViewerObject* objectp)
+ {
+ if (!objectp)
+ {
+ return false;
+ }
- if (!object)
- {
- LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL;
- return true;
- }
+ if (objectp->isAvatar())
+ {
+ mAvatarsInSelection = true;
+ return false;
+ }
- if (object->isAvatar())
- {
- LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL;
- return true;
- }
+ LLViewerObject* parent = (LLViewerObject*)objectp->getParent();
+ while (parent)
+ {
+ if (parent->isAvatar())
+ {
+ break;
+ }
+ objectp = parent;
+ parent = (LLViewerObject*)parent->getParent();
+ }
- LLAppearanceMgr::instance().removeItemFromAvatar(object->getAttachmentItemID());
+ // std::set to avoid dupplicate 'roots' from linksets
+ mRemoveSet.insert(objectp->getAttachmentItemID());
+
+ return true;
+ }
+ bool mAvatarsInSelection;
+ uuid_set_t mRemoveSet;
+ } func;
+ // Probbly can run applyToRootObjects instead,
+ // but previous version of this code worked for any selected object
+ selection->applyToObjects(&func);
+
+ if (func.mAvatarsInSelection)
+ {
+ // Not possible under normal circumstances
+ // Either avatar selection is ON or has to do with animeshes
+ // Better stop this than mess something
+ LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL;
+ return true;
+ }
+
+ if (func.mRemoveSet.empty())
+ {
+ LL_WARNS() << "handle_detach() - no valid attachments in selection to detach" << LL_ENDL;
+ return true;
+ }
+
+ uuid_vec_t detach_list(func.mRemoveSet.begin(), func.mRemoveSet.end());
+ LLAppearanceMgr::instance().removeItemsFromAvatar(detach_list);
return true;
}
@@ -8379,6 +8422,11 @@ void force_error_llerror(void *)
LLAppViewer::instance()->forceErrorLLError();
}
+void force_error_llerror_msg(void*)
+{
+ LLAppViewer::instance()->forceErrorLLErrorMsg();
+}
+
void force_error_bad_memory_access(void *)
{
LLAppViewer::instance()->forceErrorBadMemoryAccess();
@@ -9604,6 +9652,7 @@ void initialize_menus()
// Advanced > Debugging
view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint");
view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror");
+ view_listener_t::addMenu(new LLAdvancedForceErrorLlerrorMsg(), "Advanced.ForceErrorLlerrorMsg");
view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess");
view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro");
view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");