/indra/newview/llpaneloutfitsinventory.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 325 lines · 205 code · 53 blank · 67 comment · 21 complexity · 22d66bc2f312ee8ee63b402abb162185 MD5 · raw file

  1. /**
  2. * @file llpaneloutfitsinventory.cpp
  3. * @brief Outfits inventory panel
  4. *
  5. * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llpaneloutfitsinventory.h"
  28. #include "llnotificationsutil.h"
  29. #include "lltabcontainer.h"
  30. #include "llfloatersidepanelcontainer.h"
  31. #include "llinventoryfunctions.h"
  32. #include "llinventorymodelbackgroundfetch.h"
  33. #include "llagentwearables.h"
  34. #include "llappearancemgr.h"
  35. #include "lloutfitobserver.h"
  36. #include "lloutfitslist.h"
  37. #include "llpanelwearing.h"
  38. #include "llsaveoutfitcombobtn.h"
  39. #include "llsidepanelappearance.h"
  40. #include "llviewerfoldertype.h"
  41. static const std::string OUTFITS_TAB_NAME = "outfitslist_tab";
  42. static const std::string COF_TAB_NAME = "cof_tab";
  43. static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
  44. LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
  45. mMyOutfitsPanel(NULL),
  46. mCurrentOutfitPanel(NULL),
  47. mActivePanel(NULL),
  48. mInitialized(false)
  49. {
  50. gAgentWearables.addLoadedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoaded, this));
  51. gAgentWearables.addLoadingStartedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoading, this));
  52. LLOutfitObserver& observer = LLOutfitObserver::instance();
  53. observer.addBOFChangedCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
  54. observer.addCOFChangedCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
  55. observer.addOutfitLockChangedCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
  56. }
  57. LLPanelOutfitsInventory::~LLPanelOutfitsInventory()
  58. {
  59. }
  60. // virtual
  61. BOOL LLPanelOutfitsInventory::postBuild()
  62. {
  63. initTabPanels();
  64. initListCommandsHandlers();
  65. // Fetch your outfits folder so that the links are in memory.
  66. // ( This is only necessary if we want to show a warning if a user deletes an item that has a
  67. // a link in an outfit, see "ConfirmItemDeleteHasLinks". )
  68. const LLUUID &outfits_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTFIT, false);
  69. if (outfits_cat.notNull())
  70. {
  71. LLInventoryModelBackgroundFetch::instance().start(outfits_cat);
  72. }
  73. mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this, true));
  74. return TRUE;
  75. }
  76. // virtual
  77. void LLPanelOutfitsInventory::onOpen(const LLSD& key)
  78. {
  79. if (!mInitialized)
  80. {
  81. LLSidepanelAppearance* panel_appearance = getAppearanceSP();
  82. if (panel_appearance)
  83. {
  84. // *TODO: move these methods to LLPanelOutfitsInventory?
  85. panel_appearance->fetchInventory();
  86. panel_appearance->refreshCurrentOutfitName();
  87. }
  88. mInitialized = true;
  89. }
  90. // Make sure we know which tab is selected, update the filter,
  91. // and update verbs.
  92. onTabChange();
  93. // *TODO: Auto open the first outfit newly created so new users can see sample outfit contents
  94. /*
  95. static bool should_open_outfit = true;
  96. if (should_open_outfit && gAgent.isFirstLogin())
  97. {
  98. LLInventoryPanel* outfits_panel = getChild<LLInventoryPanel>(OUTFITS_TAB_NAME);
  99. if (outfits_panel)
  100. {
  101. LLUUID my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
  102. LLFolderViewFolder* my_outfits_folder = outfits_panel->getRootFolder()->getFolderByID(my_outfits_id);
  103. if (my_outfits_folder)
  104. {
  105. LLFolderViewFolder* first_outfit = dynamic_cast<LLFolderViewFolder*>(my_outfits_folder->getFirstChild());
  106. if (first_outfit)
  107. {
  108. first_outfit->setOpen(TRUE);
  109. }
  110. }
  111. }
  112. }
  113. should_open_outfit = false;
  114. */
  115. }
  116. void LLPanelOutfitsInventory::updateVerbs()
  117. {
  118. if (mListCommands)
  119. {
  120. updateListCommands();
  121. }
  122. }
  123. // virtual
  124. void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
  125. {
  126. if (!mActivePanel) return;
  127. mFilterSubString = string;
  128. if (string == "")
  129. {
  130. mActivePanel->setFilterSubString(LLStringUtil::null);
  131. }
  132. LLInventoryModelBackgroundFetch::instance().start();
  133. if (mActivePanel->getFilterSubString().empty() && string.empty())
  134. {
  135. // current filter and new filter empty, do nothing
  136. return;
  137. }
  138. // set new filter string
  139. mActivePanel->setFilterSubString(string);
  140. }
  141. void LLPanelOutfitsInventory::onWearButtonClick()
  142. {
  143. if (mMyOutfitsPanel->hasItemSelected())
  144. {
  145. mMyOutfitsPanel->wearSelectedItems();
  146. }
  147. else
  148. {
  149. mMyOutfitsPanel->performAction("replaceoutfit");
  150. }
  151. }
  152. bool LLPanelOutfitsInventory::onSaveCommit(const LLSD& notification, const LLSD& response)
  153. {
  154. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  155. if (0 == option)
  156. {
  157. std::string outfit_name = response["message"].asString();
  158. LLStringUtil::trim(outfit_name);
  159. if( !outfit_name.empty() )
  160. {
  161. LLUUID outfit_folder = LLAppearanceMgr::getInstance()->makeNewOutfitLinks(outfit_name);
  162. LLSidepanelAppearance* panel_appearance = getAppearanceSP();
  163. if (panel_appearance)
  164. {
  165. panel_appearance->showOutfitsInventoryPanel();
  166. }
  167. if (mAppearanceTabs)
  168. {
  169. mAppearanceTabs->selectTabByName(OUTFITS_TAB_NAME);
  170. }
  171. }
  172. }
  173. return false;
  174. }
  175. void LLPanelOutfitsInventory::onSave()
  176. {
  177. std::string outfit_name;
  178. if (!LLAppearanceMgr::getInstance()->getBaseOutfitName(outfit_name))
  179. {
  180. outfit_name = LLViewerFolderType::lookupNewCategoryName(LLFolderType::FT_OUTFIT);
  181. }
  182. LLSD args;
  183. args["DESC"] = outfit_name;
  184. LLSD payload;
  185. //payload["ids"].append(*it);
  186. LLNotificationsUtil::add("SaveOutfitAs", args, payload, boost::bind(&LLPanelOutfitsInventory::onSaveCommit, this, _1, _2));
  187. }
  188. //static
  189. LLPanelOutfitsInventory* LLPanelOutfitsInventory::findInstance()
  190. {
  191. return dynamic_cast<LLPanelOutfitsInventory*>(LLFloaterSidePanelContainer::getPanel("appearance", "panel_outfits_inventory"));
  192. }
  193. //////////////////////////////////////////////////////////////////////////////////
  194. // List Commands //
  195. void LLPanelOutfitsInventory::initListCommandsHandlers()
  196. {
  197. mListCommands = getChild<LLPanel>("bottom_panel");
  198. mListCommands->childSetAction("wear_btn", boost::bind(&LLPanelOutfitsInventory::onWearButtonClick, this));
  199. mMyOutfitsPanel->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this));
  200. }
  201. void LLPanelOutfitsInventory::updateListCommands()
  202. {
  203. bool trash_enabled = isActionEnabled("delete");
  204. bool wear_enabled = isActionEnabled("wear");
  205. bool wear_visible = !isCOFPanelActive();
  206. bool make_outfit_enabled = isActionEnabled("save_outfit");
  207. mMyOutfitsPanel->childSetEnabled("trash_btn", trash_enabled);
  208. mListCommands->childSetEnabled("wear_btn", wear_enabled);
  209. mListCommands->childSetVisible("wear_btn", wear_visible);
  210. mSaveComboBtn->setMenuItemEnabled("save_outfit", make_outfit_enabled);
  211. if (mMyOutfitsPanel->hasItemSelected())
  212. {
  213. mListCommands->childSetToolTip("wear_btn", getString("wear_items_tooltip"));
  214. }
  215. else
  216. {
  217. mListCommands->childSetToolTip("wear_btn", getString("wear_outfit_tooltip"));
  218. }
  219. }
  220. void LLPanelOutfitsInventory::onTrashButtonClick()
  221. {
  222. mMyOutfitsPanel->removeSelected();
  223. }
  224. bool LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
  225. {
  226. return mActivePanel && mActivePanel->isActionEnabled(userdata);
  227. }
  228. // List Commands //
  229. //////////////////////////////////////////////////////////////////////////////////
  230. //////////////////////////////////////////////////////////////////////////////////
  231. // Tab panels //
  232. void LLPanelOutfitsInventory::initTabPanels()
  233. {
  234. mCurrentOutfitPanel = findChild<LLPanelWearing>(COF_TAB_NAME);
  235. mCurrentOutfitPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
  236. mMyOutfitsPanel = findChild<LLOutfitsList>(OUTFITS_TAB_NAME);
  237. mMyOutfitsPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
  238. mAppearanceTabs = getChild<LLTabContainer>("appearance_tabs");
  239. mAppearanceTabs->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::onTabChange, this));
  240. }
  241. void LLPanelOutfitsInventory::onTabChange()
  242. {
  243. mActivePanel = dynamic_cast<LLPanelAppearanceTab*>(mAppearanceTabs->getCurrentPanel());
  244. if (!mActivePanel) return;
  245. mActivePanel->setFilterSubString(mFilterSubString);
  246. mActivePanel->onOpen(LLSD());
  247. updateVerbs();
  248. }
  249. bool LLPanelOutfitsInventory::isCOFPanelActive() const
  250. {
  251. if (!mActivePanel) return false;
  252. return mActivePanel->getName() == COF_TAB_NAME;
  253. }
  254. void LLPanelOutfitsInventory::setWearablesLoading(bool val)
  255. {
  256. updateVerbs();
  257. }
  258. void LLPanelOutfitsInventory::onWearablesLoaded()
  259. {
  260. setWearablesLoading(false);
  261. }
  262. void LLPanelOutfitsInventory::onWearablesLoading()
  263. {
  264. setWearablesLoading(true);
  265. }
  266. // static
  267. LLSidepanelAppearance* LLPanelOutfitsInventory::getAppearanceSP()
  268. {
  269. LLSidepanelAppearance* panel_appearance =
  270. dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
  271. return panel_appearance;
  272. }