Inv menus appear now. Still need to update llmenugl and its variants, since our current version is buggy. Also need to look into why inventory postfixes aren't appearing.

This commit is contained in:
Shyotl
2012-02-18 01:59:02 -06:00
parent 1810a7c7f9
commit b0240320ee
18 changed files with 943 additions and 362 deletions

View File

@@ -2485,8 +2485,12 @@ void LLFloaterView::pushVisibleAll(BOOL visible, const skip_list_t& skip_list)
void LLFloaterView::popVisibleAll(const skip_list_t& skip_list) void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)
{ {
for (child_list_const_iter_t child_iter = getChildList()->begin(); // make a copy of the list since some floaters change their
child_iter != getChildList()->end(); ++child_iter) // order in the childList when changing visibility.
child_list_t child_list_copy = *getChildList();
for (child_list_const_iter_t child_iter = child_list_copy.begin();
child_iter != child_list_copy.end(); ++child_iter)
{ {
LLView *view = *child_iter; LLView *view = *child_iter;
if (skip_list.find(view) == skip_list.end()) if (skip_list.find(view) == skip_list.end())

View File

@@ -522,31 +522,15 @@ BOOL LLMenuItemGL::setLabelArg( const std::string& key, const LLStringExplicit&
// This class represents a separator. // This class represents a separator.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLMenuItemSeparatorGL : public LLMenuItemGL
{
public:
LLMenuItemSeparatorGL( const std::string &name = SEPARATOR_NAME );
virtual LLXMLNodePtr getXML(bool save_children = true) const;
virtual std::string getType() const { return "separator"; }
// doIt() - do the primary funcationality of the menu item.
virtual void doIt( void ) {}
virtual void draw( void );
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual U32 getNominalHeight( void ) const { return SEPARATOR_HEIGHT_PIXELS; }
};
LLMenuItemSeparatorGL::LLMenuItemSeparatorGL( const std::string &name ) : LLMenuItemSeparatorGL::LLMenuItemSeparatorGL( const std::string &name ) :
LLMenuItemGL( name, SEPARATOR_LABEL ) LLMenuItemGL( name.empty() ? SEPARATOR_NAME : name, SEPARATOR_LABEL )
{ {
} }
U32 LLMenuItemSeparatorGL::getNominalHeight( void ) const
{
return SEPARATOR_HEIGHT_PIXELS;
}
LLXMLNodePtr LLMenuItemSeparatorGL::getXML(bool save_children) const LLXMLNodePtr LLMenuItemSeparatorGL::getXML(bool save_children) const
{ {
@@ -1694,7 +1678,6 @@ LLMenuGL::LLMenuGL( const std::string& name, const std::string& label, LLHandle<
: LLUICtrl( name, LLRect(), FALSE, NULL, NULL ), : LLUICtrl( name, LLRect(), FALSE, NULL, NULL ),
mBackgroundColor( sDefaultBackgroundColor ), mBackgroundColor( sDefaultBackgroundColor ),
mBgVisible( TRUE ), mBgVisible( TRUE ),
mParentMenuItem( NULL ),
mLabel( label ), mLabel( label ),
mDropShadowed( TRUE ), mDropShadowed( TRUE ),
mHorizontalLayout( FALSE ), mHorizontalLayout( FALSE ),
@@ -1720,7 +1703,6 @@ LLMenuGL::LLMenuGL( const std::string& label, LLHandle<LLFloater> parent_floater
: LLUICtrl( label, LLRect(), FALSE, NULL, NULL ), : LLUICtrl( label, LLRect(), FALSE, NULL, NULL ),
mBackgroundColor( sDefaultBackgroundColor ), mBackgroundColor( sDefaultBackgroundColor ),
mBgVisible( TRUE ), mBgVisible( TRUE ),
mParentMenuItem( NULL ),
mLabel( label ), mLabel( label ),
mDropShadowed( TRUE ), mDropShadowed( TRUE ),
mHorizontalLayout( FALSE ), mHorizontalLayout( FALSE ),
@@ -2342,6 +2324,16 @@ void LLMenuGL::arrange( void )
} }
} }
void LLMenuGL::arrangeAndClear( void )
{
if (mNeedsArrange)
{
arrange();
mNeedsArrange = FALSE;
}
}
void LLMenuGL::createSpilloverBranch() void LLMenuGL::createSpilloverBranch()
{ {
if (!mSpilloverBranch) if (!mSpilloverBranch)

View File

@@ -216,6 +216,30 @@ private:
KEY mJumpKey; KEY mJumpKey;
}; };
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLMenuItemSeparatorGL
//
// This class represents a separator.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLMenuItemSeparatorGL : public LLMenuItemGL
{
public:
LLMenuItemSeparatorGL( const std::string &name = std::string() );
virtual LLXMLNodePtr getXML(bool save_children = true) const;
virtual std::string getType() const { return "separator"; }
// doIt() - do the primary funcationality of the menu item.
virtual void doIt( void ) {}
virtual void draw( void );
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual U32 getNominalHeight( void ) const;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLMenuItemCallGL // Class LLMenuItemCallGL
@@ -483,6 +507,7 @@ public:
// when you add items. *FIX: We may need to deal with visibility // when you add items. *FIX: We may need to deal with visibility
// arrangement. // arrangement.
virtual void arrange( void ); virtual void arrange( void );
void arrangeAndClear( void );
// remove all items on the menu // remove all items on the menu
void empty( void ); void empty( void );
@@ -511,8 +536,8 @@ public:
// Whether to drop shadow menu bar // Whether to drop shadow menu bar
void setDropShadowed( const BOOL shadowed ); void setDropShadowed( const BOOL shadowed );
void setParentMenuItem( LLMenuItemGL* parent_menu_item ) { mParentMenuItem = parent_menu_item; } void setParentMenuItem( LLMenuItemGL* parent_menu_item ) { mParentMenuItem = parent_menu_item->getHandle(); }
LLMenuItemGL* getParentMenuItem() const { return mParentMenuItem; } LLMenuItemGL* getParentMenuItem() const { return dynamic_cast<LLMenuItemGL*>(mParentMenuItem.get()); }
void setTornOff(BOOL torn_off); void setTornOff(BOOL torn_off);
BOOL getTornOff() { return mTornOff; } BOOL getTornOff() { return mTornOff; }
@@ -550,7 +575,7 @@ private:
LLColor4 mBackgroundColor; LLColor4 mBackgroundColor;
BOOL mBgVisible; BOOL mBgVisible;
LLMenuItemGL* mParentMenuItem; LLHandle<LLView> mParentMenuItem;
LLUIString mLabel; LLUIString mLabel;
BOOL mDropShadowed; // Whether to drop shadow BOOL mDropShadowed; // Whether to drop shadow
BOOL mHasSelection; BOOL mHasSelection;

View File

@@ -493,6 +493,7 @@ void LLScrollableContainerView::draw()
void LLScrollableContainerView::updateScroll() void LLScrollableContainerView::updateScroll()
{ {
if(!mScrolledView)return;
LLRect doc_rect = mScrolledView->getRect(); LLRect doc_rect = mScrolledView->getRect();
S32 doc_width = doc_rect.getWidth(); S32 doc_width = doc_rect.getWidth();
S32 doc_height = doc_rect.getHeight(); S32 doc_height = doc_rect.getHeight();

View File

@@ -346,7 +346,8 @@ public:
virtual void handleVisibilityChange ( BOOL curVisibilityIn ); virtual void handleVisibilityChange ( BOOL curVisibilityIn );
void pushVisible(BOOL visible) { mLastVisible = mVisible; setVisible(visible); } void pushVisible(BOOL visible) { mLastVisible = mVisible; setVisible(visible); }
void popVisible() { setVisible(mLastVisible); mLastVisible = TRUE; } void popVisible() { setVisible(mLastVisible); }
BOOL getLastVisible() const { return mLastVisible; }
LLHandle<LLView> getHandle() { mHandle.bind(this); return mHandle; } LLHandle<LLView> getHandle() { mHandle.bind(this); return mHandle; }

View File

@@ -41,6 +41,7 @@
#include "llinventoryfilter.h" #include "llinventoryfilter.h"
#include "llinventoryfunctions.h" #include "llinventoryfunctions.h"
#include "llinventorymodelbackgroundfetch.h" #include "llinventorymodelbackgroundfetch.h"
#include "llinventorypanel.h"
#include "llfoldertype.h" #include "llfoldertype.h"
#include "llkeyboard.h" #include "llkeyboard.h"
#include "lllineeditor.h" #include "lllineeditor.h"
@@ -196,7 +197,7 @@ void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)
// Default constructor // Default constructor
LLFolderView::LLFolderView( const std::string& name, LLUIImagePtr root_folder_icon, LLFolderView::LLFolderView( const std::string& name, LLUIImagePtr root_folder_icon,
const LLRect& rect, const LLUUID& source_id, LLView *parent_view, LLFolderViewEventListener* listener ) : const LLRect& rect, const LLUUID& source_id, LLPanel *parent_view, LLFolderViewEventListener* listener ) :
#if LL_WINDOWS #if LL_WINDOWS
#pragma warning( push ) #pragma warning( push )
#pragma warning( disable : 4355 ) // warning C4355: 'this' : used in base member initializer list #pragma warning( disable : 4355 ) // warning C4355: 'this' : used in base member initializer list
@@ -205,6 +206,7 @@ LLFolderView::LLFolderView( const std::string& name, LLUIImagePtr root_folder_ic
#if LL_WINDOWS #if LL_WINDOWS
#pragma warning( pop ) #pragma warning( pop )
#endif #endif
mRunningHeight(0),
mScrollContainer( NULL ), mScrollContainer( NULL ),
mPopupMenuHandle(), mPopupMenuHandle(),
mAllowMultiSelect(TRUE), mAllowMultiSelect(TRUE),
@@ -225,8 +227,10 @@ LLFolderView::LLFolderView( const std::string& name, LLUIImagePtr root_folder_ic
mArrangeGeneration(0), mArrangeGeneration(0),
mSignalSelectCallback(0), mSignalSelectCallback(0),
mMinWidth(0), mMinWidth(0),
mDragAndDropThisFrame(FALSE) mDragAndDropThisFrame(FALSE),
mParentPanel(parent_view)
{ {
mRoot = this;
LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom); LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
setRect( rect ); setRect( rect );
reshape(rect.getWidth(), rect.getHeight()); reshape(rect.getWidth(), rect.getHeight());
@@ -267,6 +271,8 @@ LLFolderView::LLFolderView( const std::string& name, LLUIImagePtr root_folder_ic
mPopupMenuHandle = menu->getHandle(); mPopupMenuHandle = menu->getHandle();
setTabStop(TRUE); setTabStop(TRUE);
mListener->openItem();
} }
// Destroys the object // Destroys the object
@@ -282,23 +288,12 @@ LLFolderView::~LLFolderView( void )
mScrollContainer = NULL; mScrollContainer = NULL;
mRenameItem = NULL; mRenameItem = NULL;
mRenamer = NULL; mRenamer = NULL;
gFocusMgr.releaseFocusIfNeeded( this );
if( gEditMenuHandler == this )
{
gEditMenuHandler = NULL;
}
mAutoOpenItems.removeAllNodes(); mAutoOpenItems.removeAllNodes();
gIdleCallbacks.deleteFunction(idle, this); gIdleCallbacks.deleteFunction(idle, this);
if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die(); if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
if(mRenamer == gFocusMgr.getTopCtrl())
{
gFocusMgr.setTopCtrl(NULL);
}
mAutoOpenItems.removeAllNodes(); mAutoOpenItems.removeAllNodes();
clearSelection(); clearSelection();
mItems.clear(); mItems.clear();
@@ -447,6 +442,16 @@ void LLFolderView::openFolder(const std::string& foldername)
} }
} }
void LLFolderView::openTopLevelFolders()
{
for (folders_t::iterator iter = mFolders.begin();
iter != mFolders.end();)
{
folders_t::iterator fit = iter++;
(*fit)->setOpen(TRUE);
}
}
void LLFolderView::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse) void LLFolderView::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
{ {
// call base class to do proper recursion // call base class to do proper recursion
@@ -460,6 +465,18 @@ static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
// This view grows and shinks to enclose all of its children items and folders. // This view grows and shinks to enclose all of its children items and folders.
S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_generation ) S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_generation )
{ {
if(!mScrollContainer)
return 1;
if (getListener()->getUUID().notNull())
{
if (mNeedsSort)
{
mFolders.sort(mSortFunction);
mItems.sort(mSortFunction);
mNeedsSort = false;
}
}
LLFastTimer t2(FTM_ARRANGE); LLFastTimer t2(FTM_ARRANGE);
filter_generation = mFilter->getMinRequiredGeneration(); filter_generation = mFilter->getMinRequiredGeneration();
@@ -529,17 +546,21 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen
} }
} }
S32 dummy_s32; /*if(!mHasVisibleChildren)// is there any filtered items ?
BOOL dummy_bool;
S32 min_width;
mScrollContainer->calcVisibleSize( &min_width, &dummy_s32, &dummy_bool, &dummy_bool);
reshape( llmax(min_width, total_width), running_height );
S32 new_min_width;
mScrollContainer->calcVisibleSize( &new_min_width, &dummy_s32, &dummy_bool, &dummy_bool);
if (new_min_width != min_width)
{ {
reshape( llmax(min_width, total_width), running_height ); //Nope. We need to display status textbox, let's reserve some place for it
running_height = mStatusTextBox->getTextPixelHeight();
target_height = running_height;
}*/
mRunningHeight = running_height;
LLRect scroll_rect = mScrollContainer->getContentWindowRect();
reshape( llmax(scroll_rect.getWidth(), total_width), running_height );
LLRect new_scroll_rect = mScrollContainer->getContentWindowRect();
if (new_scroll_rect.getWidth() != scroll_rect.getWidth())
{
reshape( llmax(scroll_rect.getWidth(), total_width), running_height );
} }
// move item renamer text field to item's new position // move item renamer text field to item's new position
@@ -575,14 +596,14 @@ void LLFolderView::filter( LLInventoryFilter& filter )
void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent) void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
{ {
S32 min_width = 0; LLRect scroll_rect;
S32 dummy_height;
BOOL dummy_bool;
if (mScrollContainer) if (mScrollContainer)
{ {
mScrollContainer->calcVisibleSize( &min_width, &dummy_height, &dummy_bool, &dummy_bool); LLView::reshape(width, height, called_from_parent);
scroll_rect = mScrollContainer->getContentWindowRect();
} }
width = llmax(mMinWidth, min_width); width = llmax(mMinWidth, scroll_rect.getWidth());
height = llmax(mRunningHeight, scroll_rect.getHeight());
LLView::reshape(width, height, called_from_parent); LLView::reshape(width, height, called_from_parent);
mReshapeSignal(mSelectedItems, FALSE); mReshapeSignal(mSelectedItems, FALSE);
@@ -643,6 +664,8 @@ LLFolderViewItem* LLFolderView::getCurSelectedItem( void )
BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
BOOL take_keyboard_focus) BOOL take_keyboard_focus)
{ {
mSignalSelectCallback = take_keyboard_focus ? SIGNAL_KEYBOARD_FOCUS : SIGNAL_NO_KEYBOARD_FOCUS;
if( selection == this ) if( selection == this )
{ {
return FALSE; return FALSE;
@@ -650,7 +673,7 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
if( selection && take_keyboard_focus) if( selection && take_keyboard_focus)
{ {
setFocus(TRUE); mParentPanel->setFocus(TRUE);
} }
// clear selection down here because change of keyboard focus can potentially // clear selection down here because change of keyboard focus can potentially
@@ -670,8 +693,6 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
llassert(mSelectedItems.size() <= 1); llassert(mSelectedItems.size() <= 1);
mSignalSelectCallback = take_keyboard_focus ? SIGNAL_KEYBOARD_FOCUS : SIGNAL_NO_KEYBOARD_FOCUS;
return rv; return rv;
} }
@@ -921,10 +942,6 @@ void LLFolderView::draw()
{ {
closeAutoOpenedFolders(); closeAutoOpenedFolders();
} }
if(this == gFocusMgr.getKeyboardFocus() && !getVisible())
{
gFocusMgr.setKeyboardFocus( NULL );
}
// while dragging, update selection rendering to reflect single/multi drag status // while dragging, update selection rendering to reflect single/multi drag status
if (LLToolDragAndDrop::getInstance()->hasMouseCapture()) if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
@@ -996,11 +1013,40 @@ void LLFolderView::closeRenamer( void )
{ {
if (mRenamer && mRenamer->getVisible()) if (mRenamer && mRenamer->getVisible())
{ {
// Triggers onRenamerLost() that actually closes the renamer. if(mRenamer == gFocusMgr.getTopCtrl())
gFocusMgr.setTopCtrl( NULL ); gFocusMgr.setTopCtrl( NULL );
// Triggers onRenamerLost() that actually closes the renamer.
//gFocusMgr.setTopCtrl( NULL );
} }
} }
bool isDescendantOfASelectedItem(LLFolderViewItem* item, const std::vector<LLFolderViewItem*>& selectedItems)
{
LLFolderViewItem* item_parent = dynamic_cast<LLFolderViewItem*>(item->getParent());
if (item_parent)
{
for(std::vector<LLFolderViewItem*>::const_iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
{
const LLFolderViewItem* const selected_item = (*it);
LLFolderViewItem* parent = item_parent;
while (parent)
{
if (selected_item == parent)
{
return true;
}
parent = dynamic_cast<LLFolderViewItem*>(parent->getParent());
}
}
}
return false;
}
void LLFolderView::removeSelectedItems( void ) void LLFolderView::removeSelectedItems( void )
{ {
if(getVisible() && getEnabled()) if(getVisible() && getEnabled())
@@ -1049,11 +1095,11 @@ void LLFolderView::removeSelectedItems( void )
// change selection on successful delete // change selection on successful delete
if (new_selection) if (new_selection)
{ {
setSelectionFromRoot(new_selection, new_selection->isOpen(), hasFocus()); setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
} }
else else
{ {
setSelectionFromRoot(NULL, hasFocus()); setSelectionFromRoot(NULL, mParentPanel->hasFocus());
} }
} }
} }
@@ -1072,18 +1118,18 @@ void LLFolderView::removeSelectedItems( void )
if (!new_selection) if (!new_selection)
{ {
new_selection = last_item->getPreviousOpenNode(FALSE); new_selection = last_item->getPreviousOpenNode(FALSE);
while (new_selection && (new_selection->isSelected()/* || isDescendantOfASelectedItem(new_selection, items)*/)) while (new_selection && (new_selection->isSelected() || isDescendantOfASelectedItem(new_selection, items)))
{ {
new_selection = new_selection->getPreviousOpenNode(FALSE); new_selection = new_selection->getPreviousOpenNode(FALSE);
} }
} }
if (new_selection) if (new_selection)
{ {
setSelectionFromRoot(new_selection, new_selection->isOpen(), hasFocus()); setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
} }
else else
{ {
setSelectionFromRoot(NULL, hasFocus()); setSelectionFromRoot(NULL, mParentPanel->hasFocus());
} }
for(S32 i = 0; i < count; ++i) for(S32 i = 0; i < count; ++i)
@@ -1432,19 +1478,6 @@ void LLFolderView::startRenamingSelectedItem( void )
} }
} }
void LLFolderView::setFocus(BOOL focus)
{
if (focus)
{
if(!hasFocus())
{
gEditMenuHandler = this;
}
}
LLFolderViewFolder::setFocus(focus);
}
BOOL LLFolderView::handleKeyHere( KEY key, MASK mask ) BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
{ {
BOOL handled = FALSE; BOOL handled = FALSE;
@@ -1647,7 +1680,7 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
break; break;
} }
if (!handled && hasFocus()) if (!handled && mParentPanel->hasFocus())
{ {
if (key == KEY_BACKSPACE) if (key == KEY_BACKSPACE)
{ {
@@ -1679,7 +1712,7 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char)
} }
BOOL handled = FALSE; BOOL handled = FALSE;
if (hasFocus()) if (mParentPanel->hasFocus())
{ {
// SL-51858: Key presses are not being passed to the Popup menu. // SL-51858: Key presses are not being passed to the Popup menu.
// A proper fix is non-trivial so instead just close the menu. // A proper fix is non-trivial so instead just close the menu.
@@ -1736,20 +1769,13 @@ BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask )
mKeyboardSelection = FALSE; mKeyboardSelection = FALSE;
mSearchString.clear(); mSearchString.clear();
setFocus(TRUE); mParentPanel->setFocus(TRUE);
LLEditMenuHandler::gEditMenuHandler = this;
return LLView::handleMouseDown( x, y, mask ); return LLView::handleMouseDown( x, y, mask );
} }
void LLFolderView::onFocusLost( )
{
if( gEditMenuHandler == this )
{
gEditMenuHandler = NULL;
}
LLUICtrl::onFocusLost();
}
BOOL LLFolderView::search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward) BOOL LLFolderView::search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward)
{ {
// get first selected item // get first selected item
@@ -1826,35 +1852,21 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
{ {
// all user operations move keyboard focus to inventory // all user operations move keyboard focus to inventory
// this way, we know when to stop auto-updating a search // this way, we know when to stop auto-updating a search
setFocus(TRUE); mParentPanel->setFocus(TRUE);
BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL; BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
S32 count = mSelectedItems.size(); S32 count = mSelectedItems.size();
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if(handled && (count > 0) && menu) if ( handled
&& ( count > 0 && (hasVisibleChildren() || mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) ) // show menu only if selected items are visible
&& menu )
{ {
//menu->empty(); updateMenuOptions(menu);
const LLView::child_list_t *list = menu->getChildList();
LLView::child_list_t::const_iterator menu_itor;
for (menu_itor = list->begin(); menu_itor != list->end(); ++menu_itor)
{
(*menu_itor)->setVisible(TRUE);
(*menu_itor)->setEnabled(TRUE);
}
// Successively filter out invalid options
selected_items_t::iterator item_itor;
U32 flags = FIRST_SELECTED_ITEM;
for (item_itor = mSelectedItems.begin(); item_itor != mSelectedItems.end(); ++item_itor)
{
(*item_itor)->buildContextMenu(*menu, flags);
flags = 0x0;
}
menu->arrange();
menu->updateParent(LLMenuGL::sMenuContainer); menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y); LLMenuGL::showPopup(this, menu, x, y);
menu->needsArrange(); // update menu height if needed
} }
else else
{ {
@@ -1867,6 +1879,37 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
return handled; return handled;
} }
// Add "--no options--" if the menu is completely blank.
BOOL LLFolderView::addNoOptions(LLMenuGL* menu) const
{
const std::string nooptions_str = "--no options--";
LLView *nooptions_item = NULL;
const LLView::child_list_t *list = menu->getChildList();
for (LLView::child_list_t::const_iterator itor = list->begin();
itor != list->end();
++itor)
{
LLView *menu_item = (*itor);
if (menu_item->getVisible())
{
return FALSE;
}
std::string name = menu_item->getName();
if (menu_item->getName() == nooptions_str)
{
nooptions_item = menu_item;
}
}
if (nooptions_item)
{
nooptions_item->setVisible(TRUE);
nooptions_item->setEnabled(FALSE);
return TRUE;
}
return FALSE;
}
BOOL LLFolderView::handleHover( S32 x, S32 y, MASK mask ) BOOL LLFolderView::handleHover( S32 x, S32 y, MASK mask )
{ {
return LLView::handleHover( x, y, mask ); return LLView::handleHover( x, y, mask );
@@ -1901,21 +1944,25 @@ BOOL LLFolderView::handleScrollWheel(S32 x, S32 y, S32 clicks)
void LLFolderView::deleteAllChildren() void LLFolderView::deleteAllChildren()
{ {
if(mRenamer == gFocusMgr.getTopCtrl()) closeRenamer();
{ if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
gFocusMgr.setTopCtrl(NULL);
}
LLView::deleteViewByHandle(mPopupMenuHandle);
mPopupMenuHandle = LLHandle<LLView>(); mPopupMenuHandle = LLHandle<LLView>();
mRenamer = NULL; mScrollContainer = NULL;
mRenameItem = NULL; mRenameItem = NULL;
mRenamer = NULL;
clearSelection(); clearSelection();
LLView::deleteAllChildren(); LLView::deleteAllChildren();
} }
void LLFolderView::scrollToShowSelection() void LLFolderView::scrollToShowSelection()
{ {
if (mSelectedItems.size()) // If items are filtered while background fetch is in progress
// scrollbar resets to the first filtered item. See EXT-3981.
// However we allow scrolling for folder views with mAutoSelectOverride
// (used in Places SP) as an exception because the selection in them
// is not reset during items filtering. See STORM-133.
if ( (!LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() || mAutoSelectOverride)
&& mSelectedItems.size() )
{ {
mNeedsScroll = TRUE; mNeedsScroll = TRUE;
} }
@@ -1925,6 +1972,7 @@ void LLFolderView::scrollToShowSelection()
// is maximally visible. // is maximally visible.
void LLFolderView::scrollToShowItem(LLFolderViewItem* item) void LLFolderView::scrollToShowItem(LLFolderViewItem* item)
{ {
if (!mScrollContainer) return;
// don't scroll to items when mouse is being used to scroll/drag and drop // don't scroll to items when mouse is being used to scroll/drag and drop
if (gFocusMgr.childHasMouseCapture(mScrollContainer)) if (gFocusMgr.childHasMouseCapture(mScrollContainer))
{ {
@@ -2015,7 +2063,7 @@ LLFastTimer::DeclareTimer FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID");
LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id) LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
{ {
LLFastTimer _(FTM_GET_ITEM_BY_ID); LLFastTimer _(FTM_GET_ITEM_BY_ID);
if (id.isNull()) if (id == getListener()->getUUID())
{ {
return this; return this;
} }
@@ -2030,6 +2078,25 @@ LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
return NULL; return NULL;
} }
LLFolderViewFolder* LLFolderView::getFolderByID(const LLUUID& id)
{
if (id == getListener()->getUUID())
{
return this;
}
for (folders_t::iterator iter = mFolders.begin();
iter != mFolders.end();
++iter)
{
LLFolderViewFolder *folder = (*iter);
if (folder->getListener()->getUUID() == id)
{
return folder;
}
}
return NULL;
}
static LLFastTimer::DeclareTimer FTM_AUTO_SELECT("Open and Select"); static LLFastTimer::DeclareTimer FTM_AUTO_SELECT("Open and Select");
@@ -2038,6 +2105,14 @@ extern std::set<LLFolderViewItem*> sFolderViewItems; //dumb hack
// Main idle routine // Main idle routine
void LLFolderView::doIdle() void LLFolderView::doIdle()
{ {
// If this is associated with the user's inventory, don't do anything
// until that inventory is loaded up.
const LLInventoryPanel *inventory_panel = dynamic_cast<LLInventoryPanel*>(mParentPanel);
if (inventory_panel && !inventory_panel->getIsViewsInitialized())
{
return;
}
LLFastTimer t2(FTM_INVENTORY); LLFastTimer t2(FTM_INVENTORY);
BOOL debug_filters = gSavedSettings.getBOOL("DebugInventoryFilters"); BOOL debug_filters = gSavedSettings.getBOOL("DebugInventoryFilters");
@@ -2078,12 +2153,21 @@ void LLFolderView::doIdle()
clearSelection(); clearSelection();
requestArrange(); requestArrange();
} }
else if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->getFiltered())) else if ((selected_itemp && !selected_itemp->getFiltered()) && !mAutoSelectOverride)
{ {
// select first filtered item // select first filtered item
LLSelectFirstFilteredItem filter; LLSelectFirstFilteredItem filter;
applyFunctorRecursively(filter); applyFunctorRecursively(filter);
} }
// Open filtered folders for folder views with mAutoSelectOverride=TRUE.
// Used by LLPlacesFolderView.
if (mAutoSelectOverride && !mFilter->getFilterSubString().empty())
{
LLOpenFilteredFolders filter;
applyFunctorRecursively(filter);
}
scrollToShowSelection(); scrollToShowSelection();
} }
@@ -2155,8 +2239,7 @@ void LLFolderView::updateRenamerPosition()
LLRect scroller_rect(0, 0, gViewerWindow->getWindowWidthScaled(), 0); LLRect scroller_rect(0, 0, gViewerWindow->getWindowWidthScaled(), 0);
if (mScrollContainer) if (mScrollContainer)
{ {
BOOL dummy_bool; scroller_rect = mScrollContainer->getContentWindowRect();
mScrollContainer->calcVisibleSize( &scroller_rect.mRight, &scroller_rect.mTop, &dummy_bool, &dummy_bool);
} }
S32 width = llmax(llmin(mRenameItem->getRect().getWidth() - x, scroller_rect.getWidth() - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH); S32 width = llmax(llmin(mRenameItem->getRect().getWidth() - x, scroller_rect.getWidth() - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH);
@@ -2164,13 +2247,64 @@ void LLFolderView::updateRenamerPosition()
mRenamer->reshape( width, height, TRUE ); mRenamer->reshape( width, height, TRUE );
} }
} }
// Update visibility and availability (i.e. enabled/disabled) of context menu items.
void LLFolderView::updateMenuOptions(LLMenuGL* menu)
{
const LLView::child_list_t *list = menu->getChildList();
LLView::child_list_t::const_iterator menu_itor;
for (menu_itor = list->begin(); menu_itor != list->end(); ++menu_itor)
{
(*menu_itor)->setVisible(FALSE);
(*menu_itor)->pushVisible(TRUE);
(*menu_itor)->setEnabled(TRUE);
}
// Successively filter out invalid options
U32 flags = FIRST_SELECTED_ITEM;
for (selected_items_t::iterator item_itor = mSelectedItems.begin();
item_itor != mSelectedItems.end();
++item_itor)
{
LLFolderViewItem* selected_item = (*item_itor);
selected_item->buildContextMenu(*menu, flags);
flags = 0x0;
}
addNoOptions(menu);
}
// Refresh the context menu (that is already shown).
void LLFolderView::updateMenu()
{
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu && menu->getVisible())
{
updateMenuOptions(menu);
menu->needsArrange(); // update menu height if needed
}
}
///---------------------------------------------------------------------------- ///----------------------------------------------------------------------------
/// Local function definitions /// Local function definitions
///---------------------------------------------------------------------------- ///----------------------------------------------------------------------------
void LLFolderView::onRenamerLost() void LLFolderView::onRenamerLost()
{
if (mRenamer && mRenamer->getVisible())
{ {
mRenamer->setVisible(FALSE); mRenamer->setVisible(FALSE);
// will commit current name (which could be same as original name)
mRenamer->setFocus(FALSE);
}
if( mRenameItem )
{
setSelectionFromRoot( mRenameItem, TRUE );
mRenameItem = NULL;
}
} }
LLInventoryFilter* LLFolderView::getFilter() LLInventoryFilter* LLFolderView::getFilter()

View File

@@ -81,7 +81,7 @@ public:
LLFolderView( const std::string& name, LLUIImagePtr root_folder_icon, const LLRect& rect, LLFolderView( const std::string& name, LLUIImagePtr root_folder_icon, const LLRect& rect,
const LLUUID& source_id, LLView *parent_view, LLFolderViewEventListener* listener ); const LLUUID& source_id, LLPanel *parent_view, LLFolderViewEventListener* listener );
virtual ~LLFolderView( void ); virtual ~LLFolderView( void );
virtual BOOL canFocusChildren() const; virtual BOOL canFocusChildren() const;
@@ -109,7 +109,7 @@ public:
U32 getSortOrder() const; U32 getSortOrder() const;
BOOL isFilterModified(); BOOL isFilterModified();
BOOL getAllowMultiSelect() { return mAllowMultiSelect; } bool getAllowMultiSelect() { return mAllowMultiSelect; }
U32 toggleSearchType(std::string toggle); U32 toggleSearchType(std::string toggle);
U32 getSearchType() const; U32 getSearchType() const;
@@ -117,6 +117,7 @@ public:
// Close all folders in the view // Close all folders in the view
void closeAllFolders(); void closeAllFolders();
void openFolder(const std::string& foldername); void openFolder(const std::string& foldername);
void openTopLevelFolders();
virtual void toggleOpen() {}; virtual void toggleOpen() {};
virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse); virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse);
@@ -196,9 +197,6 @@ public:
//void dragItemIntoFolder( LLFolderViewItem* moving_item, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept ); //void dragItemIntoFolder( LLFolderViewItem* moving_item, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
//void dragFolderIntoFolder( LLFolderViewFolder* moving_folder, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept ); //void dragFolderIntoFolder( LLFolderViewFolder* moving_folder, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
// LLUICtrl Functionality
/*virtual*/ void setFocus(BOOL focus);
// LLView functionality // LLView functionality
///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent ); ///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent );
/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask ); /*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
@@ -213,7 +211,6 @@ public:
EAcceptance* accept, EAcceptance* accept,
std::string& tooltip_msg); std::string& tooltip_msg);
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
/*virtual*/ void onFocusLost();
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
virtual void draw(); virtual void draw();
virtual void deleteAllChildren(); virtual void deleteAllChildren();
@@ -233,6 +230,7 @@ public:
void addItemID(const LLUUID& id, LLFolderViewItem* itemp); void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
void removeItemID(const LLUUID& id); void removeItemID(const LLUUID& id);
LLFolderViewItem* getItemByID(const LLUUID& id); LLFolderViewItem* getItemByID(const LLUUID& id);
LLFolderViewFolder* getFolderByID(const LLUUID& id);
void doIdle(); // Real idle routine void doIdle(); // Real idle routine
static void idle(void* user_data); // static glue to doIdle() static void idle(void* user_data); // static glue to doIdle()
@@ -243,10 +241,16 @@ public:
BOOL getDebugFilters() { return mDebugFilters; } BOOL getDebugFilters() { return mDebugFilters; }
LLPanel* getParentPanel() { return mParentPanel; }
// DEBUG only // DEBUG only
void dumpSelectionInformation(); void dumpSelectionInformation();
void updateMenu();
private:
void updateMenuOptions(LLMenuGL* menu);
void updateRenamerPosition(); void updateRenamerPosition();
protected: protected:
LLScrollableContainerView* mScrollContainer; // NULL if this is not a child of a scroll container. LLScrollableContainerView* mScrollContainer; // NULL if this is not a child of a scroll container.
@@ -256,6 +260,8 @@ protected:
void finishRenamingItem( void ); void finishRenamingItem( void );
void closeRenamer( void ); void closeRenamer( void );
BOOL addNoOptions(LLMenuGL* menu) const;
protected: protected:
LLHandle<LLView> mPopupMenuHandle; LLHandle<LLView> mPopupMenuHandle;
@@ -295,9 +301,12 @@ protected:
signal_t mReshapeSignal; signal_t mReshapeSignal;
S32 mSignalSelectCallback; S32 mSignalSelectCallback;
S32 mMinWidth; S32 mMinWidth;
S32 mRunningHeight;
std::map<LLUUID, LLFolderViewItem*> mItemMap; std::map<LLUUID, LLFolderViewItem*> mItemMap;
BOOL mDragAndDropThisFrame; BOOL mDragAndDropThisFrame;
LLPanel* mParentPanel;
/** /**
* Contains item under mouse pointer while dragging * Contains item under mouse pointer while dragging
*/ */

