summaryrefslogtreecommitdiff
path: root/indra/newview/lllocationinputctrl.cpp
diff options
context:
space:
mode:
authorAnsariel <ansariel.hiller@phoenixviewer.com>2024-05-22 21:25:21 +0200
committerAndrey Lihatskiy <alihatskiy@productengine.com>2024-05-22 22:40:26 +0300
commite2e37cced861b98de8c1a7c9c0d3a50d2d90e433 (patch)
tree1bb897489ce524986f6196201c10ac0d8861aa5f /indra/newview/lllocationinputctrl.cpp
parent069ea06848f766466f1a281144c82a0f2bd79f3a (diff)
Fix line endlings
Diffstat (limited to 'indra/newview/lllocationinputctrl.cpp')
-rw-r--r--indra/newview/lllocationinputctrl.cpp2580
1 files changed, 1290 insertions, 1290 deletions
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 39e578eb80..54dd5792a0 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -1,1290 +1,1290 @@
-/**
- * @file lllocationinputctrl.cpp
- * @brief Combobox-like location input control
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-// file includes
-#include "lllocationinputctrl.h"
-
-// common includes
-#include "llbutton.h"
-#include "llfocusmgr.h"
-#include "llhelp.h"
-#include "llmenugl.h"
-#include "llparcel.h"
-#include "llstring.h"
-#include "lltrans.h"
-#include "lluictrlfactory.h"
-#include "lltooltip.h"
-#include "llnotificationsutil.h"
-#include "llregionflags.h"
-
-// newview includes
-#include "llagent.h"
-#include "llfloaterreg.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llinventoryobserver.h"
-#include "lllandmarkactions.h"
-#include "lllandmarklist.h"
-#include "llpathfindingmanager.h"
-#include "llpathfindingnavmesh.h"
-#include "llpathfindingnavmeshstatus.h"
-#include "llteleporthistory.h"
-#include "llslurl.h"
-#include "llstatusbar.h" // getHealth()
-#include "lltrans.h"
-#include "llviewerinventory.h"
-#include "llviewerparcelmgr.h"
-#include "llviewerregion.h"
-#include "llviewercontrol.h"
-#include "llviewermenu.h"
-#include "llurllineeditorctrl.h"
-#include "llagentui.h"
-
-#include "llmenuoptionpathfindingrebakenavmesh.h"
-#include "llpathfindingmanager.h"
-
-//============================================================================
-/*
- * "ADD LANDMARK" BUTTON UPDATING LOGIC
- *
- * If the current parcel has been landmarked, we should draw
- * a special image on the button.
- *
- * To avoid determining the appropriate image on every draw() we do that
- * only in the following cases:
- * 1) Navbar is shown for the first time after login.
- * 2) Agent moves to another parcel.
- * 3) A landmark is created or removed.
- *
- * The first case is handled by the handleLoginComplete() method.
- *
- * The second case is handled by setting the "agent parcel changed" callback
- * on LLViewerParcelMgr.
- *
- * The third case is the most complex one. We have two inventory observers for that:
- * one is designated to handle adding landmarks, the other handles removal.
- * Let's see how the former works.
- *
- * When we get notified about landmark addition, the landmark position is unknown yet. What we can
- * do at that point is initiate loading the landmark data by LLLandmarkList and set the
- * "loading finished" callback on it. Finally, when the callback is triggered,
- * we can determine whether the landmark refers to a point within the current parcel
- * and choose the appropriate image for the "Add landmark" button.
- */
-
-/**
- * Initiates loading the landmarks that have been just added.
- *
- * Once the loading is complete we'll be notified
- * with the callback we set for LLLandmarkList.
- */
-class LLAddLandmarkObserver : public LLInventoryAddedObserver
-{
-public:
- LLAddLandmarkObserver(LLLocationInputCtrl* input) : mInput(input) {}
-
-private:
- /*virtual*/ void done()
- {
- const uuid_set_t& added = gInventory.getAddedIDs();
- for (uuid_set_t::const_iterator it = added.begin(); it != added.end(); ++it)
- {
- LLInventoryItem* item = gInventory.getItem(*it);
- if (!item || item->getType() != LLAssetType::AT_LANDMARK)
- continue;
-
- // Start loading the landmark.
- LLLandmark* lm = gLandmarkList.getAsset(
- item->getAssetUUID(),
- boost::bind(&LLLocationInputCtrl::onLandmarkLoaded, mInput, _1));
- if (lm)
- {
- // Already loaded? Great, handle it immediately (the callback won't be called).
- mInput->onLandmarkLoaded(lm);
- }
- }
- }
-
- LLLocationInputCtrl* mInput;
-};
-
-/**
- * Updates the "Add landmark" button once a landmark gets removed.
- */
-class LLRemoveLandmarkObserver : public LLInventoryObserver
-{
-public:
- LLRemoveLandmarkObserver(LLLocationInputCtrl* input) : mInput(input) {}
-
-private:
- /*virtual*/ void changed(U32 mask)
- {
- if (mask & (~(LLInventoryObserver::LABEL|
- LLInventoryObserver::INTERNAL|
- LLInventoryObserver::ADD|
- LLInventoryObserver::CREATE|
- LLInventoryObserver::UPDATE_CREATE)))
- {
- mInput->updateAddLandmarkButton();
- }
- }
-
- LLLocationInputCtrl* mInput;
-};
-
-class LLParcelChangeObserver : public LLParcelObserver
-{
-public:
- LLParcelChangeObserver(LLLocationInputCtrl* input) : mInput(input) {}
-
-private:
- /*virtual*/ void changed()
- {
- if (mInput)
- {
- mInput->refreshParcelIcons();
- }
- }
-
- LLLocationInputCtrl* mInput;
-};
-
-//============================================================================
-
-
-static LLDefaultChildRegistry::Register<LLLocationInputCtrl> r("location_input");
-
-LLLocationInputCtrl::Params::Params()
-: icon_maturity_general("icon_maturity_general"),
- icon_maturity_adult("icon_maturity_adult"),
- icon_maturity_moderate("icon_maturity_moderate"),
- add_landmark_image_enabled("add_landmark_image_enabled"),
- add_landmark_image_disabled("add_landmark_image_disabled"),
- add_landmark_image_hover("add_landmark_image_hover"),
- add_landmark_image_selected("add_landmark_image_selected"),
- add_landmark_hpad("add_landmark_hpad", 0),
- icon_hpad("icon_hpad", 0),
- add_landmark_button("add_landmark_button"),
- for_sale_button("for_sale_button"),
- info_button("info_button"),
- maturity_button("maturity_button"),
- voice_icon("voice_icon"),
- fly_icon("fly_icon"),
- push_icon("push_icon"),
- build_icon("build_icon"),
- scripts_icon("scripts_icon"),
- damage_icon("damage_icon"),
- damage_text("damage_text"),
- see_avatars_icon("see_avatars_icon"),
- maturity_help_topic("maturity_help_topic"),
- pathfinding_dirty_icon("pathfinding_dirty_icon"),
- pathfinding_disabled_icon("pathfinding_disabled_icon")
-{
-}
-
-LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
-: LLComboBox(p),
- mIconHPad(p.icon_hpad),
- mAddLandmarkHPad(p.add_landmark_hpad),
- mLocationContextMenu(NULL),
- mAddLandmarkBtn(NULL),
- mForSaleBtn(NULL),
- mInfoBtn(NULL),
- mRegionCrossingSlot(),
- mNavMeshSlot(),
- mIsNavMeshDirty(false),
- mLandmarkImageOn(NULL),
- mLandmarkImageOff(NULL),
- mIconMaturityGeneral(NULL),
- mIconMaturityAdult(NULL),
- mIconMaturityModerate(NULL),
- mMaturityHelpTopic(p.maturity_help_topic)
-{
- // Lets replace default LLLineEditor with LLLocationLineEditor
- // to make needed escaping while copying and cutting url
- delete mTextEntry;
-
- // Can't access old mTextEntry fields as they are protected, so lets build new params
- // That is C&P from LLComboBox::createLineEditor function
- S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
- LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
- text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * BTN_DROP_SHADOW;
-
- LLLineEditor::Params params = p.combo_editor;
- params.rect(text_entry_rect);
- params.default_text(LLStringUtil::null);
- params.max_length.bytes(p.max_chars);
- params.keystroke_callback(boost::bind(&LLLocationInputCtrl::onTextEntry, this, _1));
- params.commit_on_focus_lost(false);
- params.follows.flags(FOLLOWS_ALL);
- mTextEntry = LLUICtrlFactory::create<LLURLLineEditor>(params);
- mTextEntry->resetContextMenu();
- addChild(mTextEntry);
- // LLLineEditor is replaced with LLLocationLineEditor
-
- // "Place information" button.
- LLButton::Params info_params = p.info_button;
- mInfoBtn = LLUICtrlFactory::create<LLButton>(info_params);
- mInfoBtn->setClickedCallback(boost::bind(&LLLocationInputCtrl::onInfoButtonClicked, this));
- addChild(mInfoBtn);
-
- // "Add landmark" button.
- LLButton::Params al_params = p.add_landmark_button;
-
- // Image for unselected state will be set in updateAddLandmarkButton(),
- // it will be either mLandmarkOn or mLandmarkOff
- if (p.add_landmark_image_enabled())
- {
- mLandmarkImageOn = p.add_landmark_image_enabled;
- }
- if (p.add_landmark_image_disabled())
- {
- mLandmarkImageOff = p.add_landmark_image_disabled;
- }
-
- if(p.add_landmark_image_selected)
- {
- al_params.image_selected = p.add_landmark_image_selected;
- }
- if (p.add_landmark_image_hover())
- {
- al_params.image_hover_unselected = p.add_landmark_image_hover;
- }
-
- al_params.click_callback.function(boost::bind(&LLLocationInputCtrl::onAddLandmarkButtonClicked, this));
- mAddLandmarkBtn = LLUICtrlFactory::create<LLButton>(al_params);
- enableAddLandmarkButton(true);
- addChild(mAddLandmarkBtn);
-
- if (p.icon_maturity_general())
- {
- mIconMaturityGeneral = p.icon_maturity_general;
- }
- if (p.icon_maturity_adult())
- {
- mIconMaturityAdult = p.icon_maturity_adult;
- }
- if(p.icon_maturity_moderate())
- {
- mIconMaturityModerate = p.icon_maturity_moderate;
- }
-
- LLButton::Params maturity_button = p.maturity_button;
- mMaturityButton = LLUICtrlFactory::create<LLButton>(maturity_button);
- addChild(mMaturityButton);
-
- LLButton::Params for_sale_button = p.for_sale_button;
- for_sale_button.tool_tip = LLTrans::getString("LocationCtrlForSaleTooltip");
- for_sale_button.click_callback.function(
- boost::bind(&LLLocationInputCtrl::onForSaleButtonClicked, this));
- mForSaleBtn = LLUICtrlFactory::create<LLButton>( for_sale_button );
- addChild(mForSaleBtn);
-
- // Parcel property icons
- // Must be mouse-opaque so cursor stays as an arrow when hovering to
- // see tooltip.
- LLIconCtrl::Params voice_icon = p.voice_icon;
- voice_icon.tool_tip = LLTrans::getString("LocationCtrlVoiceTooltip");
- voice_icon.mouse_opaque = true;
- mParcelIcon[VOICE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(voice_icon);
- mParcelIcon[VOICE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, VOICE_ICON));
- addChild(mParcelIcon[VOICE_ICON]);
-
- LLIconCtrl::Params fly_icon = p.fly_icon;
- fly_icon.tool_tip = LLTrans::getString("LocationCtrlFlyTooltip");
- fly_icon.mouse_opaque = true;
- mParcelIcon[FLY_ICON] = LLUICtrlFactory::create<LLIconCtrl>(fly_icon);
- mParcelIcon[FLY_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, FLY_ICON));
- addChild(mParcelIcon[FLY_ICON]);
-
- LLIconCtrl::Params push_icon = p.push_icon;
- push_icon.tool_tip = LLTrans::getString("LocationCtrlPushTooltip");
- push_icon.mouse_opaque = true;
- mParcelIcon[PUSH_ICON] = LLUICtrlFactory::create<LLIconCtrl>(push_icon);
- mParcelIcon[PUSH_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PUSH_ICON));
- addChild(mParcelIcon[PUSH_ICON]);
-
- LLIconCtrl::Params build_icon = p.build_icon;
- build_icon.tool_tip = LLTrans::getString("LocationCtrlBuildTooltip");
- build_icon.mouse_opaque = true;
- mParcelIcon[BUILD_ICON] = LLUICtrlFactory::create<LLIconCtrl>(build_icon);
- mParcelIcon[BUILD_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, BUILD_ICON));
- addChild(mParcelIcon[BUILD_ICON]);
-
- LLIconCtrl::Params scripts_icon = p.scripts_icon;
- scripts_icon.tool_tip = LLTrans::getString("LocationCtrlScriptsTooltip");
- scripts_icon.mouse_opaque = true;
- mParcelIcon[SCRIPTS_ICON] = LLUICtrlFactory::create<LLIconCtrl>(scripts_icon);
- mParcelIcon[SCRIPTS_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, SCRIPTS_ICON));
- addChild(mParcelIcon[SCRIPTS_ICON]);
-
- LLIconCtrl::Params damage_icon = p.damage_icon;
- damage_icon.tool_tip = LLTrans::getString("LocationCtrlDamageTooltip");
- damage_icon.mouse_opaque = true;
- mParcelIcon[DAMAGE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(damage_icon);
- mParcelIcon[DAMAGE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, DAMAGE_ICON));
- addChild(mParcelIcon[DAMAGE_ICON]);
-
- LLIconCtrl::Params pathfinding_dirty_icon = p.pathfinding_dirty_icon;
- pathfinding_dirty_icon.tool_tip = LLTrans::getString("LocationCtrlPathfindingDirtyTooltip");
- pathfinding_dirty_icon.mouse_opaque = true;
- mParcelIcon[PATHFINDING_DIRTY_ICON] = LLUICtrlFactory::create<LLIconCtrl>(pathfinding_dirty_icon);
- mParcelIcon[PATHFINDING_DIRTY_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PATHFINDING_DIRTY_ICON));
- addChild(mParcelIcon[PATHFINDING_DIRTY_ICON]);
-
- LLIconCtrl::Params pathfinding_disabled_icon = p.pathfinding_disabled_icon;
- pathfinding_disabled_icon.tool_tip = LLTrans::getString("LocationCtrlPathfindingDisabledTooltip");
- pathfinding_disabled_icon.mouse_opaque = true;
- mParcelIcon[PATHFINDING_DISABLED_ICON] = LLUICtrlFactory::create<LLIconCtrl>(pathfinding_disabled_icon);
- mParcelIcon[PATHFINDING_DISABLED_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PATHFINDING_DISABLED_ICON));
- addChild(mParcelIcon[PATHFINDING_DISABLED_ICON]);
-
- LLTextBox::Params damage_text = p.damage_text;
- damage_text.tool_tip = LLTrans::getString("LocationCtrlDamageTooltip");
- damage_text.mouse_opaque = true;
- mDamageText = LLUICtrlFactory::create<LLTextBox>(damage_text);
- addChild(mDamageText);
-
- LLIconCtrl::Params see_avatars_icon = p.see_avatars_icon;
- see_avatars_icon.tool_tip = LLTrans::getString("LocationCtrlSeeAVsTooltip");
- see_avatars_icon.mouse_opaque = true;
- mParcelIcon[SEE_AVATARS_ICON] = LLUICtrlFactory::create<LLIconCtrl>(see_avatars_icon);
- mParcelIcon[SEE_AVATARS_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, SEE_AVATARS_ICON));
- addChild(mParcelIcon[SEE_AVATARS_ICON]);
-
- // Register callbacks and load the location field context menu (NB: the order matters).
- LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Navbar.Action", boost::bind(&LLLocationInputCtrl::onLocationContextMenuItemClicked, this, _2));
- LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Navbar.EnableMenuItem", boost::bind(&LLLocationInputCtrl::onLocationContextMenuItemEnabled, this, _2));
-
- setPrearrangeCallback(boost::bind(&LLLocationInputCtrl::onLocationPrearrange, this, _2));
- getTextEntry()->setMouseUpCallback(boost::bind(&LLLocationInputCtrl::changeLocationPresentation, this));
-
- // Load the location field context menu
- mLocationContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- if (!mLocationContextMenu)
- {
- LL_WARNS() << "Error loading navigation bar context menu" << LL_ENDL;
-
- }
- //don't show default context menu
- getTextEntry()->setShowContextMenu(false);
- getTextEntry()->setRightMouseDownCallback(boost::bind(&LLLocationInputCtrl::onTextEditorRightClicked, this, _2, _3, _4));
- updateWidgetlayout();
-
- // Connecting signal for updating location on "Show Coordinates" setting change.
- LLControlVariable* coordinates_control = gSavedSettings.getControl("NavBarShowCoordinates").get();
- if (coordinates_control)
- {
- mCoordinatesControlConnection = coordinates_control->getSignal()->connect(boost::bind(&LLLocationInputCtrl::refreshLocation, this));
- }
-
- // Connecting signal for updating parcel icons on "Show Parcel Properties" setting change.
- LLControlVariable* parcel_properties_control = gSavedSettings.getControl("NavBarShowParcelProperties").get();
- if (parcel_properties_control)
- {
- mParcelPropertiesControlConnection = parcel_properties_control->getSignal()->connect(boost::bind(&LLLocationInputCtrl::refreshParcelIcons, this));
- }
-
- // - Make the "Add landmark" button updated when either current parcel gets changed
- // or a landmark gets created or removed from the inventory.
- // - Update the location string on parcel change.
- mParcelMgrConnection = gAgent.addParcelChangedCallback(
- boost::bind(&LLLocationInputCtrl::onAgentParcelChange, this));
- // LLLocationHistory instance is being created before the location input control, so we have to update initial state of button manually.
- mButton->setEnabled(LLLocationHistory::instance().getItemCount() > 0);
- mLocationHistoryConnection = LLLocationHistory::getInstance()->setChangedCallback(
- boost::bind(&LLLocationInputCtrl::onLocationHistoryChanged, this,_1));
-
- mRegionCrossingSlot = gAgent.addRegionChangedCallback(boost::bind(&LLLocationInputCtrl::onRegionBoundaryCrossed, this));
- createNavMeshStatusListenerForCurrentRegion();
-
- mRemoveLandmarkObserver = new LLRemoveLandmarkObserver(this);
- mAddLandmarkObserver = new LLAddLandmarkObserver(this);
- gInventory.addObserver(mRemoveLandmarkObserver);
- gInventory.addObserver(mAddLandmarkObserver);
-
- mParcelChangeObserver = new LLParcelChangeObserver(this);
- LLViewerParcelMgr::getInstance()->addObserver(mParcelChangeObserver);
-
- mAddLandmarkTooltip = LLTrans::getString("LocationCtrlAddLandmarkTooltip");
- mEditLandmarkTooltip = LLTrans::getString("LocationCtrlEditLandmarkTooltip");
- mButton->setToolTip(LLTrans::getString("LocationCtrlComboBtnTooltip"));
- mInfoBtn->setToolTip(LLTrans::getString("LocationCtrlInfoBtnTooltip"));
-}
-
-LLLocationInputCtrl::~LLLocationInputCtrl()
-{
- gInventory.removeObserver(mRemoveLandmarkObserver);
- gInventory.removeObserver(mAddLandmarkObserver);
- delete mRemoveLandmarkObserver;
- delete mAddLandmarkObserver;
-
- LLViewerParcelMgr::getInstance()->removeObserver(mParcelChangeObserver);
- delete mParcelChangeObserver;
-
- mRegionCrossingSlot.disconnect();
- mNavMeshSlot.disconnect();
- mCoordinatesControlConnection.disconnect();
- mParcelPropertiesControlConnection.disconnect();
- mParcelMgrConnection.disconnect();
- mLocationHistoryConnection.disconnect();
-}
-
-void LLLocationInputCtrl::setEnabled(bool enabled)
-{
- LLComboBox::setEnabled(enabled);
- mAddLandmarkBtn->setEnabled(enabled);
-}
-
-void LLLocationInputCtrl::hideList()
-{
- LLComboBox::hideList();
- if (mTextEntry && hasFocus())
- focusTextEntry();
-}
-
-bool LLLocationInputCtrl::handleToolTip(S32 x, S32 y, MASK mask)
-{
-
- if(mAddLandmarkBtn->parentPointInView(x,y))
- {
- updateAddLandmarkTooltip();
- }
- // Let the buttons show their tooltips.
- if (LLUICtrl::handleToolTip(x, y, mask))
- {
- if (mList->getRect().pointInRect(x, y))
- {
- S32 loc_x, loc_y;
- //x,y - contain coordinates related to the location input control, but without taking the expanded list into account
- //So we have to convert it again into local coordinates of mList
- localPointToOtherView(x,y,&loc_x,&loc_y,mList);
-
- LLScrollListItem* item = mList->hitItem(loc_x,loc_y);
- if (item)
- {
- LLSD value = item->getValue();
- if (value.has("tooltip"))
- {
- LLToolTipMgr::instance().show(value["tooltip"]);
- }
- }
- }
-
- return true;
- }
-
- return false;
-}
-
-bool LLLocationInputCtrl::handleKeyHere(KEY key, MASK mask)
-{
- bool result = LLComboBox::handleKeyHere(key, mask);
-
- if (key == KEY_DOWN && hasFocus() && mList->getItemCount() != 0 && !mList->getVisible())
- {
- showList();
- }
-
- return result;
-}
-
-void LLLocationInputCtrl::onTextEntry(LLLineEditor* line_editor)
-{
- KEY key = gKeyboard->currentKey();
- MASK mask = gKeyboard->currentMask(true);
-
- // Typing? (moving cursor should not affect showing the list)
- bool typing = mask != MASK_CONTROL && key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END;
- bool pasting = mask == MASK_CONTROL && key == 'V';
-
- if (line_editor->getText().empty())
- {
- prearrangeList(); // resets filter
- hideList();
- }
- else if (typing || pasting)
- {
- prearrangeList(line_editor->getText());
- if (mList->getItemCount() != 0)
- {
- showList();
- focusTextEntry();
- }
- else
- {
- // Hide the list if it's empty.
- hideList();
- }
- }
-
- LLComboBox::onTextEntry(line_editor);
-}
-
-/**
- * Useful if we want to just set the text entry value, no matter what the list contains.
- *
- * This is faster than setTextEntry().
- */
-void LLLocationInputCtrl::setText(const LLStringExplicit& text)
-{
- if (mTextEntry)
- {
- mTextEntry->setText(text);
- }
- mHasAutocompletedText = false;
-}
-
-void LLLocationInputCtrl::setFocus(bool b)
-{
- LLComboBox::setFocus(b);
-
- if (mTextEntry && b && !mList->getVisible())
- {
- mTextEntry->setFocus(true);
- }
-}
-
-void LLLocationInputCtrl::handleLoginComplete()
-{
- // An agent parcel update hasn't occurred yet, so we have to
- // manually set location and the appropriate "Add landmark" icon.
- refresh();
-}
-
-//== private methods =========================================================
-
-void LLLocationInputCtrl::onFocusReceived()
-{
- prearrangeList();
-}
-
-void LLLocationInputCtrl::onFocusLost()
-{
- LLUICtrl::onFocusLost();
- refreshLocation();
-
- // Setting cursor to 0 to show the left edge of the text. See STORM-370.
- mTextEntry->setCursor(0);
-
- if(mTextEntry->hasSelection()){
- mTextEntry->deselect();
- }
-}
-
-void LLLocationInputCtrl::draw()
-{
- static LLUICachedControl<bool> show_coords("NavBarShowCoordinates", false);
- if(!hasFocus() && show_coords)
- {
- refreshLocation();
- }
-
- static LLUICachedControl<bool> show_icons("NavBarShowParcelProperties", false);
- if (show_icons)
- {
- refreshHealth();
- }
- LLComboBox::draw();
-}
-
-void LLLocationInputCtrl::reshape(S32 width, S32 height, bool called_from_parent)
-{
- LLComboBox::reshape(width, height, called_from_parent);
-
- // Setting cursor to 0 to show the left edge of the text. See EXT-4967.
- mTextEntry->setCursor(0);
- if (mTextEntry->hasSelection())
- {
- // Deselecting because selection position is changed together with
- // cursor position change.
- mTextEntry->deselect();
- }
-
- if (isHumanReadableLocationVisible)
- {
- refreshMaturityButton();
- }
-}
-
-void LLLocationInputCtrl::onInfoButtonClicked()
-{
- LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "agent"));
-}
-
-void LLLocationInputCtrl::onForSaleButtonClicked()
-{
- handle_buy_land();
-}
-
-void LLLocationInputCtrl::onAddLandmarkButtonClicked()
-{
- LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos();
- // Landmark exists, open it for preview and edit
- if(landmark && landmark->getUUID().notNull())
- {
- LLSD key;
- key["type"] = "landmark";
- key["id"] = landmark->getUUID();
-
- LLFloaterSidePanelContainer::showPanel("places", key);
- }
- else
- {
- LLFloaterReg::showInstance("add_landmark");
- }
-}
-
-void LLLocationInputCtrl::onAgentParcelChange()
-{
- refresh();
-}
-
-void LLLocationInputCtrl::onRegionBoundaryCrossed()
-{
- createNavMeshStatusListenerForCurrentRegion();
-}
-
-void LLLocationInputCtrl::onNavMeshStatusChange(const LLPathfindingNavMeshStatus &pNavMeshStatus)
-{
- mIsNavMeshDirty = pNavMeshStatus.isValid() && (pNavMeshStatus.getStatus() != LLPathfindingNavMeshStatus::kComplete);
- refreshParcelIcons();
-}
-
-void LLLocationInputCtrl::onLandmarkLoaded(LLLandmark* lm)
-{
- (void) lm;
- updateAddLandmarkButton();
-}
-
-void LLLocationInputCtrl::onLocationHistoryChanged(LLLocationHistory::EChangeType event)
-{
- if(event == LLLocationHistory::LOAD)
- {
- rebuildLocationHistory();
- }
- mButton->setEnabled(LLLocationHistory::instance().getItemCount() > 0);
-}
-
-void LLLocationInputCtrl::onLocationPrearrange(const LLSD& data)
-{
- std::string filter = data.asString();
- rebuildLocationHistory(filter);
-
- //Let's add landmarks to the top of the list if any
- if(!filter.empty() )
- {
- LLInventoryModel::item_array_t landmark_items = LLLandmarkActions::fetchLandmarksByName(filter, true);
-
- for(U32 i=0; i < landmark_items.size(); i++)
- {
- LLSD value;
- //TODO:: DO we need tooltip for Landmark??
-
- value["item_type"] = LANDMARK;
- value["AssetUUID"] = landmark_items[i]->getAssetUUID();
- addLocationHistoryEntry(landmark_items[i]->getName(), value);
-
- }
- //Let's add teleport history items
- LLTeleportHistory* th = LLTeleportHistory::getInstance();
- LLTeleportHistory::slurl_list_t th_items = th->getItems();
-
- std::set<std::string> new_item_titles;// duplicate control
- LLTeleportHistory::slurl_list_t::iterator result = std::find_if(
- th_items.begin(), th_items.end(), boost::bind(
- &LLLocationInputCtrl::findTeleportItemsByTitle, this,
- _1, filter));
-
- while (result != th_items.end())
- {
- //mTitile format - region_name[, parcel_name]
- //mFullTitile format - region_name[, parcel_name] (local_x,local_y, local_z)
- if (new_item_titles.insert(result->mFullTitle).second)
- {
- LLSD value;
- value["item_type"] = TELEPORT_HISTORY;
- value["global_pos"] = result->mGlobalPos.getValue();
- std::string region_name = result->mTitle.substr(0, result->mTitle.find(','));
- //TODO*: add Surl to teleportitem or parse region name from title
- value["tooltip"] = LLSLURL(region_name, result->mGlobalPos).getSLURLString();
- addLocationHistoryEntry(result->getTitle(), value);
- }
- result = std::find_if(result + 1, th_items.end(), boost::bind(
- &LLLocationInputCtrl::findTeleportItemsByTitle, this,
- _1, filter));
- }
- }
- sortByName();
-
- mList->mouseOverHighlightNthItem(-1); // Clear highlight on the last selected item.
-}
-
-bool LLLocationInputCtrl::findTeleportItemsByTitle(const LLTeleportHistoryItem& item, const std::string& filter)
-{
- return item.mTitle.find(filter) != std::string::npos;
-}
-
-void LLLocationInputCtrl::onTextEditorRightClicked(S32 x, S32 y, MASK mask)
-{
- if (mLocationContextMenu)
- {
- updateContextMenu();
- mLocationContextMenu->buildDrawLabels();
- mLocationContextMenu->updateParent(LLMenuGL::sMenuContainer);
- hideList();
- setFocus(true);
- changeLocationPresentation();
- LLMenuGL::showPopup(this, mLocationContextMenu, x, y);
- }
-}
-
-void LLLocationInputCtrl::refresh()
-{
- refreshLocation(); // update location string
- refreshParcelIcons();
- updateAddLandmarkButton(); // indicate whether current parcel has been landmarked
-}
-
-void LLLocationInputCtrl::refreshLocation()
-{
- // Is one of our children focused?
- if (LLUICtrl::hasFocus() || mButton->hasFocus() || mList->hasFocus() ||
- (mTextEntry && mTextEntry->hasFocus()) ||
- (mAddLandmarkBtn->hasFocus()))
- {
- LL_WARNS() << "Location input should not be refreshed when having focus" << LL_ENDL;
- return;
- }
-
- // Update location field.
- std::string location_name;
- LLAgentUI::ELocationFormat format =
- (gSavedSettings.getBOOL("NavBarShowCoordinates")
- ? LLAgentUI::LOCATION_FORMAT_FULL
- : LLAgentUI::LOCATION_FORMAT_NO_COORDS);
-
- if (!LLAgentUI::buildLocationString(location_name, format))
- {
- location_name = "???";
- }
- // store human-readable location to compare it in changeLocationPresentation()
- mHumanReadableLocation = location_name;
- setText(location_name);
- isHumanReadableLocationVisible = true;
-
- refreshMaturityButton();
-}
-
-// returns new right edge
-static S32 layout_widget(LLUICtrl* widget, S32 right)
-{
- if (widget->getVisible())
- {
- LLRect rect = widget->getRect();
- rect.mLeft = right - rect.getWidth();
- rect.mRight = right;
- widget->setRect( rect );
- right -= rect.getWidth();
- }
- return right;
-}
-
-void LLLocationInputCtrl::refreshParcelIcons()
-{
- // Our "cursor" moving right to left
- S32 x = mAddLandmarkBtn->getRect().mLeft;
-
- LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstance();
-
- LLViewerRegion* agent_region = gAgent.getRegion();
- LLParcel* agent_parcel = vpm->getAgentParcel();
- if (!agent_region || !agent_parcel)
- return;
-
- mForSaleBtn->setVisible(vpm->canAgentBuyParcel(agent_parcel, false));
-
- x = layout_widget(mForSaleBtn, x);
-
- if (gSavedSettings.getBOOL("NavBarShowParcelProperties"))
- {
- LLParcel* current_parcel;
- LLViewerRegion* selection_region = vpm->getSelectionRegion();
- LLParcel* selected_parcel = vpm->getParcelSelection()->getParcel();
-
- // If agent is in selected parcel we use its properties because
- // they are updated more often by LLViewerParcelMgr than agent parcel properties.
- // See LLViewerParcelMgr::processParcelProperties().
- // This is needed to reflect parcel restrictions changes without having to leave
- // the parcel and then enter it again. See EXT-2987
- if (selected_parcel && selected_parcel->getLocalID() == agent_parcel->getLocalID()
- && selection_region == agent_region)
- {
- current_parcel = selected_parcel;
- }
- else
- {
- current_parcel = agent_parcel;
- }
-
- bool allow_voice = vpm->allowAgentVoice(agent_region, current_parcel);
- bool allow_fly = vpm->allowAgentFly(agent_region, current_parcel);
- bool allow_push = vpm->allowAgentPush(agent_region, current_parcel);
- bool allow_build = vpm->allowAgentBuild(current_parcel); // true when anyone is allowed to build. See EXT-4610.
- bool allow_scripts = vpm->allowAgentScripts(agent_region, current_parcel);
- bool allow_damage = vpm->allowAgentDamage(agent_region, current_parcel);
- bool see_avs = current_parcel->getSeeAVs();
- bool pathfinding_dynamic_enabled = agent_region->dynamicPathfindingEnabled();
-
- // Most icons are "block this ability"
- mParcelIcon[VOICE_ICON]->setVisible( !allow_voice );
- mParcelIcon[FLY_ICON]->setVisible( !allow_fly );
- mParcelIcon[PUSH_ICON]->setVisible( !allow_push );
- mParcelIcon[BUILD_ICON]->setVisible( !allow_build );
- mParcelIcon[SCRIPTS_ICON]->setVisible( !allow_scripts );
- mParcelIcon[DAMAGE_ICON]->setVisible( allow_damage );
- mParcelIcon[PATHFINDING_DIRTY_ICON]->setVisible(mIsNavMeshDirty);
- mParcelIcon[PATHFINDING_DISABLED_ICON]->setVisible(!mIsNavMeshDirty && !pathfinding_dynamic_enabled);
-
- mDamageText->setVisible(allow_damage);
- mParcelIcon[SEE_AVATARS_ICON]->setVisible( !see_avs );
-
- // Padding goes to left of both landmark star and for sale btn
- x -= mAddLandmarkHPad;
-
- // Slide the parcel icons rect from right to left, adjusting rectangles
- for (S32 i = 0; i < ICON_COUNT; ++i)
- {
- x = layout_widget(mParcelIcon[i], x);
- x -= mIconHPad;
- }
- x = layout_widget(mDamageText, x);
- x -= mIconHPad;
- }
- else
- {
- for (S32 i = 0; i < ICON_COUNT; ++i)
- {
- mParcelIcon[i]->setVisible(false);
- }
- mDamageText->setVisible(false);
- }
-
- if (mTextEntry)
- {
- S32 left_pad, right_pad;
- mTextEntry->getTextPadding(&left_pad, &right_pad);
- right_pad = mTextEntry->getRect().mRight - x;
- mTextEntry->setTextPadding(left_pad, right_pad);
- }
-}
-
-void LLLocationInputCtrl::refreshHealth()
-{
- // *FIXME: Status bar owns health information, should be in agent
- if (gStatusBar)
- {
- static S32 last_health = -1;
- S32 health = gStatusBar->getHealth();
- if (health != last_health)
- {
- std::string text = llformat("%d%%", health);
- mDamageText->setText(text);
- last_health = health;
- }
- }
-}
-
-void LLLocationInputCtrl::refreshMaturityButton()
-{
- // Updating maturity rating icon.
- LLViewerRegion* region = gAgent.getRegion();
- if (!region)
- return;
-
- bool button_visible = true;
- LLPointer<LLUIImage> rating_image = NULL;
- std::string rating_tooltip;
-
- U8 sim_access = region->getSimAccess();
- switch(sim_access)
- {
- case SIM_ACCESS_PG:
- rating_image = mIconMaturityGeneral;
- rating_tooltip = LLTrans::getString("LocationCtrlGeneralIconTooltip");
- break;
-
- case SIM_ACCESS_ADULT:
- rating_image = mIconMaturityAdult;
- rating_tooltip = LLTrans::getString("LocationCtrlAdultIconTooltip");
- break;
-
- case SIM_ACCESS_MATURE:
- rating_image = mIconMaturityModerate;
- rating_tooltip = LLTrans::getString("LocationCtrlModerateIconTooltip");
- break;
-
- default:
- button_visible = false;
- break;
- }
-
- mMaturityButton->setVisible(button_visible);
- mMaturityButton->setToolTip(rating_tooltip);
- if(rating_image)
- {
- mMaturityButton->setImageUnselected(rating_image);
- mMaturityButton->setImagePressed(rating_image);
- }
- if (mMaturityButton->getVisible())
- {
- positionMaturityButton();
- }
-}
-
-void LLLocationInputCtrl::positionMaturityButton()
-{
- const LLFontGL* font = mTextEntry->getFont();
- if (!font)
- return;
-
- S32 left_pad, right_pad;
- mTextEntry->getTextPadding(&left_pad, &right_pad);
-
- // Calculate the right edge of rendered text + a whitespace.
- left_pad = left_pad + font->getWidth(mTextEntry->getText()) + font->getWidth(" ");
-
- LLRect rect = mMaturityButton->getRect();
- mMaturityButton->setRect(rect.setOriginAndSize(left_pad, rect.mBottom, rect.getWidth(), rect.getHeight()));
-
- // Hide icon if it text area is not width enough to display it, show otherwise.
- mMaturityButton->setVisible(rect.mRight < mTextEntry->getRect().getWidth() - right_pad);
-}
-
-void LLLocationInputCtrl::addLocationHistoryEntry(const std::string& title, const LLSD& value)
-{
- // SL-20286 : Duplication of autocomplete results occurs when entering some search queries in the navigation bar
- // Exclude visual duplicates (items with the same titles) in the dropdown list
- LLScrollListItem* item = mList->getItemByLabel(title);
- if (!item)
- {
- add(title, value);
- }
-}
-
-void LLLocationInputCtrl::rebuildLocationHistory(const std::string& filter)
-{
- LLLocationHistory::location_list_t filtered_items;
- const LLLocationHistory::location_list_t* itemsp = NULL;
- LLLocationHistory* lh = LLLocationHistory::getInstance();
-
- if (filter.empty())
- {
- itemsp = &lh->getItems();
- }
- else
- {
- lh->getMatchingItems(filter, filtered_items);
- itemsp = &filtered_items;
- }
-
- removeall();
- for (LLLocationHistory::location_list_t::const_reverse_iterator it = itemsp->rbegin(); it != itemsp->rend(); it++)
- {
- LLSD value;
- value["tooltip"] = it->getToolTip();
- //location history can contain only typed locations
- value["item_type"] = TYPED_REGION_SLURL;
- value["global_pos"] = it->mGlobalPos.getValue();
- addLocationHistoryEntry(it->getLocation(), value);
- }
-}
-
-void LLLocationInputCtrl::focusTextEntry()
-{
- // We can't use "mTextEntry->setFocus(true)" instead because
- // if the "select_on_focus" parameter is true it places the cursor
- // at the beginning (after selecting text), thus screwing up updateSelection().
- if (mTextEntry)
- {
- gFocusMgr.setKeyboardFocus(mTextEntry);
-
- // Enable the text entry to handle accelerator keys (EXT-8104).
- LLEditMenuHandler::gEditMenuHandler = mTextEntry;
- }
-}
-
-void LLLocationInputCtrl::enableAddLandmarkButton(bool val)
-{
- // We don't want to disable the button because it should be click able at any time,
- // instead switch images.
- LLUIImage* img = val ? mLandmarkImageOn : mLandmarkImageOff;
- if(img)
- {
- mAddLandmarkBtn->setImageUnselected(img);
- }
-}
-
-// Change the "Add landmark" button image
-// depending on whether current parcel has been landmarked.
-void LLLocationInputCtrl::updateAddLandmarkButton()
-{
- enableAddLandmarkButton(LLLandmarkActions::hasParcelLandmark());
-}
-void LLLocationInputCtrl::updateAddLandmarkTooltip()
-{
- std::string tooltip;
- if(LLLandmarkActions::landmarkAlreadyExists())
- {
- tooltip = mEditLandmarkTooltip;
- }
- else
- {
- tooltip = mAddLandmarkTooltip;
- }
- mAddLandmarkBtn->setToolTip(tooltip);
-}
-
-void LLLocationInputCtrl::updateContextMenu(){
-
- if (mLocationContextMenu)
- {
- LLMenuItemGL* landmarkItem = mLocationContextMenu->getChild<LLMenuItemGL>("Landmark");
- if (!LLLandmarkActions::landmarkAlreadyExists())
- {
- landmarkItem->setLabel(LLTrans::getString("AddLandmarkNavBarMenu"));
- }
- else
- {
- landmarkItem->setLabel(LLTrans::getString("EditLandmarkNavBarMenu"));
- }
- }
-}
-void LLLocationInputCtrl::updateWidgetlayout()
-{
- const LLRect& rect = getLocalRect();
- const LLRect& hist_btn_rect = mButton->getRect();
-
- // Info button is set in the XUI XML location_input.xml
-
- // "Add Landmark" button
- LLRect al_btn_rect = mAddLandmarkBtn->getRect();
- al_btn_rect.translate(
- hist_btn_rect.mLeft - mIconHPad - al_btn_rect.getWidth(),
- (rect.getHeight() - al_btn_rect.getHeight()) / 2);
- mAddLandmarkBtn->setRect(al_btn_rect);
-}
-
-void LLLocationInputCtrl::changeLocationPresentation()
-{
- if (!mTextEntry)
- return;
-
- //change location presentation only if user does not select/paste anything and
- //human-readable region name is being displayed
- if(!mTextEntry->hasSelection() && mTextEntry->getText() == mHumanReadableLocation)
- {
- //needs unescaped one
- LLSLURL slurl;
- LLAgentUI::buildSLURL(slurl, false);
- mTextEntry->setText(LLURI::unescape(slurl.getSLURLString()));
- mTextEntry->selectAll();
-
- mMaturityButton->setVisible(false);
-
- isHumanReadableLocationVisible = false;
- }
-}
-
-void LLLocationInputCtrl::onLocationContextMenuItemClicked(const LLSD& userdata)
-{
- std::string item = userdata.asString();
-
- if (item == "show_coordinates")
- {
- gSavedSettings.setBOOL("NavBarShowCoordinates",!gSavedSettings.getBOOL("NavBarShowCoordinates"));
- }
- else if (item == "show_properties")
- {
- gSavedSettings.setBOOL("NavBarShowParcelProperties",
- !gSavedSettings.getBOOL("NavBarShowParcelProperties"));
- }
- else if (item == "landmark")
- {
- LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos();
-
- if(!landmark)
- {
- LLFloaterReg::showInstance("add_landmark");
- }
- else
- {
- LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "landmark").with("id",landmark->getUUID()));
-
- }
- }
- else if (item == "cut")
- {
- mTextEntry->cut();
- }
- else if (item == "copy")
- {
- mTextEntry->copy();
- }
- else if (item == "paste")
- {
- mTextEntry->paste();
- }
- else if (item == "delete")
- {
- mTextEntry->deleteSelection();
- }
- else if (item == "select_all")
- {
- mTextEntry->selectAll();
- }
-}
-
-bool LLLocationInputCtrl::onLocationContextMenuItemEnabled(const LLSD& userdata)
-{
- std::string item = userdata.asString();
-
- if (item == "can_cut")
- {
- return mTextEntry->canCut();
- }
- else if (item == "can_copy")
- {
- return mTextEntry->canCopy();
- }
- else if (item == "can_paste")
- {
- return mTextEntry->canPaste();
- }
- else if (item == "can_delete")
- {
- return mTextEntry->canDeselect();
- }
- else if (item == "can_select_all")
- {
- return mTextEntry->canSelectAll() && (mTextEntry->getLength() > 0);
- }
- else if(item == "show_coordinates")
- {
- return gSavedSettings.getBOOL("NavBarShowCoordinates");
- }
-
- return false;
-}
-
-void LLLocationInputCtrl::callbackRebakeRegion(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option == 0) // OK
- {
- if (LLPathfindingManager::getInstance() != NULL)
- {
- LLMenuOptionPathfindingRebakeNavmesh::getInstance()->sendRequestRebakeNavmesh();
- }
- }
-}
-
-void LLLocationInputCtrl::onParcelIconClick(EParcelIcon icon)
-{
- switch (icon)
- {
- case VOICE_ICON:
- LLNotificationsUtil::add("NoVoice");
- break;
- case FLY_ICON:
- LLNotificationsUtil::add("NoFly");
- break;
- case PUSH_ICON:
- LLNotificationsUtil::add("PushRestricted");
- break;
- case BUILD_ICON:
- LLNotificationsUtil::add("NoBuild");
- break;
- case PATHFINDING_DIRTY_ICON:
- if (LLPathfindingManager::getInstance() != NULL)
- {
- LLMenuOptionPathfindingRebakeNavmesh *rebakeInstance = LLMenuOptionPathfindingRebakeNavmesh::getInstance();
- if (rebakeInstance && rebakeInstance->canRebakeRegion() && (rebakeInstance->getMode() == LLMenuOptionPathfindingRebakeNavmesh::kRebakeNavMesh_Available))
- {
- LLNotificationsUtil::add("PathfindingDirtyRebake", LLSD(), LLSD(),
- boost::bind(&LLLocationInputCtrl::callbackRebakeRegion, this, _1, _2));
- break;
- }
- }
- LLNotificationsUtil::add("PathfindingDirty");
- break;
- case PATHFINDING_DISABLED_ICON:
- LLNotificationsUtil::add("DynamicPathfindingDisabled");
- break;
- case SCRIPTS_ICON:
- {
- LLViewerRegion* region = gAgent.getRegion();
- if(region && region->getRegionFlag(REGION_FLAGS_ESTATE_SKIP_SCRIPTS))
- {
- LLNotificationsUtil::add("ScriptsStopped");
- }
- else if(region && region->getRegionFlag(REGION_FLAGS_SKIP_SCRIPTS))
- {
- LLNotificationsUtil::add("ScriptsNotRunning");
- }
- else
- {
- LLNotificationsUtil::add("NoOutsideScripts");
- }
- break;
- }
- case DAMAGE_ICON:
- LLNotificationsUtil::add("NotSafe");
- break;
- case SEE_AVATARS_ICON:
- LLNotificationsUtil::add("SeeAvatars");
- break;
- case ICON_COUNT:
- break;
- // no default to get compiler warning when a new icon gets added
- }
-}
-
-void LLLocationInputCtrl::createNavMeshStatusListenerForCurrentRegion()
-{
- if (mNavMeshSlot.connected())
- {
- mNavMeshSlot.disconnect();
- }
-
- LLViewerRegion *currentRegion = gAgent.getRegion();
- if (currentRegion != NULL)
- {
- mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(currentRegion, boost::bind(&LLLocationInputCtrl::onNavMeshStatusChange, this, _2));
- LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(currentRegion, true);
- }
-}
+/**
+ * @file lllocationinputctrl.cpp
+ * @brief Combobox-like location input control
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+// file includes
+#include "lllocationinputctrl.h"
+
+// common includes
+#include "llbutton.h"
+#include "llfocusmgr.h"
+#include "llhelp.h"
+#include "llmenugl.h"
+#include "llparcel.h"
+#include "llstring.h"
+#include "lltrans.h"
+#include "lluictrlfactory.h"
+#include "lltooltip.h"
+#include "llnotificationsutil.h"
+#include "llregionflags.h"
+
+// newview includes
+#include "llagent.h"
+#include "llfloaterreg.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llinventoryobserver.h"
+#include "lllandmarkactions.h"
+#include "lllandmarklist.h"
+#include "llpathfindingmanager.h"
+#include "llpathfindingnavmesh.h"
+#include "llpathfindingnavmeshstatus.h"
+#include "llteleporthistory.h"
+#include "llslurl.h"
+#include "llstatusbar.h" // getHealth()
+#include "lltrans.h"
+#include "llviewerinventory.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+#include "llviewercontrol.h"
+#include "llviewermenu.h"
+#include "llurllineeditorctrl.h"
+#include "llagentui.h"
+
+#include "llmenuoptionpathfindingrebakenavmesh.h"
+#include "llpathfindingmanager.h"
+
+//============================================================================
+/*
+ * "ADD LANDMARK" BUTTON UPDATING LOGIC
+ *
+ * If the current parcel has been landmarked, we should draw
+ * a special image on the button.
+ *
+ * To avoid determining the appropriate image on every draw() we do that
+ * only in the following cases:
+ * 1) Navbar is shown for the first time after login.
+ * 2) Agent moves to another parcel.
+ * 3) A landmark is created or removed.
+ *
+ * The first case is handled by the handleLoginComplete() method.
+ *
+ * The second case is handled by setting the "agent parcel changed" callback
+ * on LLViewerParcelMgr.
+ *
+ * The third case is the most complex one. We have two inventory observers for that:
+ * one is designated to handle adding landmarks, the other handles removal.
+ * Let's see how the former works.
+ *
+ * When we get notified about landmark addition, the landmark position is unknown yet. What we can
+ * do at that point is initiate loading the landmark data by LLLandmarkList and set the
+ * "loading finished" callback on it. Finally, when the callback is triggered,
+ * we can determine whether the landmark refers to a point within the current parcel
+ * and choose the appropriate image for the "Add landmark" button.
+ */
+
+/**
+ * Initiates loading the landmarks that have been just added.
+ *
+ * Once the loading is complete we'll be notified
+ * with the callback we set for LLLandmarkList.
+ */
+class LLAddLandmarkObserver : public LLInventoryAddedObserver
+{
+public:
+ LLAddLandmarkObserver(LLLocationInputCtrl* input) : mInput(input) {}
+
+private:
+ /*virtual*/ void done()
+ {
+ const uuid_set_t& added = gInventory.getAddedIDs();
+ for (uuid_set_t::const_iterator it = added.begin(); it != added.end(); ++it)
+ {
+ LLInventoryItem* item = gInventory.getItem(*it);
+ if (!item || item->getType() != LLAssetType::AT_LANDMARK)
+ continue;
+
+ // Start loading the landmark.
+ LLLandmark* lm = gLandmarkList.getAsset(
+ item->getAssetUUID(),
+ boost::bind(&LLLocationInputCtrl::onLandmarkLoaded, mInput, _1));
+ if (lm)
+ {
+ // Already loaded? Great, handle it immediately (the callback won't be called).
+ mInput->onLandmarkLoaded(lm);
+ }
+ }
+ }
+
+ LLLocationInputCtrl* mInput;
+};
+
+/**
+ * Updates the "Add landmark" button once a landmark gets removed.
+ */
+class LLRemoveLandmarkObserver : public LLInventoryObserver
+{
+public:
+ LLRemoveLandmarkObserver(LLLocationInputCtrl* input) : mInput(input) {}
+
+private:
+ /*virtual*/ void changed(U32 mask)
+ {
+ if (mask & (~(LLInventoryObserver::LABEL|
+ LLInventoryObserver::INTERNAL|
+ LLInventoryObserver::ADD|
+ LLInventoryObserver::CREATE|
+ LLInventoryObserver::UPDATE_CREATE)))
+ {
+ mInput->updateAddLandmarkButton();
+ }
+ }
+
+ LLLocationInputCtrl* mInput;
+};
+
+class LLParcelChangeObserver : public LLParcelObserver
+{
+public:
+ LLParcelChangeObserver(LLLocationInputCtrl* input) : mInput(input) {}
+
+private:
+ /*virtual*/ void changed()
+ {
+ if (mInput)
+ {
+ mInput->refreshParcelIcons();
+ }
+ }
+
+ LLLocationInputCtrl* mInput;
+};
+
+//============================================================================
+
+
+static LLDefaultChildRegistry::Register<LLLocationInputCtrl> r("location_input");
+
+LLLocationInputCtrl::Params::Params()
+: icon_maturity_general("icon_maturity_general"),
+ icon_maturity_adult("icon_maturity_adult"),
+ icon_maturity_moderate("icon_maturity_moderate"),
+ add_landmark_image_enabled("add_landmark_image_enabled"),
+ add_landmark_image_disabled("add_landmark_image_disabled"),
+ add_landmark_image_hover("add_landmark_image_hover"),
+ add_landmark_image_selected("add_landmark_image_selected"),
+ add_landmark_hpad("add_landmark_hpad", 0),
+ icon_hpad("icon_hpad", 0),
+ add_landmark_button("add_landmark_button"),
+ for_sale_button("for_sale_button"),
+ info_button("info_button"),
+ maturity_button("maturity_button"),
+ voice_icon("voice_icon"),
+ fly_icon("fly_icon"),
+ push_icon("push_icon"),
+ build_icon("build_icon"),
+ scripts_icon("scripts_icon"),
+ damage_icon("damage_icon"),
+ damage_text("damage_text"),
+ see_avatars_icon("see_avatars_icon"),
+ maturity_help_topic("maturity_help_topic"),
+ pathfinding_dirty_icon("pathfinding_dirty_icon"),
+ pathfinding_disabled_icon("pathfinding_disabled_icon")
+{
+}
+
+LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
+: LLComboBox(p),
+ mIconHPad(p.icon_hpad),
+ mAddLandmarkHPad(p.add_landmark_hpad),
+ mLocationContextMenu(NULL),
+ mAddLandmarkBtn(NULL),
+ mForSaleBtn(NULL),
+ mInfoBtn(NULL),
+ mRegionCrossingSlot(),
+ mNavMeshSlot(),
+ mIsNavMeshDirty(false),
+ mLandmarkImageOn(NULL),
+ mLandmarkImageOff(NULL),
+ mIconMaturityGeneral(NULL),
+ mIconMaturityAdult(NULL),
+ mIconMaturityModerate(NULL),
+ mMaturityHelpTopic(p.maturity_help_topic)
+{
+ // Lets replace default LLLineEditor with LLLocationLineEditor
+ // to make needed escaping while copying and cutting url
+ delete mTextEntry;
+
+ // Can't access old mTextEntry fields as they are protected, so lets build new params
+ // That is C&P from LLComboBox::createLineEditor function
+ S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
+ LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
+ text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * BTN_DROP_SHADOW;
+
+ LLLineEditor::Params params = p.combo_editor;
+ params.rect(text_entry_rect);
+ params.default_text(LLStringUtil::null);
+ params.max_length.bytes(p.max_chars);
+ params.keystroke_callback(boost::bind(&LLLocationInputCtrl::onTextEntry, this, _1));
+ params.commit_on_focus_lost(false);
+ params.follows.flags(FOLLOWS_ALL);
+ mTextEntry = LLUICtrlFactory::create<LLURLLineEditor>(params);
+ mTextEntry->resetContextMenu();
+ addChild(mTextEntry);
+ // LLLineEditor is replaced with LLLocationLineEditor
+
+ // "Place information" button.
+ LLButton::Params info_params = p.info_button;
+ mInfoBtn = LLUICtrlFactory::create<LLButton>(info_params);
+ mInfoBtn->setClickedCallback(boost::bind(&LLLocationInputCtrl::onInfoButtonClicked, this));
+ addChild(mInfoBtn);
+
+ // "Add landmark" button.
+ LLButton::Params al_params = p.add_landmark_button;
+
+ // Image for unselected state will be set in updateAddLandmarkButton(),
+ // it will be either mLandmarkOn or mLandmarkOff
+ if (p.add_landmark_image_enabled())
+ {
+ mLandmarkImageOn = p.add_landmark_image_enabled;
+ }
+ if (p.add_landmark_image_disabled())
+ {
+ mLandmarkImageOff = p.add_landmark_image_disabled;
+ }
+
+ if(p.add_landmark_image_selected)
+ {
+ al_params.image_selected = p.add_landmark_image_selected;
+ }
+ if (p.add_landmark_image_hover())
+ {
+ al_params.image_hover_unselected = p.add_landmark_image_hover;
+ }
+
+ al_params.click_callback.function(boost::bind(&LLLocationInputCtrl::onAddLandmarkButtonClicked, this));
+ mAddLandmarkBtn = LLUICtrlFactory::create<LLButton>(al_params);
+ enableAddLandmarkButton(true);
+ addChild(mAddLandmarkBtn);
+
+ if (p.icon_maturity_general())
+ {
+ mIconMaturityGeneral = p.icon_maturity_general;
+ }
+ if (p.icon_maturity_adult())
+ {
+ mIconMaturityAdult = p.icon_maturity_adult;
+ }
+ if(p.icon_maturity_moderate())
+ {
+ mIconMaturityModerate = p.icon_maturity_moderate;
+ }
+
+ LLButton::Params maturity_button = p.maturity_button;
+ mMaturityButton = LLUICtrlFactory::create<LLButton>(maturity_button);
+ addChild(mMaturityButton);
+
+ LLButton::Params for_sale_button = p.for_sale_button;
+ for_sale_button.tool_tip = LLTrans::getString("LocationCtrlForSaleTooltip");
+ for_sale_button.click_callback.function(
+ boost::bind(&LLLocationInputCtrl::onForSaleButtonClicked, this));
+ mForSaleBtn = LLUICtrlFactory::create<LLButton>( for_sale_button );
+ addChild(mForSaleBtn);
+
+ // Parcel property icons
+ // Must be mouse-opaque so cursor stays as an arrow when hovering to
+ // see tooltip.
+ LLIconCtrl::Params voice_icon = p.voice_icon;
+ voice_icon.tool_tip = LLTrans::getString("LocationCtrlVoiceTooltip");
+ voice_icon.mouse_opaque = true;
+ mParcelIcon[VOICE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(voice_icon);
+ mParcelIcon[VOICE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, VOICE_ICON));
+ addChild(mParcelIcon[VOICE_ICON]);
+
+ LLIconCtrl::Params fly_icon = p.fly_icon;
+ fly_icon.tool_tip = LLTrans::getString("LocationCtrlFlyTooltip");
+ fly_icon.mouse_opaque = true;
+ mParcelIcon[FLY_ICON] = LLUICtrlFactory::create<LLIconCtrl>(fly_icon);
+ mParcelIcon[FLY_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, FLY_ICON));
+ addChild(mParcelIcon[FLY_ICON]);
+
+ LLIconCtrl::Params push_icon = p.push_icon;
+ push_icon.tool_tip = LLTrans::getString("LocationCtrlPushTooltip");
+ push_icon.mouse_opaque = true;
+ mParcelIcon[PUSH_ICON] = LLUICtrlFactory::create<LLIconCtrl>(push_icon);
+ mParcelIcon[PUSH_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PUSH_ICON));
+ addChild(mParcelIcon[PUSH_ICON]);
+
+ LLIconCtrl::Params build_icon = p.build_icon;
+ build_icon.tool_tip = LLTrans::getString("LocationCtrlBuildTooltip");
+ build_icon.mouse_opaque = true;
+ mParcelIcon[BUILD_ICON] = LLUICtrlFactory::create<LLIconCtrl>(build_icon);
+ mParcelIcon[BUILD_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, BUILD_ICON));
+ addChild(mParcelIcon[BUILD_ICON]);
+
+ LLIconCtrl::Params scripts_icon = p.scripts_icon;
+ scripts_icon.tool_tip = LLTrans::getString("LocationCtrlScriptsTooltip");
+ scripts_icon.mouse_opaque = true;
+ mParcelIcon[SCRIPTS_ICON] = LLUICtrlFactory::create<LLIconCtrl>(scripts_icon);
+ mParcelIcon[SCRIPTS_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, SCRIPTS_ICON));
+ addChild(mParcelIcon[SCRIPTS_ICON]);
+
+ LLIconCtrl::Params damage_icon = p.damage_icon;
+ damage_icon.tool_tip = LLTrans::getString("LocationCtrlDamageTooltip");
+ damage_icon.mouse_opaque = true;
+ mParcelIcon[DAMAGE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(damage_icon);
+ mParcelIcon[DAMAGE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, DAMAGE_ICON));
+ addChild(mParcelIcon[DAMAGE_ICON]);
+
+ LLIconCtrl::Params pathfinding_dirty_icon = p.pathfinding_dirty_icon;
+ pathfinding_dirty_icon.tool_tip = LLTrans::getString("LocationCtrlPathfindingDirtyTooltip");
+ pathfinding_dirty_icon.mouse_opaque = true;
+ mParcelIcon[PATHFINDING_DIRTY_ICON] = LLUICtrlFactory::create<LLIconCtrl>(pathfinding_dirty_icon);
+ mParcelIcon[PATHFINDING_DIRTY_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PATHFINDING_DIRTY_ICON));
+ addChild(mParcelIcon[PATHFINDING_DIRTY_ICON]);
+
+ LLIconCtrl::Params pathfinding_disabled_icon = p.pathfinding_disabled_icon;
+ pathfinding_disabled_icon.tool_tip = LLTrans::getString("LocationCtrlPathfindingDisabledTooltip");
+ pathfinding_disabled_icon.mouse_opaque = true;
+ mParcelIcon[PATHFINDING_DISABLED_ICON] = LLUICtrlFactory::create<LLIconCtrl>(pathfinding_disabled_icon);
+ mParcelIcon[PATHFINDING_DISABLED_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PATHFINDING_DISABLED_ICON));
+ addChild(mParcelIcon[PATHFINDING_DISABLED_ICON]);
+
+ LLTextBox::Params damage_text = p.damage_text;
+ damage_text.tool_tip = LLTrans::getString("LocationCtrlDamageTooltip");
+ damage_text.mouse_opaque = true;
+ mDamageText = LLUICtrlFactory::create<LLTextBox>(damage_text);
+ addChild(mDamageText);
+
+ LLIconCtrl::Params see_avatars_icon = p.see_avatars_icon;
+ see_avatars_icon.tool_tip = LLTrans::getString("LocationCtrlSeeAVsTooltip");
+ see_avatars_icon.mouse_opaque = true;
+ mParcelIcon[SEE_AVATARS_ICON] = LLUICtrlFactory::create<LLIconCtrl>(see_avatars_icon);
+ mParcelIcon[SEE_AVATARS_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, SEE_AVATARS_ICON));
+ addChild(mParcelIcon[SEE_AVATARS_ICON]);
+
+ // Register callbacks and load the location field context menu (NB: the order matters).
+ LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Navbar.Action", boost::bind(&LLLocationInputCtrl::onLocationContextMenuItemClicked, this, _2));
+ LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Navbar.EnableMenuItem", boost::bind(&LLLocationInputCtrl::onLocationContextMenuItemEnabled, this, _2));
+
+ setPrearrangeCallback(boost::bind(&LLLocationInputCtrl::onLocationPrearrange, this, _2));
+ getTextEntry()->setMouseUpCallback(boost::bind(&LLLocationInputCtrl::changeLocationPresentation, this));
+
+ // Load the location field context menu
+ mLocationContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if (!mLocationContextMenu)
+ {
+ LL_WARNS() << "Error loading navigation bar context menu" << LL_ENDL;
+
+ }
+ //don't show default context menu
+ getTextEntry()->setShowContextMenu(false);
+ getTextEntry()->setRightMouseDownCallback(boost::bind(&LLLocationInputCtrl::onTextEditorRightClicked, this, _2, _3, _4));
+ updateWidgetlayout();
+
+ // Connecting signal for updating location on "Show Coordinates" setting change.
+ LLControlVariable* coordinates_control = gSavedSettings.getControl("NavBarShowCoordinates").get();
+ if (coordinates_control)
+ {
+ mCoordinatesControlConnection = coordinates_control->getSignal()->connect(boost::bind(&LLLocationInputCtrl::refreshLocation, this));
+ }
+
+ // Connecting signal for updating parcel icons on "Show Parcel Properties" setting change.
+ LLControlVariable* parcel_properties_control = gSavedSettings.getControl("NavBarShowParcelProperties").get();
+ if (parcel_properties_control)
+ {
+ mParcelPropertiesControlConnection = parcel_properties_control->getSignal()->connect(boost::bind(&LLLocationInputCtrl::refreshParcelIcons, this));
+ }
+
+ // - Make the "Add landmark" button updated when either current parcel gets changed
+ // or a landmark gets created or removed from the inventory.
+ // - Update the location string on parcel change.
+ mParcelMgrConnection = gAgent.addParcelChangedCallback(
+ boost::bind(&LLLocationInputCtrl::onAgentParcelChange, this));
+ // LLLocationHistory instance is being created before the location input control, so we have to update initial state of button manually.
+ mButton->setEnabled(LLLocationHistory::instance().getItemCount() > 0);
+ mLocationHistoryConnection = LLLocationHistory::getInstance()->setChangedCallback(
+ boost::bind(&LLLocationInputCtrl::onLocationHistoryChanged, this,_1));
+
+ mRegionCrossingSlot = gAgent.addRegionChangedCallback(boost::bind(&LLLocationInputCtrl::onRegionBoundaryCrossed, this));
+ createNavMeshStatusListenerForCurrentRegion();
+
+ mRemoveLandmarkObserver = new LLRemoveLandmarkObserver(this);
+ mAddLandmarkObserver = new LLAddLandmarkObserver(this);
+ gInventory.addObserver(mRemoveLandmarkObserver);
+ gInventory.addObserver(mAddLandmarkObserver);
+
+ mParcelChangeObserver = new LLParcelChangeObserver(this);
+ LLViewerParcelMgr::getInstance()->addObserver(mParcelChangeObserver);
+
+ mAddLandmarkTooltip = LLTrans::getString("LocationCtrlAddLandmarkTooltip");
+ mEditLandmarkTooltip = LLTrans::getString("LocationCtrlEditLandmarkTooltip");
+ mButton->setToolTip(LLTrans::getString("LocationCtrlComboBtnTooltip"));
+ mInfoBtn->setToolTip(LLTrans::getString("LocationCtrlInfoBtnTooltip"));
+}
+
+LLLocationInputCtrl::~LLLocationInputCtrl()
+{
+ gInventory.removeObserver(mRemoveLandmarkObserver);
+ gInventory.removeObserver(mAddLandmarkObserver);
+ delete mRemoveLandmarkObserver;
+ delete mAddLandmarkObserver;
+
+ LLViewerParcelMgr::getInstance()->removeObserver(mParcelChangeObserver);
+ delete mParcelChangeObserver;
+
+ mRegionCrossingSlot.disconnect();
+ mNavMeshSlot.disconnect();
+ mCoordinatesControlConnection.disconnect();
+ mParcelPropertiesControlConnection.disconnect();
+ mParcelMgrConnection.disconnect();
+ mLocationHistoryConnection.disconnect();
+}
+
+void LLLocationInputCtrl::setEnabled(bool enabled)
+{
+ LLComboBox::setEnabled(enabled);
+ mAddLandmarkBtn->setEnabled(enabled);
+}
+
+void LLLocationInputCtrl::hideList()
+{
+ LLComboBox::hideList();
+ if (mTextEntry && hasFocus())
+ focusTextEntry();
+}
+
+bool LLLocationInputCtrl::handleToolTip(S32 x, S32 y, MASK mask)
+{
+
+ if(mAddLandmarkBtn->parentPointInView(x,y))
+ {
+ updateAddLandmarkTooltip();
+ }
+ // Let the buttons show their tooltips.
+ if (LLUICtrl::handleToolTip(x, y, mask))
+ {
+ if (mList->getRect().pointInRect(x, y))
+ {
+ S32 loc_x, loc_y;
+ //x,y - contain coordinates related to the location input control, but without taking the expanded list into account
+ //So we have to convert it again into local coordinates of mList
+ localPointToOtherView(x,y,&loc_x,&loc_y,mList);
+
+ LLScrollListItem* item = mList->hitItem(loc_x,loc_y);
+ if (item)
+ {
+ LLSD value = item->getValue();
+ if (value.has("tooltip"))
+ {
+ LLToolTipMgr::instance().show(value["tooltip"]);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+bool LLLocationInputCtrl::handleKeyHere(KEY key, MASK mask)
+{
+ bool result = LLComboBox::handleKeyHere(key, mask);
+
+ if (key == KEY_DOWN && hasFocus() && mList->getItemCount() != 0 && !mList->getVisible())
+ {
+ showList();
+ }
+
+ return result;
+}
+
+void LLLocationInputCtrl::onTextEntry(LLLineEditor* line_editor)
+{
+ KEY key = gKeyboard->currentKey();
+ MASK mask = gKeyboard->currentMask(true);
+
+ // Typing? (moving cursor should not affect showing the list)
+ bool typing = mask != MASK_CONTROL && key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END;
+ bool pasting = mask == MASK_CONTROL && key == 'V';
+
+ if (line_editor->getText().empty())
+ {
+ prearrangeList(); // resets filter
+ hideList();
+ }
+ else if (typing || pasting)
+ {
+ prearrangeList(line_editor->getText());
+ if (mList->getItemCount() != 0)
+ {
+ showList();
+ focusTextEntry();
+ }
+ else
+ {
+ // Hide the list if it's empty.
+ hideList();
+ }
+ }
+
+ LLComboBox::onTextEntry(line_editor);
+}
+
+/**
+ * Useful if we want to just set the text entry value, no matter what the list contains.
+ *
+ * This is faster than setTextEntry().
+ */
+void LLLocationInputCtrl::setText(const LLStringExplicit& text)
+{
+ if (mTextEntry)
+ {
+ mTextEntry->setText(text);
+ }
+ mHasAutocompletedText = false;
+}
+
+void LLLocationInputCtrl::setFocus(bool b)
+{
+ LLComboBox::setFocus(b);
+
+ if (mTextEntry && b && !mList->getVisible())
+ {
+ mTextEntry->setFocus(true);
+ }
+}
+
+void LLLocationInputCtrl::handleLoginComplete()
+{
+ // An agent parcel update hasn't occurred yet, so we have to
+ // manually set location and the appropriate "Add landmark" icon.
+ refresh();
+}
+
+//== private methods =========================================================
+
+void LLLocationInputCtrl::onFocusReceived()
+{
+ prearrangeList();
+}
+
+void LLLocationInputCtrl::onFocusLost()
+{
+ LLUICtrl::onFocusLost();
+ refreshLocation();
+
+ // Setting cursor to 0 to show the left edge of the text. See STORM-370.
+ mTextEntry->setCursor(0);
+
+ if(mTextEntry->hasSelection()){
+ mTextEntry->deselect();
+ }
+}
+
+void LLLocationInputCtrl::draw()
+{
+ static LLUICachedControl<bool> show_coords("NavBarShowCoordinates", false);
+ if(!hasFocus() && show_coords)
+ {
+ refreshLocation();
+ }
+
+ static LLUICachedControl<bool> show_icons("NavBarShowParcelProperties", false);
+ if (show_icons)
+ {
+ refreshHealth();
+ }
+ LLComboBox::draw();
+}
+
+void LLLocationInputCtrl::reshape(S32 width, S32 height, bool called_from_parent)
+{
+ LLComboBox::reshape(width, height, called_from_parent);
+
+ // Setting cursor to 0 to show the left edge of the text. See EXT-4967.
+ mTextEntry->setCursor(0);
+ if (mTextEntry->hasSelection())
+ {
+ // Deselecting because selection position is changed together with
+ // cursor position change.
+ mTextEntry->deselect();
+ }
+
+ if (isHumanReadableLocationVisible)
+ {
+ refreshMaturityButton();
+ }
+}
+
+void LLLocationInputCtrl::onInfoButtonClicked()
+{
+ LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "agent"));
+}
+
+void LLLocationInputCtrl::onForSaleButtonClicked()
+{
+ handle_buy_land();
+}
+
+void LLLocationInputCtrl::onAddLandmarkButtonClicked()
+{
+ LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos();
+ // Landmark exists, open it for preview and edit
+ if(landmark && landmark->getUUID().notNull())
+ {
+ LLSD key;
+ key["type"] = "landmark";
+ key["id"] = landmark->getUUID();
+
+ LLFloaterSidePanelContainer::showPanel("places", key);
+ }
+ else
+ {
+ LLFloaterReg::showInstance("add_landmark");
+ }
+}
+
+void LLLocationInputCtrl::onAgentParcelChange()
+{
+ refresh();
+}
+
+void LLLocationInputCtrl::onRegionBoundaryCrossed()
+{
+ createNavMeshStatusListenerForCurrentRegion();
+}
+
+void LLLocationInputCtrl::onNavMeshStatusChange(const LLPathfindingNavMeshStatus &pNavMeshStatus)
+{
+ mIsNavMeshDirty = pNavMeshStatus.isValid() && (pNavMeshStatus.getStatus() != LLPathfindingNavMeshStatus::kComplete);
+ refreshParcelIcons();
+}
+
+void LLLocationInputCtrl::onLandmarkLoaded(LLLandmark* lm)
+{
+ (void) lm;
+ updateAddLandmarkButton();
+}
+
+void LLLocationInputCtrl::onLocationHistoryChanged(LLLocationHistory::EChangeType event)
+{
+ if(event == LLLocationHistory::LOAD)
+ {
+ rebuildLocationHistory();
+ }
+ mButton->setEnabled(LLLocationHistory::instance().getItemCount() > 0);
+}
+
+void LLLocationInputCtrl::onLocationPrearrange(const LLSD& data)
+{
+ std::string filter = data.asString();
+ rebuildLocationHistory(filter);
+
+ //Let's add landmarks to the top of the list if any
+ if(!filter.empty() )
+ {
+ LLInventoryModel::item_array_t landmark_items = LLLandmarkActions::fetchLandmarksByName(filter, true);
+
+ for(U32 i=0; i < landmark_items.size(); i++)
+ {
+ LLSD value;
+ //TODO:: DO we need tooltip for Landmark??
+
+ value["item_type"] = LANDMARK;
+ value["AssetUUID"] = landmark_items[i]->getAssetUUID();
+ addLocationHistoryEntry(landmark_items[i]->getName(), value);
+
+ }
+ //Let's add teleport history items
+ LLTeleportHistory* th = LLTeleportHistory::getInstance();
+ LLTeleportHistory::slurl_list_t th_items = th->getItems();
+
+ std::set<std::string> new_item_titles;// duplicate control
+ LLTeleportHistory::slurl_list_t::iterator result = std::find_if(
+ th_items.begin(), th_items.end(), boost::bind(
+ &LLLocationInputCtrl::findTeleportItemsByTitle, this,
+ _1, filter));
+
+ while (result != th_items.end())
+ {
+ //mTitile format - region_name[, parcel_name]
+ //mFullTitile format - region_name[, parcel_name] (local_x,local_y, local_z)
+ if (new_item_titles.insert(result->mFullTitle).second)
+ {
+ LLSD value;
+ value["item_type"] = TELEPORT_HISTORY;
+ value["global_pos"] = result->mGlobalPos.getValue();
+ std::string region_name = result->mTitle.substr(0, result->mTitle.find(','));
+ //TODO*: add Surl to teleportitem or parse region name from title
+ value["tooltip"] = LLSLURL(region_name, result->mGlobalPos).getSLURLString();
+ addLocationHistoryEntry(result->getTitle(), value);
+ }
+ result = std::find_if(result + 1, th_items.end(), boost::bind(
+ &LLLocationInputCtrl::findTeleportItemsByTitle, this,
+ _1, filter));
+ }
+ }
+ sortByName();
+
+ mList->mouseOverHighlightNthItem(-1); // Clear highlight on the last selected item.
+}
+
+bool LLLocationInputCtrl::findTeleportItemsByTitle(const LLTeleportHistoryItem& item, const std::string& filter)
+{
+ return item.mTitle.find(filter) != std::string::npos;
+}
+
+void LLLocationInputCtrl::onTextEditorRightClicked(S32 x, S32 y, MASK mask)
+{
+ if (mLocationContextMenu)
+ {
+ updateContextMenu();
+ mLocationContextMenu->buildDrawLabels();
+ mLocationContextMenu->updateParent(LLMenuGL::sMenuContainer);
+ hideList();
+ setFocus(true);
+ changeLocationPresentation();
+ LLMenuGL::showPopup(this, mLocationContextMenu, x, y);
+ }
+}
+
+void LLLocationInputCtrl::refresh()
+{
+ refreshLocation(); // update location string
+ refreshParcelIcons();
+ updateAddLandmarkButton(); // indicate whether current parcel has been landmarked
+}
+
+void LLLocationInputCtrl::refreshLocation()
+{
+ // Is one of our children focused?
+ if (LLUICtrl::hasFocus() || mButton->hasFocus() || mList->hasFocus() ||
+ (mTextEntry && mTextEntry->hasFocus()) ||
+ (mAddLandmarkBtn->hasFocus()))
+ {
+ LL_WARNS() << "Location input should not be refreshed when having focus" << LL_ENDL;
+ return;
+ }
+
+ // Update location field.
+ std::string location_name;
+ LLAgentUI::ELocationFormat format =
+ (gSavedSettings.getBOOL("NavBarShowCoordinates")
+ ? LLAgentUI::LOCATION_FORMAT_FULL
+ : LLAgentUI::LOCATION_FORMAT_NO_COORDS);
+
+ if (!LLAgentUI::buildLocationString(location_name, format))
+ {
+ location_name = "???";
+ }
+ // store human-readable location to compare it in changeLocationPresentation()
+ mHumanReadableLocation = location_name;
+ setText(location_name);
+ isHumanReadableLocationVisible = true;
+
+ refreshMaturityButton();
+}
+
+// returns new right edge
+static S32 layout_widget(LLUICtrl* widget, S32 right)
+{
+ if (widget->getVisible())
+ {
+ LLRect rect = widget->getRect();
+ rect.mLeft = right - rect.getWidth();
+ rect.mRight = right;
+ widget->setRect( rect );
+ right -= rect.getWidth();
+ }
+ return right;
+}
+
+void LLLocationInputCtrl::refreshParcelIcons()
+{
+ // Our "cursor" moving right to left
+ S32 x = mAddLandmarkBtn->getRect().mLeft;
+
+ LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstance();
+
+ LLViewerRegion* agent_region = gAgent.getRegion();
+ LLParcel* agent_parcel = vpm->getAgentParcel();
+ if (!agent_region || !agent_parcel)
+ return;
+
+ mForSaleBtn->setVisible(vpm->canAgentBuyParcel(agent_parcel, false));
+
+ x = layout_widget(mForSaleBtn, x);
+
+ if (gSavedSettings.getBOOL("NavBarShowParcelProperties"))
+ {
+ LLParcel* current_parcel;
+ LLViewerRegion* selection_region = vpm->getSelectionRegion();
+ LLParcel* selected_parcel = vpm->getParcelSelection()->getParcel();
+
+ // If agent is in selected parcel we use its properties because
+ // they are updated more often by LLViewerParcelMgr than agent parcel properties.
+ // See LLViewerParcelMgr::processParcelProperties().
+ // This is needed to reflect parcel restrictions changes without having to leave
+ // the parcel and then enter it again. See EXT-2987
+ if (selected_parcel && selected_parcel->getLocalID() == agent_parcel->getLocalID()
+ && selection_region == agent_region)
+ {
+ current_parcel = selected_parcel;
+ }
+ else
+ {
+ current_parcel = agent_parcel;
+ }
+
+ bool allow_voice = vpm->allowAgentVoice(agent_region, current_parcel);
+ bool allow_fly = vpm->allowAgentFly(agent_region, current_parcel);
+ bool allow_push = vpm->allowAgentPush(agent_region, current_parcel);
+ bool allow_build = vpm->allowAgentBuild(current_parcel); // true when anyone is allowed to build. See EXT-4610.
+ bool allow_scripts = vpm->allowAgentScripts(agent_region, current_parcel);
+ bool allow_damage = vpm->allowAgentDamage(agent_region, current_parcel);
+ bool see_avs = current_parcel->getSeeAVs();
+ bool pathfinding_dynamic_enabled = agent_region->dynamicPathfindingEnabled();
+
+ // Most icons are "block this ability"
+ mParcelIcon[VOICE_ICON]->setVisible( !allow_voice );
+ mParcelIcon[FLY_ICON]->setVisible( !allow_fly );
+ mParcelIcon[PUSH_ICON]->setVisible( !allow_push );
+ mParcelIcon[BUILD_ICON]->setVisible( !allow_build );
+ mParcelIcon[SCRIPTS_ICON]->setVisible( !allow_scripts );
+ mParcelIcon[DAMAGE_ICON]->setVisible( allow_damage );
+ mParcelIcon[PATHFINDING_DIRTY_ICON]->setVisible(mIsNavMeshDirty);
+ mParcelIcon[PATHFINDING_DISABLED_ICON]->setVisible(!mIsNavMeshDirty && !pathfinding_dynamic_enabled);
+
+ mDamageText->setVisible(allow_damage);
+ mParcelIcon[SEE_AVATARS_ICON]->setVisible( !see_avs );
+
+ // Padding goes to left of both landmark star and for sale btn
+ x -= mAddLandmarkHPad;
+
+ // Slide the parcel icons rect from right to left, adjusting rectangles
+ for (S32 i = 0; i < ICON_COUNT; ++i)
+ {
+ x = layout_widget(mParcelIcon[i], x);
+ x -= mIconHPad;
+ }
+ x = layout_widget(mDamageText, x);
+ x -= mIconHPad;
+ }
+ else
+ {
+ for (S32 i = 0; i < ICON_COUNT; ++i)
+ {
+ mParcelIcon[i]->setVisible(false);
+ }
+ mDamageText->setVisible(false);
+ }
+
+ if (mTextEntry)
+ {
+ S32 left_pad, right_pad;
+ mTextEntry->getTextPadding(&left_pad, &right_pad);
+ right_pad = mTextEntry->getRect().mRight - x;
+ mTextEntry->setTextPadding(left_pad, right_pad);
+ }
+}
+
+void LLLocationInputCtrl::refreshHealth()
+{
+ // *FIXME: Status bar owns health information, should be in agent
+ if (gStatusBar)
+ {
+ static S32 last_health = -1;
+ S32 health = gStatusBar->getHealth();
+ if (health != last_health)
+ {
+ std::string text = llformat("%d%%", health);
+ mDamageText->setText(text);
+ last_health = health;
+ }
+ }
+}
+
+void LLLocationInputCtrl::refreshMaturityButton()
+{
+ // Updating maturity rating icon.
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ return;
+
+ bool button_visible = true;
+ LLPointer<LLUIImage> rating_image = NULL;
+ std::string rating_tooltip;
+
+ U8 sim_access = region->getSimAccess();
+ switch(sim_access)
+ {
+ case SIM_ACCESS_PG:
+ rating_image = mIconMaturityGeneral;
+ rating_tooltip = LLTrans::getString("LocationCtrlGeneralIconTooltip");
+ break;
+
+ case SIM_ACCESS_ADULT:
+ rating_image = mIconMaturityAdult;
+ rating_tooltip = LLTrans::getString("LocationCtrlAdultIconTooltip");
+ break;
+
+ case SIM_ACCESS_MATURE:
+ rating_image = mIconMaturityModerate;
+ rating_tooltip = LLTrans::getString("LocationCtrlModerateIconTooltip");
+ break;
+
+ default:
+ button_visible = false;
+ break;
+ }
+
+ mMaturityButton->setVisible(button_visible);
+ mMaturityButton->setToolTip(rating_tooltip);
+ if(rating_image)
+ {
+ mMaturityButton->setImageUnselected(rating_image);
+ mMaturityButton->setImagePressed(rating_image);
+ }
+ if (mMaturityButton->getVisible())
+ {
+ positionMaturityButton();
+ }
+}
+
+void LLLocationInputCtrl::positionMaturityButton()
+{
+ const LLFontGL* font = mTextEntry->getFont();
+ if (!font)
+ return;
+
+ S32 left_pad, right_pad;
+ mTextEntry->getTextPadding(&left_pad, &right_pad);
+
+ // Calculate the right edge of rendered text + a whitespace.
+ left_pad = left_pad + font->getWidth(mTextEntry->getText()) + font->getWidth(" ");
+
+ LLRect rect = mMaturityButton->getRect();
+ mMaturityButton->setRect(rect.setOriginAndSize(left_pad, rect.mBottom, rect.getWidth(), rect.getHeight()));
+
+ // Hide icon if it text area is not width enough to display it, show otherwise.
+ mMaturityButton->setVisible(rect.mRight < mTextEntry->getRect().getWidth() - right_pad);
+}
+
+void LLLocationInputCtrl::addLocationHistoryEntry(const std::string& title, const LLSD& value)
+{
+ // SL-20286 : Duplication of autocomplete results occurs when entering some search queries in the navigation bar
+ // Exclude visual duplicates (items with the same titles) in the dropdown list
+ LLScrollListItem* item = mList->getItemByLabel(title);
+ if (!item)
+ {
+ add(title, value);
+ }
+}
+
+void LLLocationInputCtrl::rebuildLocationHistory(const std::string& filter)
+{
+ LLLocationHistory::location_list_t filtered_items;
+ const LLLocationHistory::location_list_t* itemsp = NULL;
+ LLLocationHistory* lh = LLLocationHistory::getInstance();
+
+ if (filter.empty())
+ {
+ itemsp = &lh->getItems();
+ }
+ else
+ {
+ lh->getMatchingItems(filter, filtered_items);
+ itemsp = &filtered_items;
+ }
+
+ removeall();
+ for (LLLocationHistory::location_list_t::const_reverse_iterator it = itemsp->rbegin(); it != itemsp->rend(); it++)
+ {
+ LLSD value;
+ value["tooltip"] = it->getToolTip();
+ //location history can contain only typed locations
+ value["item_type"] = TYPED_REGION_SLURL;
+ value["global_pos"] = it->mGlobalPos.getValue();
+ addLocationHistoryEntry(it->getLocation(), value);
+ }
+}
+
+void LLLocationInputCtrl::focusTextEntry()
+{
+ // We can't use "mTextEntry->setFocus(true)" instead because
+ // if the "select_on_focus" parameter is true it places the cursor
+ // at the beginning (after selecting text), thus screwing up updateSelection().
+ if (mTextEntry)
+ {
+ gFocusMgr.setKeyboardFocus(mTextEntry);
+
+ // Enable the text entry to handle accelerator keys (EXT-8104).
+ LLEditMenuHandler::gEditMenuHandler = mTextEntry;
+ }
+}
+
+void LLLocationInputCtrl::enableAddLandmarkButton(bool val)
+{
+ // We don't want to disable the button because it should be click able at any time,
+ // instead switch images.
+ LLUIImage* img = val ? mLandmarkImageOn : mLandmarkImageOff;
+ if(img)
+ {
+ mAddLandmarkBtn->setImageUnselected(img);
+ }
+}
+
+// Change the "Add landmark" button image
+// depending on whether current parcel has been landmarked.
+void LLLocationInputCtrl::updateAddLandmarkButton()
+{
+ enableAddLandmarkButton(LLLandmarkActions::hasParcelLandmark());
+}
+void LLLocationInputCtrl::updateAddLandmarkTooltip()
+{
+ std::string tooltip;
+ if(LLLandmarkActions::landmarkAlreadyExists())
+ {
+ tooltip = mEditLandmarkTooltip;
+ }
+ else
+ {
+ tooltip = mAddLandmarkTooltip;
+ }
+ mAddLandmarkBtn->setToolTip(tooltip);
+}
+
+void LLLocationInputCtrl::updateContextMenu(){
+
+ if (mLocationContextMenu)
+ {
+ LLMenuItemGL* landmarkItem = mLocationContextMenu->getChild<LLMenuItemGL>("Landmark");
+ if (!LLLandmarkActions::landmarkAlreadyExists())
+ {
+ landmarkItem->setLabel(LLTrans::getString("AddLandmarkNavBarMenu"));
+ }
+ else
+ {
+ landmarkItem->setLabel(LLTrans::getString("EditLandmarkNavBarMenu"));
+ }
+ }
+}
+void LLLocationInputCtrl::updateWidgetlayout()
+{
+ const LLRect& rect = getLocalRect();
+ const LLRect& hist_btn_rect = mButton->getRect();
+
+ // Info button is set in the XUI XML location_input.xml
+
+ // "Add Landmark" button
+ LLRect al_btn_rect = mAddLandmarkBtn->getRect();
+ al_btn_rect.translate(
+ hist_btn_rect.mLeft - mIconHPad - al_btn_rect.getWidth(),
+ (rect.getHeight() - al_btn_rect.getHeight()) / 2);
+ mAddLandmarkBtn->setRect(al_btn_rect);
+}
+
+void LLLocationInputCtrl::changeLocationPresentation()
+{
+ if (!mTextEntry)
+ return;
+
+ //change location presentation only if user does not select/paste anything and
+ //human-readable region name is being displayed
+ if(!mTextEntry->hasSelection() && mTextEntry->getText() == mHumanReadableLocation)
+ {
+ //needs unescaped one
+ LLSLURL slurl;
+ LLAgentUI::buildSLURL(slurl, false);
+ mTextEntry->setText(LLURI::unescape(slurl.getSLURLString()));
+ mTextEntry->selectAll();
+
+ mMaturityButton->setVisible(false);
+
+ isHumanReadableLocationVisible = false;
+ }
+}
+
+void LLLocationInputCtrl::onLocationContextMenuItemClicked(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+
+ if (item == "show_coordinates")
+ {
+ gSavedSettings.setBOOL("NavBarShowCoordinates",!gSavedSettings.getBOOL("NavBarShowCoordinates"));
+ }
+ else if (item == "show_properties")
+ {
+ gSavedSettings.setBOOL("NavBarShowParcelProperties",
+ !gSavedSettings.getBOOL("NavBarShowParcelProperties"));
+ }
+ else if (item == "landmark")
+ {
+ LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos();
+
+ if(!landmark)
+ {
+ LLFloaterReg::showInstance("add_landmark");
+ }
+ else
+ {
+ LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "landmark").with("id",landmark->getUUID()));
+
+ }
+ }
+ else if (item == "cut")
+ {
+ mTextEntry->cut();
+ }
+ else if (item == "copy")
+ {
+ mTextEntry->copy();
+ }
+ else if (item == "paste")
+ {
+ mTextEntry->paste();
+ }
+ else if (item == "delete")
+ {
+ mTextEntry->deleteSelection();
+ }
+ else if (item == "select_all")
+ {
+ mTextEntry->selectAll();
+ }
+}
+
+bool LLLocationInputCtrl::onLocationContextMenuItemEnabled(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+
+ if (item == "can_cut")
+ {
+ return mTextEntry->canCut();
+ }
+ else if (item == "can_copy")
+ {
+ return mTextEntry->canCopy();
+ }
+ else if (item == "can_paste")
+ {
+ return mTextEntry->canPaste();
+ }
+ else if (item == "can_delete")
+ {
+ return mTextEntry->canDeselect();
+ }
+ else if (item == "can_select_all")
+ {
+ return mTextEntry->canSelectAll() && (mTextEntry->getLength() > 0);
+ }
+ else if(item == "show_coordinates")
+ {
+ return gSavedSettings.getBOOL("NavBarShowCoordinates");
+ }
+
+ return false;
+}
+
+void LLLocationInputCtrl::callbackRebakeRegion(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0) // OK
+ {
+ if (LLPathfindingManager::getInstance() != NULL)
+ {
+ LLMenuOptionPathfindingRebakeNavmesh::getInstance()->sendRequestRebakeNavmesh();
+ }
+ }
+}
+
+void LLLocationInputCtrl::onParcelIconClick(EParcelIcon icon)
+{
+ switch (icon)
+ {
+ case VOICE_ICON:
+ LLNotificationsUtil::add("NoVoice");
+ break;
+ case FLY_ICON:
+ LLNotificationsUtil::add("NoFly");
+ break;
+ case PUSH_ICON:
+ LLNotificationsUtil::add("PushRestricted");
+ break;
+ case BUILD_ICON:
+ LLNotificationsUtil::add("NoBuild");
+ break;
+ case PATHFINDING_DIRTY_ICON:
+ if (LLPathfindingManager::getInstance() != NULL)
+ {
+ LLMenuOptionPathfindingRebakeNavmesh *rebakeInstance = LLMenuOptionPathfindingRebakeNavmesh::getInstance();
+ if (rebakeInstance && rebakeInstance->canRebakeRegion() && (rebakeInstance->getMode() == LLMenuOptionPathfindingRebakeNavmesh::kRebakeNavMesh_Available))
+ {
+ LLNotificationsUtil::add("PathfindingDirtyRebake", LLSD(), LLSD(),
+ boost::bind(&LLLocationInputCtrl::callbackRebakeRegion, this, _1, _2));
+ break;
+ }
+ }
+ LLNotificationsUtil::add("PathfindingDirty");
+ break;
+ case PATHFINDING_DISABLED_ICON:
+ LLNotificationsUtil::add("DynamicPathfindingDisabled");
+ break;
+ case SCRIPTS_ICON:
+ {
+ LLViewerRegion* region = gAgent.getRegion();
+ if(region && region->getRegionFlag(REGION_FLAGS_ESTATE_SKIP_SCRIPTS))
+ {
+ LLNotificationsUtil::add("ScriptsStopped");
+ }
+ else if(region && region->getRegionFlag(REGION_FLAGS_SKIP_SCRIPTS))
+ {
+ LLNotificationsUtil::add("ScriptsNotRunning");
+ }
+ else
+ {
+ LLNotificationsUtil::add("NoOutsideScripts");
+ }
+ break;
+ }
+ case DAMAGE_ICON:
+ LLNotificationsUtil::add("NotSafe");
+ break;
+ case SEE_AVATARS_ICON:
+ LLNotificationsUtil::add("SeeAvatars");
+ break;
+ case ICON_COUNT:
+ break;
+ // no default to get compiler warning when a new icon gets added
+ }
+}
+
+void LLLocationInputCtrl::createNavMeshStatusListenerForCurrentRegion()
+{
+ if (mNavMeshSlot.connected())
+ {
+ mNavMeshSlot.disconnect();
+ }
+
+ LLViewerRegion *currentRegion = gAgent.getRegion();
+ if (currentRegion != NULL)
+ {
+ mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(currentRegion, boost::bind(&LLLocationInputCtrl::onNavMeshStatusChange, this, _2));
+ LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(currentRegion, true);
+ }
+}