Newer
Older
/**
* @file llpanelmaininventory.cpp
* @brief Implementation of llpanelmaininventory.
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llpanelmaininventory.h"
Eric M. Tulla (BigPapi)
committed
#include "llagent.h"
#include "llagentcamera.h"
Eugene Mutavchi
committed
#include "llavataractions.h"
Dmitry Zaporozhan
committed
#include "lleconomy.h"
#include "llfilepicker.h"
#include "llfloaterinventory.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
Loren Shih
committed
#include "llinventorymodelbackgroundfetch.h"
#include "llinventorypanel.h"
#include "llfiltereditor.h"
#include "llfloatersidepanelcontainer.h"
Seth ProductEngine
committed
#include "llmenubutton.h"
Loren Shih
committed
#include "llresmgr.h"
#include "llscrollcontainer.h"
#include "llsdserialize.h"
#include "llspinctrl.h"
Seth ProductEngine
committed
#include "lltoggleablemenu.h"
#include "lltooldraganddrop.h"
#include "llviewermenu.h"
#include "llviewertexturelist.h"
Vladimir Pchelko
committed
#include "llsidepanelinventory.h"
#include "llfolderview.h"
Tofu Linden
committed
const std::string FILTERS_FILENAME("filters.xml");
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
static LLRegisterPanelClassWrapper<LLPanelMainInventory> t_inventory("panel_main_inventory");
void on_file_loaded_for_save(BOOL success,
LLViewerFetchedTexture *src_vi,
LLImageRaw* src,
LLImageRaw* aux_src,
S32 discard_level,
BOOL final,
void* userdata);
///----------------------------------------------------------------------------
/// LLFloaterInventoryFinder
///----------------------------------------------------------------------------
class LLFloaterInventoryFinder : public LLFloater
{
public:
LLFloaterInventoryFinder( LLPanelMainInventory* inventory_view);
virtual void draw();
/*virtual*/ BOOL postBuild();
void changeFilter(LLInventoryFilter* filter);
void updateElementsFromFilter();
BOOL getCheckShowEmpty();
BOOL getCheckSinceLogoff();
static void onTimeAgo(LLUICtrl*, void *);
static void onCloseBtn(void* user_data);
static void selectAllTypes(void* user_data);
static void selectNoTypes(void* user_data);
private:
LLPanelMainInventory* mPanelMainInventory;
LLSpinCtrl* mSpinSinceDays;
LLSpinCtrl* mSpinSinceHours;
LLInventoryFilter* mFilter;
};
///----------------------------------------------------------------------------
/// LLPanelMainInventory
///----------------------------------------------------------------------------
LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
: LLPanel(p),
mActivePanel(NULL),
mSavedFolderState(NULL),
mFilterText(""),
mMenuGearDefault(NULL),
Dmitry Zaporozhan
committed
mMenuAdd(NULL),
mNeedUploadCost(true)
{
LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_INIT);
// Menu Callbacks (non contex menus)
mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelMainInventory::doToSelected, this, _2));
mCommitCallbackRegistrar.add("Inventory.CloseAllFolders", boost::bind(&LLPanelMainInventory::closeAllFolders, this));
mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH));
mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND));
mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLPanelMainInventory::doCreate, this, _2));
//mCommitCallbackRegistrar.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow, this));
mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this));
mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this));
mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2));
Eugene Mutavchi
committed
mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars));
mSavedFolderState = new LLSaveFolderState();
mSavedFolderState->setApply(FALSE);
}
BOOL LLPanelMainInventory::postBuild()
{
gInventory.addObserver(this);
mFilterTabs = getChild<LLTabContainer>("inventory filter tabs");
mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this));
//panel->getFilter()->markDefault();
// Set up the default inv. panel/filter settings.
mActivePanel = getChild<LLInventoryPanel>("All Items");
if (mActivePanel)
{
// "All Items" is the previous only view, so it gets the InventorySortOrder
mActivePanel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER));
mActivePanel->getFilter()->markDefault();
mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
mActivePanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mActivePanel, _1, _2));
mResortActivePanel = true;
}
LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
if (recent_items_panel)
{
recent_items_panel->setSinceLogoff(TRUE);
recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
recent_items_panel->getFilter()->markDefault();
recent_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, recent_items_panel, _1, _2));
}
// Now load the stored settings from disk, if available.
std::ostringstream filterSaveName;
Tofu Linden
committed
filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME);
Mike Antipov
committed
llinfos << "LLPanelMainInventory::init: reading from " << filterSaveName.str() << llendl;
llifstream file(filterSaveName.str());
LLSD savedFilterState;
if (file.is_open())
{
LLSDSerialize::fromXML(savedFilterState, file);
file.close();
// Load the persistent "Recent Items" settings.
// Note that the "All Items" settings do not persist.
if(recent_items_panel)
{
if(savedFilterState.has(recent_items_panel->getFilter()->getName()))
{
LLSD recent_items = savedFilterState.get(
recent_items_panel->getFilter()->getName());
LLInventoryFilter::Params p;
LLParamSDParser parser;
parser.readSD(recent_items, p);
recent_items_panel->getFilter()->fromParams(p);
}
}
}
mFilterEditor = getChild<LLFilterEditor>("inventory search editor");
if (mFilterEditor)
{
mFilterEditor->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterEdit, this, _2));
}
Seth ProductEngine
committed
mGearMenuButton = getChild<LLMenuButton>("options_gear_btn");
// *TODO:Get the cost info from the server
const std::string upload_cost("10");
mMenuAdd->getChild<LLMenuItemGL>("Upload Image")->setLabelArg("[COST]", upload_cost);
mMenuAdd->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", upload_cost);
mMenuAdd->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", upload_cost);
mMenuAdd->getChild<LLMenuItemGL>("Bulk Upload")->setLabelArg("[COST]", upload_cost);
// Trigger callback for focus received so we can deselect items in inbox/outbox
LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMainInventory::onFocusReceived, this));
return TRUE;
}
// Destroys the object
LLPanelMainInventory::~LLPanelMainInventory( void )
{
// Save the filters state.
LLSD filterRoot;
LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items");
if (all_items_panel)
{
LLInventoryFilter* filter = all_items_panel->getFilter();
if (filter)
{
LLSD filterState;
LLInventoryFilter::Params p;
filter->toParams(p);
if (p.validateBlock(false))
{
LLParamSDParser().writeSD(filterState, p);
filterRoot[filter->getName()] = filterState;
}
}
}
LLInventoryFilter* filter = getChild<LLInventoryPanel>("Recent Items")->getFilter();
if (filter)
{
LLSD filterState;
filter->toLLSD(filterState);
filterRoot[filter->getName()] = filterState;
}
std::ostringstream filterSaveName;
Tofu Linden
committed
filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME);
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
llofstream filtersFile(filterSaveName.str());
if(!LLSDSerialize::toPrettyXML(filterRoot, filtersFile))
{
llwarns << "Could not write to filters save file " << filterSaveName << llendl;
}
else
filtersFile.close();
gInventory.removeObserver(this);
delete mSavedFolderState;
}
void LLPanelMainInventory::startSearch()
{
// this forces focus to line editor portion of search editor
if (mFilterEditor)
{
mFilterEditor->focusFirstItem(TRUE);
}
}
BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask)
{
LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL;
if (root_folder)
{
// first check for user accepting current search results
if (mFilterEditor
&& mFilterEditor->hasFocus()
&& (key == KEY_RETURN
|| key == KEY_DOWN)
&& mask == MASK_NONE)
{
// move focus to inventory proper
mActivePanel->setFocus(TRUE);
root_folder->scrollToShowSelection();
return TRUE;
}
if (mActivePanel->hasFocus() && key == KEY_UP)
{
startSearch();
}
}
return LLPanel::handleKeyHere(key, mask);
}
//----------------------------------------------------------------------------
// menu callbacks
void LLPanelMainInventory::doToSelected(const LLSD& userdata)
{
getPanel()->getRootFolder()->doToSelected(&gInventory, userdata);
}
void LLPanelMainInventory::closeAllFolders()
{
getPanel()->getRootFolder()->closeAllFolders();
}
void LLPanelMainInventory::newWindow()
{
static S32 instance_num = 0;
instance_num = (instance_num + 1) % S32_MAX;
if (!gAgentCamera.cameraMouselook())
{
LLFloaterReg::showTypedInstance<LLFloaterSidePanelContainer>("inventory", LLSD(instance_num));
}
}
void LLPanelMainInventory::doCreate(const LLSD& userdata)
{
menu_create_inventory_item(getPanel(), NULL, userdata);
}
void LLPanelMainInventory::resetFilters()
{
LLFloaterInventoryFinder *finder = getFinder();
getActivePanel()->getFilter()->resetDefault();
if (finder)
{
finder->updateElementsFromFilter();
}
setFilterTextFromFilter();
}
void LLPanelMainInventory::setSortBy(const LLSD& userdata)
{
U32 sort_order_mask = getActivePanel()->getSortOrder();
std::string sort_type = userdata.asString();
if (sort_type == "name")
sort_order_mask &= ~LLInventoryFilter::SO_DATE;
else if (sort_type == "date")
sort_order_mask |= LLInventoryFilter::SO_DATE;
else if (sort_type == "foldersalwaysbyname")
if ( sort_order_mask & LLInventoryFilter::SO_FOLDERS_BY_NAME )
sort_order_mask &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME;
sort_order_mask |= LLInventoryFilter::SO_FOLDERS_BY_NAME;
else if (sort_type == "systemfolderstotop")
if ( sort_order_mask & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP )
sort_order_mask &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
sort_order_mask |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
getActivePanel()->setSortOrder(sort_order_mask);
gSavedSettings.setU32("InventorySortOrder", sort_order_mask);
}
// static
BOOL LLPanelMainInventory::filtersVisible(void* user_data)
{
LLPanelMainInventory* self = (LLPanelMainInventory*)user_data;
if(!self) return FALSE;
return self->getFinder() != NULL;
}
void LLPanelMainInventory::onClearSearch()
{
LLFloater *finder = getFinder();
if (mActivePanel)
{
mActivePanel->setFilterSubString(LLStringUtil::null);
mActivePanel->setFilterTypes(0xffffffffffffffffULL);
mActivePanel->setFilterLinks(LLInventoryFilter::FILTERLINK_INCLUDE_LINKS);
}
if (finder)
{
LLFloaterInventoryFinder::selectAllTypes(finder);
}
// re-open folders that were initially open
if (mActivePanel)
{
mSavedFolderState->setApply(TRUE);
mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
LLOpenFoldersWithSelection opener;
mActivePanel->getRootFolder()->applyFunctorRecursively(opener);
mActivePanel->getRootFolder()->scrollToShowSelection();
}
Brad Payne (Vir Linden)
committed
mFilterSubString = "";
}
void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
{
if (search_string == "")
{
onClearSearch();
}
if (!mActivePanel)
{
return;
}
Loren Shih
committed
LLInventoryModelBackgroundFetch::instance().start();
mFilterSubString = search_string;
if (mActivePanel->getFilterSubString().empty() && mFilterSubString.empty())
{
// current filter and new filter empty, do nothing
return;
}
// save current folder open state if no filter currently applied
if (!mActivePanel->getFilter()->isNotDefault())
{
mSavedFolderState->setApply(FALSE);
mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
}
// set new filter string
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
}
//static
BOOL LLPanelMainInventory::incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward)
{
LLPanelMainInventory* active_view = NULL;
LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
{
LLPanelMainInventory* iv = dynamic_cast<LLPanelMainInventory*>(*iter);
if (iv)
{
if (gFocusMgr.childHasKeyboardFocus(iv))
{
active_view = iv;
break;
}
}
}
if (!active_view)
{
return FALSE;
}
std::string search_string(find_text);
if (search_string.empty())
{
return FALSE;
}
if (active_view->getPanel() &&
active_view->getPanel()->getRootFolder()->search(first_item, search_string, backward))
{
return TRUE;
}
return FALSE;
}
void LLPanelMainInventory::onFilterSelected()
{
// Find my index
mActivePanel = (LLInventoryPanel*)getChild<LLTabContainer>("inventory filter tabs")->getCurrentPanel();
if (!mActivePanel)
{
return;
}
Mike Antipov
committed
Brad Payne (Vir Linden)
committed
setFilterSubString(mFilterSubString);
LLInventoryFilter* filter = mActivePanel->getFilter();
LLFloaterInventoryFinder *finder = getFinder();
if (finder)
{
finder->changeFilter(filter);
}
if (filter->isActive())
{
// If our filter is active we may be the first thing requiring a fetch so we better start it here.
Loren Shih
committed
LLInventoryModelBackgroundFetch::instance().start();
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
}
setFilterTextFromFilter();
}
const std::string LLPanelMainInventory::getFilterSubString()
{
return mActivePanel->getFilterSubString();
}
void LLPanelMainInventory::setFilterSubString(const std::string& string)
{
mActivePanel->setFilterSubString(string);
}
BOOL LLPanelMainInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg)
{
// Check to see if we are auto scrolling from the last frame
LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel();
BOOL needsToScroll = panel->getScrollableContainer()->autoScroll(x, y);
if(mFilterTabs)
{
if(needsToScroll)
{
mFilterTabs->startDragAndDropDelayTimer();
}
}
BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
return handled;
}
// virtual
void LLPanelMainInventory::changed(U32)
Loren Shih
committed
updateItemcountText();
// virtual
void LLPanelMainInventory::draw()
{
if (mActivePanel && mFilterEditor)
{
Brad Payne (Vir Linden)
committed
mFilterEditor->setText(mFilterSubString);
if (mActivePanel && mResortActivePanel)
{
// EXP-756: Force resorting of the list the first time we draw the list:
// In the case of date sorting, we don't have enough information at initialization time
// to correctly sort the folders. Later manual resort doesn't do anything as the order value is
// set correctly. The workaround is to reset the order to alphabetical (or anything) then to the correct order.
U32 order = mActivePanel->getSortOrder();
mActivePanel->setSortOrder(LLInventoryFilter::SO_NAME);
mActivePanel->setSortOrder(order);
mResortActivePanel = false;
}
Loren Shih
committed
updateItemcountText();
}
void LLPanelMainInventory::updateItemcountText()
{
// *TODO: Calling setlocale() on each frame may be inefficient.
LLLocale locale(LLStringUtil::getLocale());
Loren Shih
committed
std::string item_count_string;
LLResMgr::getInstance()->getIntegerString(item_count_string, gInventory.getItemCount());
LLStringUtil::format_map_t string_args;
string_args["[ITEM_COUNT]"] = item_count_string;
string_args["[FILTER]"] = getFilterText();
std::string text = "";
Richard Linden
committed
if (LLInventoryModelBackgroundFetch::instance().folderFetchActive())
Loren Shih
committed
{
text = getString("ItemcountFetching", string_args);
}
Loren Shih
committed
else if (LLInventoryModelBackgroundFetch::instance().isEverythingFetched())
Loren Shih
committed
{
text = getString("ItemcountCompleted", string_args);
}
else
{
text = getString("ItemcountUnknown");
}
Leslie Linden
committed
// *TODO: Cache the LLUICtrl* for the ItemcountText control
getChild<LLUICtrl>("ItemcountText")->setValue(text);
void LLPanelMainInventory::onFocusReceived()
{
Leslie Linden
committed
LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
if (!sidepanel_inventory)
{
llwarns << "Could not find Inventory Panel in My Inventory floater" << llendl;
return;
}
sidepanel_inventory->clearSelections(false, true);
void LLPanelMainInventory::setFilterTextFromFilter()
{
mFilterText = mActivePanel->getFilter()->getFilterText();
}
void LLPanelMainInventory::toggleFindOptions()
{
LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_TOGGLE);
LLFloater *floater = getFinder();
if (!floater)
{
LLFloaterInventoryFinder * finder = new LLFloaterInventoryFinder(this);
mFinderHandle = finder->getHandle();
finder->openFloater();
LLFloater* parent_floater = gFloaterView->getParentFloater(this);
parent_floater->addDependentFloater(mFinderHandle);
// start background fetch of folders
Loren Shih
committed
LLInventoryModelBackgroundFetch::instance().start();
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
}
else
{
floater->closeFloater();
}
}
void LLPanelMainInventory::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)
{
getChild<LLInventoryPanel>("All Items")->setSelectCallback(cb);
getChild<LLInventoryPanel>("Recent Items")->setSelectCallback(cb);
}
void LLPanelMainInventory::onSelectionChange(LLInventoryPanel *panel, const std::deque<LLFolderViewItem*>& items, BOOL user_action)
{
updateListCommands();
panel->onSelectionChange(items, user_action);
}
///----------------------------------------------------------------------------
/// LLFloaterInventoryFinder
///----------------------------------------------------------------------------
LLFloaterInventoryFinder* LLPanelMainInventory::getFinder()
{
return (LLFloaterInventoryFinder*)mFinderHandle.get();
}
LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view) :
LLFloater(LLSD()),
mPanelMainInventory(inventory_view),
mFilter(inventory_view->getPanel()->getFilter())
{
buildFromFile("floater_inventory_view_finder.xml");
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
updateElementsFromFilter();
}
BOOL LLFloaterInventoryFinder::postBuild()
{
const LLRect& viewrect = mPanelMainInventory->getRect();
setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight()));
childSetAction("All", selectAllTypes, this);
childSetAction("None", selectNoTypes, this);
mSpinSinceHours = getChild<LLSpinCtrl>("spin_hours_ago");
childSetCommitCallback("spin_hours_ago", onTimeAgo, this);
mSpinSinceDays = getChild<LLSpinCtrl>("spin_days_ago");
childSetCommitCallback("spin_days_ago", onTimeAgo, this);
childSetAction("Close", onCloseBtn, this);
updateElementsFromFilter();
return TRUE;
}
void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data)
{
LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
if (!self) return;
if ( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() )
{
Paul ProductEngine
committed
self->getChild<LLUICtrl>("check_since_logoff")->setValue(false);
}
}
void LLFloaterInventoryFinder::changeFilter(LLInventoryFilter* filter)
{
mFilter = filter;
updateElementsFromFilter();
}
void LLFloaterInventoryFinder::updateElementsFromFilter()
{
if (!mFilter)
return;
// Get data needed for filter display
U32 filter_types = mFilter->getFilterObjectTypes();
std::string filter_string = mFilter->getFilterSubString();
LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState();
U32 hours = mFilter->getHoursAgo();
// update the ui elements
setTitle(mFilter->getName());
getChild<LLUICtrl>("check_animation")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION));
getChild<LLUICtrl>("check_calling_card")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD));
getChild<LLUICtrl>("check_clothing")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
getChild<LLUICtrl>("check_gesture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
getChild<LLUICtrl>("check_landmark")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
getChild<LLUICtrl>("check_mesh")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MESH));
getChild<LLUICtrl>("check_notecard")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
getChild<LLUICtrl>("check_object")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
getChild<LLUICtrl>("check_script")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
getChild<LLUICtrl>("check_sound")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND));
getChild<LLUICtrl>("check_texture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE));
getChild<LLUICtrl>("check_snapshot")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT));
getChild<LLUICtrl>("check_show_empty")->setValue(show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS);
getChild<LLUICtrl>("check_since_logoff")->setValue(mFilter->isSinceLogoff());
mSpinSinceHours->set((F32)(hours % 24));
mSpinSinceDays->set((F32)(hours / 24));
}
void LLFloaterInventoryFinder::draw()
{
LLMemType mt(LLMemType::MTYPE_INVENTORY_DRAW);
U64 filter = 0xffffffffffffffffULL;
BOOL filtered_by_all_types = TRUE;
if (!getChild<LLUICtrl>("check_animation")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_ANIMATION);
filtered_by_all_types = FALSE;
}
if (!getChild<LLUICtrl>("check_calling_card")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD);
filtered_by_all_types = FALSE;
}
if (!getChild<LLUICtrl>("check_clothing")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_WEARABLE);
filtered_by_all_types = FALSE;
}
if (!getChild<LLUICtrl>("check_gesture")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_GESTURE);
filtered_by_all_types = FALSE;
}
if (!getChild<LLUICtrl>("check_landmark")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_LANDMARK);
filtered_by_all_types = FALSE;
}
if (!getChild<LLUICtrl>("check_mesh")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_MESH);
filtered_by_all_types = FALSE;
}
if (!getChild<LLUICtrl>("check_notecard")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
filtered_by_all_types = FALSE;
}
if (!getChild<LLUICtrl>("check_object")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_OBJECT);
filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT);
filtered_by_all_types = FALSE;
}
if (!getChild<LLUICtrl>("check_script")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_LSL);
filtered_by_all_types = FALSE;
}
if (!getChild<LLUICtrl>("check_sound")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_SOUND);
filtered_by_all_types = FALSE;
}
if (!getChild<LLUICtrl>("check_texture")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_TEXTURE);
filtered_by_all_types = FALSE;
}
if (!getChild<LLUICtrl>("check_snapshot")->getValue())
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
{
filter &= ~(0x1 << LLInventoryType::IT_SNAPSHOT);
filtered_by_all_types = FALSE;
}
if (!filtered_by_all_types)
{
// don't include folders in filter, unless I've selected everything
filter &= ~(0x1 << LLInventoryType::IT_CATEGORY);
}
// update the panel, panel will update the filter
mPanelMainInventory->getPanel()->setShowFolderState(getCheckShowEmpty() ?
LLInventoryFilter::SHOW_ALL_FOLDERS : LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
mPanelMainInventory->getPanel()->setFilterTypes(filter);
if (getCheckSinceLogoff())
{
mSpinSinceDays->set(0);
mSpinSinceHours->set(0);
}
U32 days = (U32)mSpinSinceDays->get();
U32 hours = (U32)mSpinSinceHours->get();
if (hours > 24)
{
days += hours / 24;
hours = (U32)hours % 24;
mSpinSinceDays->set((F32)days);
mSpinSinceHours->set((F32)hours);
}
hours += days * 24;
mPanelMainInventory->getPanel()->setHoursAgo(hours);
mPanelMainInventory->getPanel()->setSinceLogoff(getCheckSinceLogoff());
mPanelMainInventory->setFilterTextFromFilter();
LLPanel::draw();
}
BOOL LLFloaterInventoryFinder::getCheckShowEmpty()
{
return getChild<LLUICtrl>("check_show_empty")->getValue();
}
BOOL LLFloaterInventoryFinder::getCheckSinceLogoff()
{
return getChild<LLUICtrl>("check_since_logoff")->getValue();
}
void LLFloaterInventoryFinder::onCloseBtn(void* user_data)
{
LLFloaterInventoryFinder* finderp = (LLFloaterInventoryFinder*)user_data;
finderp->closeFloater();
}
// static
void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
{
LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
if(!self) return;
self->getChild<LLUICtrl>("check_animation")->setValue(TRUE);
self->getChild<LLUICtrl>("check_calling_card")->setValue(TRUE);
self->getChild<LLUICtrl>("check_clothing")->setValue(TRUE);
self->getChild<LLUICtrl>("check_gesture")->setValue(TRUE);
self->getChild<LLUICtrl>("check_landmark")->setValue(TRUE);
self->getChild<LLUICtrl>("check_mesh")->setValue(TRUE);
self->getChild<LLUICtrl>("check_notecard")->setValue(TRUE);
self->getChild<LLUICtrl>("check_object")->setValue(TRUE);
self->getChild<LLUICtrl>("check_script")->setValue(TRUE);
self->getChild<LLUICtrl>("check_sound")->setValue(TRUE);
self->getChild<LLUICtrl>("check_texture")->setValue(TRUE);
self->getChild<LLUICtrl>("check_snapshot")->setValue(TRUE);
}
//static
void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
{
LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
if(!self) return;
self->getChild<LLUICtrl>("check_animation")->setValue(FALSE);
self->getChild<LLUICtrl>("check_calling_card")->setValue(FALSE);
self->getChild<LLUICtrl>("check_clothing")->setValue(FALSE);
self->getChild<LLUICtrl>("check_gesture")->setValue(FALSE);
self->getChild<LLUICtrl>("check_landmark")->setValue(FALSE);
self->getChild<LLUICtrl>("check_mesh")->setValue(FALSE);
self->getChild<LLUICtrl>("check_notecard")->setValue(FALSE);
self->getChild<LLUICtrl>("check_object")->setValue(FALSE);
self->getChild<LLUICtrl>("check_script")->setValue(FALSE);
self->getChild<LLUICtrl>("check_sound")->setValue(FALSE);
self->getChild<LLUICtrl>("check_texture")->setValue(FALSE);
self->getChild<LLUICtrl>("check_snapshot")->setValue(FALSE);
}
//////////////////////////////////////////////////////////////////////////////////
// List Commands //
void LLPanelMainInventory::initListCommandsHandlers()
{
Andrew Polunin
committed
childSetAction("trash_btn", boost::bind(&LLPanelMainInventory::onTrashButtonClick, this));
childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this));
Andrew Polunin
committed
mTrashButton = getChild<LLDragAndDropButton>("trash_btn");
mTrashButton->setDragAndDropHandler(boost::bind(&LLPanelMainInventory::handleDragAndDropToTrash, this
, _4 // BOOL drop
, _5 // EDragAndDropType cargo_type
, _7 // EAcceptance* accept
));
mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2));
Seth ProductEngine
committed
mEnableCallbackRegistrar.add("Inventory.GearDefault.Check", boost::bind(&LLPanelMainInventory::isActionChecked, this, _2));
mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
Seth ProductEngine
committed
mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
Seth ProductEngine
committed
mGearMenuButton->setMenu(mMenuGearDefault);
mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
// Update the trash button when selected item(s) get worn or taken off.
LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this));
}
void LLPanelMainInventory::updateListCommands()
{
bool trash_enabled = isActionEnabled("delete");
Andrew Polunin
committed
mTrashButton->setEnabled(trash_enabled);
}
void LLPanelMainInventory::onAddButtonClick()
{
// Gray out the "New Folder" option when the Recent tab is active as new folders will not be displayed
// unless "Always show folders" is checked in the filter options.
bool recent_active = ("Recent Items" == mActivePanel->getName());
mMenuAdd->getChild<LLMenuItemGL>("New Folder")->setEnabled(!recent_active);
Jonathan Yap
committed
Dmitry Zaporozhan
committed
setUploadCostIfNeeded();
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
showActionMenu(mMenuAdd,"add_btn");
}
void LLPanelMainInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name)
{
if (menu)
{
menu->buildDrawLabels();
menu->updateParent(LLMenuGL::sMenuContainer);
LLView* spawning_view = getChild<LLView> (spawning_view_name);
S32 menu_x, menu_y;
//show menu in co-ordinates of panel
spawning_view->localPointToOtherView(0, spawning_view->getRect().getHeight(), &menu_x, &menu_y, this);
menu_y += menu->getRect().getHeight();
LLMenuGL::showPopup(this, menu, menu_x, menu_y);
}
}
void LLPanelMainInventory::onTrashButtonClick()
{
onClipboardAction("delete");
}
void LLPanelMainInventory::onClipboardAction(const LLSD& userdata)
{
std::string command_name = userdata.asString();
getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
}
void LLPanelMainInventory::saveTexture(const LLSD& userdata)
{
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
if (!current_item)
{
return;
}
const LLUUID& item_id = current_item->getViewModelItem()->getUUID();
LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item_id), TAKE_FOCUS_YES);
if (preview_texture)
{
preview_texture->openToSave();
}
}
void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
{
if (!isActionEnabled(userdata))
return;
const std::string command_name = userdata.asString();
if (command_name == "new_window")
{
newWindow();
}
if (command_name == "sort_by_name")
{
const LLSD arg = "name";