View File

@@ -1046,7 +1046,8 @@ LLFolderViewFolder::LLFolderViewFolder( const std::string& name, LLUIImagePtr ic
mLastArrangeGeneration( -1 ), mLastArrangeGeneration( -1 ),
mLastCalculatedWidth(0), mLastCalculatedWidth(0),
mCompletedFilterGeneration(-1), mCompletedFilterGeneration(-1),
mMostFilteredDescendantGeneration(-1) mMostFilteredDescendantGeneration(-1),
mNeedsSort(false)
{ {
} }
@@ -1075,6 +1076,14 @@ BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* r
// makes sure that this view and it's children are the right size. // makes sure that this view and it's children are the right size.
S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation) S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
{ {
// sort before laying out contents
if (mNeedsSort)
{
mFolders.sort(mSortFunction);
mItems.sort(mSortFunction);
mNeedsSort = false;
}
mHasVisibleChildren = hasFilteredDescendants(filter_generation); mHasVisibleChildren = hasFilteredDescendants(filter_generation);
LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getFilter()->getShowFolderState(); LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getFilter()->getShowFolderState();
@@ -1219,6 +1228,12 @@ BOOL LLFolderViewFolder::needsArrange()
return mLastArrangeGeneration < getRoot()->getArrangeGeneration(); return mLastArrangeGeneration < getRoot()->getArrangeGeneration();
} }
void LLFolderViewFolder::requestSort()
{
mNeedsSort = true;
// whenever item order changes, we need to lay things out again
requestArrange();
}
void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up) void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up)
{ {
mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation); mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation);
@@ -1404,6 +1419,11 @@ void LLFolderViewFolder::dirtyFilter()
LLFolderViewItem::dirtyFilter(); LLFolderViewItem::dirtyFilter();
} }
BOOL LLFolderViewFolder::hasFilteredDescendants(S32 filter_generation)
{
return mMostFilteredDescendantGeneration >= filter_generation;
}
BOOL LLFolderViewFolder::hasFilteredDescendants() BOOL LLFolderViewFolder::hasFilteredDescendants()
{ {
return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration(); return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration();
@@ -1871,7 +1891,7 @@ void LLFolderViewFolder::destroyView()
folderp->destroyView(); // removes entry from mFolders folderp->destroyView(); // removes entry from mFolders
} }
deleteAllChildren(); //deleteAllChildren();
if (mParentFolder) if (mParentFolder)
{ {
@@ -2190,12 +2210,16 @@ void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType r
{ {
BOOL was_open = mIsOpen; BOOL was_open = mIsOpen;
mIsOpen = openitem; mIsOpen = openitem;
if(!was_open && openitem)
{
if (mListener) if (mListener)
{
if(!was_open && openitem)
{ {
mListener->openItem(); mListener->openItem();
} }
else if(was_open && !openitem)
{
mListener->closeItem();
}
} }
if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN) if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN)

View File

@@ -364,6 +364,7 @@ protected:
S32 mLastCalculatedWidth; S32 mLastCalculatedWidth;
S32 mCompletedFilterGeneration; S32 mCompletedFilterGeneration;
S32 mMostFilteredDescendantGeneration; S32 mMostFilteredDescendantGeneration;
bool mNeedsSort;
public: public:
typedef enum e_recurse_type typedef enum e_recurse_type
{ {
@@ -389,6 +390,7 @@ public:
virtual S32 arrange( S32* width, S32* height, S32 filter_generation ); virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
BOOL needsArrange(); BOOL needsArrange();
void requestSort();
// Returns the sort group (system, trash, folder) for this folder. // Returns the sort group (system, trash, folder) for this folder.
virtual EInventorySortGroup getSortGroup() const; virtual EInventorySortGroup getSortGroup() const;
@@ -396,7 +398,7 @@ public:
virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up); virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up);
virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; } virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; }
BOOL hasFilteredDescendants(S32 filter_generation) { return mMostFilteredDescendantGeneration >= filter_generation; } BOOL hasFilteredDescendants(S32 filter_generation);
BOOL hasFilteredDescendants(); BOOL hasFilteredDescendants();
// applies filters to control visibility of inventory items // applies filters to control visibility of inventory items

