From 2a58e320cb06308860de1df0ac30a40d1fa6e2ba Mon Sep 17 00:00:00 2001 From: skolb Date: Mon, 1 Mar 2010 18:08:00 -0800 Subject: https://jira.secondlife.com/browse/EXT-5884 Added code to support SLAPPS for Media on a Prim Reviewed by Monroe and Callum via Code Collab (Review 143). --- indra/newview/llmediactrl.cpp | 7 ------- indra/newview/llviewermedia.cpp | 9 +++++++++ indra/newview/llviewerparcelmedia.cpp | 6 ------ 3 files changed, 9 insertions(+), 13 deletions(-) (limited to 'indra') diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index bf33d8527e..c244bc38ed 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -943,13 +943,6 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) }; break; - case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL; - onClickLinkNoFollow(self); - }; - break; - case MEDIA_EVENT_PLUGIN_FAILED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL; diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 86336e353c..4620ce6354 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -50,6 +50,7 @@ #include "llcallbacklist.h" #include "llparcel.h" #include "llaudioengine.h" // for gAudiop +#include "llurldispatcher.h" #include "llvoavatar.h" #include "llvoavatarself.h" #include "llviewerregion.h" @@ -2340,6 +2341,14 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla { switch(event) { + case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: + { + LL_DEBUGS("Media") << "MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is: " << plugin->getClickURL() << LL_ENDL; + std::string url = plugin->getClickURL(); + LLURLDispatcher::dispatch(url, NULL, false); + + } + break; case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: { // The plugin failed to load properly. Make sure the timer doesn't retry. diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index 2c5c0a37e8..dbf7fdf20c 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -543,12 +543,6 @@ void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent }; break; - case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL; - }; - break; - case MEDIA_EVENT_PLUGIN_FAILED: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL; -- cgit v1.2.3 From 41a30a59fb1b6dea2d531333d0429632f1fef2fe Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Tue, 2 Mar 2010 14:21:58 -0800 Subject: initial work changing topctrl to popup layer --- indra/llui/llcombobox.cpp | 7 +-- indra/llui/llfloater.cpp | 15 +---- indra/llui/llfocusmgr.cpp | 47 +-------------- indra/llui/llfocusmgr.h | 8 +-- indra/llui/llhandle.h | 7 +++ indra/llui/llmodaldialog.cpp | 6 +- indra/llui/llui.cpp | 29 +++++++++ indra/llui/llui.h | 10 +++ indra/llui/llview.cpp | 5 -- indra/newview/CMakeLists.txt | 2 + indra/newview/llappviewer.cpp | 6 +- indra/newview/llexpandabletextbox.cpp | 15 +---- indra/newview/llexpandabletextbox.h | 5 -- indra/newview/llfolderview.cpp | 13 ++-- indra/newview/llpanelnearbymedia.cpp | 22 ------- indra/newview/llpanelnearbymedia.h | 1 - indra/newview/llprogressview.cpp | 5 +- indra/newview/llsplitbutton.cpp | 7 +-- indra/newview/lluploaddialog.cpp | 2 +- indra/newview/llviewerwindow.cpp | 77 ++++++++++++++++-------- indra/newview/llviewerwindow.h | 9 ++- indra/newview/skins/default/xui/en/main_view.xml | 13 ++-- 22 files changed, 146 insertions(+), 165 deletions(-) (limited to 'indra') diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 9d23daf56d..de3bf719ee 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -615,7 +615,7 @@ void LLComboBox::showList() // register ourselves as a "top" control // effectively putting us into a special draw layer // and not affecting the bounding rectangle calculation - gFocusMgr.setTopCtrl(this); + LLUI::addPopup(this); // Show the list and push the button down mButton->setToggleState(TRUE); @@ -644,10 +644,7 @@ void LLComboBox::hideList() mList->mouseOverHighlightNthItem(-1); setUseBoundingRect(FALSE); - if( gFocusMgr.getTopCtrl() == this ) - { - gFocusMgr.setTopCtrl(NULL); - } + LLUI::removePopup(this); } } diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index b6d73cda3c..b93b72abf6 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -527,10 +527,7 @@ void LLFloater::setVisible( BOOL visible ) if( !visible ) { - if( gFocusMgr.childIsTopCtrl( this ) ) - { - gFocusMgr.setTopCtrl(NULL); - } + LLUI::removePopup(this); if( gFocusMgr.childHasMouseCapture( this ) ) { @@ -704,10 +701,7 @@ void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent) void LLFloater::releaseFocus() { - if( gFocusMgr.childIsTopCtrl( this ) ) - { - gFocusMgr.setTopCtrl(NULL); - } + LLUI::removePopup(this); setFocus(FALSE); @@ -2503,10 +2497,7 @@ void LLFloaterView::syncFloaterTabOrder() if (modal_dialog) { // If we have a visible modal dialog, make sure that it has focus - if( gFocusMgr.getTopCtrl() != modal_dialog ) - { - gFocusMgr.setTopCtrl( modal_dialog ); - } + LLUI::addPopup(modal_dialog); if( !gFocusMgr.childHasKeyboardFocus( modal_dialog ) ) { diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index 35fbc7b0a8..ad2940e685 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -38,8 +38,6 @@ const F32 FOCUS_FADE_TIME = 0.3f; -// NOTE: the LLFocusableElement implementation has been moved here from lluictrl.cpp. - LLFocusableElement::LLFocusableElement() : mFocusLostCallback(NULL), mFocusReceivedCallback(NULL), @@ -124,8 +122,7 @@ boost::signals2::connection LLFocusableElement::setTopLostCallback(const focus_s LLFocusMgr gFocusMgr; LLFocusMgr::LLFocusMgr() - : - mLockedView( NULL ), +: mLockedView( NULL ), mMouseCaptor( NULL ), mKeyboardFocus( NULL ), mLastKeyboardFocus( NULL ), @@ -133,16 +130,11 @@ LLFocusMgr::LLFocusMgr() mKeystrokesOnly(FALSE), mTopCtrl( NULL ), mAppHasFocus(TRUE) // Macs don't seem to notify us that we've gotten focus, so default to true - #ifdef _DEBUG - , mMouseCaptorName("none") - , mKeyboardFocusName("none") - , mTopCtrlName("none") - #endif { } -void LLFocusMgr::releaseFocusIfNeeded( const LLView* view ) +void LLFocusMgr::releaseFocusIfNeeded( LLView* view ) { if( childHasMouseCapture( view ) ) { @@ -162,10 +154,7 @@ void LLFocusMgr::releaseFocusIfNeeded( const LLView* view ) } } - if( childIsTopCtrl( view ) ) - { - setTopCtrl( NULL ); - } + LLUI::removePopup(view); } @@ -248,11 +237,6 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL return; } - #ifdef _DEBUG - LLUICtrl* focus_ctrl = dynamic_cast(new_focus); - mKeyboardFocusName = focus_ctrl ? focus_ctrl->getName() : std::string("none"); - #endif - // If we've got a default keyboard focus, and the caller is // releasing keyboard focus, move to the default. if (mDefaultKeyboardFocus != NULL && mKeyboardFocus == NULL) @@ -334,20 +318,12 @@ void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLFocusableElement* f if( mKeyboardFocus == focus ) { mKeyboardFocus = NULL; - #ifdef _DEBUG - mKeyboardFocusName = std::string("none"); - #endif } } void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor ) { - //if (mFocusLocked) - //{ - // return; - //} - if( new_captor != mMouseCaptor ) { LLMouseHandler* old_captor = mMouseCaptor; @@ -370,24 +346,14 @@ void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor ) old_captor->onMouseCaptureLost(); } - #ifdef _DEBUG - mMouseCaptorName = new_captor ? new_captor->getName() : std::string("none"); - #endif } } void LLFocusMgr::removeMouseCaptureWithoutCallback( const LLMouseHandler* captor ) { - //if (mFocusLocked) - //{ - // return; - //} if( mMouseCaptor == captor ) { mMouseCaptor = NULL; - #ifdef _DEBUG - mMouseCaptorName = std::string("none"); - #endif } } @@ -416,10 +382,6 @@ void LLFocusMgr::setTopCtrl( LLUICtrl* new_top ) { mTopCtrl = new_top; - #ifdef _DEBUG - mTopCtrlName = new_top ? new_top->getName() : std::string("none"); - #endif - if (old_top) { old_top->onTopLost(); @@ -432,9 +394,6 @@ void LLFocusMgr::removeTopCtrlWithoutCallback( const LLUICtrl* top_view ) if( mTopCtrl == top_view ) { mTopCtrl = NULL; - #ifdef _DEBUG - mTopCtrlName = std::string("none"); - #endif } } diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h index 83ecd1d301..5b08c628d4 100644 --- a/indra/llui/llfocusmgr.h +++ b/indra/llui/llfocusmgr.h @@ -119,7 +119,7 @@ public: BOOL childIsTopCtrl( const LLView* parent ) const; // All Three - void releaseFocusIfNeeded( const LLView* top_view ); + void releaseFocusIfNeeded( LLView* top_view ); void lockFocus(); void unlockFocus(); BOOL focusLocked() const { return mLockedView != NULL; } @@ -149,12 +149,6 @@ private: typedef std::map, LLHandle > focus_history_map_t; focus_history_map_t mFocusHistory; - - #ifdef _DEBUG - std::string mMouseCaptorName; - std::string mKeyboardFocusName; - std::string mTopCtrlName; - #endif }; extern LLFocusMgr gFocusMgr; diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h index 899f6b9326..8ade327044 100644 --- a/indra/llui/llhandle.h +++ b/indra/llui/llhandle.h @@ -67,6 +67,13 @@ public: return *this; } + template + LLHandle& operator =(const LLHandle& other) + { + mTombStone = other.mTombStone; + return *this; + } + bool isDead() const { return mTombStone->getTarget() == NULL; diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp index 387af05935..6cff68c20b 100644 --- a/indra/llui/llmodaldialog.cpp +++ b/indra/llui/llmodaldialog.cpp @@ -111,7 +111,7 @@ void LLModalDialog::onOpen(const LLSD& key) // This is a modal dialog. It sucks up all mouse and keyboard operations. gFocusMgr.setMouseCapture( this ); - gFocusMgr.setTopCtrl( this ); + LLUI::addPopup(this); setFocus(TRUE); sModalStack.push_front( this ); @@ -153,7 +153,7 @@ void LLModalDialog::setVisible( BOOL visible ) gFocusMgr.setMouseCapture( this ); // The dialog view is a root view - gFocusMgr.setTopCtrl( this ); + LLUI::addPopup(this); setFocus( TRUE ); } else @@ -291,7 +291,7 @@ void LLModalDialog::onAppFocusGained() // This is a modal dialog. It sucks up all mouse and keyboard operations. gFocusMgr.setMouseCapture( instance ); instance->setFocus(TRUE); - gFocusMgr.setTopCtrl( instance ); + LLUI::addPopup(instance); instance->centerOnScreen(); } diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index b348ec2d29..64df1dbc7a 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -86,6 +86,9 @@ std::list gUntranslated; /*static*/ LLHelp* LLUI::sHelpImpl = NULL; /*static*/ std::vector LLUI::sXUIPaths; /*static*/ LLFrameTimer LLUI::sMouseIdleTimer; +/*static*/ LLUI::add_popup_t LLUI::sAddPopupFunc; +/*static*/ LLUI::remove_popup_t LLUI::sRemovePopupFunc; +/*static*/ LLUI::clear_popups_t LLUI::sClearPopupsFunc; // register filtereditor here static LLDefaultChildRegistry::Register register_filter_editor("filter_editor"); @@ -1607,6 +1610,13 @@ void LLUI::cleanupClass() sImageProvider->cleanUp(); } +void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup, const clear_popups_t& clear_popups) +{ + sAddPopupFunc = add_popup; + sRemovePopupFunc = remove_popup; + sClearPopupsFunc = clear_popups; +} + //static void LLUI::dirtyRect(LLRect rect) { @@ -1877,6 +1887,25 @@ LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname) return *sSettingGroups["config"]; // default group } +//static +void LLUI::addPopup(LLView* viewp) +{ + if (sAddPopupFunc) + { + sAddPopupFunc(viewp); + } +} + +//static +void LLUI::removePopup(LLView* viewp) +{ + if (sRemovePopupFunc) + { + sRemovePopupFunc(viewp); + } +} + + //static // spawn_x and spawn_y are top left corner of view in screen GL coordinates void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y) diff --git a/indra/llui/llui.h b/indra/llui/llui.h index af8d4ea03b..824d76f526 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -160,12 +160,17 @@ public: // Methods // typedef std::map settings_map_t; + typedef boost::function add_popup_t; + typedef boost::function remove_popup_t; + typedef boost::function clear_popups_t; + static void initClass(const settings_map_t& settings, LLImageProviderInterface* image_provider, LLUIAudioCallback audio_callback = NULL, const LLVector2 *scale_factor = NULL, const std::string& language = LLStringUtil::null); static void cleanupClass(); + static void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& ); static void pushMatrix(); static void popMatrix(); @@ -207,6 +212,8 @@ public: static F32 getMouseIdleTime() { return sMouseIdleTimer.getElapsedTimeF32(); } static void resetMouseIdleTimer() { sMouseIdleTimer.reset(); } static LLWindow* getWindow() { return sWindow; } + static void addPopup(LLView*); + static void removePopup(LLView*); // Ensures view does not overlap mouse cursor, but is inside // the view's parent rectangle. Used for tooltips, inspectors. @@ -227,6 +234,9 @@ private: static LLImageProviderInterface* sImageProvider; static std::vector sXUIPaths; static LLFrameTimer sMouseIdleTimer; + static add_popup_t sAddPopupFunc; + static remove_popup_t sRemovePopupFunc; + static clear_popups_t sClearPopupsFunc; }; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 63e627ceb5..db2c460eec 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -592,11 +592,6 @@ void LLView::setVisible(BOOL visible) { if ( mVisible != visible ) { - if( !visible && (gFocusMgr.getTopCtrl() == this) ) - { - gFocusMgr.setTopCtrl( NULL ); - } - mVisible = visible; // notify children of visibility change if root, or part of visible hierarchy diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 14eb75e457..8ad3b2085d 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -347,6 +347,7 @@ set(viewer_SOURCE_FILES llpatchvertexarray.cpp llplacesinventorybridge.cpp llplacesinventorypanel.cpp + llpopupview.cpp llpolymesh.cpp llpolymorph.cpp llpreview.cpp @@ -844,6 +845,7 @@ set(viewer_HEADER_FILES llplacesinventorypanel.h llpolymesh.h llpolymorph.h + llpopupview.h llpreview.h llpreviewanim.h llpreviewgesture.h diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 948d38befb..a06e54e208 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -702,9 +702,9 @@ bool LLAppViewer::init() settings_map["account"] = &gSavedPerAccountSettings; LLUI::initClass(settings_map, - LLUIImageList::getInstance(), - ui_audio_callback, - &LLUI::sGLScaleFactor); + LLUIImageList::getInstance(), + ui_audio_callback, + &LLUI::sGLScaleFactor); // Setup paths and LLTrans after LLUI::initClass has been called LLUI::setupPaths(); diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index 3818ee6f78..9a906d8323 100644 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -35,6 +35,7 @@ #include "llscrollcontainer.h" #include "llwindow.h" +#include "llviewerwindow.h" static LLDefaultChildRegistry::Register t1("expandable_text"); @@ -382,7 +383,7 @@ void LLExpandableTextBox::expandTextBox() setFocus(TRUE); // this lets us receive top_lost event(needed to collapse text box) // it also draws text box above all other ui elements - gFocusMgr.setTopCtrl(this); + gViewerWindow->addPopup(this); mExpanded = true; } @@ -401,10 +402,7 @@ void LLExpandableTextBox::collapseTextBox() updateTextBoxRect(); - if(gFocusMgr.getTopCtrl() == this) - { - gFocusMgr.setTopCtrl(NULL); - } + gViewerWindow->removePopup(this); } void LLExpandableTextBox::onFocusLost() @@ -414,13 +412,6 @@ void LLExpandableTextBox::onFocusLost() LLUICtrl::onFocusLost(); } -void LLExpandableTextBox::onTopLost() -{ - collapseTextBox(); - - LLUICtrl::onTopLost(); -} - void LLExpandableTextBox::setValue(const LLSD& value) { collapseTextBox(); diff --git a/indra/newview/llexpandabletextbox.h b/indra/newview/llexpandabletextbox.h index 58316ddb98..690c500e84 100644 --- a/indra/newview/llexpandabletextbox.h +++ b/indra/newview/llexpandabletextbox.h @@ -139,11 +139,6 @@ public: */ /*virtual*/ void onFocusLost(); - /** - * Collapses text box on top_lost event - */ - /*virtual*/ void onTopLost(); - /** * Draws text box, collapses text box if its expanded and its parent's position changed */ diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 23f19a38a6..ff19a974bb 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -284,10 +284,7 @@ LLFolderView::~LLFolderView( void ) LLView::deleteViewByHandle(mPopupMenuHandle); - if(mRenamer == gFocusMgr.getTopCtrl()) - { - gFocusMgr.setTopCtrl(NULL); - } + gViewerWindow->removePopup(mRenamer); mAutoOpenItems.removeAllNodes(); clearSelection(); @@ -971,7 +968,7 @@ void LLFolderView::finishRenamingItem( void ) mRenameItem->rename( mRenamer->getText() ); } - gFocusMgr.setTopCtrl( NULL ); + gViewerWindow->removePopup(mRenamer); if( mRenameItem ) { @@ -988,7 +985,7 @@ void LLFolderView::closeRenamer( void ) // will commit current name (which could be same as original name) mRenamer->setFocus( FALSE ); mRenamer->setVisible( FALSE ); - gFocusMgr.setTopCtrl( NULL ); + gViewerWindow->removePopup(mRenamer); if( mRenameItem ) { @@ -1420,7 +1417,7 @@ void LLFolderView::startRenamingSelectedItem( void ) mRenamer->setFocus( TRUE ); mRenamer->setTopLostCallback(boost::bind(onRenamerLost, _1)); mRenamer->setFocusLostCallback(boost::bind(onRenamerLost, _1)); - gFocusMgr.setTopCtrl( mRenamer ); + gViewerWindow->addPopup(mRenamer); } } @@ -1901,7 +1898,7 @@ void LLFolderView::deleteAllChildren() { if(mRenamer == gFocusMgr.getTopCtrl()) { - gFocusMgr.setTopCtrl(NULL); + gViewerWindow->removePopup(mRenamer); } LLView::deleteViewByHandle(mPopupMenuHandle); mPopupMenuHandle = LLHandle(); diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index c02f154dc8..41e37a9b1b 100644 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -193,28 +193,13 @@ void LLPanelNearByMedia::handleVisibilityChange ( BOOL new_visibility ) if (new_visibility) { mHoverTimer.start(); // timer will be stopped when mouse hovers over panel - //gFocusMgr.setTopCtrl(this); } else { mHoverTimer.stop(); - //if (gFocusMgr.getTopCtrl() == this) - //{ - // gFocusMgr.setTopCtrl(NULL); - //} } } -/*virtual*/ -void LLPanelNearByMedia::onTopLost () -{ - //LLUICtrl* new_top = gFocusMgr.getTopCtrl(); - //if (!new_top || !new_top->hasAncestor(this)) - //{ - // setVisible(FALSE); - //} -} - /*virtual*/ void LLPanelNearByMedia::reshape(S32 width, S32 height, BOOL called_from_parent) { @@ -234,13 +219,6 @@ const F32 AUTO_CLOSE_FADE_TIME_END = 5.0f; /*virtual*/ void LLPanelNearByMedia::draw() { - //LLUICtrl* new_top = gFocusMgr.getTopCtrl(); - //if (new_top != this) - //{ - // // reassert top ctrl - // gFocusMgr.setTopCtrl(this); - //} - // keep bottom of panel on screen LLRect screen_rect = calcScreenRect(); if (screen_rect.mBottom < 0) diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h index 4f864519f5..809a8d81a1 100644 --- a/indra/newview/llpanelnearbymedia.h +++ b/indra/newview/llpanelnearbymedia.h @@ -54,7 +54,6 @@ public: /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); /*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); - /*virtual*/ void onTopLost (); /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 0476e785a5..15831d85a0 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -128,11 +128,14 @@ void LLProgressView::setVisible(BOOL visible) { if (getVisible() && !visible) { + gViewerWindow->removePopup(this); + mFadeTimer.start(); } else if (!getVisible() && visible) { - gFocusMgr.setTopCtrl(this); + gViewerWindow->addPopup(this); + setFocus(TRUE); mFadeTimer.stop(); mProgressTimer.start(); diff --git a/indra/newview/llsplitbutton.cpp b/indra/newview/llsplitbutton.cpp index ffd9bc7624..e5323db466 100644 --- a/indra/newview/llsplitbutton.cpp +++ b/indra/newview/llsplitbutton.cpp @@ -165,7 +165,7 @@ void LLSplitButton::showButtons() // register ourselves as a "top" control // effectively putting us into a special draw layer - gFocusMgr.setTopCtrl(this); + gViewerWindow->addPopup(this); mItemsPanel->setFocus(TRUE); @@ -182,10 +182,7 @@ void LLSplitButton::hideButtons() mArrowBtn->setToggleState(FALSE); setUseBoundingRect(FALSE); - if(gFocusMgr.getTopCtrl() == this) - { - gFocusMgr.setTopCtrl(NULL); - } + gViewerWindow->removePopup(this); } diff --git a/indra/newview/lluploaddialog.cpp b/indra/newview/lluploaddialog.cpp index 577b5952e5..22c7d670f8 100644 --- a/indra/newview/lluploaddialog.cpp +++ b/indra/newview/lluploaddialog.cpp @@ -91,7 +91,7 @@ LLUploadDialog::LLUploadDialog( const std::string& msg) setMessage(msg); // The dialog view is a root view - gFocusMgr.setTopCtrl( this ); + gViewerWindow->addPopup(this); } void LLUploadDialog::setMessage( const std::string& msg) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index f1ec489a20..5bd79c67c3 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -131,6 +131,7 @@ #include "llmorphview.h" #include "llmoveview.h" #include "llnavigationbar.h" +#include "llpopupview.h" #include "llpreviewtexture.h" #include "llprogressview.h" #include "llresmgr.h" @@ -690,30 +691,30 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK } // Topmost view gets a chance before the hierarchy - LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); - if (top_ctrl) - { - S32 local_x, local_y; - top_ctrl->screenPointToLocal( x, y, &local_x, &local_y ); - if (down) - { - if (top_ctrl->pointInView(local_x, local_y)) - { - return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down) ; - } - else - { - gFocusMgr.setTopCtrl(NULL); - } - } - else - { - if (top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleMouseUp(local_x, local_y, mask)) - { - return TRUE; - } - } - } + //LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); + //if (top_ctrl) + //{ + // S32 local_x, local_y; + // top_ctrl->screenPointToLocal( x, y, &local_x, &local_y ); + // if (down) + // { + // if (top_ctrl->pointInView(local_x, local_y)) + // { + // return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down) ; + // } + // else + // { + // gFocusMgr.setTopCtrl(NULL); + // } + // } + // else + // { + // if (top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleMouseUp(local_x, local_y, mask)) + // { + // return TRUE; + // } + // } + //} // Give the UI views a chance to process the click if( mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) ) @@ -1367,6 +1368,8 @@ LLViewerWindow::LLViewerWindow( LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications")); llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl; + LLUI::setPopupFuncs(boost::bind(&LLViewerWindow::addPopup, this, _1), boost::bind(&LLViewerWindow::removePopup, this, _1), boost::bind(&LLViewerWindow::clearPopups, this)); + // Default to application directory. LLViewerWindow::sSnapshotBaseName = "Snapshot"; LLViewerWindow::sMovieBaseName = "SLmovie"; @@ -1559,11 +1562,13 @@ void LLViewerWindow::initBase() mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle(); mNonSideTrayView = main_view->getChildView("non_side_tray_view")->getHandle(); mFloaterViewHolder = main_view->getChildView("floater_view_holder")->getHandle(); + mPopupView = main_view->getChild("popup_holder"); // Constrain floaters to inside the menu and status bar regions. gFloaterView = main_view->getChild("Floater View"); gSnapshotFloaterView = main_view->getChild("Snapshot Floater View"); + // Console llassert( !gConsole ); LLConsole::Params cp; @@ -2433,6 +2438,30 @@ void LLViewerWindow::handleScrollWheel(S32 clicks) return; } +void LLViewerWindow::addPopup(LLView* popup) +{ + if (mPopupView) + { + mPopupView->addPopup(popup); + } +} + +void LLViewerWindow::removePopup(LLView* popup) +{ + if (mPopupView) + { + mPopupView->removePopup(popup); + } +} + +void LLViewerWindow::clearPopups() +{ + if (mPopupView) + { + mPopupView->clearPopups(); + } +} + void LLViewerWindow::moveCursorToCenter() { if (! gSavedSettings.getBOOL("DisableMouseWarp")) diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index bfce65f2ba..410445d97f 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -69,6 +69,7 @@ class LLHUDIcon; class LLWindow; class LLRootView; class LLViewerWindowListener; +class LLPopupView; #define PICK_HALF_WIDTH 5 #define PICK_DIAMETER (2 * PICK_HALF_WIDTH + 1) @@ -300,6 +301,11 @@ public: BOOL handleKey(KEY key, MASK mask); void handleScrollWheel (S32 clicks); + // add and remove views from "popup" layer + void addPopup(LLView* popup); + void removePopup(LLView* popup); + void clearPopups(); + // Hide normal UI when a logon fails, re-show everything when logon is attempted again void setNormalControlsVisible( BOOL visible ); void setMenuBackgroundColor(bool god_mode = false, bool dev_grid = false); @@ -458,6 +464,7 @@ protected: LLHandle mWorldViewPlaceholder; // widget that spans the portion of screen dedicated to rendering the 3d world LLHandle mNonSideTrayView; // parent of world view + bottom bar, etc...everything but the side tray LLHandle mFloaterViewHolder; // container for floater_view + LLPopupView* mPopupView; // container for transient popups class LLDebugText* mDebugText; // Internal class for debug text @@ -477,7 +484,7 @@ protected: private: // Object temporarily hovered over while dragging LLPointer mDragHoveredObject; -}; +}; void toggle_flying(void*); void toggle_first_person(); diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml index 7b6081d7be..85853f39bb 100644 --- a/indra/newview/skins/default/xui/en/main_view.xml +++ b/indra/newview/skins/default/xui/en/main_view.xml @@ -156,18 +156,19 @@ name="notify_container" tab_group="-2" width="1024"/> - + Date: Tue, 2 Mar 2010 15:11:56 -0800 Subject: added missing files --- indra/newview/llpopupview.cpp | 202 ++++++++++++++++++++++++++++++++++++++++++ indra/newview/llpopupview.h | 64 +++++++++++++ 2 files changed, 266 insertions(+) create mode 100644 indra/newview/llpopupview.cpp create mode 100644 indra/newview/llpopupview.h (limited to 'indra') diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp new file mode 100644 index 0000000000..964ca4d361 --- /dev/null +++ b/indra/newview/llpopupview.cpp @@ -0,0 +1,202 @@ +/** + * @file llpopupview.cpp + * @brief Holds transient popups + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llpopupview.h" + +static LLRegisterPanelClassWrapper r("popup_holder"); + +bool view_visible_and_enabled(LLView* viewp) +{ + return viewp->getVisible() && viewp->getEnabled(); +} + +bool view_visible(LLView* viewp) +{ + return viewp->getVisible(); +} + + +LLPopupView::LLPopupView() +{ +} + +void LLPopupView::draw() +{ + S32 screen_x, screen_y; + + for (popup_list_t::iterator popup_it = mPopups.begin(); + popup_it != mPopups.end();) + { + LLView* popup = popup_it->get(); + if (!popup) + { + popup_list_t::iterator cur_popup_it = popup_it; + ++popup_it; + mPopups.erase(cur_popup_it); + continue; + } + + if (popup->getVisible()) + { + popup->localPointToScreen(0, 0, &screen_x, &screen_y); + + LLUI::pushMatrix(); + { + LLUI::translate( (F32) screen_x, (F32) screen_y, 0.f); + popup->draw(); + } + LLUI::popMatrix(); + } + ++popup_it; + } + + LLPanel::draw(); +} + +BOOL LLPopupView::handleMouseEvent(boost::function func, + boost::function predicate, + S32 x, S32 y) +{ + for (popup_list_t::reverse_iterator popup_it = mPopups.rbegin(); + popup_it != mPopups.rend(); + ++popup_it) + { + LLView* popup = popup_it->get(); + if (!popup + || !predicate(popup)) + { + continue; + } + + S32 popup_x, popup_y; + if (localPointToOtherView(x, y, &popup_x, &popup_y, popup) + && popup->getRect().pointInRect(popup_x, popup_y)) + { + if (func(popup, popup_x, popup_y)) + { + return TRUE; + } + } + } + + return FALSE; +} + + +BOOL LLPopupView::handleMouseDown(S32 x, S32 y, MASK mask) +{ + if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y)) + { + clearPopups(); + return FALSE; + } + return TRUE; +} + +BOOL LLPopupView::handleMouseUp(S32 x, S32 y, MASK mask) +{ + return handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y); +} + +BOOL LLPopupView::handleMiddleMouseDown(S32 x, S32 y, MASK mask) +{ + if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y)) + { + clearPopups(); + return FALSE; + } + return TRUE; +} + +BOOL LLPopupView::handleMiddleMouseUp(S32 x, S32 y, MASK mask) +{ + return handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y); +} + +BOOL LLPopupView::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y)) + { + clearPopups(); + return FALSE; + } + return TRUE; +} + +BOOL LLPopupView::handleRightMouseUp(S32 x, S32 y, MASK mask) +{ + return handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y); +} + +BOOL LLPopupView::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + return handleMouseEvent(boost::bind(&LLMouseHandler::handleDoubleClick, _1, _2, _3, mask), view_visible_and_enabled, x, y); +} + +BOOL LLPopupView::handleHover(S32 x, S32 y, MASK mask) +{ + return handleMouseEvent(boost::bind(&LLMouseHandler::handleHover, _1, _2, _3, mask), view_visible_and_enabled, x, y); +} + +BOOL LLPopupView::handleScrollWheel(S32 x, S32 y, S32 clicks) +{ + return handleMouseEvent(boost::bind(&LLMouseHandler::handleScrollWheel, _1, _2, _3, clicks), view_visible_and_enabled, x, y); +} + +BOOL LLPopupView::handleToolTip(S32 x, S32 y, MASK mask) +{ + return handleMouseEvent(boost::bind(&LLMouseHandler::handleToolTip, _1, _2, _3, mask), view_visible, x, y); +} + +void LLPopupView::addPopup(LLView* popup) +{ + removePopup(popup); + if (popup) + { + mPopups.push_back(popup->getHandle()); + } +} + +void LLPopupView::removePopup(LLView* popup) +{ + if (popup) + { + mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle())); + } +} + +void LLPopupView::clearPopups() +{ + mPopups.clear(); +} + diff --git a/indra/newview/llpopupview.h b/indra/newview/llpopupview.h new file mode 100644 index 0000000000..591e033161 --- /dev/null +++ b/indra/newview/llpopupview.h @@ -0,0 +1,64 @@ +/** + * @file llpopupview.h + * @brief Holds transient popups + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPOPUPVIEW_H +#define LL_LLPOPUPVIEW_H + +#include "llpanel.h" + +class LLPopupView : public LLPanel +{ +public: + LLPopupView(); + + /*virtual*/ void draw(); + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); + + void addPopup(LLView* popup); + void removePopup(LLView* popup); + void clearPopups(); + +private: + BOOL handleMouseEvent(boost::function, boost::function, S32 x, S32 y); + typedef std::list > popup_list_t; + popup_list_t mPopups; +}; +#endif //LL_LLROOTVIEW_H -- cgit v1.2.3 From 6ebc1d8858e77ed00d3363ce1d8d18be5dc2a3a2 Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Tue, 2 Mar 2010 19:56:28 -0500 Subject: EXT-5547 : Autopopulation broken due to new web deploy accounts EXT-5673 : Autopopulation: Created outfits copy subfolder contents as well as immediate folder contents EXT-5632 : Autopopulation is including subfolders even if those aren't outfits DEV-46683 : Post-Deployment Cleanup This is a series of changes to fix autopopulation behavior that was broken due to the new surprise web avatar deploy. That deploy surfaced a number of serious issues with the original AP code. I did not write this code and the person who did is no longer here, so I've done my best to fix those issues up. This is a fairly comprehensive set of changes, but it's necessary given the poor state of the pre-existing code and how many problems it caused the new web avatar deploy. This new version of the AP code will: (1) Look for a Library->Clothing->Initial Outfits folder and use that if it exists (2) Not create outfits out of folders that aren't complete outfits (3) No longer string match against "More Outfits" in order to ignore outfits (4) No longer recursively collect folder contents when creating an outfit (i.e. will only look at direct descendents) --- indra/newview/llagentwearables.cpp | 134 ++++++++++++++++++++++++------------- indra/newview/llappearancemgr.cpp | 100 +++++++++++++++++++-------- indra/newview/llappearancemgr.h | 3 + 3 files changed, 164 insertions(+), 73 deletions(-) (limited to 'indra') diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 11ac103b3a..7b55282ee5 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -119,9 +119,9 @@ protected: void importedFolderDone(void); void contentsDone(void); enum ELibraryOutfitFetchStep mCurrFetchStep; - typedef std::vector< std::pair< LLUUID, std::string > > cloth_folder_vec_t; - cloth_folder_vec_t mLibraryClothingFolders; - cloth_folder_vec_t mImportedClothingFolders; + typedef std::vector clothing_folder_vec_t; + clothing_folder_vec_t mLibraryClothingFolders; + clothing_folder_vec_t mImportedClothingFolders; bool mOutfitsPopulated; LLUUID mClothingID; LLUUID mLibraryClothingID; @@ -2240,7 +2240,7 @@ void LLAgentWearables::updateServer() void LLAgentWearables::populateMyOutfitsFolder(void) { - llinfos << "starting outfit populate" << llendl; + llinfos << "starting outfit population" << llendl; LLLibraryOutfitsFetch* outfits = new LLLibraryOutfitsFetch(); @@ -2312,17 +2312,28 @@ void LLLibraryOutfitsFetch::folderDone(void) LLInventoryModel::item_array_t wearable_array; gInventory.collectDescendents(mMyOutfitsID, cat_array, wearable_array, LLInventoryModel::EXCLUDE_TRASH); - // Early out if we already have items in My Outfits. if (cat_array.count() > 0 || wearable_array.count() > 0) { mOutfitsPopulated = true; return; } - + mClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING); mLibraryClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING, false, true); - + + // If Library->Clothing->Initial Outfits exists, use that. + LLNameCategoryCollector matchFolderFunctor("Initial Outfits"); + gInventory.collectDescendentsIf(mLibraryClothingID, + cat_array, wearable_array, + LLInventoryModel::EXCLUDE_TRASH, + matchFolderFunctor); + if (cat_array.count() > 0) + { + const LLViewerInventoryCategory *cat = cat_array.get(0); + mLibraryClothingID = cat->getUUID(); + } + mCompleteFolders.clear(); // Get the complete information on the items in the inventory. @@ -2353,31 +2364,28 @@ void LLLibraryOutfitsFetch::outfitsDone(void) { const LLViewerInventoryCategory *cat = iter->get(); - // Get the names and id's of every outfit in the library, except for ruth and other "misc" outfits. - if (cat->getName() != "More Outfits" && cat->getName() != "Ruth") + // Get the names and id's of every outfit in the library, skip "Ruth" + // because it's a low quality legacy outfit + if (cat->getName() != "Ruth") { // Get the name of every outfit in the library folders.push_back(cat->getUUID()); - mLibraryClothingFolders.push_back(std::make_pair(cat->getUUID(), cat->getName())); + mLibraryClothingFolders.push_back(cat->getUUID()); } } - - // Collect the contents of your Inventory Clothing folder cat_array.clear(); wearable_array.clear(); - gInventory.collectDescendents(mClothingID, cat_array, wearable_array, - LLInventoryModel::EXCLUDE_TRASH); // Check if you already have an "Imported Library Clothing" folder - for (LLInventoryModel::cat_array_t::const_iterator iter = cat_array.begin(); - iter != cat_array.end(); - ++iter) + LLNameCategoryCollector matchFolderFunctor(mImportedClothingName); + gInventory.collectDescendentsIf(mClothingID, + cat_array, wearable_array, + LLInventoryModel::EXCLUDE_TRASH, + matchFolderFunctor); + if (cat_array.size() > 0) { - const LLViewerInventoryCategory *cat = iter->get(); - if (cat->getName() == mImportedClothingName) - { - mImportedClothingID = cat->getUUID(); - } + const LLViewerInventoryCategory *cat = cat_array.get(0); + mImportedClothingID = cat->getUUID(); } mCompleteFolders.clear(); @@ -2415,31 +2423,59 @@ private: LLLibraryOutfitsFetch * mLibraryOutfitsFetcher; }; +// Copy the clothing folders from the library into the imported clothing folder void LLLibraryOutfitsFetch::libraryDone(void) { - // Copy the clothing folders from the library into the imported clothing folder if necessary. - if (mImportedClothingID == LLUUID::null) + if (mImportedClothingID != LLUUID::null) { - gInventory.removeObserver(this); - LLPointer copy_waiter = new LLLibraryOutfitsCopyDone(this); - mImportedClothingID = gInventory.createNewCategory(mClothingID, - LLFolderType::FT_NONE, - mImportedClothingName); + // Skip straight to fetching the contents of the imported folder + importedFolderFetch(); + return; + } + + // Remove observer; next autopopulation step will be triggered externally by LLLibraryOutfitsCopyDone. + gInventory.removeObserver(this); + + LLPointer copy_waiter = new LLLibraryOutfitsCopyDone(this); + mImportedClothingID = gInventory.createNewCategory(mClothingID, + LLFolderType::FT_NONE, + mImportedClothingName); + // Copy each folder from library into clothing unless it already exists. + for (clothing_folder_vec_t::const_iterator iter = mLibraryClothingFolders.begin(); + iter != mLibraryClothingFolders.end(); + ++iter) + { + const LLUUID& src_folder_id = (*iter); // Library clothing folder ID + const LLViewerInventoryCategory *cat = gInventory.getCategory(src_folder_id); + if (!cat) + { + llwarns << "Library folder import for uuid:" << src_folder_id << " failed to find folder." << llendl; + continue; + } - for (cloth_folder_vec_t::const_iterator iter = mLibraryClothingFolders.begin(); - iter != mLibraryClothingFolders.end(); - ++iter) + if (!LLAppearanceManager::getInstance()->getCanMakeFolderIntoOutfit(src_folder_id)) { - LLUUID folder_id = gInventory.createNewCategory(mImportedClothingID, - LLFolderType::FT_NONE, - iter->second); - LLAppearanceManager::getInstance()->shallowCopyCategoryContents(iter->first, folder_id, copy_waiter); + llinfos << "Skipping non-outfit folder name:" << cat->getName() << llendl; + continue; } - } - else - { - // Skip straight to fetching the contents of the imported folder - importedFolderFetch(); + + // Don't copy the category if it already exists. + LLNameCategoryCollector matchFolderFunctor(cat->getName()); + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t wearable_array; + gInventory.collectDescendentsIf(mImportedClothingID, + cat_array, wearable_array, + LLInventoryModel::EXCLUDE_TRASH, + matchFolderFunctor); + if (cat_array.size() > 0) + { + continue; + } + + LLUUID dst_folder_id = gInventory.createNewCategory(mImportedClothingID, + LLFolderType::FT_NONE, + cat->getName()); + LLAppearanceManager::getInstance()->shallowCopyCategoryContents(src_folder_id, dst_folder_id, copy_waiter); } } @@ -2476,7 +2512,7 @@ void LLLibraryOutfitsFetch::importedFolderDone(void) // Get the name of every imported outfit folders.push_back(cat->getUUID()); - mImportedClothingFolders.push_back(std::make_pair(cat->getUUID(), cat->getName())); + mImportedClothingFolders.push_back(cat->getUUID()); } mCompleteFolders.clear(); @@ -2492,17 +2528,25 @@ void LLLibraryOutfitsFetch::contentsDone(void) LLInventoryModel::cat_array_t cat_array; LLInventoryModel::item_array_t wearable_array; - for (cloth_folder_vec_t::const_iterator folder_iter = mImportedClothingFolders.begin(); + for (clothing_folder_vec_t::const_iterator folder_iter = mImportedClothingFolders.begin(); folder_iter != mImportedClothingFolders.end(); ++folder_iter) { + const LLUUID &folder_id = (*folder_iter); + const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id); + if (!cat) + { + llwarns << "Library folder import for uuid:" << folder_id << " failed to find folder." << llendl; + continue; + } + // First, make a folder in the My Outfits directory. - LLUUID new_outfit_folder_id = gInventory.createNewCategory(mMyOutfitsID, LLFolderType::FT_OUTFIT, folder_iter->second); + LLUUID new_outfit_folder_id = gInventory.createNewCategory(mMyOutfitsID, LLFolderType::FT_OUTFIT, cat->getName()); cat_array.clear(); wearable_array.clear(); // Collect the contents of each imported clothing folder, so we can create new outfit links for it - gInventory.collectDescendents(folder_iter->first, cat_array, wearable_array, + gInventory.collectDescendents(folder_id, cat_array, wearable_array, LLInventoryModel::EXCLUDE_TRASH); for (LLInventoryModel::item_array_t::const_iterator wearable_iter = wearable_array.begin(); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 5c21be8c32..f08d8decfe 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -807,47 +807,91 @@ void LLAppearanceManager::shallowCopyCategory(const LLUUID& src_id, const LLUUID void LLAppearanceManager::shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id, LLPointer cb) { - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - gInventory.collectDescendents(src_id, cats, items, - LLInventoryModel::EXCLUDE_TRASH); - for (S32 i = 0; i < items.count(); ++i) - { - const LLViewerInventoryItem* item = items.get(i).get(); - if (item->getActualType() == LLAssetType::AT_LINK) - { - link_inventory_item(gAgent.getID(), - item->getLinkedUUID(), - dst_id, - item->getName(), - LLAssetType::AT_LINK, cb); - } - else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER) + LLInventoryModel::cat_array_t* cats; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(src_id, cats, items); + for (LLInventoryModel::item_array_t::const_iterator iter = items->begin(); + iter != items->end(); + ++iter) + { + const LLViewerInventoryItem* item = (*iter); + switch (item->getActualType()) { - LLViewerInventoryCategory *catp = item->getLinkedCategory(); - // Skip copying outfit links. - if (catp && catp->getPreferredType() != LLFolderType::FT_OUTFIT) + case LLAssetType::AT_LINK: { link_inventory_item(gAgent.getID(), item->getLinkedUUID(), dst_id, item->getName(), - LLAssetType::AT_LINK_FOLDER, cb); + LLAssetType::AT_LINK, cb); + break; + } + case LLAssetType::AT_LINK_FOLDER: + { + LLViewerInventoryCategory *catp = item->getLinkedCategory(); + // Skip copying outfit links. + if (catp && catp->getPreferredType() != LLFolderType::FT_OUTFIT) + { + link_inventory_item(gAgent.getID(), + item->getLinkedUUID(), + dst_id, + item->getName(), + LLAssetType::AT_LINK_FOLDER, cb); + } + break; } + case LLAssetType::AT_CLOTHING: + case LLAssetType::AT_OBJECT: + case LLAssetType::AT_BODYPART: + case LLAssetType::AT_GESTURE: + { + copy_inventory_item(gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + dst_id, + item->getName(), + cb); + break; + } + default: + // Ignore non-outfit asset types + break; } - else + } +} + +BOOL LLAppearanceManager::getCanMakeFolderIntoOutfit(const LLUUID& folder_id) +{ + // These are the wearable items that are required for considering this + // folder as containing a complete outfit. + U32 required_wearables = 0; + required_wearables |= 1LL << WT_SHAPE; + required_wearables |= 1LL << WT_SKIN; + required_wearables |= 1LL << WT_HAIR; + required_wearables |= 1LL << WT_EYES; + + // These are the wearables that the folder actually contains. + U32 folder_wearables = 0; + LLInventoryModel::cat_array_t* cats; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(folder_id, cats, items); + for (LLInventoryModel::item_array_t::const_iterator iter = items->begin(); + iter != items->end(); + ++iter) + { + const LLViewerInventoryItem* item = (*iter); + if (item->isWearableType()) { - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - dst_id, - item->getName(), - cb); + const EWearableType wearable_type = item->getWearableType(); + folder_wearables |= 1LL << wearable_type; } } + + // If the folder contains the required wearables, return TRUE. + return ((required_wearables & folder_wearables) == required_wearables); } + void LLAppearanceManager::purgeBaseOutfitLink(const LLUUID& category) { LLInventoryModel::cat_array_t cats; diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index e7e2f33520..9d6cd34ad7 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -60,6 +60,9 @@ public: void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id, LLPointer cb); + // Return whether this folder contains minimal contents suitable for making a full outfit. + BOOL getCanMakeFolderIntoOutfit(const LLUUID& folder_id); + // Copy all items in a category. void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id, LLPointer cb); -- cgit v1.2.3 From 97a0bde0ed94d2ed6b81761cee00985e051c4cf1 Mon Sep 17 00:00:00 2001 From: Eli Linden Date: Wed, 3 Mar 2010 01:27:56 -0800 Subject: VWR-17361 --- indra/newview/skins/default/xui/en/floater_tools.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra') diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 4e59a9b1ca..affe74d148 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -581,7 +581,7 @@ left="0" name="radio select land" top="-1" - width="114" /> + width="134" /> @@ -2816,7 +2816,7 @@ even though the user gets a free copy. left="20" name="label_parcel_info" top="24" - width="150"> + width="240"> Parcel Information Date: Wed, 3 Mar 2010 15:04:59 +0000 Subject: EXT-5863 Enabling Admin mode allows "Dump baked avatar textures" to work. No matter what you are wearing. --- indra/newview/llvoavatarself.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 131c6ac1a1..acd12099cd 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1723,7 +1723,7 @@ BOOL LLVOAvatarSelf::canGrabLocalTexture(ETextureIndex type, U32 index) const return FALSE; } - if (gAgent.isGodlike()) + if (gAgent.isGodlikeWithoutAdminMenuFakery()) return TRUE; // Check permissions of textures that show up in the -- cgit v1.2.3 From 0ac63ffbb1acb32278645f6a9ab97cdc271c8d30 Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Wed, 3 Mar 2010 11:03:46 -0500 Subject: EXT-4013 : Functionality loss: Inspect object Detail button implemented as instructed; this brings up the old 1.23 multi-inspect floater. --- indra/newview/llsidepaneltaskinfo.cpp | 16 ++++++++++++++++ indra/newview/llsidepaneltaskinfo.h | 2 ++ .../newview/skins/default/xui/en/sidepanel_task_info.xml | 11 +++++++++++ 3 files changed, 29 insertions(+) (limited to 'indra') diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index 0630981d7e..6ebe55e362 100644 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -100,6 +100,8 @@ BOOL LLSidepanelTaskInfo::postBuild() mPayBtn->setClickedCallback(boost::bind(&LLSidepanelTaskInfo::onPayButtonClicked, this)); mBuyBtn = getChild("buy_btn"); mBuyBtn->setClickedCallback(boost::bind(&LLSidepanelTaskInfo::onBuyButtonClicked, this)); + mDetailsBtn = getChild("details_btn"); + mDetailsBtn->setClickedCallback(boost::bind(&LLSidepanelTaskInfo::onDetailsButtonClicked, this)); mLabelGroupName = getChild("Group Name Proxy"); @@ -1122,6 +1124,15 @@ void LLSidepanelTaskInfo::updateVerbs() //mEditBtn->setEnabled(obj && obj->permModify()); */ + LLSafeHandle object_selection = LLSelectMgr::getInstance()->getSelection(); + const BOOL multi_select = (object_selection->getNumNodes() > 1); + + mOpenBtn->setVisible(!multi_select); + mPayBtn->setVisible(!multi_select); + mBuyBtn->setVisible(!multi_select); + mDetailsBtn->setVisible(multi_select); + mDetailsBtn->setEnabled(multi_select); + mOpenBtn->setEnabled(enable_object_open()); mPayBtn->setEnabled(enable_pay_object()); mBuyBtn->setEnabled(enable_buy_object()); @@ -1145,6 +1156,11 @@ void LLSidepanelTaskInfo::onBuyButtonClicked() doClickAction(CLICK_ACTION_BUY); } +void LLSidepanelTaskInfo::onDetailsButtonClicked() +{ + LLFloaterReg::showInstance("inspect", LLSD()); +} + // virtual void LLSidepanelTaskInfo::save() { diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h index cf36c20767..e41627435f 100644 --- a/indra/newview/llsidepaneltaskinfo.h +++ b/indra/newview/llsidepaneltaskinfo.h @@ -109,10 +109,12 @@ protected: void onOpenButtonClicked(); void onPayButtonClicked(); void onBuyButtonClicked(); + void onDetailsButtonClicked(); private: LLButton* mOpenBtn; LLButton* mPayBtn; LLButton* mBuyBtn; + LLButton* mDetailsBtn; protected: LLViewerObject* getObject(); diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml index d2c9e56bc3..6588663bac 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml @@ -549,5 +549,16 @@ name="buy_btn" top="0" width="100" /> +