/indra/newview/lltoolbarview.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 697 lines · 525 code · 109 blank · 63 comment · 100 complexity · 655549b13943feeb074c7b4966aedd28 MD5 · raw file

  1. /**
  2. * @file lltoolbarview.cpp
  3. * @author Merov Linden
  4. * @brief User customizable toolbar class
  5. *
  6. * $LicenseInfo:firstyear=2011&license=viewerlgpl$
  7. * Second Life Viewer Source Code
  8. * Copyright (C) 2011, Linden Research, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation;
  13. * version 2.1 of the License only.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  25. * $/LicenseInfo$
  26. */
  27. #include "llviewerprecompiledheaders.h"
  28. #include "lltoolbarview.h"
  29. #include "llappviewer.h"
  30. #include "llbutton.h"
  31. #include "llclipboard.h"
  32. #include "lldir.h"
  33. #include "lldockablefloater.h"
  34. #include "lldockcontrol.h"
  35. #include "llimview.h"
  36. #include "lltransientfloatermgr.h"
  37. #include "lltoolbar.h"
  38. #include "lltooldraganddrop.h"
  39. #include "llxmlnode.h"
  40. #include "llagent.h" // HACK for destinations guide on startup
  41. #include "llfloaterreg.h" // HACK for destinations guide on startup
  42. #include "llviewercontrol.h" // HACK for destinations guide on startup
  43. #include <boost/foreach.hpp>
  44. LLToolBarView* gToolBarView = NULL;
  45. static LLDefaultChildRegistry::Register<LLToolBarView> r("toolbar_view");
  46. void handleLoginToolbarSetup();
  47. bool isToolDragged()
  48. {
  49. return (LLToolDragAndDrop::getInstance()->getSource() == LLToolDragAndDrop::SOURCE_VIEWER);
  50. }
  51. LLToolBarView::Toolbar::Toolbar()
  52. : button_display_mode("button_display_mode"),
  53. commands("command")
  54. {}
  55. LLToolBarView::ToolbarSet::ToolbarSet()
  56. : left_toolbar("left_toolbar"),
  57. right_toolbar("right_toolbar"),
  58. bottom_toolbar("bottom_toolbar")
  59. {}
  60. LLToolBarView::LLToolBarView(const LLToolBarView::Params& p)
  61. : LLUICtrl(p),
  62. mDragStarted(false),
  63. mShowToolbars(true),
  64. mDragToolbarButton(NULL),
  65. mToolbarsLoaded(false)
  66. {
  67. for (S32 i = 0; i < TOOLBAR_COUNT; i++)
  68. {
  69. mToolbars[i] = NULL;
  70. }
  71. }
  72. void LLToolBarView::initFromParams(const LLToolBarView::Params& p)
  73. {
  74. // Initialize the base object
  75. LLUICtrl::initFromParams(p);
  76. }
  77. LLToolBarView::~LLToolBarView()
  78. {
  79. saveToolbars();
  80. }
  81. BOOL LLToolBarView::postBuild()
  82. {
  83. mToolbars[TOOLBAR_LEFT] = getChild<LLToolBar>("toolbar_left");
  84. mToolbars[TOOLBAR_RIGHT] = getChild<LLToolBar>("toolbar_right");
  85. mToolbars[TOOLBAR_BOTTOM] = getChild<LLToolBar>("toolbar_bottom");
  86. for (int i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
  87. {
  88. mToolbars[i]->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
  89. mToolbars[i]->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
  90. mToolbars[i]->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4));
  91. mToolbars[i]->setButtonAddCallback(boost::bind(LLToolBarView::onToolBarButtonAdded,_1));
  92. mToolbars[i]->setButtonRemoveCallback(boost::bind(LLToolBarView::onToolBarButtonRemoved,_1));
  93. }
  94. LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&handleLoginToolbarSetup));
  95. return TRUE;
  96. }
  97. S32 LLToolBarView::hasCommand(const LLCommandId& commandId) const
  98. {
  99. S32 command_location = TOOLBAR_NONE;
  100. for (S32 loc = TOOLBAR_FIRST; loc <= TOOLBAR_LAST; loc++)
  101. {
  102. if (mToolbars[loc]->hasCommand(commandId))
  103. {
  104. command_location = loc;
  105. break;
  106. }
  107. }
  108. return command_location;
  109. }
  110. S32 LLToolBarView::addCommand(const LLCommandId& commandId, EToolBarLocation toolbar, int rank)
  111. {
  112. int old_rank;
  113. removeCommand(commandId, old_rank);
  114. S32 command_location = mToolbars[toolbar]->addCommand(commandId, rank);
  115. return command_location;
  116. }
  117. S32 LLToolBarView::removeCommand(const LLCommandId& commandId, int& rank)
  118. {
  119. S32 command_location = hasCommand(commandId);
  120. rank = LLToolBar::RANK_NONE;
  121. if (command_location != TOOLBAR_NONE)
  122. {
  123. rank = mToolbars[command_location]->removeCommand(commandId);
  124. }
  125. return command_location;
  126. }
  127. S32 LLToolBarView::enableCommand(const LLCommandId& commandId, bool enabled)
  128. {
  129. S32 command_location = hasCommand(commandId);
  130. if (command_location != TOOLBAR_NONE)
  131. {
  132. mToolbars[command_location]->enableCommand(commandId, enabled);
  133. }
  134. return command_location;
  135. }
  136. S32 LLToolBarView::stopCommandInProgress(const LLCommandId& commandId)
  137. {
  138. S32 command_location = hasCommand(commandId);
  139. if (command_location != TOOLBAR_NONE)
  140. {
  141. mToolbars[command_location]->stopCommandInProgress(commandId);
  142. }
  143. return command_location;
  144. }
  145. S32 LLToolBarView::flashCommand(const LLCommandId& commandId, bool flash)
  146. {
  147. S32 command_location = hasCommand(commandId);
  148. if (command_location != TOOLBAR_NONE)
  149. {
  150. mToolbars[command_location]->flashCommand(commandId, flash);
  151. }
  152. return command_location;
  153. }
  154. bool LLToolBarView::addCommandInternal(const LLCommandId& command, LLToolBar* toolbar)
  155. {
  156. LLCommandManager& mgr = LLCommandManager::instance();
  157. if (mgr.getCommand(command))
  158. {
  159. toolbar->addCommand(command);
  160. }
  161. else
  162. {
  163. llwarns << "Toolbars creation : the command with id " << command.uuid().asString() << " cannot be found in the command manager" << llendl;
  164. return false;
  165. }
  166. return true;
  167. }
  168. bool LLToolBarView::loadToolbars(bool force_default)
  169. {
  170. LLToolBarView::ToolbarSet toolbar_set;
  171. bool err = false;
  172. // Load the toolbars.xml file
  173. std::string toolbar_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "toolbars.xml");
  174. if (force_default)
  175. {
  176. toolbar_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "toolbars.xml");
  177. }
  178. else if (!gDirUtilp->fileExists(toolbar_file))
  179. {
  180. llwarns << "User toolbars def not found -> use default" << llendl;
  181. toolbar_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "toolbars.xml");
  182. }
  183. LLXMLNodePtr root;
  184. if(!LLXMLNode::parseFile(toolbar_file, root, NULL))
  185. {
  186. llwarns << "Unable to load toolbars from file: " << toolbar_file << llendl;
  187. err = true;
  188. }
  189. if (!err && !root->hasName("toolbars"))
  190. {
  191. llwarns << toolbar_file << " is not a valid toolbars definition file" << llendl;
  192. err = true;
  193. }
  194. // Parse the toolbar settings
  195. LLXUIParser parser;
  196. if (!err)
  197. {
  198. parser.readXUI(root, toolbar_set, toolbar_file);
  199. }
  200. if (!err && !toolbar_set.validateBlock())
  201. {
  202. llwarns << "Unable to validate toolbars from file: " << toolbar_file << llendl;
  203. err = true;
  204. }
  205. if (err)
  206. {
  207. if (force_default)
  208. {
  209. llerrs << "Unable to load toolbars from default file : " << toolbar_file << llendl;
  210. return false;
  211. }
  212. // Try to load the default toolbars
  213. return loadToolbars(true);
  214. }
  215. // Clear the toolbars now before adding the loaded commands and settings
  216. for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
  217. {
  218. if (mToolbars[i])
  219. {
  220. mToolbars[i]->clearCommandsList();
  221. }
  222. }
  223. // Add commands to each toolbar
  224. if (toolbar_set.left_toolbar.isProvided() && mToolbars[TOOLBAR_LEFT])
  225. {
  226. if (toolbar_set.left_toolbar.button_display_mode.isProvided())
  227. {
  228. LLToolBarEnums::ButtonType button_type = toolbar_set.left_toolbar.button_display_mode;
  229. mToolbars[TOOLBAR_LEFT]->setButtonType(button_type);
  230. }
  231. BOOST_FOREACH(const LLCommandId::Params& command_params, toolbar_set.left_toolbar.commands)
  232. {
  233. if (addCommandInternal(LLCommandId(command_params), mToolbars[TOOLBAR_LEFT]))
  234. {
  235. llwarns << "Error adding command '" << command_params.name() << "' to left toolbar." << llendl;
  236. }
  237. }
  238. }
  239. if (toolbar_set.right_toolbar.isProvided() && mToolbars[TOOLBAR_RIGHT])
  240. {
  241. if (toolbar_set.right_toolbar.button_display_mode.isProvided())
  242. {
  243. LLToolBarEnums::ButtonType button_type = toolbar_set.right_toolbar.button_display_mode;
  244. mToolbars[TOOLBAR_RIGHT]->setButtonType(button_type);
  245. }
  246. BOOST_FOREACH(const LLCommandId::Params& command_params, toolbar_set.right_toolbar.commands)
  247. {
  248. if (addCommandInternal(LLCommandId(command_params), mToolbars[TOOLBAR_RIGHT]))
  249. {
  250. llwarns << "Error adding command '" << command_params.name() << "' to right toolbar." << llendl;
  251. }
  252. }
  253. }
  254. if (toolbar_set.bottom_toolbar.isProvided() && mToolbars[TOOLBAR_BOTTOM])
  255. {
  256. if (toolbar_set.bottom_toolbar.button_display_mode.isProvided())
  257. {
  258. LLToolBarEnums::ButtonType button_type = toolbar_set.bottom_toolbar.button_display_mode;
  259. mToolbars[TOOLBAR_BOTTOM]->setButtonType(button_type);
  260. }
  261. BOOST_FOREACH(const LLCommandId::Params& command_params, toolbar_set.bottom_toolbar.commands)
  262. {
  263. if (addCommandInternal(LLCommandId(command_params), mToolbars[TOOLBAR_BOTTOM]))
  264. {
  265. llwarns << "Error adding command '" << command_params.name() << "' to bottom toolbar." << llendl;
  266. }
  267. }
  268. }
  269. mToolbarsLoaded = true;
  270. return true;
  271. }
  272. bool LLToolBarView::clearToolbars()
  273. {
  274. for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
  275. {
  276. if (mToolbars[i])
  277. {
  278. mToolbars[i]->clearCommandsList();
  279. }
  280. }
  281. return true;
  282. }
  283. //static
  284. bool LLToolBarView::loadDefaultToolbars()
  285. {
  286. bool retval = false;
  287. if (gToolBarView)
  288. {
  289. retval = gToolBarView->loadToolbars(true);
  290. if (retval)
  291. {
  292. gToolBarView->saveToolbars();
  293. }
  294. }
  295. return retval;
  296. }
  297. //static
  298. bool LLToolBarView::clearAllToolbars()
  299. {
  300. bool retval = false;
  301. if (gToolBarView)
  302. {
  303. retval = gToolBarView->clearToolbars();
  304. if (retval)
  305. {
  306. gToolBarView->saveToolbars();
  307. }
  308. }
  309. return retval;
  310. }
  311. void LLToolBarView::saveToolbars() const
  312. {
  313. if (!mToolbarsLoaded)
  314. return;
  315. // Build the parameter tree from the toolbar data
  316. LLToolBarView::ToolbarSet toolbar_set;
  317. if (mToolbars[TOOLBAR_LEFT])
  318. {
  319. toolbar_set.left_toolbar.button_display_mode = mToolbars[TOOLBAR_LEFT]->getButtonType();
  320. addToToolset(mToolbars[TOOLBAR_LEFT]->getCommandsList(), toolbar_set.left_toolbar);
  321. }
  322. if (mToolbars[TOOLBAR_RIGHT])
  323. {
  324. toolbar_set.right_toolbar.button_display_mode = mToolbars[TOOLBAR_RIGHT]->getButtonType();
  325. addToToolset(mToolbars[TOOLBAR_RIGHT]->getCommandsList(), toolbar_set.right_toolbar);
  326. }
  327. if (mToolbars[TOOLBAR_BOTTOM])
  328. {
  329. toolbar_set.bottom_toolbar.button_display_mode = mToolbars[TOOLBAR_BOTTOM]->getButtonType();
  330. addToToolset(mToolbars[TOOLBAR_BOTTOM]->getCommandsList(), toolbar_set.bottom_toolbar);
  331. }
  332. // Serialize the parameter tree
  333. LLXMLNodePtr output_node = new LLXMLNode("toolbars", false);
  334. LLXUIParser parser;
  335. parser.writeXUI(output_node, toolbar_set);
  336. // Write the resulting XML to file
  337. if(!output_node->isNull())
  338. {
  339. const std::string& filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "toolbars.xml");
  340. LLFILE *fp = LLFile::fopen(filename, "w");
  341. if (fp != NULL)
  342. {
  343. LLXMLNode::writeHeaderToFile(fp);
  344. output_node->writeToFile(fp);
  345. fclose(fp);
  346. }
  347. }
  348. }
  349. // Enumerate the commands in command_list and add them as Params to the toolbar
  350. void LLToolBarView::addToToolset(command_id_list_t& command_list, Toolbar& toolbar) const
  351. {
  352. LLCommandManager& mgr = LLCommandManager::instance();
  353. for (command_id_list_t::const_iterator it = command_list.begin();
  354. it != command_list.end();
  355. ++it)
  356. {
  357. LLCommand* command = mgr.getCommand(*it);
  358. if (command)
  359. {
  360. LLCommandId::Params command_name_param;
  361. command_name_param.name = command->name();
  362. toolbar.commands.add(command_name_param);
  363. }
  364. }
  365. }
  366. void LLToolBarView::onToolBarButtonAdded(LLView* button)
  367. {
  368. llassert(button);
  369. if (button->getName() == "speak")
  370. {
  371. // Add the "Speak" button as a control view in LLTransientFloaterMgr
  372. // to prevent hiding the transient IM floater upon pressing "Speak".
  373. LLTransientFloaterMgr::getInstance()->addControlView(button);
  374. // Redock incoming and/or outgoing call windows, if applicable
  375. LLFloater* incoming_floater = LLFloaterReg::getLastFloaterInGroup("incoming_call");
  376. LLFloater* outgoing_floater = LLFloaterReg::getLastFloaterInGroup("outgoing_call");
  377. if (incoming_floater && incoming_floater->isShown())
  378. {
  379. LLCallDialog* incoming = dynamic_cast<LLCallDialog *>(incoming_floater);
  380. llassert(incoming);
  381. LLDockControl* dock_control = incoming->getDockControl();
  382. if (dock_control->getDock() == NULL)
  383. {
  384. incoming->dockToToolbarButton("speak");
  385. }
  386. }
  387. if (outgoing_floater && outgoing_floater->isShown())
  388. {
  389. LLCallDialog* outgoing = dynamic_cast<LLCallDialog *>(outgoing_floater);
  390. llassert(outgoing);
  391. LLDockControl* dock_control = outgoing->getDockControl();
  392. if (dock_control->getDock() == NULL)
  393. {
  394. outgoing->dockToToolbarButton("speak");
  395. }
  396. }
  397. }
  398. else if (button->getName() == "voice")
  399. {
  400. // Add the "Voice controls" button as a control view in LLTransientFloaterMgr
  401. // to prevent hiding the transient IM floater upon pressing "Voice controls".
  402. LLTransientFloaterMgr::getInstance()->addControlView(button);
  403. }
  404. }
  405. void LLToolBarView::onToolBarButtonRemoved(LLView* button)
  406. {
  407. llassert(button);
  408. if (button->getName() == "speak")
  409. {
  410. LLTransientFloaterMgr::getInstance()->removeControlView(button);
  411. // Undock incoming and/or outgoing call windows
  412. LLFloater* incoming_floater = LLFloaterReg::getLastFloaterInGroup("incoming_call");
  413. LLFloater* outgoing_floater = LLFloaterReg::getLastFloaterInGroup("outgoing_call");
  414. if (incoming_floater && incoming_floater->isShown())
  415. {
  416. LLDockableFloater* incoming = dynamic_cast<LLDockableFloater *>(incoming_floater);
  417. llassert(incoming);
  418. LLDockControl* dock_control = incoming->getDockControl();
  419. dock_control->setDock(NULL);
  420. }
  421. if (outgoing_floater && outgoing_floater->isShown())
  422. {
  423. LLDockableFloater* outgoing = dynamic_cast<LLDockableFloater *>(outgoing_floater);
  424. llassert(outgoing);
  425. LLDockControl* dock_control = outgoing->getDockControl();
  426. dock_control->setDock(NULL);
  427. }
  428. }
  429. else if (button->getName() == "voice")
  430. {
  431. LLTransientFloaterMgr::getInstance()->removeControlView(button);
  432. }
  433. }
  434. void LLToolBarView::draw()
  435. {
  436. LLRect toolbar_rects[TOOLBAR_COUNT];
  437. for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
  438. {
  439. if (mToolbars[i])
  440. {
  441. LLLayoutStack::ELayoutOrientation orientation = LLToolBarEnums::getOrientation(mToolbars[i]->getSideType());
  442. if (orientation == LLLayoutStack::HORIZONTAL)
  443. {
  444. mToolbars[i]->getParent()->reshape(mToolbars[i]->getParent()->getRect().getWidth(), mToolbars[i]->getRect().getHeight());
  445. }
  446. else
  447. {
  448. mToolbars[i]->getParent()->reshape(mToolbars[i]->getRect().getWidth(), mToolbars[i]->getParent()->getRect().getHeight());
  449. }
  450. mToolbars[i]->localRectToOtherView(mToolbars[i]->getLocalRect(), &toolbar_rects[i], this);
  451. }
  452. }
  453. for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
  454. {
  455. mToolbars[i]->getParent()->setVisible(mShowToolbars
  456. && (mToolbars[i]->hasButtons()
  457. || isToolDragged()));
  458. }
  459. // Draw drop zones if drop of a tool is active
  460. if (isToolDragged())
  461. {
  462. LLColor4 drop_color = LLUIColorTable::instance().getColor( "ToolbarDropZoneColor" );
  463. for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
  464. {
  465. gl_rect_2d(toolbar_rects[i], drop_color, TRUE);
  466. }
  467. }
  468. LLUICtrl::draw();
  469. }
  470. // ----------------------------------------
  471. // Drag and Drop Handling
  472. // ----------------------------------------
  473. void LLToolBarView::startDragTool(S32 x, S32 y, LLToolBarButton* toolbarButton)
  474. {
  475. resetDragTool(toolbarButton);
  476. // Flag the tool dragging but don't start it yet
  477. LLToolDragAndDrop::getInstance()->setDragStart( x, y );
  478. }
  479. BOOL LLToolBarView::handleDragTool( S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type)
  480. {
  481. if (LLToolDragAndDrop::getInstance()->isOverThreshold( x, y ))
  482. {
  483. if (!gToolBarView->mDragStarted)
  484. {
  485. // Start the tool dragging:
  486. // First, create the global drag and drop object
  487. std::vector<EDragAndDropType> types;
  488. uuid_vec_t cargo_ids;
  489. types.push_back(DAD_WIDGET);
  490. cargo_ids.push_back(uuid);
  491. gClipboard.setSourceObject(uuid,LLAssetType::AT_WIDGET);
  492. LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_VIEWER;
  493. LLUUID srcID;
  494. LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, src, srcID);
  495. // Second, stop the command if it is in progress and requires stopping!
  496. LLCommandId command_id = LLCommandId(uuid);
  497. gToolBarView->stopCommandInProgress(command_id);
  498. gToolBarView->mDragStarted = true;
  499. return TRUE;
  500. }
  501. else
  502. {
  503. MASK mask = 0;
  504. return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask );
  505. }
  506. }
  507. return FALSE;
  508. }
  509. BOOL LLToolBarView::handleDropTool( void* cargo_data, S32 x, S32 y, LLToolBar* toolbar)
  510. {
  511. BOOL handled = FALSE;
  512. LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
  513. LLAssetType::EType type = inv_item->getType();
  514. if (type == LLAssetType::AT_WIDGET)
  515. {
  516. handled = TRUE;
  517. // Get the command from its uuid
  518. LLCommandManager& mgr = LLCommandManager::instance();
  519. LLCommandId command_id(inv_item->getUUID());
  520. LLCommand* command = mgr.getCommand(command_id);
  521. if (command)
  522. {
  523. // Suppress the command from the toolbars (including the one it's dropped in,
  524. // this will handle move position).
  525. S32 old_toolbar_loc = gToolBarView->hasCommand(command_id);
  526. LLToolBar* old_toolbar = NULL;
  527. if (old_toolbar_loc != TOOLBAR_NONE)
  528. {
  529. llassert(gToolBarView->mDragToolbarButton);
  530. old_toolbar = gToolBarView->mDragToolbarButton->getParentByType<LLToolBar>();
  531. if (old_toolbar->isReadOnly() && toolbar->isReadOnly())
  532. {
  533. // do nothing
  534. }
  535. else
  536. {
  537. int old_rank = LLToolBar::RANK_NONE;
  538. gToolBarView->removeCommand(command_id, old_rank);
  539. }
  540. }
  541. // Convert the (x,y) position in rank in toolbar
  542. if (!toolbar->isReadOnly())
  543. {
  544. int new_rank = toolbar->getRankFromPosition(x,y);
  545. toolbar->addCommand(command_id, new_rank);
  546. }
  547. // Save the new toolbars configuration
  548. gToolBarView->saveToolbars();
  549. }
  550. else
  551. {
  552. llwarns << "Command couldn't be found in command manager" << llendl;
  553. }
  554. }
  555. resetDragTool(NULL);
  556. return handled;
  557. }
  558. void LLToolBarView::resetDragTool(LLToolBarButton* toolbarButton)
  559. {
  560. // Clear the saved command, toolbar and rank
  561. gToolBarView->mDragStarted = false;
  562. gToolBarView->mDragToolbarButton = toolbarButton;
  563. }
  564. void LLToolBarView::setToolBarsVisible(bool visible)
  565. {
  566. mShowToolbars = visible;
  567. }
  568. bool LLToolBarView::isModified() const
  569. {
  570. bool modified = false;
  571. for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
  572. {
  573. modified |= mToolbars[i]->isModified();
  574. }
  575. return modified;
  576. }
  577. //
  578. // HACK to bring up destinations guide at startup
  579. //
  580. void handleLoginToolbarSetup()
  581. {
  582. // Open the destinations guide by default on first login, per Rhett
  583. if (gSavedPerAccountSettings.getBOOL("DisplayDestinationsOnInitialRun") || gAgent.isFirstLogin())
  584. {
  585. LLFloaterReg::showInstance("destinations");
  586. gSavedPerAccountSettings.setBOOL("DisplayDestinationsOnInitialRun", FALSE);
  587. }
  588. }