View File

@@ -213,7 +213,7 @@ LLInvFVBridge::LLInvFVBridge(LLInventoryPanel* inventory,
mInvType(LLInventoryType::IT_NONE), mInvType(LLInventoryType::IT_NONE),
mIsLink(FALSE) mIsLink(FALSE)
{ {
mInventoryPanel = inventory; mInventoryPanel = inventory->getHandle();
const LLInventoryObject* obj = getInventoryObject(); const LLInventoryObject* obj = getInventoryObject();
mIsLink = obj && obj->getIsLinkType(); mIsLink = obj && obj->getIsLinkType();
} }
@@ -592,6 +592,22 @@ void hide_context_entries(LLMenuGL& menu,
{ {
const LLView::child_list_t *list = menu.getChildList(); const LLView::child_list_t *list = menu.getChildList();
// For removing double separators or leading separator. Start at true so that
// if the first element is a separator, it will not be shown.
bool is_previous_entry_separator = true;
for (menuentry_vec_t::const_iterator itor = entries_to_show.begin(); itor != entries_to_show.end(); ++itor)
{
bool found = false;
for (LLView::child_list_t::const_iterator itor2 = list->begin(); itor2 != list->end(); ++itor2)
{
if(*itor == (*itor2)->getName())
found = true;
}
if(!found)
llinfos << "Failed to find entry '" << *itor << "'" << llendl;
}
for (LLView::child_list_t::const_iterator itor = list->begin(); for (LLView::child_list_t::const_iterator itor = list->begin();
itor != list->end(); itor != list->end();
++itor) ++itor)
@@ -606,7 +622,6 @@ void hide_context_entries(LLMenuGL& menu,
hide_context_entries(*branchp->getBranch(), entries_to_show, disabled_entries); hide_context_entries(*branchp->getBranch(), entries_to_show, disabled_entries);
} }
bool found = false; bool found = false;
menuentry_vec_t::const_iterator itor2; menuentry_vec_t::const_iterator itor2;
for (itor2 = entries_to_show.begin(); itor2 != entries_to_show.end(); ++itor2) for (itor2 = entries_to_show.begin(); itor2 != entries_to_show.end(); ++itor2)
@@ -614,21 +629,42 @@ void hide_context_entries(LLMenuGL& menu,
if (*itor2 == name) if (*itor2 == name)
{ {
found = true; found = true;
break;
} }
} }
// Don't allow multiple separators in a row (e.g. such as if there are no items
// between two separators).
if (found)
{
const bool is_entry_separator = (dynamic_cast<LLMenuItemSeparatorGL *>(menu_item) != NULL);
found = !(is_entry_separator && is_previous_entry_separator);
is_previous_entry_separator = is_entry_separator;
}
if (!found) if (!found)
{
if (!menu_item->getLastVisible())
{ {
menu_item->setVisible(FALSE); menu_item->setVisible(FALSE);
} }
else
{
for (itor2 = disabled_entries.begin(); itor2 != disabled_entries.end(); ++itor2)
{
if (*itor2 == name)
{
menu_item->setEnabled(FALSE); menu_item->setEnabled(FALSE);
} }
else
{
menu_item->setVisible(TRUE);
// A bit of a hack so we can remember that some UI element explicitly set this to be visible
// so that some other UI element from multi-select doesn't later set this invisible.
menu_item->pushVisible(TRUE);
bool enabled = (menu_item->getEnabled() == TRUE);
for (itor2 = disabled_entries.begin(); enabled && (itor2 != disabled_entries.end()); ++itor2)
{
enabled &= (*itor2 != name);
} }
llinfos << (enabled ? "Showing" : "hiding") << " " << menu_item->getName() << llendl;
menu_item->setEnabled(enabled);
} }
} }
} }
@@ -738,7 +774,8 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
// [RLVa:KB] - Checked: 2009-11-11 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a // [RLVa:KB] - Checked: 2009-11-11 (RLVa-1.1.0a) | Modified: RLVa-1.1.0a
if (rlv_handler_t::isEnabled()) if (rlv_handler_t::isEnabled())
{ {
LLInventoryObject* pItem = (mInventoryPanel->getModel()) ? mInventoryPanel->getModel()->getObject(mUUID) : NULL; LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
LLInventoryObject* pItem = (panel && panel->getModel()) ? panel->getModel()->getObject(mUUID) : NULL;
if ( (pItem) && if ( (pItem) &&
( ((LLAssetType::AT_NOTECARD == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE))) || ( ((LLAssetType::AT_NOTECARD == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE))) ||
((LLAssetType::AT_LSL_TEXT == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT))) || ((LLAssetType::AT_LSL_TEXT == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT))) ||
@@ -855,7 +892,7 @@ LLInventoryObject* LLInvFVBridge::getInventoryObject() const
LLInventoryModel* LLInvFVBridge::getInventoryModel() const LLInventoryModel* LLInvFVBridge::getInventoryModel() const
{ {
LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel); LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
return panel ? panel->getModel() : NULL; return panel ? panel->getModel() : NULL;
} }
@@ -1089,6 +1126,27 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid)
model->notifyObservers(); model->notifyObservers();
} }
} }
// +=================================================+
// | InventoryFVBridgeBuilder |
// +=================================================+
LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset_type,
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
LLFolderView* root,
const LLUUID& uuid,
U32 flags /* = 0x00 */) const
{
return LLInvFVBridge::createBridge(asset_type,
actual_asset_type,
inv_type,
inventory,
root,
uuid,
flags);
}
// +=================================================+ // +=================================================+
// | LLItemBridge | // | LLItemBridge |
// +=================================================+ // +=================================================+
@@ -1627,7 +1685,7 @@ BOOL LLFolderBridge::isItemRemovable() const
return FALSE; return FALSE;
} }
LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel); LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL); LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL);
if (folderp) if (folderp)
{ {
@@ -1661,16 +1719,58 @@ BOOL LLFolderBridge::isItemCopyable() const
return InventoryLinksEnabled(); return InventoryLinksEnabled();
} }
BOOL LLFolderBridge::copyToClipboard() const
BOOL LLFolderBridge::isClipboardPasteable() const
{ {
if(LLInventoryClipboard::instance().hasContents() && isAgentInventory()) if(isItemCopyable())
{ {
LLInventoryClipboard::instance().add(mUUID);
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
BOOL LLFolderBridge::isClipboardPasteable() const
{
if ( ! LLInvFVBridge::isClipboardPasteable() )
return FALSE;
/* TODO
// Don't allow pasting duplicates to the Calling Card/Friends subfolders, see bug EXT-1599
if ( LLFriendCardsManager::instance().isCategoryInFriendFolder( getCategory() ) )
{
LLInventoryModel* model = getInventoryModel();
if ( !model )
{
return FALSE;
}
LLDynamicArray<LLUUID> objects;
LLInventoryClipboard::instance().retrieve(objects);
const LLViewerInventoryCategory *current_cat = getCategory();
// Search for the direct descendent of current Friends subfolder among all pasted items,
// and return false if is found.
for(S32 i = objects.count() - 1; i >= 0; --i)
{
const LLUUID &obj_id = objects.get(i);
if ( LLFriendCardsManager::instance().isObjDirectDescendentOfCategory(model->getObject(obj_id), current_cat) )
{
return FALSE;
}
}
}
*/
return TRUE;
//Old, less restrictive behavior
/*if(LLInventoryClipboard::instance().hasContents() && isAgentInventory())
{
return TRUE;
}
return FALSE;*/
}
BOOL LLFolderBridge::isClipboardPasteableAsLink() const BOOL LLFolderBridge::isClipboardPasteableAsLink() const
{ {
@@ -2312,6 +2412,11 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
modifyOutfit(TRUE); modifyOutfit(TRUE);
return; return;
} }
else if ("copy" == action)
{
copyToClipboard();
return;
}
else if ("wearitems" == action) else if ("wearitems" == action)
{ {
modifyOutfit(TRUE); modifyOutfit(TRUE);
@@ -2604,8 +2709,7 @@ void LLFolderBridge::staticFolderOptionsMenu()
if (selfp && selfp->mRoot) if (selfp && selfp->mRoot)
{ {
//selfp->mRoot->updateMenu(); selfp->mRoot->updateMenu();
selfp->buildContextMenuFolderOptions(0);
} }
} }
@@ -2623,7 +2727,6 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv
void LLFolderBridge::buildContextMenuBaseOptions(U32 flags) void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
{ {
LLUUID cof_id = LLAppearanceMgr::instance().getCOF();
LLInventoryModel* model = getInventoryModel(); LLInventoryModel* model = getInventoryModel();
llassert(model != NULL); llassert(model != NULL);
@@ -2649,13 +2752,7 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
mDisabledItems.push_back(std::string("New Body Parts")); mDisabledItems.push_back(std::string("New Body Parts"));
} }
// clear out old menu and folder pointers if(trash_id == mUUID)
mMenu.markDead();
if (cof_id == mUUID)
{
mItems.push_back(std::string("Take Off Items"));
}
else if(trash_id == mUUID)
{ {
// This is the trash. // This is the trash.
mItems.push_back(std::string("Empty Trash")); mItems.push_back(std::string("Empty Trash"));
@@ -2792,15 +2889,20 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
{ {
mItems.push_back(std::string("Add To Outfit")); mItems.push_back(std::string("Add To Outfit"));
} }
else if(!InventoryLinksEnabled())
mItems.push_back(std::string("Wear Items")); mItems.push_back(std::string("Wear Items"));
mItems.push_back(std::string("Replace Outfit")); mItems.push_back(std::string("Replace Outfit"));
} }
mItems.push_back(std::string("Take Off Items")); mItems.push_back(std::string("Remove From Outfit"));
} if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID))
LLMenuGL* menup = dynamic_cast<LLMenuGL*>(mMenu.get());
if (menup)
{ {
hide_context_entries(*menup, mItems, mDisabledItems); mDisabledItems.push_back(std::string("Remove From Outfit"));
}
if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
{
mDisabledItems.push_back(std::string("Replace Outfit"));
}
mItems.push_back(std::string("Outfit Separator"));
} }
} }
@@ -2827,31 +2929,26 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
uuid_vec_t folders; uuid_vec_t folders;
folders.push_back(category->getUUID()); folders.push_back(category->getUUID());
mMenu = menu.getHandle();
sSelf = getHandle(); sSelf = getHandle();
LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders, FALSE); LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders, FALSE);
fetch->startFetch(); fetch->startFetch();
inc_busy_count(); inc_busy_count();
if (fetch->isFinished()) if (fetch->isFinished())
{ {
//buildContextMenuFolderOptions(flags); buildContextMenuFolderOptions(flags);
// everything is already here - call done.
fetch->done();
} }
else else
{ {
// it's all on it's way - add an observer, and the inventory // it's all on its way - add an observer, and the inventory will call done for us when everything is here.
// will call done for us when everything is here.
gInventory.addObserver(fetch); gInventory.addObserver(fetch);
} }
} }
else
{
mItems.push_back(std::string("--no options--"));
mDisabledItems.push_back(std::string("--no options--"));
}
hide_context_entries(menu, mItems, mDisabledItems); hide_context_entries(menu, mItems, mDisabledItems);
// Reposition the menu, in case we're adding items to an existing menu.
menu.needsArrange();
menu.arrangeAndClear();
} }
BOOL LLFolderBridge::hasChildren() const BOOL LLFolderBridge::hasChildren() const
@@ -2939,7 +3036,7 @@ void LLFolderBridge::createNewCategory(void* user_data)
{ {
LLFolderBridge* bridge = (LLFolderBridge*)user_data; LLFolderBridge* bridge = (LLFolderBridge*)user_data;
if(!bridge) return; if(!bridge) return;
LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(bridge->mInventoryPanel); LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(bridge->mInventoryPanel.get());
if (!panel) return; if (!panel) return;
LLInventoryModel* model = panel->getModel(); LLInventoryModel* model = panel->getModel();
if(!model) return; if(!model) return;
@@ -3133,7 +3230,7 @@ void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item)
// use callback to rearrange favorite landmarks after adding // use callback to rearrange favorite landmarks after adding
// to have new one placed before target (on which it was dropped). See EXT-4312. // to have new one placed before target (on which it was dropped). See EXT-4312.
LLPointer<AddFavoriteLandmarkCallback> cb = new AddFavoriteLandmarkCallback(); LLPointer<AddFavoriteLandmarkCallback> cb = new AddFavoriteLandmarkCallback();
LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel); LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL; LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL;
if (drag_over_item && drag_over_item->getListener()) if (drag_over_item && drag_over_item->getListener())
{ {
@@ -3228,6 +3325,20 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
{ {
is_movable &= inv_item->getIsLinkType() || !get_is_item_worn(inv_item->getUUID()); is_movable &= inv_item->getIsLinkType() || !get_is_item_worn(inv_item->getUUID());
} }
/* TODO
if (is_movable)
{
// Don't allow creating duplicates in the Calling Card/Friends
// subfolders, see bug EXT-1599. Check is item direct descendent
// of target folder and forbid item's movement if it so.
// Note: isItemDirectDescendentOfCategory checks if
// passed category is in the Calling Card/Friends folder
is_movable &= !LLFriendCardsManager::instance().isObjDirectDescendentOfCategory(inv_item, getCategory());
}
*/
//
//--------------------------------------------------------------------------------
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Determine if item can be moved & dropped // Determine if item can be moved & dropped
@@ -3264,7 +3375,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
if (active_panel) if (active_panel)
{ {
LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel); LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
if (active_panel && (panel != active_panel)) if (active_panel && (panel != active_panel))
{ {
active_panel->unSelectAll(); active_panel->unSelectAll();
@@ -3297,7 +3408,6 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// //
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
} }
} }
else if(LLToolDragAndDrop::SOURCE_WORLD == source) else if(LLToolDragAndDrop::SOURCE_WORLD == source)
@@ -3490,6 +3600,50 @@ void LLTextureBridge::openItem()
} }
} }
// virtual
void LLTextureBridge::performAction(LLInventoryModel* model, std::string action)
{
// TODO
/*if ("save_as" == action)
{
LLFloaterReg::showInstance("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES);
LLPreviewTexture* preview_texture = LLFloaterReg::findTypedInstance<LLPreviewTexture>("preview_texture", mUUID);
if (preview_texture)
{
preview_texture->openToSave();
}
}
else*/
LLItemBridge::performAction(model, action);
}
void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
lldebugs << "LLTextureBridge::buildContextMenu()" << llendl;
menuentry_vec_t items;
menuentry_vec_t disabled_items;
if(isItemInTrash())
{
addTrashContextMenuOptions(items, disabled_items);
}
else
{
addOpenRightClickMenuOption(items);
items.push_back(std::string("Properties"));
getClipboardEntries(true, items, disabled_items, flags);
//TODO
/*items.push_back(std::string("Texture Separator"));
items.push_back(std::string("Save As"));
if (!canSaveTexture())
{
disabled_items.push_back(std::string("Save As"));
}*/
}
hide_context_entries(menu, items, disabled_items);
}
// +=================================================+ // +=================================================+
// | LLSoundBridge | // | LLSoundBridge |
// +=================================================+ // +=================================================+
@@ -3747,7 +3901,7 @@ LLCallingCardBridge::~LLCallingCardBridge()
void LLCallingCardBridge::refreshFolderViewItem() void LLCallingCardBridge::refreshFolderViewItem()
{ {
LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel); LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL; LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL;
if (itemp) if (itemp)
{ {
@@ -4217,12 +4371,11 @@ void LLAnimationBridge::performAction(LLInventoryModel* model, std::string actio
if(LLPreview::show( mUUID )) if(LLPreview::show( mUUID ))
return; return;
LLViewerInventoryItem *item = getItem(); if( getItem() )
if( item )
{ {
S32 activate = 0; LLPreviewAnim::e_activation_type activate = LLPreviewAnim::NONE;
if ("playworld" == action) activate = 1; if ("playworld" == action) activate = LLPreviewAnim::PLAY;
if ("playlocal" == action) activate = 2; if ("playlocal" == action) activate = LLPreviewAnim::AUDITION;
S32 left, top; S32 left, top;
gFloaterView->getNewFloaterPosition(&left, &top); gFloaterView->getNewFloaterPosition(&left, &top);
@@ -4230,7 +4383,7 @@ void LLAnimationBridge::performAction(LLInventoryModel* model, std::string actio
rect.translate( left - rect.mLeft, top - rect.mTop ); rect.translate( left - rect.mLeft, top - rect.mTop );
LLPreviewAnim* preview = new LLPreviewAnim("preview anim", LLPreviewAnim* preview = new LLPreviewAnim("preview anim",
rect, rect,
getPrefix() + item->getName(), getPrefix() + getItem()->getName(),
mUUID, mUUID,
activate); activate);
// Force to be entirely onscreen. // Force to be entirely onscreen.
@@ -4260,7 +4413,7 @@ void LLAnimationBridge::openItem()
rect, rect,
getPrefix() + item->getName(), getPrefix() + item->getName(),
mUUID, mUUID,
0); LLPreviewAnim::NONE);
preview->setFocus(TRUE); preview->setFocus(TRUE);
// Force to be entirely onscreen. // Force to be entirely onscreen.
gFloaterView->adjustToFitScreen(preview, FALSE); gFloaterView->adjustToFitScreen(preview, FALSE);
@@ -4629,7 +4782,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
// [/RLVa:KB] // [/RLVa:KB]
} }
LLSimpleListener* callback = mInventoryPanel->getListenerByName("Inventory.AttachObject"); LLSimpleListener* callback = mInventoryPanel.get()->getListenerByName("Inventory.AttachObject");
if (callback) if (callback)
{ {
@@ -4638,7 +4791,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
} }
LLMenuItemCallGL *new_item = new LLMenuItemCallGL("Custom...", NULL, NULL); LLMenuItemCallGL *new_item = new LLMenuItemCallGL("Custom...", NULL, NULL);
attach_menu->append(new_item); attach_menu->append(new_item);
LLSimpleListener* callback = mInventoryPanel->getListenerByName("Inventory.AttachCustom"); LLSimpleListener* callback = mInventoryPanel.get()->getListenerByName("Inventory.AttachCustom");
new_item->addListener(callback, "on_click", LLSD()); new_item->addListener(callback, "on_click", LLSD());
} }
} }
@@ -4984,12 +5137,11 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Wearable And Object Separator")); items.push_back(std::string("Wearable And Object Separator"));
items.push_back(std::string("Wearable Wear"));
items.push_back(std::string("Wearable Edit")); items.push_back(std::string("Wearable Edit"));
// [RLVa:KB] - Checked: 2011-09-16 (RLVa-1.1.4a) | Added: RLVa-1.1.4a // [RLVa:KB] - Checked: 2011-09-16 (RLVa-1.1.4a) | Added: RLVa-1.1.4a
if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canRemove(item)) ) if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canRemove(item)) )
{ {
disabled_items.push_back(std::string("Wearable Wear")); disabled_items.push_back(std::string("Wearable And Object Wear"));
disabled_items.push_back(std::string("Wearable Edit")); disabled_items.push_back(std::string("Wearable Edit"));
} }
// [/RLVa:KB] // [/RLVa:KB]
@@ -5294,6 +5446,7 @@ void LLWearableBridge::removeFromAvatar()
} }
} }
// +=================================================+ // +=================================================+
// | LLLinkItemBridge | // | LLLinkItemBridge |
// +=================================================+ // +=================================================+
@@ -5400,6 +5553,7 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
std::string LLLinkFolderBridge::sPrefix("Link: "); std::string LLLinkFolderBridge::sPrefix("Link: ");
LLUIImagePtr LLLinkFolderBridge::getIcon() const LLUIImagePtr LLLinkFolderBridge::getIcon() const
{ {
//For now, all inv links share this icon. There is no 'overlay' mechanism yet.
return LLUI::getUIImage("inv_link_folder.tga"); return LLUI::getUIImage("inv_link_folder.tga");
} }

