void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected) { mLastSelectedFlatlList = selected; LLTeleportHistoryFlatItem* item = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem()); if (item) mLastSelectedItemIndex = item->getIndex(); S32 tabs_cnt = mItemContainers.size(); for (S32 n = 0; n < tabs_cnt; n++) { LLAccordionCtrlTab* tab = mItemContainers.get(n); if (!tab->getVisible()) continue; LLFlatListView *flv = getFlatListViewFromTab(tab); if (!flv) continue; if (flv == selected) continue; flv->resetSelection(true); } updateVerbs(); }
void LLTeleportHistoryPanel::showTeleportHistory() { mDirty = true; // Starting to add items from last one, in reverse order, // since TeleportHistory keeps most recent item at the end if (!mTeleportHistory) { mTeleportHistory = LLTeleportHistoryStorage::getInstance(); } mCurrentItem = mTeleportHistory->getItems().size() - 1; for (S32 n = mItemContainers.size() - 1; n >= 0; --n) { LLAccordionCtrlTab* tab = mItemContainers.get(n); if (tab) { tab->setVisible(false); LLFlatListView* fv = getFlatListViewFromTab(tab); if (fv) { // Detached panels are managed by LLTeleportHistoryFlatItemStorage std::vector<LLPanel*> detached_items; fv->detachItems(detached_items); } } } }
void LLCOFWearables::refresh() { const LLUUID cof_id = LLAppearanceMgr::instance().getCOF(); if (cof_id.isNull()) { llwarns << "COF ID cannot be NULL" << llendl; return; } LLViewerInventoryCategory* catp = gInventory.getCategory(cof_id); if (!catp) { llwarns << "COF category cannot be NULL" << llendl; return; } // BAP - this check has to be removed because an item name change does not // change cat version - ie, checking version is not a complete way // of finding out whether anything has changed in this category. //if (mCOFVersion == catp->getVersion()) return; mCOFVersion = catp->getVersion(); // Save current scrollbar position. typedef std::map<LLFlatListView*, LLRect> scroll_pos_map_t; scroll_pos_map_t saved_scroll_pos; saved_scroll_pos[mAttachments] = mAttachments->getVisibleContentRect(); saved_scroll_pos[mClothing] = mClothing->getVisibleContentRect(); saved_scroll_pos[mBodyParts] = mBodyParts->getVisibleContentRect(); // Save current selection. typedef std::vector<LLSD> values_vector_t; typedef std::map<LLFlatListView*, values_vector_t> selection_map_t; selection_map_t preserve_selection; mAttachments->getSelectedValues(preserve_selection[mAttachments]); mClothing->getSelectedValues(preserve_selection[mClothing]); mBodyParts->getSelectedValues(preserve_selection[mBodyParts]); clear(); LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t cof_items; gInventory.collectDescendents(cof_id, cats, cof_items, LLInventoryModel::EXCLUDE_TRASH); populateAttachmentsAndBodypartsLists(cof_items); LLAppearanceMgr::wearables_by_type_t clothing_by_type(LLWearableType::WT_COUNT); LLAppearanceMgr::getInstance()->divvyWearablesByType(cof_items, clothing_by_type); populateClothingList(clothing_by_type); // Restore previous selection for (selection_map_t::iterator iter = preserve_selection.begin(), iter_end = preserve_selection.end(); iter != iter_end; ++iter) { LLFlatListView* list = iter->first; if (!list) continue; //restoring selection should not fire commit callbacks list->setCommitOnSelectionChange(false); const values_vector_t& values = iter->second; for (values_vector_t::const_iterator value_it = values.begin(), value_it_end = values.end(); value_it != value_it_end; ++value_it) { // value_it may be null because of dummy items // Dummy items have no ID if(value_it->asUUID().notNull()) { list->selectItemByValue(*value_it); } } list->setCommitOnSelectionChange(true); } // Restore previous scrollbar position. for (scroll_pos_map_t::const_iterator it = saved_scroll_pos.begin(); it != saved_scroll_pos.end(); ++it) { LLFlatListView* list = it->first; LLRect scroll_pos = it->second; list->scrollToShowRect(scroll_pos); } }
void LLTeleportHistoryPanel::replaceItem(S32 removed_index) { // Flat list for 'Today' (mItemContainers keeps accordion tabs in reverse order) LLFlatListView* fv = NULL; if (mItemContainers.size() > 0) { fv = getFlatListViewFromTab(mItemContainers[mItemContainers.size() - 1]); } // Empty flat list for 'Today' means that other flat lists are empty as well, // so all items from teleport history should be added. if (!fv || fv->size() == 0) { showTeleportHistory(); return; } const LLTeleportHistoryStorage::slurl_list_t& history_items = mTeleportHistory->getItems(); LLTeleportHistoryFlatItem* item = LLTeleportHistoryFlatItemStorage::instance() .getFlatItemForPersistentItem(&mContextMenu, history_items[history_items.size() - 1], // Most recent item, it was added instead of removed history_items.size(), // index will be decremented inside loop below sFilterSubString); fv->addItem(item, LLUUID::null, ADD_TOP); // Index of each item, from last to removed item should be decremented // to point to the right item in LLTeleportHistoryStorage for (S32 tab_idx = mItemContainers.size() - 1; tab_idx >= 0; --tab_idx) { LLAccordionCtrlTab* tab = mItemContainers.get(tab_idx); if (!tab->getVisible()) continue; fv = getFlatListViewFromTab(tab); if (!fv) { showTeleportHistory(); return; } std::vector<LLPanel*> items; fv->getItems(items); S32 items_cnt = items.size(); for (S32 n = 0; n < items_cnt; ++n) { LLTeleportHistoryFlatItem *item = (LLTeleportHistoryFlatItem*) items[n]; if (item->getIndex() == removed_index) { LLTeleportHistoryFlatItemStorage::instance().removeItem(item); fv->removeItem(item); // If flat list becames empty, then accordion tab should be hidden if (fv->size() == 0) tab->setVisible(false); mHistoryAccordion->arrange(); return; // No need to decrement idexes for the rest of items } item->setIndex(item->getIndex() - 1); } } }
// Called to add items, no more, than ADD_LIMIT at time void LLTeleportHistoryPanel::refresh() { if (!mHistoryAccordion) { mDirty = false; return; } const LLTeleportHistoryStorage::slurl_list_t& items = mTeleportHistory->getItems(); // Setting tab_boundary_date to "now", so date from any item would be earlier, than boundary. // That leads to call to getNextTab to get right tab_idx in first pass LLDate tab_boundary_date = LLDate::now(); LLFlatListView* curr_flat_view = NULL; std::string filter_string = sFilterSubString; LLStringUtil::toUpper(filter_string); U32 added_items = 0; while (mCurrentItem >= 0) { // Filtering if (!filter_string.empty()) { std::string landmark_title(items[mCurrentItem].mTitle); LLStringUtil::toUpper(landmark_title); if( std::string::npos == landmark_title.find(filter_string) ) { mCurrentItem--; continue; } } // Checking whether date of item is earlier, than tab_boundary_date. // In that case, item should be added to another tab const LLDate &date = items[mCurrentItem].mDate; if (date < tab_boundary_date) { // Getting apropriate tab_idx for this and subsequent items, // tab_boundary_date would be earliest possible date for this tab S32 tab_idx = 0; getNextTab(date, tab_idx, tab_boundary_date); tab_idx = mItemContainers.size() - 1 - tab_idx; if (tab_idx >= 0) { LLAccordionCtrlTab* tab = mItemContainers.get(tab_idx); tab->setVisible(true); // Expand all accordion tabs when filtering if(!sFilterSubString.empty()) { //store accordion tab state when filter is not empty tab->notifyChildren(LLSD().with("action","store_state")); tab->setDisplayChildren(true); } // Restore each tab's expand state when not filtering else { bool collapsed = isAccordionCollapsedByUser(tab); tab->setDisplayChildren(!collapsed); //restore accordion state after all those accodrion tabmanipulations tab->notifyChildren(LLSD().with("action","restore_state")); } curr_flat_view = getFlatListViewFromTab(tab); } } if (curr_flat_view) { LLTeleportHistoryFlatItem* item = LLTeleportHistoryFlatItemStorage::instance() .getFlatItemForPersistentItem(&mContextMenu, items[mCurrentItem], mCurrentItem, filter_string); if ( !curr_flat_view->addItem(item, LLUUID::null, ADD_BOTTOM, false) ) llerrs << "Couldn't add flat item to teleport history." << llendl; if (mLastSelectedItemIndex == mCurrentItem) curr_flat_view->selectItem(item, true); } mCurrentItem--; if (++added_items >= ADD_LIMIT) break; } for (S32 n = mItemContainers.size() - 1; n >= 0; --n) { LLAccordionCtrlTab* tab = mItemContainers.get(n); LLFlatListView* fv = getFlatListViewFromTab(tab); if (fv) { fv->notify(LLSD().with("rearrange", LLSD())); } } mHistoryAccordion->setFilterSubString(sFilterSubString); mHistoryAccordion->arrange(); updateVerbs(); if (mCurrentItem < 0) mDirty = false; }
BOOL LLTeleportHistoryPanel::postBuild() { mTeleportHistory = LLTeleportHistoryStorage::getInstance(); if (mTeleportHistory) { mTeleportHistoryChangedConnection = mTeleportHistory->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryPanel::onTeleportHistoryChange, this, _1)); } mHistoryAccordion = getChild<LLAccordionCtrl>("history_accordion"); if (mHistoryAccordion) { for (child_list_const_iter_t iter = mHistoryAccordion->beginChild(); iter != mHistoryAccordion->endChild(); iter++) { if (dynamic_cast<LLAccordionCtrlTab*>(*iter)) { LLAccordionCtrlTab* tab = (LLAccordionCtrlTab*)*iter; tab->setRightMouseDownCallback(boost::bind(&LLTeleportHistoryPanel::onAccordionTabRightClick, this, _1, _2, _3, _4)); tab->setDisplayChildren(false); tab->setDropDownStateChangedCallback(boost::bind(&LLTeleportHistoryPanel::onAccordionExpand, this, _1, _2)); // All accordion tabs are collapsed initially setAccordionCollapsedByUser(tab, true); mItemContainers.put(tab); LLFlatListView* fl = getFlatListViewFromTab(tab); if (fl) { fl->setCommitOnSelectionChange(true); fl->setDoubleClickCallback(boost::bind(&LLTeleportHistoryPanel::onDoubleClickItem, this)); fl->setCommitCallback(boost::bind(&LLTeleportHistoryPanel::handleItemSelect, this, fl)); fl->setReturnCallback(boost::bind(&LLTeleportHistoryPanel::onReturnKeyPressed, this)); } } } // Open first 2 accordion tabs if (mItemContainers.size() > 1) { LLAccordionCtrlTab* tab = mItemContainers.get(mItemContainers.size() - 1); tab->setDisplayChildren(true); setAccordionCollapsedByUser(tab, false); } if (mItemContainers.size() > 2) { LLAccordionCtrlTab* tab = mItemContainers.get(mItemContainers.size() - 2); tab->setDisplayChildren(true); setAccordionCollapsedByUser(tab, false); } } LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("TeleportHistory.ExpandAllFolders", boost::bind(&LLTeleportHistoryPanel::onExpandAllFolders, this)); registrar.add("TeleportHistory.CollapseAllFolders", boost::bind(&LLTeleportHistoryPanel::onCollapseAllFolders, this)); registrar.add("TeleportHistory.ClearTeleportHistory", boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistory, this)); mEnableCallbackRegistrar.add("TeleportHistory.GearMenu.Enable", boost::bind(&LLTeleportHistoryPanel::isActionEnabled, this, _2)); mMenuGearButton = getChild<LLMenuButton>("gear_btn"); LLToggleableMenu* gear_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_teleport_history_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());; if(gear_menu) { mGearMenuHandle = gear_menu->getHandle(); mMenuGearButton->setMenu(gear_menu); } return TRUE; }