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