View File

@@ -154,9 +154,8 @@ protected:
const LLUUID& new_parent, const LLUUID& new_parent,
BOOL restamp); BOOL restamp);
void removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch); void removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch);
protected: protected:
LLInventoryPanel* mInventoryPanel; LLHandle<LLPanel> mInventoryPanel;
LLFolderView* mRoot; LLFolderView* mRoot;
LLUUID mUUID; // item id LLUUID mUUID; // item id
LLInventoryType::EType mInvType; LLInventoryType::EType mInvType;
@@ -165,6 +164,24 @@ protected:
}; };
class AIFilePicker; class AIFilePicker;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInvFVBridgeBuilder
//
// This class intended to build Folder View Bridge via LLInvFVBridge::createBridge.
// It can be overridden with another way of creation necessary Inventory-Folder-View-Bridge.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLInventoryFVBridgeBuilder
{
public:
virtual ~LLInventoryFVBridgeBuilder() {}
virtual LLInvFVBridge* createBridge(LLAssetType::EType asset_type,
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
LLFolderView* root,
const LLUUID& uuid,
U32 flags = 0x00) const;
};
class LLItemBridge : public LLInvFVBridge class LLItemBridge : public LLInvFVBridge
{ {
@@ -251,9 +268,9 @@ public:
virtual BOOL isItemCopyable() const; virtual BOOL isItemCopyable() const;
virtual BOOL isClipboardPasteable() const; virtual BOOL isClipboardPasteable() const;
virtual BOOL isClipboardPasteableAsLink() const; virtual BOOL isClipboardPasteableAsLink() const;
virtual BOOL copyToClipboard() const;
static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type); static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type);
//static void createWearable(LLUUID parent_folder_id, LLWearableType::EType type);
LLViewerInventoryCategory* getCategory() const; LLViewerInventoryCategory* getCategory() const;
LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; } LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; }
@@ -302,13 +319,11 @@ public:
private: private:
BOOL mCallingCards; BOOL mCallingCards;
BOOL mWearables; BOOL mWearables;
LLHandle<LLView> mMenu;
menuentry_vec_t mItems; menuentry_vec_t mItems;
menuentry_vec_t mDisabledItems; menuentry_vec_t mDisabledItems;
LLRootHandle<LLFolderBridge> mHandle; LLRootHandle<LLFolderBridge> mHandle;
}; };
class LLTextureBridge : public LLItemBridge class LLTextureBridge : public LLItemBridge
{ {
public: public:
@@ -323,8 +338,8 @@ public:
} }
virtual LLUIImagePtr getIcon() const; virtual LLUIImagePtr getIcon() const;
virtual void openItem(); virtual void openItem();
//virtual void buildContextMenu(LLMenuGL& menu, U32 flags); virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
//virtual void performAction(LLInventoryModel* model, std::string action); virtual void performAction(LLInventoryModel* model, std::string action);
bool canSaveTexture(void); bool canSaveTexture(void);
}; };

