diff options
Diffstat (limited to 'indra/newview/llpanelmaininventory.cpp')
-rw-r--r-- | indra/newview/llpanelmaininventory.cpp | 1843 |
1 files changed, 1025 insertions, 818 deletions
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 25be09fa24..15a75cb930 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -1,818 +1,1025 @@ -/** - * @file llsidepanelmaininventory.cpp - * @brief Implementation of llsidepanelmaininventory. - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" -#include "llpanelmaininventory.h" - -#include "llfloaterinventory.h" -#include "llinventorybridge.h" -#include "llinventoryfunctions.h" -#include "llinventorypanel.h" -#include "llfiltereditor.h" -#include "llfloaterreg.h" -#include "llscrollcontainer.h" -#include "llsdserialize.h" -#include "llspinctrl.h" -#include "lltooldraganddrop.h" - -static LLRegisterPanelClassWrapper<LLPanelMainInventory> t_inventory("panel_main_inventory"); // Seraph is this redundant with constructor? - -///---------------------------------------------------------------------------- -/// 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 onCheckSinceLogoff(LLUICtrl*, void *); - static void onCloseBtn(void* user_data); - static void selectAllTypes(void* user_data); - static void selectNoTypes(void* user_data); -private: - LLPanelMainInventory* mPanelInventoryDecorated; - LLSpinCtrl* mSpinSinceDays; - LLSpinCtrl* mSpinSinceHours; - LLInventoryFilter* mFilter; -}; - -///---------------------------------------------------------------------------- -/// LLPanelMainInventory -///---------------------------------------------------------------------------- - -LLPanelMainInventory::LLPanelMainInventory() - : LLPanel() -{ - 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)); - - // Controls - // *TODO: Just use persistant settings for each of these - U32 sort_order = gSavedSettings.getU32("InventorySortOrder"); - BOOL sort_by_name = ! ( sort_order & LLInventoryFilter::SO_DATE ); - BOOL sort_folders_by_name = ( sort_order & LLInventoryFilter::SO_FOLDERS_BY_NAME ); - BOOL sort_system_folders_to_top = ( sort_order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP ); - - gSavedSettings.declareBOOL("Inventory.SortByName", sort_by_name, "Declared in code", FALSE); - gSavedSettings.declareBOOL("Inventory.SortByDate", !sort_by_name, "Declared in code", FALSE); - gSavedSettings.declareBOOL("Inventory.FoldersAlwaysByName", sort_folders_by_name, "Declared in code", FALSE); - gSavedSettings.declareBOOL("Inventory.SystemFoldersToTop", sort_system_folders_to_top, "Declared in code", FALSE); - - 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("InventorySortOrder")); - mActivePanel->getFilter()->markDefault(); - mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); - mActivePanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mActivePanel, _1, _2)); - } - 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(&LLInventoryPanel::onSelectionChange, recent_items_panel, _1, _2)); - } - - // Now load the stored settings from disk, if available. - std::ostringstream filterSaveName; - filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml"); - llinfos << "LLPanelMainInventory::init: reading from " << filterSaveName << 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()); - recent_items_panel->getFilter()->fromLLSD(recent_items); - } - } - - } - - - mFilterEditor = getChild<LLFilterEditor>("inventory search editor"); - if (mFilterEditor) - { - mFilterEditor->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterEdit, this, _2)); - } - - // *TODO:Get the cost info from the server - const std::string upload_cost("10"); - childSetLabelArg("Upload Image", "[COST]", upload_cost); - childSetLabelArg("Upload Sound", "[COST]", upload_cost); - childSetLabelArg("Upload Animation", "[COST]", upload_cost); - childSetLabelArg("Bulk Upload", "[COST]", upload_cost); - - 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; - filter->toLLSD(filterState); - filterRoot[filter->getName()] = filterState; - } - } - - LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items"); - if (recent_items_panel) - { - LLInventoryFilter* filter = recent_items_panel->getFilter(); - if (filter) - { - LLSD filterState; - filter->toLLSD(filterState); - filterRoot[filter->getName()] = filterState; - } - } - - std::ostringstream filterSaveName; - filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml"); - 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() -{ - LLFloaterInventory::showAgentInventory(); -} - -void LLPanelMainInventory::doCreate(const LLSD& userdata) -{ - menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata); -} - -void LLPanelMainInventory::resetFilters() -{ - LLFloaterInventoryFinder *finder = getFinder(); - getActivePanel()->getFilter()->resetDefault(); - if (finder) - { - finder->updateElementsFromFilter(); - } - - setFilterTextFromFilter(); -} - -void LLPanelMainInventory::setSortBy(const LLSD& userdata) -{ - std::string sort_field = userdata.asString(); - if (sort_field == "name") - { - U32 order = getActivePanel()->getSortOrder(); - getActivePanel()->setSortOrder( order & ~LLInventoryFilter::SO_DATE ); - - gSavedSettings.setBOOL("Inventory.SortByName", TRUE ); - gSavedSettings.setBOOL("Inventory.SortByDate", FALSE ); - } - else if (sort_field == "date") - { - U32 order = getActivePanel()->getSortOrder(); - getActivePanel()->setSortOrder( order | LLInventoryFilter::SO_DATE ); - - gSavedSettings.setBOOL("Inventory.SortByName", FALSE ); - gSavedSettings.setBOOL("Inventory.SortByDate", TRUE ); - } - else if (sort_field == "foldersalwaysbyname") - { - U32 order = getActivePanel()->getSortOrder(); - if ( order & LLInventoryFilter::SO_FOLDERS_BY_NAME ) - { - order &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME; - - gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", FALSE ); - } - else - { - order |= LLInventoryFilter::SO_FOLDERS_BY_NAME; - - gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", TRUE ); - } - getActivePanel()->setSortOrder( order ); - } - else if (sort_field == "systemfolderstotop") - { - U32 order = getActivePanel()->getSortOrder(); - if ( order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP ) - { - order &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; - - gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", FALSE ); - } - else - { - order |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; - - gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", TRUE ); - } - getActivePanel()->setSortOrder( order ); - } -} - -// 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(0xffffffff); - } - - 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(); - } -} - -void LLPanelMainInventory::onFilterEdit(const std::string& search_string ) -{ - if (search_string == "") - { - onClearSearch(); - } - if (!mActivePanel) - { - return; - } - - gInventory.startBackgroundFetch(); - - std::string uppercase_search_string = search_string; - LLStringUtil::toUpper(uppercase_search_string); - if (mActivePanel->getFilterSubString().empty() && uppercase_search_string.empty()) - { - // current filter and new filter empty, do nothing - return; - } - - // save current folder open state if no filter currently applied - if (!mActivePanel->getRootFolder()->isFilterModified()) - { - mSavedFolderState->setApply(FALSE); - mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); - } - - // set new filter string - mActivePanel->setFilterSubString(uppercase_search_string); -} - - - //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*)childGetVisibleTab("inventory filter tabs"); - - if (!mActivePanel) - { - return; - } - 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. - gInventory.startBackgroundFetch(); - } - 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; -} - -void LLPanelMainInventory::changed(U32 mask) -{ -} - - -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); - if (parent_floater) // Seraph: Fix this, shouldn't be null even for sidepanel - parent_floater->addDependentFloater(mFinderHandle); - // start background fetch of folders - gInventory.startBackgroundFetch(); - } - 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); -} - -///---------------------------------------------------------------------------- -/// LLFloaterInventoryFinder -///---------------------------------------------------------------------------- - -LLFloaterInventoryFinder* LLPanelMainInventory::getFinder() -{ - return (LLFloaterInventoryFinder*)mFinderHandle.get(); -} - - -LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view) : - LLFloater(LLSD()), - mPanelInventoryDecorated(inventory_view), - mFilter(inventory_view->getPanel()->getFilter()) -{ - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory_view_finder.xml", NULL); - updateElementsFromFilter(); -} - - -void LLFloaterInventoryFinder::onCheckSinceLogoff(LLUICtrl *ctrl, void *user_data) -{ - LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data; - if (!self) return; - - bool since_logoff= self->childGetValue("check_since_logoff"); - - if (!since_logoff && - !( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() ) ) - { - self->mSpinSinceHours->set(1.0f); - } -} -BOOL LLFloaterInventoryFinder::postBuild() -{ - const LLRect& viewrect = mPanelInventoryDecorated->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); - - // mCheckSinceLogoff = getChild<LLSpinCtrl>("check_since_logoff"); - childSetCommitCallback("check_since_logoff", onCheckSinceLogoff, this); - - childSetAction("Close", onCloseBtn, this); - - updateElementsFromFilter(); - return TRUE; -} -void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data) -{ - LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data; - if (!self) return; - - bool since_logoff=true; - if ( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() ) - { - since_logoff = false; - } - self->childSetValue("check_since_logoff", since_logoff); -} - -void LLFloaterInventoryFinder::changeFilter(LLInventoryFilter* filter) -{ - mFilter = filter; - updateElementsFromFilter(); -} - -void LLFloaterInventoryFinder::updateElementsFromFilter() -{ - if (!mFilter) - return; - - // Get data needed for filter display - U32 filter_types = mFilter->getFilterTypes(); - std::string filter_string = mFilter->getFilterSubString(); - LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState(); - U32 hours = mFilter->getHoursAgo(); - - // update the ui elements - setTitle(mFilter->getName()); - - childSetValue("check_animation", (S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION)); - - childSetValue("check_calling_card", (S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD)); - childSetValue("check_clothing", (S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE)); - childSetValue("check_gesture", (S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE)); - childSetValue("check_landmark", (S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK)); - childSetValue("check_notecard", (S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD)); - childSetValue("check_object", (S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT)); - childSetValue("check_script", (S32) (filter_types & 0x1 << LLInventoryType::IT_LSL)); - childSetValue("check_sound", (S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND)); - childSetValue("check_texture", (S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE)); - childSetValue("check_snapshot", (S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT)); - childSetValue("check_show_empty", show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS); - childSetValue("check_since_logoff", mFilter->isSinceLogoff()); - mSpinSinceHours->set((F32)(hours % 24)); - mSpinSinceDays->set((F32)(hours / 24)); -} - -void LLFloaterInventoryFinder::draw() -{ - LLMemType mt(LLMemType::MTYPE_INVENTORY_DRAW); - U32 filter = 0xffffffff; - BOOL filtered_by_all_types = TRUE; - - if (!childGetValue("check_animation")) - { - filter &= ~(0x1 << LLInventoryType::IT_ANIMATION); - filtered_by_all_types = FALSE; - } - - - if (!childGetValue("check_calling_card")) - { - filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD); - filtered_by_all_types = FALSE; - } - - if (!childGetValue("check_clothing")) - { - filter &= ~(0x1 << LLInventoryType::IT_WEARABLE); - filtered_by_all_types = FALSE; - } - - if (!childGetValue("check_gesture")) - { - filter &= ~(0x1 << LLInventoryType::IT_GESTURE); - filtered_by_all_types = FALSE; - } - - if (!childGetValue("check_landmark")) - - - { - filter &= ~(0x1 << LLInventoryType::IT_LANDMARK); - filtered_by_all_types = FALSE; - } - - if (!childGetValue("check_notecard")) - { - filter &= ~(0x1 << LLInventoryType::IT_NOTECARD); - filtered_by_all_types = FALSE; - } - - if (!childGetValue("check_object")) - { - filter &= ~(0x1 << LLInventoryType::IT_OBJECT); - filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT); - filtered_by_all_types = FALSE; - } - - if (!childGetValue("check_script")) - { - filter &= ~(0x1 << LLInventoryType::IT_LSL); - filtered_by_all_types = FALSE; - } - - if (!childGetValue("check_sound")) - { - filter &= ~(0x1 << LLInventoryType::IT_SOUND); - filtered_by_all_types = FALSE; - } - - if (!childGetValue("check_texture")) - { - filter &= ~(0x1 << LLInventoryType::IT_TEXTURE); - filtered_by_all_types = FALSE; - } - - if (!childGetValue("check_snapshot")) - { - 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 - mPanelInventoryDecorated->getPanel()->setShowFolderState(getCheckShowEmpty() ? - LLInventoryFilter::SHOW_ALL_FOLDERS : LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); - mPanelInventoryDecorated->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; - mPanelInventoryDecorated->getPanel()->setHoursAgo(hours); - mPanelInventoryDecorated->getPanel()->setSinceLogoff(getCheckSinceLogoff()); - mPanelInventoryDecorated->setFilterTextFromFilter(); - - LLPanel::draw(); -} - -BOOL LLFloaterInventoryFinder::getCheckShowEmpty() -{ - return childGetValue("check_show_empty"); -} - -BOOL LLFloaterInventoryFinder::getCheckSinceLogoff() -{ - return childGetValue("check_since_logoff"); -} - -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->childSetValue("check_animation", TRUE); - self->childSetValue("check_calling_card", TRUE); - self->childSetValue("check_clothing", TRUE); - self->childSetValue("check_gesture", TRUE); - self->childSetValue("check_landmark", TRUE); - self->childSetValue("check_notecard", TRUE); - self->childSetValue("check_object", TRUE); - self->childSetValue("check_script", TRUE); - self->childSetValue("check_sound", TRUE); - self->childSetValue("check_texture", TRUE); - self->childSetValue("check_snapshot", TRUE); -} - -//static -void LLFloaterInventoryFinder::selectNoTypes(void* user_data) -{ - LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data; - if(!self) return; - - self->childSetValue("check_animation", FALSE); - self->childSetValue("check_calling_card", FALSE); - self->childSetValue("check_clothing", FALSE); - self->childSetValue("check_gesture", FALSE); - self->childSetValue("check_landmark", FALSE); - self->childSetValue("check_notecard", FALSE); - self->childSetValue("check_object", FALSE); - self->childSetValue("check_script", FALSE); - self->childSetValue("check_sound", FALSE); - self->childSetValue("check_texture", FALSE); - self->childSetValue("check_snapshot", FALSE); -} +/**
+ * @file llsidepanelmaininventory.cpp
+ * @brief Implementation of llsidepanelmaininventory.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llpanelmaininventory.h"
+
+#include "lldndbutton.h"
+#include "llfilepicker.h"
+#include "llfloaterinventory.h"
+#include "llinventorybridge.h"
+#include "llinventoryfunctions.h"
+#include "llinventorypanel.h"
+#include "llfiltereditor.h"
+#include "llfloaterreg.h"
+#include "llpreviewtexture.h"
+#include "llscrollcontainer.h"
+#include "llsdserialize.h"
+#include "llspinctrl.h"
+#include "lltooldraganddrop.h"
+#include "llviewermenu.h"
+#include "llviewertexturelist.h"
+
+static LLRegisterPanelClassWrapper<LLPanelMainInventory> t_inventory("panel_main_inventory"); // Seraph is this redundant with constructor?
+
+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 onCheckSinceLogoff(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()
+ : LLPanel(),
+ mActivePanel(NULL),
+ mSavedFolderState(NULL),
+ mFilterText(""),
+ mMenuGearDefault(NULL),
+ mMenuAdd(NULL)
+{
+ 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));
+
+ // Controls
+ // *TODO: Just use persistant settings for each of these
+ U32 sort_order = gSavedSettings.getU32("InventorySortOrder");
+ BOOL sort_by_name = ! ( sort_order & LLInventoryFilter::SO_DATE );
+ BOOL sort_folders_by_name = ( sort_order & LLInventoryFilter::SO_FOLDERS_BY_NAME );
+ BOOL sort_system_folders_to_top = ( sort_order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP );
+
+ gSavedSettings.declareBOOL("Inventory.SortByName", sort_by_name, "Declared in code", FALSE);
+ gSavedSettings.declareBOOL("Inventory.SortByDate", !sort_by_name, "Declared in code", FALSE);
+ gSavedSettings.declareBOOL("Inventory.FoldersAlwaysByName", sort_folders_by_name, "Declared in code", FALSE);
+ gSavedSettings.declareBOOL("Inventory.SystemFoldersToTop", sort_system_folders_to_top, "Declared in code", FALSE);
+
+ 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("InventorySortOrder"));
+ mActivePanel->getFilter()->markDefault();
+ mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+ mActivePanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mActivePanel, _1, _2));
+ }
+ 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;
+ filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml");
+ llinfos << "LLPanelMainInventory::init: reading from " << filterSaveName << 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());
+ recent_items_panel->getFilter()->fromLLSD(recent_items);
+ }
+ }
+
+ }
+
+ mFilterEditor = getChild<LLFilterEditor>("inventory search editor");
+ if (mFilterEditor)
+ {
+ mFilterEditor->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterEdit, this, _2));
+ }
+
+ // *TODO:Get the cost info from the server
+ const std::string upload_cost("10");
+ childSetLabelArg("Upload Image", "[COST]", upload_cost);
+ childSetLabelArg("Upload Sound", "[COST]", upload_cost);
+ childSetLabelArg("Upload Animation", "[COST]", upload_cost);
+ childSetLabelArg("Bulk Upload", "[COST]", upload_cost);
+
+ initListCommandsHandlers();
+ return TRUE;
+}
+
+void LLPanelMainInventory::initListCommandsHandlers()
+{
+ mListCommands = getChild<LLPanel>("bottom_panel");
+
+ mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelMainInventory::onGearButtonClick, this));
+ mListCommands->childSetAction("trash_btn", boost::bind(&LLPanelMainInventory::onTrashButtonClick, this));
+ mListCommands->childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this));
+ /*
+ mListCommands->getChild<LLButton>("add_btn")->setHeldDownCallback(boost::bind(&LLPanelMainInventory::onAddButtonHeldDown, this));
+ static const LLSD add_landmark_command("add_landmark");
+ mListCommands->childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddAction, this, add_landmark_command));
+ */
+
+ LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>("trash_btn");
+ trash_btn->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));
+ mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
+ mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+
+}
+
+// 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;
+ filter->toLLSD(filterState);
+ filterRoot[filter->getName()] = filterState;
+ }
+ }
+
+ LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
+ if (recent_items_panel)
+ {
+ LLInventoryFilter* filter = recent_items_panel->getFilter();
+ if (filter)
+ {
+ LLSD filterState;
+ filter->toLLSD(filterState);
+ filterRoot[filter->getName()] = filterState;
+ }
+ }
+
+ std::ostringstream filterSaveName;
+ filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml");
+ 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()
+{
+ LLFloaterInventory::showAgentInventory();
+}
+
+void LLPanelMainInventory::doCreate(const LLSD& userdata)
+{
+ menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata);
+}
+
+void LLPanelMainInventory::resetFilters()
+{
+ LLFloaterInventoryFinder *finder = getFinder();
+ getActivePanel()->getFilter()->resetDefault();
+ if (finder)
+ {
+ finder->updateElementsFromFilter();
+ }
+
+ setFilterTextFromFilter();
+}
+
+void LLPanelMainInventory::setSortBy(const LLSD& userdata)
+{
+ std::string sort_field = userdata.asString();
+ if (sort_field == "name")
+ {
+ U32 order = getActivePanel()->getSortOrder();
+ getActivePanel()->setSortOrder( order & ~LLInventoryFilter::SO_DATE );
+
+ gSavedSettings.setBOOL("Inventory.SortByName", TRUE );
+ gSavedSettings.setBOOL("Inventory.SortByDate", FALSE );
+ }
+ else if (sort_field == "date")
+ {
+ U32 order = getActivePanel()->getSortOrder();
+ getActivePanel()->setSortOrder( order | LLInventoryFilter::SO_DATE );
+
+ gSavedSettings.setBOOL("Inventory.SortByName", FALSE );
+ gSavedSettings.setBOOL("Inventory.SortByDate", TRUE );
+ }
+ else if (sort_field == "foldersalwaysbyname")
+ {
+ U32 order = getActivePanel()->getSortOrder();
+ if ( order & LLInventoryFilter::SO_FOLDERS_BY_NAME )
+ {
+ order &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME;
+
+ gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", FALSE );
+ }
+ else
+ {
+ order |= LLInventoryFilter::SO_FOLDERS_BY_NAME;
+
+ gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", TRUE );
+ }
+ getActivePanel()->setSortOrder( order );
+ }
+ else if (sort_field == "systemfolderstotop")
+ {
+ U32 order = getActivePanel()->getSortOrder();
+ if ( order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP )
+ {
+ order &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
+
+ gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", FALSE );
+ }
+ else
+ {
+ order |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
+
+ gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", TRUE );
+ }
+ getActivePanel()->setSortOrder( order );
+ }
+}
+
+// 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(0xffffffff);
+ }
+
+ 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();
+ }
+}
+
+void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
+{
+ if (search_string == "")
+ {
+ onClearSearch();
+ }
+ if (!mActivePanel)
+ {
+ return;
+ }
+
+ gInventory.startBackgroundFetch();
+
+ std::string uppercase_search_string = search_string;
+ LLStringUtil::toUpper(uppercase_search_string);
+ if (mActivePanel->getFilterSubString().empty() && uppercase_search_string.empty())
+ {
+ // current filter and new filter empty, do nothing
+ return;
+ }
+
+ // save current folder open state if no filter currently applied
+ if (!mActivePanel->getRootFolder()->isFilterModified())
+ {
+ mSavedFolderState->setApply(FALSE);
+ mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+ }
+
+ // set new filter string
+ mActivePanel->setFilterSubString(uppercase_search_string);
+}
+
+
+ //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*)childGetVisibleTab("inventory filter tabs");
+
+ if (!mActivePanel)
+ {
+ return;
+ }
+ 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.
+ gInventory.startBackgroundFetch();
+ }
+ 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;
+}
+
+void LLPanelMainInventory::changed(U32 mask)
+{
+}
+
+
+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);
+ if (parent_floater) // Seraph: Fix this, shouldn't be null even for sidepanel
+ parent_floater->addDependentFloater(mFinderHandle);
+ // start background fetch of folders
+ gInventory.startBackgroundFetch();
+ }
+ 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())
+{
+ LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory_view_finder.xml", NULL);
+ updateElementsFromFilter();
+}
+
+
+void LLFloaterInventoryFinder::onCheckSinceLogoff(LLUICtrl *ctrl, void *user_data)
+{
+ LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
+ if (!self) return;
+
+ bool since_logoff= self->childGetValue("check_since_logoff");
+
+ if (!since_logoff &&
+ !( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() ) )
+ {
+ self->mSpinSinceHours->set(1.0f);
+ }
+}
+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);
+
+ // mCheckSinceLogoff = getChild<LLSpinCtrl>("check_since_logoff");
+ childSetCommitCallback("check_since_logoff", onCheckSinceLogoff, this);
+
+ childSetAction("Close", onCloseBtn, this);
+
+ updateElementsFromFilter();
+ return TRUE;
+}
+void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data)
+{
+ LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
+ if (!self) return;
+
+ bool since_logoff=true;
+ if ( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() )
+ {
+ since_logoff = false;
+ }
+ self->childSetValue("check_since_logoff", since_logoff);
+}
+
+void LLFloaterInventoryFinder::changeFilter(LLInventoryFilter* filter)
+{
+ mFilter = filter;
+ updateElementsFromFilter();
+}
+
+void LLFloaterInventoryFinder::updateElementsFromFilter()
+{
+ if (!mFilter)
+ return;
+
+ // Get data needed for filter display
+ U32 filter_types = mFilter->getFilterTypes();
+ std::string filter_string = mFilter->getFilterSubString();
+ LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState();
+ U32 hours = mFilter->getHoursAgo();
+
+ // update the ui elements
+ setTitle(mFilter->getName());
+
+ childSetValue("check_animation", (S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION));
+
+ childSetValue("check_calling_card", (S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD));
+ childSetValue("check_clothing", (S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
+ childSetValue("check_gesture", (S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
+ childSetValue("check_landmark", (S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
+ childSetValue("check_notecard", (S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
+ childSetValue("check_object", (S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
+ childSetValue("check_script", (S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
+ childSetValue("check_sound", (S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND));
+ childSetValue("check_texture", (S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE));
+ childSetValue("check_snapshot", (S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT));
+ childSetValue("check_show_empty", show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS);
+ childSetValue("check_since_logoff", mFilter->isSinceLogoff());
+ mSpinSinceHours->set((F32)(hours % 24));
+ mSpinSinceDays->set((F32)(hours / 24));
+}
+
+void LLFloaterInventoryFinder::draw()
+{
+ LLMemType mt(LLMemType::MTYPE_INVENTORY_DRAW);
+ U32 filter = 0xffffffff;
+ BOOL filtered_by_all_types = TRUE;
+
+ if (!childGetValue("check_animation"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_ANIMATION);
+ filtered_by_all_types = FALSE;
+ }
+
+
+ if (!childGetValue("check_calling_card"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_clothing"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_WEARABLE);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_gesture"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_GESTURE);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_landmark"))
+
+
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_LANDMARK);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_notecard"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_object"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_OBJECT);
+ filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_script"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_LSL);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_sound"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_SOUND);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_texture"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_TEXTURE);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_snapshot"))
+ {
+ 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 childGetValue("check_show_empty");
+}
+
+BOOL LLFloaterInventoryFinder::getCheckSinceLogoff()
+{
+ return childGetValue("check_since_logoff");
+}
+
+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->childSetValue("check_animation", TRUE);
+ self->childSetValue("check_calling_card", TRUE);
+ self->childSetValue("check_clothing", TRUE);
+ self->childSetValue("check_gesture", TRUE);
+ self->childSetValue("check_landmark", TRUE);
+ self->childSetValue("check_notecard", TRUE);
+ self->childSetValue("check_object", TRUE);
+ self->childSetValue("check_script", TRUE);
+ self->childSetValue("check_sound", TRUE);
+ self->childSetValue("check_texture", TRUE);
+ self->childSetValue("check_snapshot", TRUE);
+}
+
+//static
+void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
+{
+ LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
+ if(!self) return;
+
+ self->childSetValue("check_animation", FALSE);
+ self->childSetValue("check_calling_card", FALSE);
+ self->childSetValue("check_clothing", FALSE);
+ self->childSetValue("check_gesture", FALSE);
+ self->childSetValue("check_landmark", FALSE);
+ self->childSetValue("check_notecard", FALSE);
+ self->childSetValue("check_object", FALSE);
+ self->childSetValue("check_script", FALSE);
+ self->childSetValue("check_sound", FALSE);
+ self->childSetValue("check_texture", FALSE);
+ self->childSetValue("check_snapshot", FALSE);
+}
+
+
+
+
+
+void LLPanelMainInventory::updateListCommands()
+{
+ bool trash_enabled = isActionEnabled("delete");
+
+ mListCommands->childSetEnabled("trash_btn", trash_enabled);
+}
+
+void LLPanelMainInventory::onGearButtonClick()
+{
+ showActionMenu(mMenuGearDefault,"options_gear_btn");
+}
+
+void LLPanelMainInventory::onAddButtonClick()
+{
+ 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::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";
+ setSortBy(arg);
+ }
+ if (command_name == "sort_by_recent")
+ {
+ const LLSD arg = "date";
+ setSortBy(arg);
+ }
+ if (command_name == "show_filters")
+ {
+ toggleFindOptions();
+ }
+ if (command_name == "reset_filters")
+ {
+ resetFilters();
+ }
+ if (command_name == "close_folders")
+ {
+ closeAllFolders();
+ }
+ if (command_name == "empty_trash")
+ {
+ const std::string notification = "ConfirmEmptyTrash";
+ gInventory.emptyFolderType(notification, LLFolderType::FT_TRASH);
+ }
+ if (command_name == "empty_lostnfound")
+ {
+ const std::string notification = "ConfirmEmptyLostAndFound";
+ gInventory.emptyFolderType(notification, LLFolderType::FT_LOST_AND_FOUND);
+ }
+ if (command_name == "save_texture")
+ {
+ LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+ if (!current_item)
+ {
+ return;
+ }
+
+ const LLUUID& item_id = current_item->getListener()->getUUID();
+ LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item_id), TAKE_FOCUS_YES);
+ if (preview_texture)
+ {
+ preview_texture->openToSave();
+ }
+ }
+}
+
+BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
+{
+ const std::string command_name = userdata.asString();
+ if (command_name == "delete")
+ {
+ BOOL can_delete = FALSE;
+ LLFolderView *folder = getActivePanel()->getRootFolder();
+ if (folder)
+ {
+ can_delete = TRUE;
+ std::set<LLUUID> selection_set;
+ folder->getSelectionList(selection_set);
+ for (std::set<LLUUID>::iterator iter = selection_set.begin();
+ iter != selection_set.end();
+ ++iter)
+ {
+ const LLUUID &item_id = (*iter);
+ LLFolderViewItem *item = folder->getItemByID(item_id);
+ can_delete &= item->getListener()->isItemRemovable();
+ }
+ return can_delete;
+ }
+ return FALSE;
+ }
+ if (command_name == "save_texture")
+ {
+ LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+ if (current_item)
+ {
+ return (current_item->getListener()->getInventoryType() == LLInventoryType::IT_TEXTURE);
+ }
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool LLPanelMainInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept)
+{
+ *accept = ACCEPT_NO;
+
+ const bool is_enabled = isActionEnabled("delete");
+ if (is_enabled) *accept = ACCEPT_YES_MULTI;
+
+ if (is_enabled && drop)
+ {
+ onClipboardAction("delete");
+ }
+ return true;
+}
|