00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include <utility>
00035
00036 #include "llinventoryview.h"
00037 #include "llinventorybridge.h"
00038
00039 #include "message.h"
00040
00041 #include "llagent.h"
00042 #include "llcallingcard.h"
00043 #include "llcheckboxctrl.h"
00044 #include "llradiogroup.h"
00045 #include "llspinctrl.h"
00046 #include "lltextbox.h"
00047 #include "llui.h"
00048
00049 #include "llfirstuse.h"
00050 #include "llfloateravatarinfo.h"
00051 #include "llfloaterchat.h"
00052 #include "llfloatercustomize.h"
00053 #include "llfocusmgr.h"
00054 #include "llfolderview.h"
00055 #include "llgesturemgr.h"
00056 #include "lliconctrl.h"
00057 #include "llinventorymodel.h"
00058 #include "llinventoryclipboard.h"
00059 #include "lllineeditor.h"
00060 #include "llmenugl.h"
00061 #include "llpreviewanim.h"
00062 #include "llpreviewgesture.h"
00063 #include "llpreviewlandmark.h"
00064 #include "llpreviewnotecard.h"
00065 #include "llpreviewscript.h"
00066 #include "llpreviewsound.h"
00067 #include "llpreviewtexture.h"
00068 #include "llresmgr.h"
00069 #include "llscrollcontainer.h"
00070 #include "llscrollbar.h"
00071 #include "llimview.h"
00072 #include "lltooldraganddrop.h"
00073 #include "llviewerimagelist.h"
00074 #include "llviewerinventory.h"
00075 #include "llviewerobjectlist.h"
00076 #include "llviewerwindow.h"
00077 #include "llwearablelist.h"
00078 #include "viewer.h"
00079 #include "llviewermessage.h"
00080 #include "llviewerregion.h"
00081 #include "lltabcontainer.h"
00082 #include "llvieweruictrlfactory.h"
00083 #include "llselectmgr.h"
00084
00085 #include "llsdserialize.h"
00086
00087 LLDynamicArray<LLInventoryView*> LLInventoryView::sActiveViews;
00088
00089
00090 BOOL LLInventoryView::sWearNewClothing = FALSE;
00091 LLUUID LLInventoryView::sWearNewClothingTransactionID;
00092
00096
00097 const S32 INV_MIN_WIDTH = 240;
00098 const S32 INV_MIN_HEIGHT = 150;
00099 const S32 INV_FINDER_WIDTH = 160;
00100 const S32 INV_FINDER_HEIGHT = 408;
00101
00105
00106 LLInventoryViewFinder::LLInventoryViewFinder(const LLString& name,
00107 const LLRect& rect,
00108 LLInventoryView* inventory_view) :
00109 LLFloater(name, rect, "Filters", RESIZE_NO,
00110 INV_FINDER_WIDTH, INV_FINDER_HEIGHT, DRAG_ON_TOP,
00111 MINIMIZE_NO, CLOSE_YES),
00112 mInventoryView(inventory_view),
00113 mFilter(inventory_view->mActivePanel->getFilter())
00114 {
00115
00116 gUICtrlFactory->buildFloater(this, "floater_inventory_view_finder.xml");
00117
00118 childSetAction("All", selectAllTypes, this);
00119 childSetAction("None", selectNoTypes, this);
00120
00121 mSpinSinceHours = LLUICtrlFactory::getSpinnerByName(this, "spin_hours_ago");
00122 childSetCommitCallback("spin_hours_ago", onTimeAgo, this);
00123
00124 mSpinSinceDays = LLUICtrlFactory::getSpinnerByName(this, "spin_days_ago");
00125 childSetCommitCallback("spin_days_ago", onTimeAgo, this);
00126
00127
00128 childSetCommitCallback("check_since_logoff", onCheckSinceLogoff, this);
00129
00130 childSetAction("Close", onCloseBtn, this);
00131
00132 updateElementsFromFilter();
00133 }
00134
00135
00136 void LLInventoryViewFinder::onCheckSinceLogoff(LLUICtrl *ctrl, void *user_data)
00137 {
00138 LLInventoryViewFinder *self = (LLInventoryViewFinder *)user_data;
00139 if (!self) return;
00140
00141 bool since_logoff= self->childGetValue("check_since_logoff");
00142
00143 if (!since_logoff &&
00144 !( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() ) )
00145 {
00146 self->mSpinSinceHours->set(1.0f);
00147 }
00148 }
00149
00150 void LLInventoryViewFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data)
00151 {
00152 LLInventoryViewFinder *self = (LLInventoryViewFinder *)user_data;
00153 if (!self) return;
00154
00155 bool since_logoff=true;
00156 if ( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() )
00157 {
00158 since_logoff = false;
00159 }
00160 self->childSetValue("check_since_logoff", since_logoff);
00161 }
00162
00163 void LLInventoryViewFinder::changeFilter(LLInventoryFilter* filter)
00164 {
00165 mFilter = filter;
00166 updateElementsFromFilter();
00167 }
00168
00169 void LLInventoryViewFinder::updateElementsFromFilter()
00170 {
00171 if (!mFilter)
00172 return;
00173
00174
00175 U32 filter_types = mFilter->getFilterTypes();
00176 LLString filter_string = mFilter->getFilterSubString();
00177 LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState();
00178 U32 hours = mFilter->getHoursAgo();
00179
00180
00181 LLFloater::setTitle(mFilter->getName());
00182 childSetValue("check_animation", (S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION));
00183
00184 childSetValue("check_calling_card", (S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD));
00185 childSetValue("check_clothing", (S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
00186 childSetValue("check_gesture", (S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
00187 childSetValue("check_landmark", (S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
00188 childSetValue("check_notecard", (S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
00189 childSetValue("check_object", (S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
00190 childSetValue("check_script", (S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
00191 childSetValue("check_sound", (S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND));
00192 childSetValue("check_texture", (S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE));
00193 childSetValue("check_snapshot", (S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT));
00194 childSetValue("check_show_empty", show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS);
00195 childSetValue("check_since_logoff", mFilter->isSinceLogoff());
00196 mSpinSinceHours->set((F32)(hours % 24));
00197 mSpinSinceDays->set((F32)(hours / 24));
00198 }
00199
00200 void LLInventoryViewFinder::draw()
00201 {
00202 U32 filter = 0xffffffff;
00203 BOOL filtered_by_all_types = TRUE;
00204
00205 if (!childGetValue("check_animation"))
00206 {
00207 filter &= ~(0x1 << LLInventoryType::IT_ANIMATION);
00208 filtered_by_all_types = FALSE;
00209 }
00210
00211
00212 if (!childGetValue("check_calling_card"))
00213 {
00214 filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD);
00215 filtered_by_all_types = FALSE;
00216 }
00217
00218 if (!childGetValue("check_clothing"))
00219 {
00220 filter &= ~(0x1 << LLInventoryType::IT_WEARABLE);
00221 filtered_by_all_types = FALSE;
00222 }
00223
00224 if (!childGetValue("check_gesture"))
00225 {
00226 filter &= ~(0x1 << LLInventoryType::IT_GESTURE);
00227 filtered_by_all_types = FALSE;
00228 }
00229
00230 if (!childGetValue("check_landmark"))
00231
00232
00233 {
00234 filter &= ~(0x1 << LLInventoryType::IT_LANDMARK);
00235 filtered_by_all_types = FALSE;
00236 }
00237
00238 if (!childGetValue("check_notecard"))
00239 {
00240 filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
00241 filtered_by_all_types = FALSE;
00242 }
00243
00244 if (!childGetValue("check_object"))
00245 {
00246 filter &= ~(0x1 << LLInventoryType::IT_OBJECT);
00247 filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT);
00248 filtered_by_all_types = FALSE;
00249 }
00250
00251 if (!childGetValue("check_script"))
00252 {
00253 filter &= ~(0x1 << LLInventoryType::IT_LSL);
00254 filtered_by_all_types = FALSE;
00255 }
00256
00257 if (!childGetValue("check_sound"))
00258 {
00259 filter &= ~(0x1 << LLInventoryType::IT_SOUND);
00260 filtered_by_all_types = FALSE;
00261 }
00262
00263 if (!childGetValue("check_texture"))
00264 {
00265 filter &= ~(0x1 << LLInventoryType::IT_TEXTURE);
00266 filtered_by_all_types = FALSE;
00267 }
00268
00269 if (!childGetValue("check_snapshot"))
00270 {
00271 filter &= ~(0x1 << LLInventoryType::IT_SNAPSHOT);
00272 filtered_by_all_types = FALSE;
00273 }
00274
00275 if (!filtered_by_all_types)
00276 {
00277
00278 filter &= ~(0x1 << LLInventoryType::IT_CATEGORY);
00279 }
00280
00281
00282 mInventoryView->mActivePanel->setShowFolderState(getCheckShowEmpty() ?
00283 LLInventoryFilter::SHOW_ALL_FOLDERS : LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
00284 mInventoryView->mActivePanel->setFilterTypes(filter);
00285 if (getCheckSinceLogoff())
00286 {
00287 mSpinSinceDays->set(0);
00288 mSpinSinceHours->set(0);
00289 }
00290 U32 days = (U32)mSpinSinceDays->get();
00291 U32 hours = (U32)mSpinSinceHours->get();
00292 if (hours > 24)
00293 {
00294 days += hours / 24;
00295 hours = (U32)hours % 24;
00296 mSpinSinceDays->set((F32)days);
00297 mSpinSinceHours->set((F32)hours);
00298 }
00299 hours += days * 24;
00300 mInventoryView->mActivePanel->setHoursAgo(hours);
00301 mInventoryView->mActivePanel->setSinceLogoff(getCheckSinceLogoff());
00302 mInventoryView->setFilterTextFromFilter();
00303
00304 LLFloater::draw();
00305 }
00306
00307 void LLInventoryViewFinder::onClose(bool app_quitting)
00308 {
00309 if (mInventoryView) mInventoryView->getControl("Inventory.ShowFilters")->setValue(FALSE);
00310
00311
00312 #if 0
00313 if (mInventoryView)
00314 {
00315 LLInventoryView::onResetFilter((void *)mInventoryView);
00316 }
00317 #endif
00318 destroy();
00319 }
00320
00321
00322 BOOL LLInventoryViewFinder::getCheckShowEmpty()
00323 {
00324 return childGetValue("check_show_empty");
00325 }
00326
00327 BOOL LLInventoryViewFinder::getCheckSinceLogoff()
00328 {
00329 return childGetValue("check_since_logoff");
00330 }
00331
00332 void LLInventoryViewFinder::onCloseBtn(void* user_data)
00333 {
00334 LLInventoryViewFinder* finderp = (LLInventoryViewFinder*)user_data;
00335 finderp->close();
00336 }
00337
00338
00339 void LLInventoryViewFinder::selectAllTypes(void* user_data)
00340 {
00341 LLInventoryViewFinder* self = (LLInventoryViewFinder*)user_data;
00342 if(!self) return;
00343
00344 self->childSetValue("check_animation", TRUE);
00345 self->childSetValue("check_calling_card", TRUE);
00346 self->childSetValue("check_clothing", TRUE);
00347 self->childSetValue("check_gesture", TRUE);
00348 self->childSetValue("check_landmark", TRUE);
00349 self->childSetValue("check_notecard", TRUE);
00350 self->childSetValue("check_object", TRUE);
00351 self->childSetValue("check_script", TRUE);
00352 self->childSetValue("check_sound", TRUE);
00353 self->childSetValue("check_texture", TRUE);
00354 self->childSetValue("check_snapshot", TRUE);
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 }
00368
00369
00370 void LLInventoryViewFinder::selectNoTypes(void* user_data)
00371 {
00372 LLInventoryViewFinder* self = (LLInventoryViewFinder*)user_data;
00373 if(!self) return;
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 self->childSetValue("check_animation", FALSE);
00390 self->childSetValue("check_calling_card", FALSE);
00391 self->childSetValue("check_clothing", FALSE);
00392 self->childSetValue("check_gesture", FALSE);
00393 self->childSetValue("check_landmark", FALSE);
00394 self->childSetValue("check_notecard", FALSE);
00395 self->childSetValue("check_object", FALSE);
00396 self->childSetValue("check_script", FALSE);
00397 self->childSetValue("check_sound", FALSE);
00398 self->childSetValue("check_texture", FALSE);
00399 self->childSetValue("check_snapshot", FALSE);
00400 }
00401
00402
00406 void LLSaveFolderState::setApply(BOOL apply)
00407 {
00408 mApply = apply;
00409
00410 if(!apply)
00411 {
00412 clearOpenFolders();
00413 }
00414 }
00415
00416 void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
00417 {
00418 if(mApply)
00419 {
00420
00421 LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
00422 if(!bridge) return;
00423 LLUUID id(bridge->getUUID());
00424 if(mOpenFolders.find(id) != mOpenFolders.end())
00425 {
00426 folder->setOpen(TRUE);
00427 }
00428 else
00429 {
00430
00431 if (!folder->isSelected())
00432 {
00433 folder->setOpen(FALSE);
00434 }
00435 }
00436 }
00437 else
00438 {
00439
00440 if(folder->isOpen())
00441 {
00442 LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
00443 if(!bridge) return;
00444 mOpenFolders.insert(bridge->getUUID());
00445 }
00446 }
00447 }
00448
00449
00450 LLInventoryView::LLInventoryView(const LLString& name,
00451 const LLString& rect,
00452 LLInventoryModel* inventory) :
00453 LLFloater(name, rect, "Inventory", RESIZE_YES,
00454 INV_MIN_WIDTH, INV_MIN_HEIGHT, DRAG_ON_TOP,
00455 MINIMIZE_NO, CLOSE_YES)
00456
00457 {
00458 init(inventory);
00459 }
00460
00461 LLInventoryView::LLInventoryView(const LLString& name,
00462 const LLRect& rect,
00463 LLInventoryModel* inventory) :
00464 LLFloater(name, rect, "Inventory", RESIZE_YES,
00465 INV_MIN_WIDTH, INV_MIN_HEIGHT, DRAG_ON_TOP,
00466 MINIMIZE_NO, CLOSE_YES)
00467
00468 {
00469 init(inventory);
00470 setRect(rect);
00471 }
00472
00473
00474 void LLInventoryView::init(LLInventoryModel* inventory)
00475 {
00476
00477 init_inventory_actions(this);
00478
00479
00480 U32 sort_order = gSavedSettings.getU32("InventorySortOrder");
00481 BOOL sort_by_name = ! ( sort_order & LLInventoryFilter::SO_DATE );
00482 BOOL sort_folders_by_name = ( sort_order & LLInventoryFilter::SO_FOLDERS_BY_NAME );
00483 BOOL sort_system_folders_to_top = ( sort_order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP );
00484
00485 addBoolControl("Inventory.ShowFilters", FALSE);
00486 addBoolControl("Inventory.SortByName", sort_by_name );
00487 addBoolControl("Inventory.SortByDate", ! sort_by_name );
00488 addBoolControl("Inventory.FoldersAlwaysByName", sort_folders_by_name );
00489 addBoolControl("Inventory.SystemFoldersToTop", sort_system_folders_to_top );
00490
00491 mSavedFolderState = new LLSaveFolderState();
00492 mSavedFolderState->setApply(FALSE);
00493
00494 gUICtrlFactory->buildFloater(this, "floater_inventory.xml", NULL);
00495
00496 mFilterTabs = (LLTabContainer*)LLUICtrlFactory::getTabContainerByName(this, "inventory filter tabs");
00497
00498
00499 mActivePanel = (LLInventoryPanel*)getCtrlByNameAndType("All Items", WIDGET_TYPE_INVENTORY_PANEL);
00500 if (mActivePanel)
00501 {
00502
00503 mActivePanel->setSortOrder(gSavedSettings.getU32("InventorySortOrder"));
00504 mActivePanel->getFilter()->markDefault();
00505 mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
00506 mActivePanel->setSelectCallback(onSelectionChange, mActivePanel);
00507 }
00508 LLInventoryPanel* recent_items_panel = (LLInventoryPanel*)getCtrlByNameAndType("Recent Items", WIDGET_TYPE_INVENTORY_PANEL);
00509 if (recent_items_panel)
00510 {
00511 recent_items_panel->setSinceLogoff(TRUE);
00512 recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
00513 recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
00514 recent_items_panel->getFilter()->markDefault();
00515 recent_items_panel->setSelectCallback(onSelectionChange, recent_items_panel);
00516 }
00517
00518
00519 std::ostringstream filterSaveName;
00520 filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml");
00521 llinfos << "LLInventoryView::init: reading from " << filterSaveName << llendl;
00522 llifstream file(filterSaveName.str().c_str());
00523 LLSD savedFilterState;
00524 if (file.is_open())
00525 {
00526 LLSDSerialize::fromXML(savedFilterState, file);
00527 file.close();
00528
00529
00530
00531 if(recent_items_panel)
00532 {
00533 if(savedFilterState.has(recent_items_panel->getFilter()->getName()))
00534 {
00535 LLSD recent_items = savedFilterState.get(
00536 recent_items_panel->getFilter()->getName());
00537 recent_items_panel->getFilter()->fromLLSD(recent_items);
00538 }
00539 }
00540
00541 }
00542
00543
00544 mSearchEditor = (LLSearchEditor*)getCtrlByNameAndType("inventory search editor", WIDGET_TYPE_SEARCH_EDITOR);
00545 if (mSearchEditor)
00546 {
00547 mSearchEditor->setSearchCallback(onSearchEdit, this);
00548 }
00549
00550 sActiveViews.put(this);
00551
00552 gInventory.addObserver(this);
00553 }
00554
00555 BOOL LLInventoryView::postBuild()
00556 {
00557 childSetTabChangeCallback("inventory filter tabs", "All Items", onFilterSelected, this);
00558 childSetTabChangeCallback("inventory filter tabs", "Recent Items", onFilterSelected, this);
00559
00560 return TRUE;
00561 }
00562
00563
00564 LLInventoryView::~LLInventoryView( void )
00565 {
00566
00567 LLSD filterRoot;
00568 LLInventoryPanel* all_items_panel = (LLInventoryPanel*)getCtrlByNameAndType("All Items", WIDGET_TYPE_INVENTORY_PANEL);
00569 if (all_items_panel)
00570 {
00571 LLInventoryFilter* filter = all_items_panel->getFilter();
00572 LLSD filterState;
00573 filter->toLLSD(filterState);
00574 filterRoot[filter->getName()] = filterState;
00575 }
00576
00577 LLInventoryPanel* recent_items_panel = (LLInventoryPanel*)getCtrlByNameAndType("Recent Items", WIDGET_TYPE_INVENTORY_PANEL);
00578 if (recent_items_panel)
00579 {
00580 LLInventoryFilter* filter = recent_items_panel->getFilter();
00581 LLSD filterState;
00582 filter->toLLSD(filterState);
00583 filterRoot[filter->getName()] = filterState;
00584 }
00585
00586 std::ostringstream filterSaveName;
00587 filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml");
00588 llofstream filtersFile(filterSaveName.str().c_str());
00589 if(!LLSDSerialize::toPrettyXML(filterRoot, filtersFile))
00590 {
00591 llwarns << "Could not write to filters save file " << filterSaveName << llendl;
00592 }
00593 else
00594 filtersFile.close();
00595
00596 sActiveViews.removeObj(this);
00597 gInventory.removeObserver(this);
00598 delete mSavedFolderState;
00599 }
00600
00601 void LLInventoryView::draw()
00602 {
00603 if (LLInventoryModel::isEverythingFetched())
00604 {
00605 LLLocale locale(LLLocale::USER_LOCALE);
00606 std::ostringstream title;
00607 title << "Inventory";
00608 LLString item_count_string;
00609 gResMgr->getIntegerString(item_count_string, gInventory.getItemCount());
00610 title << " (" << item_count_string << " items)";
00611 title << mFilterText;
00612 setTitle(title.str());
00613 }
00614 if (mActivePanel && mSearchEditor)
00615 {
00616 mSearchEditor->setText(mActivePanel->getFilterSubString());
00617 }
00618 LLFloater::draw();
00619 }
00620
00621 void LLOpenFilteredFolders::doItem(LLFolderViewItem *item)
00622 {
00623 if (item->getFiltered())
00624 {
00625 item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
00626 }
00627 }
00628
00629 void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder)
00630 {
00631 if (folder->getFiltered() && folder->getParentFolder())
00632 {
00633 folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
00634 }
00635
00636 else if (!folder->getFiltered() && !folder->hasFilteredDescendants())
00637 {
00638 folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_NO);
00639 }
00640 }
00641
00642 void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item)
00643 {
00644 if (item->getFiltered() && !mItemSelected)
00645 {
00646 item->getRoot()->setSelection(item, FALSE, FALSE);
00647 if (item->getParentFolder())
00648 {
00649 item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
00650 }
00651 item->getRoot()->scrollToShowSelection();
00652 mItemSelected = TRUE;
00653 }
00654 }
00655
00656 void LLSelectFirstFilteredItem::doFolder(LLFolderViewFolder* folder)
00657 {
00658 if (folder->getFiltered() && !mItemSelected)
00659 {
00660 folder->getRoot()->setSelection(folder, FALSE, FALSE);
00661 if (folder->getParentFolder())
00662 {
00663 folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
00664 }
00665 folder->getRoot()->scrollToShowSelection();
00666 mItemSelected = TRUE;
00667 }
00668 }
00669
00670 void LLOpenFoldersWithSelection::doItem(LLFolderViewItem *item)
00671 {
00672 if (item->getParentFolder() && item->isSelected())
00673 {
00674 item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
00675 }
00676 }
00677
00678 void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder)
00679 {
00680 if (folder->getParentFolder() && folder->isSelected())
00681 {
00682 folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
00683 }
00684 }
00685
00686 void LLInventoryView::startSearch()
00687 {
00688
00689 if (mSearchEditor)
00690 {
00691 mSearchEditor->focusFirstItem(TRUE);
00692 }
00693 }
00694
00695
00696 void LLInventoryView::setVisible( BOOL visible )
00697 {
00698 gSavedSettings.setBOOL("ShowInventory", visible);
00699 LLFloater::setVisible(visible);
00700 }
00701
00702
00703 void LLInventoryView::onClose(bool app_quitting)
00704 {
00705 S32 count = sActiveViews.count();
00706 if (count > 1)
00707 {
00708 destroy();
00709 }
00710 else
00711 {
00712 if (!app_quitting)
00713 {
00714 gSavedSettings.setBOOL("ShowInventory", FALSE);
00715 }
00716
00717 if (!mActivePanel->getRootFolder()->isFilterModified())
00718 {
00719 mSavedFolderState->setApply(FALSE);
00720 mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
00721 }
00722
00723
00724
00725
00726 LLFloater::setVisible(FALSE);
00727 }
00728 }
00729
00730 BOOL LLInventoryView::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)
00731 {
00732 LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL;
00733 if (root_folder)
00734 {
00735
00736 if (!called_from_parent
00737 && mSearchEditor && mSearchEditor->hasFocus()
00738 && (key == KEY_RETURN || key == KEY_DOWN)
00739 && mask == MASK_NONE)
00740 {
00741
00742 root_folder->setFocus(TRUE);
00743 root_folder->scrollToShowSelection();
00744 return TRUE;
00745 }
00746
00747 if (root_folder->hasFocus() && key == KEY_UP)
00748 {
00749 startSearch();
00750 }
00751 }
00752
00753 return LLFloater::handleKeyHere(key, mask, called_from_parent);
00754
00755 }
00756
00757 void LLInventoryView::changed(U32 mask)
00758 {
00759 std::ostringstream title;
00760 title << "Inventory";
00761 if (LLInventoryModel::backgroundFetchActive())
00762 {
00763 LLLocale locale(LLLocale::USER_LOCALE);
00764 LLString item_count_string;
00765 gResMgr->getIntegerString(item_count_string, gInventory.getItemCount());
00766 title << " (Fetched " << item_count_string << " items...)";
00767 }
00768 title << mFilterText;
00769 setTitle(title.str());
00770 }
00771
00772
00773
00774 LLInventoryView* LLInventoryView::showAgentInventory(BOOL take_keyboard_focus)
00775 {
00776 if (gDisconnected || gNoRender)
00777 {
00778 return NULL;
00779 }
00780
00781 LLInventoryView* iv = LLInventoryView::getActiveInventory();
00782 #if 0 && !LL_RELEASE_FOR_DOWNLOAD
00783 if (sActiveViews.count() == 1)
00784 {
00785 delete iv;
00786 iv = NULL;
00787 }
00788 #endif
00789 if(!iv && !gAgent.cameraMouselook())
00790 {
00791
00792 iv = new LLInventoryView("Inventory",
00793 "FloaterInventoryRect",
00794 &gInventory);
00795 iv->open();
00796
00797 gFloaterView->adjustToFitScreen(iv, FALSE);
00798
00799 gSavedSettings.setBOOL("ShowInventory", TRUE);
00800 }
00801 if(iv)
00802 {
00803
00804 iv->setTitle("Inventory");
00805 iv->open();
00806 }
00807
00808
00809
00810
00811
00812 return iv;
00813 }
00814
00815
00816 LLInventoryView* LLInventoryView::getActiveInventory()
00817 {
00818 LLInventoryView* iv = NULL;
00819 S32 count = sActiveViews.count();
00820 if(count > 0)
00821 {
00822 iv = sActiveViews.get(0);
00823 S32 z_order = gFloaterView->getZOrder(iv);
00824 S32 z_next = 0;
00825 LLInventoryView* next_iv = NULL;
00826 for(S32 i = 1; i < count; ++i)
00827 {
00828 next_iv = sActiveViews.get(i);
00829 z_next = gFloaterView->getZOrder(next_iv);
00830 if(z_next < z_order)
00831 {
00832 iv = next_iv;
00833 z_order = z_next;
00834 }
00835 }
00836 }
00837 return iv;
00838 }
00839
00840
00841 void LLInventoryView::toggleVisibility()
00842 {
00843 S32 count = sActiveViews.count();
00844 if (0 == count)
00845 {
00846 showAgentInventory(TRUE);
00847 }
00848 else if (1 == count)
00849 {
00850 if (sActiveViews.get(0)->getVisible())
00851 {
00852 sActiveViews.get(0)->close();
00853 gSavedSettings.setBOOL("ShowInventory", FALSE);
00854 }
00855 else
00856 {
00857 showAgentInventory(TRUE);
00858 }
00859 }
00860 else
00861 {
00862
00863
00864
00865
00866 S32 last_index = sActiveViews.count() - 1;
00867 sActiveViews.get(last_index)->close();
00868 }
00869 }
00870
00871
00872 void LLInventoryView::cleanup()
00873 {
00874 S32 count = sActiveViews.count();
00875 for (S32 i = 0; i < count; i++)
00876 {
00877 sActiveViews.get(i)->destroy();
00878 }
00879 }
00880
00881 void LLInventoryView::toggleFindOptions()
00882 {
00883 LLFloater *floater = getFinder();
00884 if (!floater)
00885 {
00886 LLInventoryViewFinder * finder = new LLInventoryViewFinder("Inventory Finder",
00887 LLRect(mRect.mLeft - INV_FINDER_WIDTH, mRect.mTop, mRect.mLeft, mRect.mTop - INV_FINDER_HEIGHT),
00888 this);
00889 mFinderHandle = finder->getHandle();
00890 finder->open();
00891 addDependentFloater(mFinderHandle);
00892
00893
00894 gInventory.startBackgroundFetch();
00895
00896 mFloaterControls["Inventory.ShowFilters"]->setValue(TRUE);
00897 }
00898 else
00899 {
00900 floater->close();
00901
00902 mFloaterControls["Inventory.ShowFilters"]->setValue(FALSE);
00903 }
00904 }
00905
00906
00907 BOOL LLInventoryView::filtersVisible(void* user_data)
00908 {
00909 LLInventoryView* self = (LLInventoryView*)user_data;
00910 if(!self) return FALSE;
00911
00912 return self->getFinder() != NULL;
00913 }
00914
00915
00916 void LLInventoryView::onClearSearch(void* user_data)
00917 {
00918 LLInventoryView* self = (LLInventoryView*)user_data;
00919 if(!self) return;
00920
00921 LLFloater *finder = self->getFinder();
00922 if (self->mActivePanel)
00923 {
00924 self->mActivePanel->setFilterSubString("");
00925 self->mActivePanel->setFilterTypes(0xffffffff);
00926 }
00927
00928 if (finder)
00929 {
00930 LLInventoryViewFinder::selectAllTypes(finder);
00931 }
00932
00933
00934 if (self->mActivePanel)
00935 {
00936 self->mSavedFolderState->setApply(TRUE);
00937 self->mActivePanel->getRootFolder()->applyFunctorRecursively(*self->mSavedFolderState);
00938 LLOpenFoldersWithSelection opener;
00939 self->mActivePanel->getRootFolder()->applyFunctorRecursively(opener);
00940 self->mActivePanel->getRootFolder()->scrollToShowSelection();
00941 }
00942 }
00943
00944
00945 void LLInventoryView::onSearchEdit(const LLString& search_string, void* user_data )
00946 {
00947 if (search_string == "")
00948 {
00949 onClearSearch(user_data);
00950 }
00951 LLInventoryView* self = (LLInventoryView*)user_data;
00952 if (!self->mActivePanel)
00953 {
00954 return;
00955 }
00956
00957 gInventory.startBackgroundFetch();
00958
00959 LLString filter_text = search_string;
00960 LLString uppercase_search_string = filter_text;
00961 LLString::toUpper(uppercase_search_string);
00962 if (self->mActivePanel->getFilterSubString().empty() && uppercase_search_string.empty())
00963 {
00964
00965 return;
00966 }
00967
00968
00969 if (!self->mActivePanel->getRootFolder()->isFilterModified())
00970 {
00971 self->mSavedFolderState->setApply(FALSE);
00972 self->mActivePanel->getRootFolder()->applyFunctorRecursively(*self->mSavedFolderState);
00973 }
00974
00975
00976 self->mActivePanel->setFilterSubString(uppercase_search_string);
00977 }
00978
00979
00980
00981 BOOL LLInventoryView::incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward)
00982 {
00983 LLInventoryView* active_view = NULL;
00984
00985 for (S32 i = 0; i < sActiveViews.count(); i++)
00986 {
00987 if (gFocusMgr.childHasKeyboardFocus(sActiveViews[i]))
00988 {
00989 active_view = sActiveViews[i];
00990 break;
00991 }
00992 }
00993
00994 if (!active_view)
00995 {
00996 return FALSE;
00997 }
00998
00999 LLString search_string(find_text);
01000
01001 if (search_string.empty())
01002 {
01003 return FALSE;
01004 }
01005
01006 if (active_view->mActivePanel &&
01007 active_view->mActivePanel->getRootFolder()->search(first_item, search_string, backward))
01008 {
01009 return TRUE;
01010 }
01011
01012 return FALSE;
01013 }
01014
01015
01016 void LLInventoryView::onFilterSelected(void* userdata, bool from_click)
01017 {
01018 LLInventoryView* self = (LLInventoryView*) userdata;
01019 LLInventoryFilter* filter;
01020
01021 LLInventoryViewFinder *finder = self->getFinder();
01022
01023 self->mActivePanel = (LLInventoryPanel*)self->childGetVisibleTab("inventory filter tabs");
01024
01025 if (!self->mActivePanel)
01026 {
01027 return;
01028 }
01029 filter = self->mActivePanel->getFilter();
01030 if (finder)
01031 {
01032 finder->changeFilter(filter);
01033 }
01034 if (filter->isActive())
01035 {
01036
01037 gInventory.startBackgroundFetch();
01038 }
01039 self->setFilterTextFromFilter();
01040 }
01041
01042
01043 void LLInventoryView::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data)
01044 {
01045 LLInventoryPanel* panel = (LLInventoryPanel*)data;
01046 LLFolderView* fv = panel->getRootFolder();
01047 if (fv->needsAutoRename())
01048 {
01049 fv->setNeedsAutoRename(FALSE);
01050 if (items.size())
01051 {
01052 fv->startRenamingSelectedItem();
01053 }
01054 }
01055 }
01056
01057 BOOL LLInventoryView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
01058 EDragAndDropType cargo_type,
01059 void* cargo_data,
01060 EAcceptance* accept,
01061 LLString& tooltip_msg)
01062 {
01063
01064 LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel();
01065 BOOL needsToScroll = panel->getScrollableContainer()->needsToScroll(x, y, LLScrollableContainerView::VERTICAL);
01066 if(mFilterTabs)
01067 {
01068 if(needsToScroll)
01069 {
01070 mFilterTabs->setDragAndDropDelayTimer();
01071 }
01072 }
01073
01074 BOOL handled = LLFloater::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
01075
01076 return handled;
01077 }
01078 LLUUID get_item_icon_uuid(LLAssetType::EType asset_type,
01079 LLInventoryType::EType inventory_type,
01080 U32 attachment_point,
01081 BOOL item_is_multi )
01082 {
01083 EInventoryIcon idx = OBJECT_ICON_NAME;
01084 if ( item_is_multi )
01085 {
01086 idx = OBJECT_MULTI_ICON_NAME;
01087 }
01088
01089 switch(asset_type)
01090 {
01091 case LLAssetType::AT_TEXTURE:
01092 if(LLInventoryType::IT_SNAPSHOT == inventory_type)
01093 {
01094 idx = SNAPSHOT_ICON_NAME;
01095 }
01096 else
01097 {
01098 idx = TEXTURE_ICON_NAME;
01099 }
01100 break;
01101
01102 case LLAssetType::AT_SOUND:
01103 idx = SOUND_ICON_NAME;
01104 break;
01105 case LLAssetType::AT_CALLINGCARD:
01106 if(attachment_point!= 0)
01107 {
01108 idx = CALLINGCARD_ONLINE_ICON_NAME;
01109 }
01110 else
01111 {
01112 idx = CALLINGCARD_OFFLINE_ICON_NAME;
01113 }
01114 break;
01115 case LLAssetType::AT_LANDMARK:
01116 if(attachment_point!= 0)
01117 {
01118 idx = LANDMARK_VISITED_ICON_NAME;
01119 }
01120 else
01121 {
01122 idx = LANDMARK_ICON_NAME;
01123 }
01124 break;
01125 case LLAssetType::AT_SCRIPT:
01126 case LLAssetType::AT_LSL_TEXT:
01127 case LLAssetType::AT_LSL_BYTECODE:
01128 idx = SCRIPT_ICON_NAME;
01129 break;
01130 case LLAssetType::AT_CLOTHING:
01131 idx = CLOTHING_ICON_NAME;
01132 case LLAssetType::AT_BODYPART :
01133 if(LLAssetType::AT_BODYPART == asset_type)
01134 {
01135 idx = BODYPART_ICON_NAME;
01136 }
01137 switch(attachment_point)
01138 {
01139 case WT_SHAPE:
01140 idx = BODYPART_SHAPE_ICON_NAME;
01141 break;
01142 case WT_SKIN:
01143 idx = BODYPART_SKIN_ICON_NAME;
01144 break;
01145 case WT_HAIR:
01146 idx = BODYPART_HAIR_ICON_NAME;
01147 break;
01148 case WT_EYES:
01149 idx = BODYPART_EYES_ICON_NAME;
01150 break;
01151 case WT_SHIRT:
01152 idx = CLOTHING_SHIRT_ICON_NAME;
01153 break;
01154 case WT_PANTS:
01155 idx = CLOTHING_PANTS_ICON_NAME;
01156 break;
01157 case WT_SHOES:
01158 idx = CLOTHING_SHOES_ICON_NAME;
01159 break;
01160 case WT_SOCKS:
01161 idx = CLOTHING_SOCKS_ICON_NAME;
01162 break;
01163 case WT_JACKET:
01164 idx = CLOTHING_JACKET_ICON_NAME;
01165 break;
01166 case WT_GLOVES:
01167 idx = CLOTHING_GLOVES_ICON_NAME;
01168 break;
01169 case WT_UNDERSHIRT:
01170 idx = CLOTHING_UNDERSHIRT_ICON_NAME;
01171 break;
01172 case WT_UNDERPANTS:
01173 idx = CLOTHING_UNDERPANTS_ICON_NAME;
01174 break;
01175 case WT_SKIRT:
01176 idx = CLOTHING_SKIRT_ICON_NAME;
01177 break;
01178 default:
01179
01180 break;
01181 }
01182 break;
01183 case LLAssetType::AT_NOTECARD:
01184 idx = NOTECARD_ICON_NAME;
01185 break;
01186 case LLAssetType::AT_ANIMATION:
01187 idx = ANIMATION_ICON_NAME;
01188 break;
01189 case LLAssetType::AT_GESTURE:
01190 idx = GESTURE_ICON_NAME;
01191 break;
01192 default:
01193 break;
01194 }
01195 LLString uuid_string = gViewerArt.getString(ICON_NAME[idx]);
01196 return LLUUID(uuid_string);
01197 }
01198
01199 LLViewerImage* get_item_icon(LLAssetType::EType asset_type,
01200 LLInventoryType::EType inventory_type,
01201 U32 attachment_point,
01202 BOOL item_is_multi)
01203 {
01204 LLUUID icon_uuid = get_item_icon_uuid(asset_type, inventory_type, attachment_point, item_is_multi );
01205 LLViewerImage* imagep = gImageList.getImage(icon_uuid, MIPMAP_FALSE, TRUE);
01206 imagep->setClamp(TRUE, TRUE);
01207 return imagep;
01208 }
01209
01210 const LLString LLInventoryPanel::DEFAULT_SORT_ORDER = LLString("InventorySortOrder");
01211 const LLString LLInventoryPanel::RECENTITEMS_SORT_ORDER = LLString("RecentItemsSortOrder");
01212 const LLString LLInventoryPanel::INHERIT_SORT_ORDER = LLString("");
01213
01214 LLInventoryPanel::LLInventoryPanel(const LLString& name,
01215 const LLString& sort_order_setting,
01216 const LLRect& rect,
01217 LLInventoryModel* inventory,
01218 LLFolderSearchFunction search,
01219 BOOL allow_multi_select,
01220 LLView *parent_view) :
01221 LLPanel(name, rect, TRUE),
01222 mInventory(inventory),
01223 mInventoryObserver(NULL),
01224 mFolders(NULL),
01225 mScroller(NULL),
01226 mAllowMultiSelect(allow_multi_select),
01227 mSortOrderSetting(sort_order_setting),
01228 mSearchFunction(search)
01229 {
01230 }
01231
01232 BOOL LLInventoryPanel::postBuild()
01233 {
01234 init_inventory_panel_actions(this);
01235
01236 LLRect folder_rect(0,
01237 0,
01238 mRect.getWidth(),
01239 0);
01240 mFolders = new LLFolderView(mName, NULL, folder_rect, LLUUID::null, this);
01241 mFolders->setAllowMultiSelect(mAllowMultiSelect);
01242
01243
01244 LLRect scroller_view_rect = mRect;
01245 scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
01246 mScroller = new LLScrollableContainerView("Inventory Scroller",
01247 scroller_view_rect,
01248 mFolders);
01249 mScroller->setFollowsAll();
01250 mScroller->setReserveScrollCorner(TRUE);
01251 addChild(mScroller);
01252 mFolders->setScrollContainer(mScroller);
01253
01254
01255
01256 mInventoryObserver = new LLInventoryPanelObserver(this);
01257 mInventory->addObserver(mInventoryObserver);
01258 rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD);
01259
01260
01261 mFolders->openFolder("My Inventory");
01262
01263 if (mSortOrderSetting != INHERIT_SORT_ORDER)
01264 {
01265 setSortOrder(gSavedSettings.getU32(mSortOrderSetting));
01266 }
01267 else
01268 {
01269 setSortOrder(gSavedSettings.getU32(DEFAULT_SORT_ORDER));
01270 }
01271 mFolders->setSortOrder(mFolders->getFilter()->getSortOrder());
01272
01273
01274 return TRUE;
01275 }
01276
01277 LLInventoryPanel::~LLInventoryPanel()
01278 {
01279
01280 U32 sort_order = mFolders->getSortOrder();
01281 if (mSortOrderSetting != INHERIT_SORT_ORDER)
01282 {
01283 gSavedSettings.setU32(mSortOrderSetting, sort_order);
01284 }
01285
01286
01287 mInventory->removeObserver(mInventoryObserver);
01288 delete mInventoryObserver;
01289 mScroller = NULL;
01290 }
01291
01292
01293 LLXMLNodePtr LLInventoryPanel::getXML(bool save_children) const
01294 {
01295 LLXMLNodePtr node = LLPanel::getXML(false);
01296
01297 node->createChild("allow_multi_select", TRUE)->setBoolValue(mFolders->getAllowMultiSelect());
01298
01299 return node;
01300 }
01301
01302 LLView* LLInventoryPanel::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
01303 {
01304 LLInventoryPanel* panel;
01305
01306 LLString name("inventory_panel");
01307 node->getAttributeString("name", name);
01308
01309 BOOL allow_multi_select = TRUE;
01310 node->getAttributeBOOL("allow_multi_select", allow_multi_select);
01311
01312 LLRect rect;
01313 createRect(node, rect, parent, LLRect());
01314
01315 LLString sort_order(INHERIT_SORT_ORDER);
01316 node->getAttributeString("sort_order", sort_order);
01317
01318 panel = new LLInventoryPanel(name, sort_order,
01319 rect, &gInventory,
01320 LLInventoryView::incrementalFind, allow_multi_select, parent);
01321
01322 panel->initFromXML(node, parent);
01323
01324 panel->postBuild();
01325
01326 return panel;
01327 }
01328
01329 void LLInventoryPanel::setFilterTypes(U32 filter_types)
01330 {
01331 mFolders->getFilter()->setFilterTypes(filter_types);
01332 }
01333
01334 void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask)
01335 {
01336 mFolders->getFilter()->setFilterPermissions(filter_perm_mask);
01337 }
01338
01339 void LLInventoryPanel::setFilterSubString(const LLString& string)
01340 {
01341 mFolders->getFilter()->setFilterSubString(string);
01342 }
01343
01344 void LLInventoryPanel::setSortOrder(U32 order)
01345 {
01346 mFolders->getFilter()->setSortOrder(order);
01347 if (mFolders->getFilter()->isModified())
01348 {
01349 mFolders->setSortOrder(order);
01350
01351 mFolders->scrollToShowSelection();
01352 }
01353 }
01354
01355 void LLInventoryPanel::setSinceLogoff(BOOL sl)
01356 {
01357 mFolders->getFilter()->setDateRangeLastLogoff(sl);
01358 }
01359
01360 void LLInventoryPanel::setHoursAgo(U32 hours)
01361 {
01362 mFolders->getFilter()->setHoursAgo(hours);
01363 }
01364
01365 void LLInventoryPanel::setShowFolderState(LLInventoryFilter::EFolderShow show)
01366 {
01367 mFolders->getFilter()->setShowFolderState(show);
01368 }
01369
01370 LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState()
01371 {
01372 return mFolders->getFilter()->getShowFolderState();
01373 }
01374
01375 void LLInventoryPanel::modelChanged(U32 mask)
01376 {
01377 LLFastTimer t2(LLFastTimer::FTM_REFRESH);
01378
01379 bool handled = false;
01380 if(mask & LLInventoryObserver::LABEL)
01381 {
01382 handled = true;
01383
01384
01385 const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
01386 std::set<LLUUID>::const_iterator id_it = changed_items.begin();
01387 std::set<LLUUID>::const_iterator id_end = changed_items.end();
01388 LLFolderViewItem* view = NULL;
01389 LLInvFVBridge* bridge = NULL;
01390 for (;id_it != id_end; ++id_it)
01391 {
01392 view = mFolders->getItemByID(*id_it);
01393 if(view)
01394 {
01395
01396 bridge = (LLInvFVBridge*)view->getListener();
01397 if(bridge)
01398 {
01399 bridge->clearDisplayName();
01400 }
01401 view->refresh();
01402 }
01403 }
01404 }
01405 if((mask & (LLInventoryObserver::STRUCTURE
01406 | LLInventoryObserver::ADD
01407 | LLInventoryObserver::REMOVE)) != 0)
01408 {
01409 handled = true;
01410
01411 LLInventoryModel* model = getModel();
01412 if (model)
01413 {
01414 const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
01415
01416 std::set<LLUUID>::const_iterator id_it = changed_items.begin();
01417 std::set<LLUUID>::const_iterator id_end = changed_items.end();
01418 for (;id_it != id_end; ++id_it)
01419 {
01420
01421 LLInventoryObject* model_item = model->getObject(*id_it);
01422 LLFolderViewItem* view_item = mFolders->getItemByID(*id_it);
01423
01424 if (model_item)
01425 {
01426 if (!view_item)
01427 {
01428
01429 if ((mask & LLInventoryObserver::ADD) != LLInventoryObserver::ADD)
01430 {
01431 llwarns << *id_it << " is in model but not in view, but ADD flag not set" << llendl;
01432 }
01433 buildNewViews(*id_it);
01434
01435
01436
01437
01438 if(mFolders->getRoot()->needsAutoRename())
01439 {
01440 setSelection(*id_it, FALSE);
01441 }
01442 }
01443 else
01444 {
01445
01446 if ((mask & LLInventoryObserver::STRUCTURE) != LLInventoryObserver::STRUCTURE)
01447 {
01448 llwarns << *id_it << " is in model and in view, but STRUCTURE flag not set" << llendl;
01449 }
01450
01451 LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolders->getItemByID(model_item->getParentUUID());
01452 if (view_item->getParentFolder() != new_parent)
01453 {
01454 view_item->getParentFolder()->extractItem(view_item);
01455 view_item->addToFolder(new_parent, mFolders);
01456 }
01457 }
01458 }
01459 else
01460 {
01461 if (view_item)
01462 {
01463 if ((mask & LLInventoryObserver::REMOVE) != LLInventoryObserver::REMOVE)
01464 {
01465 llwarns << *id_it << " is not in model but in view, but REMOVE flag not set" << llendl;
01466 }
01467
01468 view_item->destroyView();
01469 }
01470 else
01471 {
01472 llwarns << *id_it << "Item does not exist in either view or model, but notification triggered" << llendl;
01473 }
01474 }
01475 }
01476 }
01477 }
01478
01479 if (!handled)
01480 {
01481
01482
01483
01484 mFolders->refresh();
01485 }
01486 }
01487
01488 void LLInventoryPanel::rebuildViewsFor(const LLUUID& id, U32 mask)
01489 {
01490 LLFolderViewItem* old_view = NULL;
01491
01492
01493 old_view = mFolders->getItemByID(id);
01494 if (old_view && id.notNull())
01495 {
01496 old_view->destroyView();
01497 }
01498
01499 buildNewViews(id);
01500 }
01501
01502 void LLInventoryPanel::buildNewViews(const LLUUID& id)
01503 {
01504 LLFolderViewItem* itemp = NULL;
01505 LLInventoryObject* objectp = gInventory.getObject(id);
01506 S32 i;
01507 S32 count;
01508
01509 if (objectp)
01510 {
01511 if (objectp->getType() <= LLAssetType::AT_NONE ||
01512 objectp->getType() >= LLAssetType::AT_COUNT)
01513 {
01514 llwarns << "LLInventoryPanel::buildNewViews called with objectp->mType == "
01515 << ((S32) objectp->getType())
01516 << " (shouldn't happen)" << llendl;
01517 }
01518 else if (objectp->getType() == LLAssetType::AT_CATEGORY)
01519 {
01520 LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(objectp->getType(),
01521 LLInventoryType::IT_CATEGORY,
01522 this,
01523 objectp->getUUID());
01524
01525 if (new_listener)
01526 {
01527 LLFolderViewFolder* folderp = new LLFolderViewFolder(new_listener->getDisplayName(),
01528 new_listener->getIcon(),
01529 mFolders,
01530 new_listener);
01531
01532 folderp->setItemSortOrder(mFolders->getSortOrder());
01533 itemp = folderp;
01534 }
01535 }
01536 else
01537 {
01538 LLInventoryItem* item = (LLInventoryItem*)objectp;
01539 LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(
01540 item->getType(),
01541 item->getInventoryType(),
01542 this,
01543 item->getUUID(),
01544 item->getFlags());
01545 if (new_listener)
01546 {
01547 itemp = new LLFolderViewItem(new_listener->getDisplayName(),
01548 new_listener->getIcon(),
01549 new_listener->getCreationDate(),
01550 mFolders,
01551 new_listener);
01552 }
01553 }
01554
01555 LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolders->getItemByID(objectp->getParentUUID());
01556
01557 if (itemp)
01558 {
01559 if (parent_folder)
01560 {
01561 itemp->addToFolder(parent_folder, mFolders);
01562 }
01563 else
01564 {
01565 llwarns << "Couldn't find parent folder for child " << itemp->getLabel() << llendl;
01566 delete itemp;
01567 }
01568 }
01569 }
01570
01571 if ((id.isNull() ||
01572 (objectp && objectp->getType() == LLAssetType::AT_CATEGORY)))
01573 {
01574 LLViewerInventoryCategory::cat_array_t* categories;
01575 LLViewerInventoryItem::item_array_t* items;
01576
01577 mInventory->getDirectDescendentsOf(id, categories, items);
01578 if(categories)
01579 {
01580 count = categories->count();
01581 for(i = 0; i < count; ++i)
01582 {
01583 LLInventoryCategory* cat = categories->get(i);
01584 buildNewViews(cat->getUUID());
01585 }
01586 }
01587 if(items)
01588 {
01589 count = items->count();
01590 for(i = 0; i < count; ++i)
01591 {
01592 LLInventoryItem* item = items->get(i);
01593 buildNewViews(item->getUUID());
01594 }
01595 }
01596 }
01597 }
01598
01599 struct LLConfirmPurgeData
01600 {
01601 LLUUID mID;
01602 LLInventoryModel* mModel;
01603 };
01604
01605 class LLIsNotWorn : public LLInventoryCollectFunctor
01606 {
01607 public:
01608 LLIsNotWorn() {}
01609 virtual ~LLIsNotWorn() {}
01610 virtual bool operator()(LLInventoryCategory* cat,
01611 LLInventoryItem* item)
01612 {
01613 return !gAgent.isWearingItem(item->getUUID());
01614 }
01615 };
01616
01617 class LLOpenFolderByID : public LLFolderViewFunctor
01618 {
01619 public:
01620 LLOpenFolderByID(const LLUUID& id) : mID(id) {}
01621 virtual ~LLOpenFolderByID() {}
01622 virtual void doFolder(LLFolderViewFolder* folder)
01623 {
01624 if (folder->getListener() && folder->getListener()->getUUID() == mID) folder->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
01625 }
01626 virtual void doItem(LLFolderViewItem* item) {}
01627 protected:
01628 const LLUUID& mID;
01629 };
01630
01631
01632 void LLInventoryPanel::openSelected()
01633 {
01634 LLFolderViewItem* folder_item = mFolders->getCurSelectedItem();
01635 if(!folder_item) return;
01636 LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
01637 if(!bridge) return;
01638 bridge->openItem();
01639 }
01640
01641 BOOL LLInventoryPanel::handleHover(S32 x, S32 y, MASK mask)
01642 {
01643 BOOL handled = LLView::handleHover(x, y, mask);
01644 if(handled)
01645 {
01646 ECursorType cursor = getWindow()->getCursor();
01647 if (LLInventoryModel::backgroundFetchActive() && cursor == UI_CURSOR_ARROW)
01648 {
01649
01650 getWindow()->setCursor(UI_CURSOR_WORKING);
01651 }
01652 }
01653 else
01654 {
01655 getWindow()->setCursor(UI_CURSOR_ARROW);
01656 }
01657 return TRUE;
01658 }
01659
01660 BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
01661 EDragAndDropType cargo_type,
01662 void* cargo_data,
01663 EAcceptance* accept,
01664 LLString& tooltip_msg)
01665 {
01666
01667 BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
01668
01669 if (handled)
01670 {
01671 mFolders->setDragAndDropThisFrame();
01672 }
01673
01674 return handled;
01675 }
01676
01677
01678 void LLInventoryPanel::openAllFolders()
01679 {
01680 mFolders->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN);
01681 mFolders->arrangeAll();
01682 }
01683
01684 void LLInventoryPanel::closeAllFolders()
01685 {
01686 mFolders->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
01687 mFolders->arrangeAll();
01688 }
01689
01690 void LLInventoryPanel::openDefaultFolderForType(LLAssetType::EType type)
01691 {
01692 LLUUID category_id = mInventory->findCategoryUUIDForType(type);
01693 LLOpenFolderByID opener(category_id);
01694 mFolders->applyFunctorRecursively(opener);
01695 }
01696
01697 void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus)
01698 {
01699 LLFolderViewItem* itemp = mFolders->getItemByID(obj_id);
01700 if(itemp && itemp->getListener())
01701 {
01702 itemp->getListener()->arrangeAndSet(itemp,
01703 TRUE,
01704 take_keyboard_focus);
01705 }
01706 }
01707
01708 void LLInventoryPanel::clearSelection()
01709 {
01710 mFolders->clearSelection();
01711 }
01712
01713 void LLInventoryPanel::createNewItem(const char* name,
01714 const LLUUID& parent_id,
01715 LLAssetType::EType asset_type,
01716 LLInventoryType::EType inv_type,
01717 U32 next_owner_perm)
01718 {
01719 LLString desc;
01720 LLAssetType::generateDescriptionFor(asset_type, desc);
01721 next_owner_perm = (next_owner_perm) ? next_owner_perm : PERM_MOVE | PERM_TRANSFER;
01722
01723 LLPointer<LLInventoryCallback> cb = NULL;
01724 create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
01725 parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type,
01726 NOT_WEARABLE, next_owner_perm, cb);
01727
01728 }
01729
01730
01731 void LLInventoryPanel::dumpSelectionInformation(void* user_data)
01732 {
01733 LLInventoryPanel* iv = (LLInventoryPanel*)user_data;
01734 iv->mFolders->dumpSelectionInformation();
01735 }