View File

@@ -1,32 +1,26 @@
/** /*
* @file llinventoryview.cpp * @file llinventorypanel.cpp
* @brief Implementation of the inventory view and associated stuff. * @brief Implementation of the inventory panel and associated stuff.
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
* *
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* 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 * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
@@ -37,6 +31,7 @@
#include "llagent.h" #include "llagent.h"
#include "llagentwearables.h" #include "llagentwearables.h"
#include "llappearancemgr.h"
#include "lluictrlfactory.h" #include "lluictrlfactory.h"
#include "llfloatercustomize.h" #include "llfloatercustomize.h"
#include "llfolderview.h" #include "llfolderview.h"
@@ -58,12 +53,11 @@
static LLRegisterWidget<LLInventoryPanel> r("inventory_panel"); static LLRegisterWidget<LLInventoryPanel> r("inventory_panel");
const std::string LLInventoryPanel::DEFAULT_SORT_ORDER = std::string("InventorySortOrder");
const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("RecentItemsSortOrder");
///---------------------------------------------------------------------------- const std::string LLInventoryPanel::WORNITEMS_SORT_ORDER = std::string("WornItemsSortOrder");
/// Local function declarations, constants, enums, and typedefs const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string("");
///---------------------------------------------------------------------------- static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -89,10 +83,50 @@ protected:
const std::string LLInventoryPanel::DEFAULT_SORT_ORDER = std::string("InventorySortOrder");
const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("RecentItemsSortOrder");
const std::string LLInventoryPanel::WORNITEMS_SORT_ORDER = std::string("WornItemsSortOrder"); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string(""); // Class LLInvPanelComplObserver
//
// Calls specified callback when all specified items become complete.
//
// Usage:
// observer = new LLInvPanelComplObserver(boost::bind(onComplete));
// inventory->addObserver(observer);
// observer->reset(); // (optional)
// observer->watchItem(incomplete_item1_id);
// observer->watchItem(incomplete_item2_id);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLInvPanelComplObserver : public LLInventoryCompletionObserver
{
public:
typedef boost::function<void()> callback_t;
LLInvPanelComplObserver(callback_t cb)
: mCallback(cb)
{
}
void reset();
private:
/*virtual*/ void done();
/// Called when all the items are complete.
callback_t mCallback;
};
void LLInvPanelComplObserver::reset()
{
mIncomplete.clear();
mComplete.clear();
}
void LLInvPanelComplObserver::done()
{
mCallback();
}
LLInventoryPanel::LLInventoryPanel(const std::string& name, LLInventoryPanel::LLInventoryPanel(const std::string& name,
const std::string& sort_order_setting, const std::string& sort_order_setting,
@@ -101,37 +135,40 @@ LLInventoryPanel::LLInventoryPanel(const std::string& name,
BOOL allow_multi_select, BOOL allow_multi_select,
LLView *parent_view) : LLView *parent_view) :
LLPanel(name, rect, TRUE), LLPanel(name, rect, TRUE),
mInventory(inventory),
mInventoryObserver(NULL), mInventoryObserver(NULL),
mCompletionObserver(NULL),
mFolderRoot(NULL), mFolderRoot(NULL),
mScroller(NULL), mScroller(NULL),
mSortOrderSetting(sort_order_setting),
mInventory(inventory),
mAllowMultiSelect(allow_multi_select), mAllowMultiSelect(allow_multi_select),
mSortOrderSetting(sort_order_setting) mViewsInitialized(false),
mInvFVBridgeBuilder(NULL)
{ {
mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
setBackgroundColor(gColors.getColor("InventoryBackgroundColor")); setBackgroundColor(gColors.getColor("InventoryBackgroundColor"));
setBackgroundVisible(TRUE); setBackgroundVisible(TRUE);
setBackgroundOpaque(TRUE); setBackgroundOpaque(TRUE);
} }
BOOL LLInventoryPanel::postBuild() void LLInventoryPanel::buildFolderView()
{ {
init_inventory_panel_actions(this); LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
LLRect folder_rect(0,
0,
getRect().getWidth(),
0);
LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(LLAssetType::AT_CATEGORY,
LLAssetType::AT_CATEGORY, LLAssetType::AT_CATEGORY,
LLInventoryType::IT_CATEGORY, LLInventoryType::IT_CATEGORY,
this, this,
NULL, NULL,
LLUUID::null); LLUUID::null);
mFolderRoot = new LLFolderView(getName(), NULL, folder_rect, LLUUID::null, this, new_listener); mFolderRoot = createFolderView(new_listener, true/*params.use_label_suffix()*/);
mFolderRoot->setAllowMultiSelect(mAllowMultiSelect); }
BOOL LLInventoryPanel::postBuild()
{
init_inventory_panel_actions(this);
buildFolderView();
{
// scroller // scroller
LLRect scroller_view_rect = getRect(); LLRect scroller_view_rect = getRect();
scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
@@ -142,15 +179,22 @@ BOOL LLInventoryPanel::postBuild()
mScroller->setReserveScrollCorner(TRUE); mScroller->setReserveScrollCorner(TRUE);
addChild(mScroller); addChild(mScroller);
mFolderRoot->setScrollContainer(mScroller); mFolderRoot->setScrollContainer(mScroller);
}
// set up the callbacks from the inventory we're viewing, and then // Set up the callbacks from the inventory we're viewing, and then build everything.
// build everything.
mInventoryObserver = new LLInventoryPanelObserver(this); mInventoryObserver = new LLInventoryPanelObserver(this);
mInventory->addObserver(mInventoryObserver); mInventory->addObserver(mInventoryObserver);
rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD);
// bit of a hack to make sure the inventory is open. mCompletionObserver = new LLInvPanelComplObserver(boost::bind(&LLInventoryPanel::onItemsCompletion, this));
mFolderRoot->openFolder(std::string("My Inventory")); mInventory->addObserver(mCompletionObserver);
// Build view of inventory if we need default full hierarchy and inventory ready,
// otherwise wait for idle callback.
if (mInventory->isInventoryUsable() && !mViewsInitialized)
{
initializeViews();
}
gIdleCallbacks.addFunction(onIdle, (void*)this);
if (mSortOrderSetting != INHERIT_SORT_ORDER) if (mSortOrderSetting != INHERIT_SORT_ORDER)
{ {
@@ -177,9 +221,14 @@ LLInventoryPanel::~LLInventoryPanel()
} }
} }
gIdleCallbacks.deleteFunction(onIdle, this);
// LLView destructor will take care of the sub-views. // LLView destructor will take care of the sub-views.
mInventory->removeObserver(mInventoryObserver); mInventory->removeObserver(mInventoryObserver);
mInventory->removeObserver(mCompletionObserver);
delete mInventoryObserver; delete mInventoryObserver;
delete mCompletionObserver;
mScroller = NULL; mScroller = NULL;
} }
@@ -301,11 +350,9 @@ U32 LLInventoryPanel::getSortOrder() const
return mFolderRoot->getSortOrder(); return mFolderRoot->getSortOrder();
} }
// static void LLInventoryPanel::requestSort()
LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel()
{ {
LLInventoryView *view = LLInventoryView::getActiveInventory(); mFolderRoot->requestSort();
return view ? view->getPanel() : NULL;
} }
void LLInventoryPanel::setSinceLogoff(BOOL sl) void LLInventoryPanel::setSinceLogoff(BOOL sl)
@@ -335,7 +382,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
bool handled = false; bool handled = false;
//if (!mViewsInitialized) return; if (!mViewsInitialized) return;
const LLInventoryModel* model = getModel(); const LLInventoryModel* model = getModel();
if (!model) return; if (!model) return;
@@ -353,7 +400,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
// LLFolderViewFolder is derived from LLFolderViewItem so dynamic_cast from item // LLFolderViewFolder is derived from LLFolderViewItem so dynamic_cast from item
// to folder is the fast way to get a folder without searching through folders tree. // to folder is the fast way to get a folder without searching through folders tree.
//LLFolderViewFolder* view_folder = dynamic_cast<LLFolderViewFolder*>(view_item); LLFolderViewFolder* view_folder = dynamic_cast<LLFolderViewFolder*>(view_item);
////////////////////////////// //////////////////////////////
// LABEL Operation // LABEL Operation
@@ -377,7 +424,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
////////////////////////////// //////////////////////////////
// REBUILD Operation // REBUILD Operation
// Destroy and regenerate the UI. // Destroy and regenerate the UI.
/*if (mask & LLInventoryObserver::REBUILD) if (mask & LLInventoryObserver::REBUILD)
{ {
handled = true; handled = true;
if (model_item && view_item) if (model_item && view_item)
@@ -386,7 +433,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
} }
view_item = buildNewViews(item_id); view_item = buildNewViews(item_id);
view_folder = dynamic_cast<LLFolderViewFolder *>(view_item); view_folder = dynamic_cast<LLFolderViewFolder *>(view_item);
}*/ }
////////////////////////////// //////////////////////////////
// INTERNAL Operation // INTERNAL Operation
@@ -402,13 +449,13 @@ void LLInventoryPanel::modelChanged(U32 mask)
////////////////////////////// //////////////////////////////
// SORT Operation // SORT Operation
// Sort the folder. // Sort the folder.
/*if (mask & LLInventoryObserver::SORT) if (mask & LLInventoryObserver::SORT)
{ {
if (view_folder) if (view_folder)
{ {
view_folder->requestSort(); view_folder->requestSort();
} }
}*/ }
// We don't typically care which of these masks the item is actually flagged with, since the masks // We don't typically care which of these masks the item is actually flagged with, since the masks
// may not be accurate (e.g. in the main inventory panel, I move an item from My Inventory into // may not be accurate (e.g. in the main inventory panel, I move an item from My Inventory into
@@ -479,11 +526,60 @@ LLFolderView* LLInventoryPanel::getRootFolder()
{ {
return mFolderRoot; return mFolderRoot;
} }
// static
void LLInventoryPanel::onIdle(void *userdata)
{
if (!gInventory.isInventoryUsable())
return;
LLInventoryPanel *self = (LLInventoryPanel*)userdata;
// Inventory just initialized, do complete build
if (!self->mViewsInitialized)
{
self->initializeViews();
}
if (self->mViewsInitialized)
{
gIdleCallbacks.deleteFunction(onIdle, (void*)self);
}
}
const LLUUID& LLInventoryPanel::getRootFolderID() const const LLUUID& LLInventoryPanel::getRootFolderID() const
{ {
return mFolderRoot->getListener()->getUUID(); return mFolderRoot->getListener()->getUUID();
} }
LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id, U32 mask)
void LLInventoryPanel::initializeViews()
{
if (!gInventory.isInventoryUsable()) return;
rebuildViewsFor(getRootFolderID());
mViewsInitialized = true;
openStartFolderOrMyInventory();
// Special case for new user login
if (gAgent.isFirstLogin())
{
// Auto open the user's library
LLFolderViewFolder* lib_folder = mFolderRoot->getFolderByID(gInventory.getLibraryRootFolderID());
if (lib_folder)
{
lib_folder->setOpen(TRUE);
}
// Auto close the user's my inventory folder
LLFolderViewFolder* my_inv_folder = mFolderRoot->getFolderByID(gInventory.getRootFolderID());
if (my_inv_folder)
{
my_inv_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
}
}
}
LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
{ {
// Destroy the old view for this ID so we can rebuild it. // Destroy the old view for this ID so we can rebuild it.
LLFolderViewItem* old_view = mFolderRoot->getItemByID(id); LLFolderViewItem* old_view = mFolderRoot->getItemByID(id);
@@ -495,6 +591,18 @@ LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id, U32 mask)
return buildNewViews(id); return buildNewViews(id);
} }
LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix)
{
LLRect folder_rect(0,
0,
getRect().getWidth(),
0);
LLFolderView* ret = new LLFolderView(getName(), NULL, folder_rect, LLUUID::null, this, bridge);
ret->setAllowMultiSelect(mAllowMultiSelect);
return ret;
}
LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge) LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
{ {
return new LLFolderViewFolder( return new LLFolderViewFolder(
@@ -544,7 +652,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
if ((objectp->getType() == LLAssetType::AT_CATEGORY) && if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER)) (objectp->getActualType() != LLAssetType::AT_LINK_FOLDER))
{ {
LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(objectp->getType(), LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
objectp->getType(), objectp->getType(),
LLInventoryType::IT_CATEGORY, LLInventoryType::IT_CATEGORY,
this, this,
@@ -564,7 +672,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
{ {
// Build new view for item. // Build new view for item.
LLInventoryItem* item = (LLInventoryItem*)objectp; LLInventoryItem* item = (LLInventoryItem*)objectp;
LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(item->getType(), LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(),
item->getActualType(), item->getActualType(),
item->getInventoryType(), item->getInventoryType(),
this, this,
@@ -622,6 +730,23 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
return itemp; return itemp;
} }
// bit of a hack to make sure the inventory is open.
void LLInventoryPanel::openStartFolderOrMyInventory()
{
// Find My Inventory folder and open it up by name
for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child))
{
LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
if (fchild
&& fchild->getListener()
&& fchild->getListener()->getUUID() == gInventory.getRootFolderID())
{
fchild->setOpen(TRUE);
break;
}
}
}
struct LLConfirmPurgeData struct LLConfirmPurgeData
{ {
LLUUID mID; LLUUID mID;
@@ -654,6 +779,10 @@ protected:
const LLUUID& mID; const LLUUID& mID;
}; };
void LLInventoryPanel::onItemsCompletion()
{
if (mFolderRoot) mFolderRoot->updateMenu();
}
void LLInventoryPanel::openSelected() void LLInventoryPanel::openSelected()
{ {
@@ -707,6 +836,26 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
} }
void LLInventoryPanel::onFocusLost()
{
// inventory no longer handles cut/copy/paste/delete
if (LLEditMenuHandler::gEditMenuHandler == mFolderRoot)
{
LLEditMenuHandler::gEditMenuHandler = NULL;
}
LLPanel::onFocusLost();
}
void LLInventoryPanel::onFocusReceived()
{
// inventory now handles cut/copy/paste/delete
LLEditMenuHandler::gEditMenuHandler = mFolderRoot;
LLPanel::onFocusReceived();
}
void LLInventoryPanel::openAllFolders() void LLInventoryPanel::openAllFolders()
{ {
mFolderRoot->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN); mFolderRoot->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN);
@@ -757,6 +906,19 @@ void LLInventoryPanel::clearSelection()
void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action) void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action)
{ {
// Schedule updating the folder view context menu when all selected items become complete (STORM-373).
mCompletionObserver->reset();
for (std::deque<LLFolderViewItem*>::const_iterator it = items.begin(); it != items.end(); ++it)
{
LLUUID id = (*it)->getListener()->getUUID();
LLViewerInventoryItem* inv_item = mInventory->getItem(id);
if (inv_item && !inv_item->isFinished())
{
mCompletionObserver->watchItem(id);
}
}
LLFolderView* fv = getRootFolder(); LLFolderView* fv = getRootFolder();
if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename
{ {
@@ -808,3 +970,30 @@ void LLInventoryPanel::dumpSelectionInformation(void* user_data)
LLInventoryPanel* iv = (LLInventoryPanel*)user_data; LLInventoryPanel* iv = (LLInventoryPanel*)user_data;
iv->mFolderRoot->dumpSelectionInformation(); iv->mFolderRoot->dumpSelectionInformation();
} }
// static
LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
{
LLInventoryPanel* res = NULL;
LLInventoryView* floater_inventory = LLInventoryView::getActiveInventory();
if (!floater_inventory)
{
llwarns << "Could not find My Inventory floater" << llendl;
return FALSE;
}
res = floater_inventory ? floater_inventory->getActivePanel() : NULL;
if (res)
{
// Make sure the floater is not minimized (STORM-438).
if (floater_inventory && floater_inventory->isMinimized())
{
floater_inventory->setMinimized(FALSE);
}
}
else if (auto_open)
{
floater_inventory->open();
res = floater_inventory->getActivePanel();
}
return res;
}

View File

@@ -47,16 +47,13 @@
#include "lluictrlfactory.h" #include "lluictrlfactory.h"
#include <set> #include <set>
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLFolderView;
// Class LLInventoryView class LLFolderViewFolder;
// class LLFolderViewItem;
// This is the controller class specific for handling agent class LLInventoryFilter;
// inventory. It deals with the buttons and views used to navigate as
// well as controls the behavior of the overall object.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLInventoryModel; class LLInventoryModel;
class LLInvFVBridge; class LLInvFVBridge;
class LLInventoryFVBridgeBuilder;
class LLMenuBarGL; class LLMenuBarGL;
class LLCheckBoxCtrl; class LLCheckBoxCtrl;
class LLSpinCtrl; class LLSpinCtrl;
@@ -65,19 +62,21 @@ class LLTextBox;
class LLIconCtrl; class LLIconCtrl;
class LLSaveFolderState; class LLSaveFolderState;
class LLSearchEditor; class LLSearchEditor;
class LLInvPanelComplObserver;
class LLInventoryPanel : public LLPanel class LLInventoryPanel : public LLPanel
{ {
public: protected:
LLInventoryPanel(const std::string& name, LLInventoryPanel(const std::string& name,
const std::string& sort_order_setting, const std::string& sort_order_setting,
const LLRect& rect, const LLRect& rect,
LLInventoryModel* inventory, LLInventoryModel* inventory,
BOOL allow_multi_select, BOOL allow_multi_select,
LLView *parent_view = NULL); LLView *parent_view = NULL);
~LLInventoryPanel(); public:
virtual ~LLInventoryPanel();
public:
LLInventoryModel* getModel() { return mInventory; } LLInventoryModel* getModel() { return mInventory; }
BOOL postBuild(); BOOL postBuild();
@@ -93,6 +92,9 @@ public:
void* cargo_data, void* cargo_data,
EAcceptance* accept, EAcceptance* accept,
std::string& tooltip_msg); std::string& tooltip_msg);
// LLUICtrl methods
/*virtual*/ void onFocusLost();
/*virtual*/ void onFocusReceived();
// Call this method to set the selection. // Call this method to set the selection.
void openAllFolders(); void openAllFolders();
@@ -131,6 +133,11 @@ public:
void openSelected(); void openSelected();
void unSelectAll(); void unSelectAll();
static void onIdle(void* user_data);
// Find whichever inventory panel is active / on top.
// "Auto_open" determines if we open an inventory panel if none are open.
static LLInventoryPanel *getActiveInventoryPanel(BOOL auto_open = TRUE);
public: public:
// TomY TODO: Move this elsewhere? // TomY TODO: Move this elsewhere?
@@ -144,13 +151,27 @@ public:
U32 next_owner_perm = 0); U32 next_owner_perm = 0);
protected: protected:
void openStartFolderOrMyInventory(); // open the first level of inventory
void onItemsCompletion(); // called when selected items are complete
LLInventoryModel* mInventory; LLInventoryModel* mInventory;
LLInventoryObserver* mInventoryObserver; LLInventoryObserver* mInventoryObserver;
LLInvPanelComplObserver* mCompletionObserver;
BOOL mAllowMultiSelect; BOOL mAllowMultiSelect;
LLFolderView* mFolderRoot; LLFolderView* mFolderRoot;
LLScrollableContainerView* mScroller; LLScrollableContainerView* mScroller;
/**
* Pointer to LLInventoryFVBridgeBuilder.
*
* It is set in LLInventoryPanel's constructor and can be overridden in derived classes with
* another implementation.
* Take into account it will not be deleted by LLInventoryPanel itself.
*/
const LLInventoryFVBridgeBuilder* mInvFVBridgeBuilder;
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Sorting // Sorting
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@@ -162,21 +183,27 @@ public:
void setSortOrder(U32 order); void setSortOrder(U32 order);
U32 getSortOrder() const; U32 getSortOrder() const;
void requestSort();
static LLInventoryPanel *getActiveInventoryPanel();
private: private:
const std::string mSortOrderSetting; const std::string mSortOrderSetting;
LLUUID mSelectThisID; // if non null, select this item LLUUID mSelectThisID; // if non null, select this item
public: public:
BOOL getIsViewsInitialized() const { return mViewsInitialized; }
const LLUUID& getRootFolderID() const; const LLUUID& getRootFolderID() const;
protected: protected:
// Given the id and the parent, build all of the folder views. // Builds the UI. Call this once the inventory is usable.
LLFolderViewItem* rebuildViewsFor(const LLUUID& id, U32 mask); void initializeViews();
LLFolderViewItem* rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views.
virtual void buildFolderView();
LLFolderViewItem* buildNewViews(const LLUUID& id); LLFolderViewItem* buildNewViews(const LLUUID& id);
virtual LLFolderView* createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix);
virtual LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge); virtual LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge);
virtual LLFolderViewItem* createFolderViewItem(LLInvFVBridge * bridge); virtual LLFolderViewItem* createFolderViewItem(LLInvFVBridge * bridge);
BOOL mViewsInitialized; // Views have been generated
}; };
class LLInventoryView; class LLInventoryView;

