diff options
Diffstat (limited to 'indra/newview/llpanellandmarks.cpp')
-rw-r--r-- | indra/newview/llpanellandmarks.cpp | 463 |
1 files changed, 335 insertions, 128 deletions
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 40ea75ea7a..24bf67a000 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -2,30 +2,25 @@ * @file llpanellandmarks.cpp * @brief Landmarks tab for Side Bar "Places" panel * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * - * Copyright (c) 2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * 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. + * 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$ */ @@ -49,6 +44,7 @@ #include "lldndbutton.h" #include "llfloaterworldmap.h" #include "llfolderviewitem.h" +#include "llinventorymodelbackgroundfetch.h" #include "llinventorypanel.h" #include "lllandmarkactions.h" #include "llplacesinventorybridge.h" @@ -69,6 +65,10 @@ static const std::string TRASH_BUTTON_NAME = "trash_btn"; // helper functions static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::string& string); static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list); +static void collapse_all_folders(LLFolderView* root_folder); +static void expand_all_folders(LLFolderView* root_folder); +static bool has_expanded_folders(LLFolderView* root_folder); +static bool has_collapsed_folders(LLFolderView* root_folder); /** * Functor counting expanded and collapsed folders in folder view tree to know @@ -216,8 +216,6 @@ BOOL LLLandmarksPanel::postBuild() // mast be called before any other initXXX methods to init Gear menu initListCommandsHandlers(); - U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER); - mSortByDate = sort_order & LLInventoryFilter::SO_DATE; initFavoritesInventoryPanel(); initLandmarksInventoryPanel(); initMyInventoryPanel(); @@ -275,6 +273,17 @@ void LLLandmarksPanel::onShowOnMap() doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doShowOnMap, this, _1)); } +//virtual +void LLLandmarksPanel::onShowProfile() +{ + LLFolderViewItem* cur_item = getCurSelectedItem(); + + if(!cur_item) + return; + + cur_item->getListener()->performAction(mCurrentSelectedList->getModel(),"about"); +} + // virtual void LLLandmarksPanel::onTeleport() { @@ -293,6 +302,25 @@ void LLLandmarksPanel::onTeleport() } // virtual +bool LLLandmarksPanel::isSingleItemSelected() +{ + bool result = false; + + if (mCurrentSelectedList != NULL) + { + LLPlacesFolderView* root_view = + static_cast<LLPlacesFolderView*>(mCurrentSelectedList->getRootFolder()); + + if (root_view->getSelectedCount() == 1) + { + result = isLandmarkSelected(); + } + } + + return result; +} + +// virtual void LLLandmarksPanel::updateVerbs() { if (!isTabVisible()) @@ -300,6 +328,7 @@ void LLLandmarksPanel::updateVerbs() bool landmark_selected = isLandmarkSelected(); mTeleportBtn->setEnabled(landmark_selected && isActionEnabled("teleport")); + mShowProfile->setEnabled(landmark_selected && isActionEnabled("more_info")); mShowOnMapBtn->setEnabled(landmark_selected && isActionEnabled("show_on_map")); // TODO: mantipov: Uncomment when mShareBtn is supported @@ -430,9 +459,9 @@ LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPa if (!inventory_list) return NULL; - LLFolderView* folder_view = inventory_list->getRootFolder(); + LLFolderView* root = inventory_list->getRootFolder(); - LLFolderViewItem* item = folder_view->getItemByID(obj_id); + LLFolderViewItem* item = root->getItemByID(obj_id); if (!item) return NULL; @@ -442,7 +471,7 @@ LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPa tab->changeOpenClose(false); } - folder_view->setSelection(item, FALSE, take_keyboard_focus); + root->setSelection(item, FALSE, take_keyboard_focus); LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion"); LLRect screen_rc; @@ -488,6 +517,9 @@ void LLLandmarksPanel::setParcelID(const LLUUID& parcel_id) { if (!parcel_id.isNull()) { + //ext-4655, defensive. remove now incase this gets called twice without a remove + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(parcel_id, this); + LLRemoteParcelInfoProcessor::getInstance()->addObserver(parcel_id, this); LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id); } @@ -530,7 +562,7 @@ void LLLandmarksPanel::initLandmarksInventoryPanel() // subscribe to have auto-rename functionality while creating New Folder mLandmarksInventoryPanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mLandmarksInventoryPanel, _1, _2)); - initAccordion("tab_landmarks", mLandmarksInventoryPanel, true); + mMyLandmarksAccordionTab = initAccordion("tab_landmarks", mLandmarksInventoryPanel, true); } void LLLandmarksPanel::initMyInventoryPanel() @@ -552,7 +584,7 @@ void LLLandmarksPanel::initLibraryInventoryPanel() const LLUUID &landmarks_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false, true); if (landmarks_cat.notNull()) { - gInventory.startBackgroundFetch(landmarks_cat); + LLInventoryModelBackgroundFetch::instance().start(landmarks_cat); } // Expanding "Library" tab for new users who have no landmarks in "My Inventory". @@ -566,11 +598,13 @@ void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list if (!inventory_list->getFilter()) return; + inventory_list->getFilter()->setEmptyLookupMessage("PlacesNoMatchingItems"); inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK); inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2)); inventory_list->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); - updateSortOrder(inventory_list, mSortByDate); + bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate"); + updateSortOrder(inventory_list, sorting_order); LLPlacesFolderView* root_folder = dynamic_cast<LLPlacesFolderView*>(inventory_list->getRootFolder()); if (root_folder) @@ -584,7 +618,7 @@ void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list inventory_list->saveFolderState(); } -void LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list, bool expand_tab) +LLAccordionCtrlTab* LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list, bool expand_tab) { LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>(accordion_tab_name); @@ -592,6 +626,7 @@ void LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLPl accordion_tab->setDropDownStateChangedCallback( boost::bind(&LLLandmarksPanel::onAccordionExpandedCollapsed, this, _2, inventory_list)); accordion_tab->setDisplayChildren(expand_tab); + return accordion_tab; } void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list) @@ -615,7 +650,7 @@ void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesI if (!gInventory.isCategoryComplete(cat_id)) */ { - gInventory.startBackgroundFetch(cat_id); + LLInventoryModelBackgroundFetch::instance().start(cat_id); } // Apply filter substring because it might have been changed @@ -652,14 +687,12 @@ void LLLandmarksPanel::initListCommandsHandlers() mListCommands->childSetAction(OPTIONS_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onActionsButtonClick, this)); mListCommands->childSetAction(TRASH_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onTrashButtonClick, this)); - mListCommands->getChild<LLButton>(ADD_BUTTON_NAME)->setHeldDownCallback(boost::bind(&LLLandmarksPanel::onAddButtonHeldDown, this)); - static const LLSD add_landmark_command("add_landmark"); - mListCommands->childSetAction(ADD_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onAddAction, this, add_landmark_command)); LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>(TRASH_BUTTON_NAME); trash_btn->setDragAndDropHandler(boost::bind(&LLLandmarksPanel::handleDragAndDropToTrash, this , _4 // BOOL drop , _5 // EDragAndDropType cargo_type + , _6 // void* cargo_data , _7 // EAcceptance* accept )); @@ -672,6 +705,8 @@ void LLLandmarksPanel::initListCommandsHandlers() mGearLandmarkMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_places_gear_landmark.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mGearFolderMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_places_gear_folder.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_place_add_button.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + + mListCommands->childSetAction(ADD_BUTTON_NAME, boost::bind(&LLLandmarksPanel::showActionMenu, this, mMenuAdd, ADD_BUTTON_NAME)); } @@ -681,39 +716,32 @@ void LLLandmarksPanel::updateListCommands() bool trash_enabled = isActionEnabled("delete"); // keep Options & Add Landmark buttons always enabled - mListCommands->childSetEnabled(ADD_FOLDER_BUTTON_NAME, add_folder_enabled); - mListCommands->childSetEnabled(TRASH_BUTTON_NAME, trash_enabled); - mListCommands->childSetEnabled(OPTIONS_BUTTON_NAME,getCurSelectedItem() != NULL); + mListCommands->getChildView(ADD_FOLDER_BUTTON_NAME)->setEnabled(add_folder_enabled); + mListCommands->getChildView(TRASH_BUTTON_NAME)->setEnabled(trash_enabled); } void LLLandmarksPanel::onActionsButtonClick() { + LLMenuGL* menu = mGearFolderMenu; + LLFolderViewItem* cur_item = NULL; if(mCurrentSelectedList) - cur_item = mCurrentSelectedList->getRootFolder()->getCurSelectedItem(); - - if(!cur_item) - return; - - LLFolderViewEventListener* listenerp = cur_item->getListener(); - - LLMenuGL* menu =NULL; - if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) { - menu = mGearLandmarkMenu; - } - else if (listenerp->getInventoryType() == LLInventoryType::IT_CATEGORY) - { - mGearFolderMenu->getChild<LLMenuItemCallGL>("expand")->setVisible(!cur_item->isOpen()); - mGearFolderMenu->getChild<LLMenuItemCallGL>("collapse")->setVisible(cur_item->isOpen()); - menu = mGearFolderMenu; + cur_item = mCurrentSelectedList->getRootFolder()->getCurSelectedItem(); + if(!cur_item) + return; + + LLFolderViewEventListener* listenerp = cur_item->getListener(); + if(!listenerp) + return; + + if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) + { + menu = mGearLandmarkMenu; + } } - showActionMenu(menu,OPTIONS_BUTTON_NAME); -} -void LLLandmarksPanel::onAddButtonHeldDown() -{ - showActionMenu(mMenuAdd,ADD_BUTTON_NAME); + showActionMenu(menu,OPTIONS_BUTTON_NAME); } void LLLandmarksPanel::showActionMenu(LLMenuGL* menu, std::string spawning_view_name) @@ -775,6 +803,17 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const "category"), gInventory.findCategoryUUIDForType( LLFolderType::FT_LANDMARK)); } + else + { + //in case My Landmarks tab is completely empty (thus cannot be determined as being selected) + menu_create_inventory_item(mLandmarksInventoryPanel->getRootFolder(), NULL, LLSD("category"), + gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK)); + + if (mMyLandmarksAccordionTab) + { + mMyLandmarksAccordionTab->changeOpenClose(false); + } + } } } @@ -805,35 +844,47 @@ void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const void LLLandmarksPanel::onFoldingAction(const LLSD& userdata) { - if(!mCurrentSelectedList) return; - - LLFolderView* root_folder = mCurrentSelectedList->getRootFolder(); std::string command_name = userdata.asString(); if ("expand_all" == command_name) { - root_folder->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN); - root_folder->arrangeAll(); + expand_all_folders(mFavoritesInventoryPanel->getRootFolder()); + expand_all_folders(mLandmarksInventoryPanel->getRootFolder()); + expand_all_folders(mMyInventoryPanel->getRootFolder()); + expand_all_folders(mLibraryInventoryPanel->getRootFolder()); + + for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) + { + (*iter)->changeOpenClose(false); + } } else if ("collapse_all" == command_name) { - root_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN); + collapse_all_folders(mFavoritesInventoryPanel->getRootFolder()); + collapse_all_folders(mLandmarksInventoryPanel->getRootFolder()); + collapse_all_folders(mMyInventoryPanel->getRootFolder()); + collapse_all_folders(mLibraryInventoryPanel->getRootFolder()); - // The top level folder is invisible, it must be open to - // display its sub-folders. - root_folder->openTopLevelFolders(); - root_folder->arrangeAll(); + for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) + { + (*iter)->changeOpenClose(true); + } } - else if ( "sort_by_date" == command_name) + else if ("sort_by_date" == command_name) { - mSortByDate = !mSortByDate; - updateSortOrder(mLandmarksInventoryPanel, mSortByDate); - updateSortOrder(mMyInventoryPanel, mSortByDate); - updateSortOrder(mLibraryInventoryPanel, mSortByDate); + bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate"); + sorting_order=!sorting_order; + gSavedSettings.setBOOL("LandmarksSortedByDate",sorting_order); + updateSortOrder(mLandmarksInventoryPanel, sorting_order); + updateSortOrder(mMyInventoryPanel, sorting_order); + updateSortOrder(mLibraryInventoryPanel, sorting_order); } else { - root_folder->doToSelected(&gInventory, userdata); + if(mCurrentSelectedList) + { + mCurrentSelectedList->getRootFolder()->doToSelected(&gInventory, userdata); + } } } @@ -843,7 +894,8 @@ bool LLLandmarksPanel::isActionChecked(const LLSD& userdata) const if ( "sort_by_date" == command_name) { - return mSortByDate; + bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate"); + return sorting_order; } return false; @@ -853,53 +905,126 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const { std::string command_name = userdata.asString(); - - LLPlacesFolderView* rootFolderView = mCurrentSelectedList ? + LLPlacesFolderView* root_folder_view = mCurrentSelectedList ? static_cast<LLPlacesFolderView*>(mCurrentSelectedList->getRootFolder()) : NULL; - if (NULL == rootFolderView) return false; + if ("collapse_all" == command_name) + { + bool disable_collapse_all = !has_expanded_folders(mFavoritesInventoryPanel->getRootFolder()) + && !has_expanded_folders(mLandmarksInventoryPanel->getRootFolder()) + && !has_expanded_folders(mMyInventoryPanel->getRootFolder()) + && !has_expanded_folders(mLibraryInventoryPanel->getRootFolder()); + if (disable_collapse_all) + { + for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) + { + if ((*iter)->isExpanded()) + { + disable_collapse_all = false; + break; + } + } + } + + return !disable_collapse_all; + } + else if ("expand_all" == command_name) + { + bool disable_expand_all = !has_collapsed_folders(mFavoritesInventoryPanel->getRootFolder()) + && !has_collapsed_folders(mLandmarksInventoryPanel->getRootFolder()) + && !has_collapsed_folders(mMyInventoryPanel->getRootFolder()) + && !has_collapsed_folders(mLibraryInventoryPanel->getRootFolder()); + if (disable_expand_all) + { + for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) + { + if (!(*iter)->isExpanded()) + { + disable_expand_all = false; + break; + } + } + } - // disable some commands for multi-selection. EXT-1757 - if (rootFolderView->getSelectedCount() > 1) + return !disable_expand_all; + } + else if ("sort_by_date" == command_name) + { + // disable "sort_by_date" for Favorites accordion because + // it has its own items order. EXT-1758 + if (mCurrentSelectedList == mFavoritesInventoryPanel) + { + return false; + } + } + else if ( "paste" == command_name + || "cut" == command_name + || "copy" == command_name + || "delete" == command_name + || "collapse" == command_name + || "expand" == command_name + ) { - if ( "teleport" == command_name + if (!root_folder_view) return false; + + std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList(); + + // Allow to execute the command only if it can be applied to all selected items. + for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter) + { + LLFolderViewItem* item = root_folder_view->getItemByID(*iter); + + // If no item is found it might be a folder id. + if (!item) + { + item = root_folder_view->getFolderByID(*iter); + } + if (!item) return false; + + if (!canItemBeModified(command_name, item)) return false; + } + + return true; + } + else if ( "teleport" == command_name || "more_info" == command_name - || "rename" == command_name || "show_on_map" == command_name || "copy_slurl" == command_name + || "rename" == command_name ) + { + // disable some commands for multi-selection. EXT-1757 + bool is_single_selection = root_folder_view && root_folder_view->getSelectedCount() == 1; + if (!is_single_selection) { return false; } - } + if ("show_on_map" == command_name) + { + LLFolderViewItem* cur_item = root_folder_view->getCurSelectedItem(); + if (!cur_item) return false; - // disable some commands for Favorites accordion. EXT-1758 - if (mCurrentSelectedList == mFavoritesInventoryPanel) - { - if ( "expand_all" == command_name - || "collapse_all" == command_name - || "sort_by_date" == command_name - ) - return false; - } + LLViewerInventoryItem* inv_item = cur_item->getInventoryItem(); + if (!inv_item) return false; - LLCheckFolderState checker; - rootFolderView->applyFunctorRecursively(checker); + LLUUID asset_uuid = inv_item->getAssetUUID(); + if (asset_uuid.isNull()) return false; - // We assume that the root folder is always expanded so we enable "collapse_all" - // command when we have at least one more expanded folder. - if (checker.getExpandedFolders() < 2 && "collapse_all" == command_name) - { - return false; - } + // Disable "Show on Map" if landmark loading is in progress. + return !gLandmarkList.isAssetInLoadedCallbackMap(asset_uuid); + } + else if ("rename" == command_name) + { + LLFolderViewItem* selected_item = getCurSelectedItem(); + if (!selected_item) return false; - if (checker.getCollapsedFolders() < 1 && "expand_all" == command_name) - { - return false; - } + return canItemBeModified(command_name, selected_item); + } - if("category" == command_name) + return true; + } + else if("category" == command_name) { // we can add folder only in Landmarks Accordion if (mCurrentSelectedList == mLandmarksInventoryPanel) @@ -907,18 +1032,18 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const // ... but except Received folder return !isReceivedFolderSelected(); } - else return false; - } - else if("paste" == command_name || "rename" == command_name || "cut" == command_name || "delete" == command_name) - { - return canSelectedBeModified(command_name); + //"Add a folder" is enabled by default (case when My Landmarks is empty) + else return true; } else if("create_pick" == command_name) { - std::set<LLUUID> selection; - if ( mCurrentSelectedList && mCurrentSelectedList->getRootFolder()->getSelectionList(selection) ) + if (mCurrentSelectedList) { - return ( 1 == selection.size() && !LLAgentPicksInfo::getInstance()->isPickLimitReached() ); + std::set<LLUUID> selection = mCurrentSelectedList->getRootFolder()->getSelectionList(); + if (!selection.empty()) + { + return ( 1 == selection.size() && !LLAgentPicksInfo::getInstance()->isPickLimitReached() ); + } } return false; } @@ -932,13 +1057,10 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const void LLLandmarksPanel::onCustomAction(const LLSD& userdata) { - LLFolderViewItem* cur_item = getCurSelectedItem(); - if(!cur_item) - return; std::string command_name = userdata.asString(); if("more_info" == command_name) { - cur_item->getListener()->performAction(mCurrentSelectedList->getRootFolder(),mCurrentSelectedList->getModel(),"about"); + onShowProfile(); } else if ("teleport" == command_name) { @@ -966,17 +1088,19 @@ Rules: 4. We can not paste folders from Clipboard (processed by LLFolderView::canPaste()) 5. Check LLFolderView/Inventory Bridges rules */ -bool LLLandmarksPanel::canSelectedBeModified(const std::string& command_name) const +bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const { // validate own rules first + if (!item) return false; + // nothing can be modified in Library if (mLibraryInventoryPanel == mCurrentSelectedList) return false; bool can_be_modified = false; // landmarks can be modified in any other accordion... - if (isLandmarkSelected()) + if (item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK) { can_be_modified = true; @@ -996,24 +1120,42 @@ bool LLLandmarksPanel::canSelectedBeModified(const std::string& command_name) co } // then ask LLFolderView permissions + + LLFolderView* root_folder = mCurrentSelectedList->getRootFolder(); + + if ("copy" == command_name) + { + return root_folder->canCopy(); + } + else if ("collapse" == command_name) + { + return item->isOpen(); + } + else if ("expand" == command_name) + { + return !item->isOpen(); + } + if (can_be_modified) { - LLFolderViewItem* selected = getCurSelectedItem(); + LLFolderViewEventListener* listenerp = item->getListener(); + if ("cut" == command_name) { - can_be_modified = mCurrentSelectedList->getRootFolder()->canCut(); + // "Cut" disabled for folders. See EXT-8697. + can_be_modified = root_folder->canCut() && listenerp->getInventoryType() != LLInventoryType::IT_CATEGORY; } else if ("rename" == command_name) { - can_be_modified = selected ? selected->getListener()->isItemRenameable() : false; + can_be_modified = listenerp ? listenerp->isItemRenameable() : false; } else if ("delete" == command_name) { - can_be_modified = selected ? selected->getListener()->isItemRemovable(): false; + can_be_modified = listenerp ? listenerp->isItemRemovable() && !listenerp->isItemInTrash() : false; } else if("paste" == command_name) { - return mCurrentSelectedList->getRootFolder()->canPaste(); + can_be_modified = root_folder->canPaste(); } else { @@ -1035,7 +1177,7 @@ void LLLandmarksPanel::onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* own pick_panel = NULL; } -bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept) +bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data , EAcceptance* accept) { *accept = ACCEPT_NO; @@ -1051,7 +1193,21 @@ bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType carg if (is_enabled && drop) { - onClipboardAction("delete"); + // don't call onClipboardAction("delete") + // this lead to removing (N * 2 - 1) items if drag N>1 items into trash. EXT-6757 + // So, let remove items one by one. + LLInventoryItem* item = static_cast<LLInventoryItem*>(cargo_data); + if (item) + { + LLFolderViewItem* fv_item = (mCurrentSelectedList && mCurrentSelectedList->getRootFolder()) ? + mCurrentSelectedList->getRootFolder()->getItemByID(item->getUUID()) : NULL; + + if (fv_item) + { + // is Item Removable checked inside of remove() + fv_item->remove(); + } + } } } break; @@ -1076,6 +1232,7 @@ void LLLandmarksPanel::doShowOnMap(LLLandmark* landmark) } mShowOnMapBtn->setEnabled(TRUE); + mGearLandmarkMenu->setItemEnabled("show_on_map", TRUE); } void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark, @@ -1197,4 +1354,54 @@ static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list) return false; } + +static void collapse_all_folders(LLFolderView* root_folder) +{ + if (!root_folder) + return; + + root_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN); + + // The top level folder is invisible, it must be open to + // display its sub-folders. + root_folder->openTopLevelFolders(); + root_folder->arrangeAll(); +} + +static void expand_all_folders(LLFolderView* root_folder) +{ + if (!root_folder) + return; + + root_folder->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN); + root_folder->arrangeAll(); +} + +static bool has_expanded_folders(LLFolderView* root_folder) +{ + LLCheckFolderState checker; + root_folder->applyFunctorRecursively(checker); + + // We assume that the root folder is always expanded so we enable "collapse_all" + // command when we have at least one more expanded folder. + if (checker.getExpandedFolders() < 2) + { + return false; + } + + return true; +} + +static bool has_collapsed_folders(LLFolderView* root_folder) +{ + LLCheckFolderState checker; + root_folder->applyFunctorRecursively(checker); + + if (checker.getCollapsedFolders() < 1) + { + return false; + } + + return true; +} // EOF |