View File

@@ -105,7 +105,7 @@ void LLLocalInventory::open(LLUUID item_id)
rect, rect,
"", "",
item_id, item_id,
0); LLPreviewAnim::NONE);
floaterp->setFocus(TRUE); floaterp->setFocus(TRUE);
gFloaterView->adjustToFitScreen(floaterp, FALSE); gFloaterView->adjustToFitScreen(floaterp, FALSE);
} }

View File

@@ -1434,7 +1434,7 @@ void LLTaskAnimationBridge::openItem()
rect, rect,
getName(), getName(),
mUUID, mUUID,
0, LLPreviewAnim::NONE,
mPanel->getTaskUUID()); mPanel->getTaskUUID());
preview->setFocus(TRUE); // take focus if you're looking at one of these preview->setFocus(TRUE); // take focus if you're looking at one of these

View File

@@ -51,55 +51,18 @@
extern LLAgent gAgent; extern LLAgent gAgent;
LLPreviewAnim::LLPreviewAnim(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const S32& activate, const LLUUID& object_uuid ) : LLPreviewAnim::LLPreviewAnim(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const e_activation_type& _activate, const LLUUID& object_uuid ) :
LLPreview( name, rect, title, item_uuid, object_uuid) LLPreview( name, rect, title, item_uuid, object_uuid)
{ {
LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_animation.xml"); mIsCopyable = false;
childSetAction("Anim play btn",playAnim,this);
childSetAction("Anim audition btn",auditionAnim,this);
const LLInventoryItem* item = getItem();
childSetCommitCallback("desc", LLPreview::onText, this);
childSetText("desc", item->getDescription());
childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
setTitle(title); setTitle(title);
LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_animation.xml");
if (!getHost()) if (!getHost())
{ {
LLRect curRect = getRect(); LLRect curRect = getRect();
translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop); translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop);
} }
activate(_activate);
mIsCopyable = false;
// preload the animation
if(item)
{
gAgentAvatarp->createMotion(item->getAssetUUID());
const LLPermissions& perm = item->getPermissions();
mIsCopyable = (perm.getCreator() == gAgent.getID());
}
switch ( activate )
{
case 1:
{
playAnim( (void *) this );
break;
}
case 2:
{
auditionAnim( (void *) this );
break;
}
default:
{
//do nothing
}
}
} }
// static // static
@@ -115,6 +78,50 @@ void LLPreviewAnim::endAnimCallback( void *userdata )
} }
} }
// virtual
BOOL LLPreviewAnim::postBuild()
{
const LLInventoryItem* item = getItem();
// preload the animation
if(item)
{
gAgentAvatarp->createMotion(item->getAssetUUID());
childSetText("desc", item->getDescription());
const LLPermissions& perm = item->getPermissions();
mIsCopyable = (perm.getCreator() == gAgent.getID());
}
childSetAction("Anim play btn",playAnim,this);
childSetAction("Anim audition btn",auditionAnim,this);
childSetCommitCallback("desc", LLPreview::onText, this);
childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
return LLPreview::postBuild();
}
void LLPreviewAnim::activate(e_activation_type type)
{
switch ( type )
{
case PLAY:
{
playAnim( (void *) this );
break;
}
case AUDITION:
{
auditionAnim( (void *) this );
break;
}
default:
{
//do nothing
}
}
}
// static // static
void LLPreviewAnim::playAnim( void *userdata ) void LLPreviewAnim::playAnim( void *userdata )
{ {
@@ -135,10 +142,7 @@ void LLPreviewAnim::playAnim( void *userdata )
{ {
self->mPauseRequest = NULL; self->mPauseRequest = NULL;
gAgent.sendAnimationRequest(itemID, ANIM_REQUEST_START); gAgent.sendAnimationRequest(itemID, ANIM_REQUEST_START);
LLMotion* motion = gAgentAvatarp->findMotion(itemID);
LLVOAvatar* avatar = gAgentAvatarp;
LLMotion* motion = avatar->findMotion(itemID);
if (motion) if (motion)
{ {
motion->setDeactivateCallback(&endAnimCallback, (void *)(new LLHandle<LLFloater>(self->getHandle()))); motion->setDeactivateCallback(&endAnimCallback, (void *)(new LLHandle<LLFloater>(self->getHandle())));
@@ -172,9 +176,7 @@ void LLPreviewAnim::auditionAnim( void *userdata )
{ {
self->mPauseRequest = NULL; self->mPauseRequest = NULL;
gAgentAvatarp->startMotion(item->getAssetUUID()); gAgentAvatarp->startMotion(item->getAssetUUID());
LLMotion* motion = gAgentAvatarp->findMotion(itemID);
LLVOAvatar* avatar = gAgentAvatarp;
LLMotion* motion = avatar->findMotion(itemID);
if (motion) if (motion)
{ {
@@ -434,9 +436,7 @@ void LLPreviewAnim::onClose(bool app_quitting)
{ {
gAgentAvatarp->stopMotion(item->getAssetUUID()); gAgentAvatarp->stopMotion(item->getAssetUUID());
gAgent.sendAnimationRequest(item->getAssetUUID(), ANIM_REQUEST_STOP); gAgent.sendAnimationRequest(item->getAssetUUID(), ANIM_REQUEST_STOP);
LLMotion* motion = gAgentAvatarp->findMotion(item->getAssetUUID());
LLVOAvatar* avatar = gAgentAvatarp;
LLMotion* motion = avatar->findMotion(item->getAssetUUID());
if (motion) if (motion)
{ {

View File

@@ -41,9 +41,10 @@ class AIFilePicker;
class LLPreviewAnim : public LLPreview class LLPreviewAnim : public LLPreview
{ {
public: public:
enum e_activation_type { NONE = 0, PLAY = 1, AUDITION = 2 };
LLPreviewAnim(const std::string& name, const LLRect& rect, const std::string& title, LLPreviewAnim(const std::string& name, const LLRect& rect, const std::string& title,
const LLUUID& item_uuid, const LLUUID& item_uuid,
const S32& activate, const e_activation_type& activate,
const LLUUID& object_uuid = LLUUID::null); const LLUUID& object_uuid = LLUUID::null);
static void playAnim( void* userdata ); static void playAnim( void* userdata );
@@ -65,6 +66,8 @@ public:
static void copyAnimID(void* userdata); static void copyAnimID(void* userdata);
// </edit> // </edit>
static void endAnimCallback( void *userdata ); static void endAnimCallback( void *userdata );
/*virtual*/ BOOL postBuild();
void activate(e_activation_type type);
protected: protected:
virtual void onClose(bool app_quitting); virtual void onClose(bool app_quitting);

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<menu bottom="100" color="MenuDefaultBgColor" drop_shadow="true" height="101" left="100" <menu bottom="100" color="MenuDefaultBgColor" drop_shadow="true" height="101" left="100"
mouse_opaque="false" name="Popup" opaque="true" width="128"> mouse_opaque="false" name="Popup" opaque="true" width="128">
<menu_item_call bottom_delta="-18" height="18" label="Buy" left="0" mouse_opaque="true" <menu_item_call bottom_delta="-18" height="18" label="Buy" left="0" mouse_opaque="true"
@@ -224,10 +224,11 @@
mouse_opaque="true" name="Replace Outfit" width="128"> mouse_opaque="true" name="Replace Outfit" width="128">
<on_click filter="" function="Inventory.DoToSelected" userdata="replaceoutfit" /> <on_click filter="" function="Inventory.DoToSelected" userdata="replaceoutfit" />
</menu_item_call> </menu_item_call>
<menu_item_call bottom_delta="-18" height="18" label="Take Off Items" left="0" <menu_item_call bottom_delta="-18" height="18" label="Remove From Outfit" left="0"
mouse_opaque="true" name="Take Off Items" width="128"> mouse_opaque="true" name="Remove From Outfit" width="128">
<on_click filter="" function="Inventory.DoToSelected" userdata="removefromoutfit" /> <on_click filter="" function="Inventory.DoToSelected" userdata="removefromoutfit" />
</menu_item_call> </menu_item_call>
<menu_item_separator name="Outfit Separator"></menu_item_separator>
<menu_item_separator name="Calling Card Separator" /> <menu_item_separator name="Calling Card Separator" />
<menu_item_call bottom_delta="-18" height="18" label="Start Conference Chat" left="0" <menu_item_call bottom_delta="-18" height="18" label="Start Conference Chat" left="0"
mouse_opaque="true" name="Conference Chat Folder" width="128"> mouse_opaque="true" name="Conference Chat Folder" width="128">
@@ -276,11 +277,11 @@
</menu_item_call> </menu_item_call>
<menu_item_separator name="Wearable And Object Separator" /> <menu_item_separator name="Wearable And Object Separator" />
<menu_item_call bottom_delta="-18" height="18" label="Wear" left="0" mouse_opaque="true" <menu_item_call bottom_delta="-18" height="18" label="Wear" left="0" mouse_opaque="true"
name="Wearable And Object Wear" width="128"> name="Object Wear" width="128">
<on_click filter="" function="Inventory.DoToSelected" userdata="attach" /> <on_click filter="" function="Inventory.DoToSelected" userdata="attach" />
</menu_item_call> </menu_item_call>
<menu_item_call bottom_delta="-18" height="18" label="Add to Worn" left="0" mouse_opaque="true" <menu_item_call bottom_delta="-18" height="18" label="Add to Worn" left="0" mouse_opaque="true"
name="Wearable Add" width="128"> name="Object Add" width="128">
<on_click filter="" function="Inventory.DoToSelected" userdata="wear_add" /> <on_click filter="" function="Inventory.DoToSelected" userdata="wear_add" />
</menu_item_call> </menu_item_call>
<menu bottom_delta="-18" height="18" label="Attach To" left="0" mouse_opaque="true" <menu bottom_delta="-18" height="18" label="Attach To" left="0" mouse_opaque="true"
@@ -297,7 +298,7 @@
<on_click filter="" function="Inventory.DoToSelected" userdata="edit" /> <on_click filter="" function="Inventory.DoToSelected" userdata="edit" />
</menu_item_call> </menu_item_call>
<menu_item_call bottom_delta="-18" height="18" label="Wear" left="0" mouse_opaque="true" <menu_item_call bottom_delta="-18" height="18" label="Wear" left="0" mouse_opaque="true"
name="Wearable Wear" width="128"> name="Wearable And Object Wear" width="128">
<on_click filter="" function="Inventory.DoToSelected" userdata="wear" /> <on_click filter="" function="Inventory.DoToSelected" userdata="wear" />
</menu_item_call> </menu_item_call>
<menu_item_call bottom_delta="-18" height="18" label="Take Off" left="0" mouse_opaque="true" <menu_item_call bottom_delta="-18" height="18" label="Take Off" left="0" mouse_opaque="true"