diff options
Diffstat (limited to 'indra/newview/lllocationinputctrl.cpp')
-rw-r--r-- | indra/newview/lllocationinputctrl.cpp | 315 |
1 files changed, 270 insertions, 45 deletions
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 404e266806..4100e2fc61 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -39,16 +39,19 @@ #include "llbutton.h" #include "llfocusmgr.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 "llinventoryobserver.h" #include "lllandmarkactions.h" #include "lllandmarklist.h" -#include "lllocationhistory.h" #include "llteleporthistory.h" #include "llsidetray.h" #include "llslurl.h" @@ -56,6 +59,7 @@ #include "lltrans.h" #include "llviewerinventory.h" #include "llviewerparcelmgr.h" +#include "llviewerregion.h" #include "llviewercontrol.h" #include "llviewermenu.h" #include "llurllineeditorctrl.h" @@ -148,13 +152,32 @@ private: 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() -: add_landmark_image_enabled("add_landmark_image_enabled"), +: icon_maturity_general("icon_maturity_general"), + icon_maturity_adult("icon_maturity_adult"), + 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"), @@ -163,6 +186,7 @@ LLLocationInputCtrl::Params::Params() add_landmark_button("add_landmark_button"), for_sale_button("for_sale_button"), info_button("info_button"), + maturity_icon("maturity_icon"), voice_icon("voice_icon"), fly_icon("fly_icon"), push_icon("push_icon"), @@ -182,7 +206,9 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) mForSaleBtn(NULL), mInfoBtn(NULL), mLandmarkImageOn(NULL), - mLandmarkImageOff(NULL) + mLandmarkImageOff(NULL), + mIconMaturityGeneral(NULL), + mIconMaturityAdult(NULL) { // Lets replace default LLLineEditor with LLLocationLineEditor // to make needed escaping while copying and cutting url @@ -205,6 +231,7 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) params.commit_on_focus_lost(false); params.follows.flags(FOLLOWS_ALL); mTextEntry = LLUICtrlFactory::create<LLURLLineEditor>(params); + mTextEntry->setContextMenu(NULL); addChild(mTextEntry); // LLLineEditor is replaced with LLLocationLineEditor @@ -241,7 +268,20 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) 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; + } + + LLIconCtrl::Params maturity_icon = p.maturity_icon; + mMaturityIcon = LLUICtrlFactory::create<LLIconCtrl>(maturity_icon); + addChild(mMaturityIcon); + LLButton::Params for_sale_button = p.for_sale_button; for_sale_button.tool_tip = LLTrans::getString("LocationCtrlForSaleTooltip"); for_sale_button.click_callback.function( @@ -256,36 +296,42 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) 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]); LLTextBox::Params damage_text = p.damage_text; @@ -311,20 +357,38 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) getTextEntry()->setRightMouseUpCallback(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 = LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback( boost::bind(&LLLocationInputCtrl::onAgentParcelChange, this)); - - mLocationHistoryConnection = LLLocationHistory::getInstance()->setLoadedCallback( - boost::bind(&LLLocationInputCtrl::onLocationHistoryLoaded, 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)); 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"); getChild<LLView>("Location History")->setToolTip(LLTrans::getString("LocationCtrlComboBtnTooltip")); @@ -338,6 +402,11 @@ LLLocationInputCtrl::~LLLocationInputCtrl() delete mRemoveLandmarkObserver; delete mAddLandmarkObserver; + LLViewerParcelMgr::getInstance()->removeObserver(mParcelChangeObserver); + delete mParcelChangeObserver; + + mCoordinatesControlConnection.disconnect(); + mParcelPropertiesControlConnection.disconnect(); mParcelMgrConnection.disconnect(); mLocationHistoryConnection.disconnect(); } @@ -404,6 +473,7 @@ BOOL LLLocationInputCtrl::handleKeyHere(KEY key, MASK mask) void LLLocationInputCtrl::onTextEntry(LLLineEditor* line_editor) { KEY key = gKeyboard->currentKey(); + MASK mask = gKeyboard->currentMask(TRUE); if (line_editor->getText().empty()) { @@ -411,7 +481,7 @@ void LLLocationInputCtrl::onTextEntry(LLLineEditor* line_editor) hideList(); } // Typing? (moving cursor should not affect showing the list) - else if (key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END) + else if (mask != MASK_CONTROL && key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END) { prearrangeList(line_editor->getText()); if (mList->getItemCount() != 0) @@ -436,7 +506,10 @@ void LLLocationInputCtrl::onTextEntry(LLLineEditor* line_editor) */ void LLLocationInputCtrl::setText(const LLStringExplicit& text) { - mTextEntry->setText(text); + if (mTextEntry) + { + mTextEntry->setText(text); + } mHasAutocompletedText = FALSE; } @@ -445,7 +518,9 @@ void LLLocationInputCtrl::setFocus(BOOL b) LLComboBox::setFocus(b); if (mTextEntry && b && !mList->getVisible()) + { mTextEntry->setFocus(TRUE); + } } void LLLocationInputCtrl::handleLoginComplete() @@ -487,6 +562,25 @@ void LLLocationInputCtrl::draw() 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) + { + refreshMaturityIcon(); + } +} + void LLLocationInputCtrl::onInfoButtonClicked() { LLSideTray::getInstance()->showPanel("panel_places", LLSD().with("type", "agent")); @@ -526,9 +620,13 @@ void LLLocationInputCtrl::onLandmarkLoaded(LLLandmark* lm) updateAddLandmarkButton(); } -void LLLocationInputCtrl::onLocationHistoryLoaded() +void LLLocationInputCtrl::onLocationHistoryChanged(LLLocationHistory::EChangeType event) { - rebuildLocationHistory(); + if(event == LLLocationHistory::LOAD) + { + rebuildLocationHistory(); + } + mButton->setEnabled(LLLocationHistory::instance().getItemCount() > 0); } void LLLocationInputCtrl::onLocationPrearrange(const LLSD& data) @@ -571,7 +669,7 @@ void LLLocationInputCtrl::onLocationPrearrange(const LLSD& data) 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 + //TODO*: add slurl to teleportitem or parse region name from title value["tooltip"] = LLSLURL::buildSLURLfromPosGlobal(region_name, result->mGlobalPos, false); add(result->getTitle(), value); @@ -616,8 +714,8 @@ void LLLocationInputCtrl::refreshLocation() { // Is one of our children focused? if (LLUICtrl::hasFocus() || mButton->hasFocus() || mList->hasFocus() || - (mTextEntry && mTextEntry->hasFocus()) || (mAddLandmarkBtn->hasFocus())) - + (mTextEntry && mTextEntry->hasFocus()) || + (mAddLandmarkBtn->hasFocus())) { llwarns << "Location input should not be refreshed when having focus" << llendl; return; @@ -637,6 +735,9 @@ void LLLocationInputCtrl::refreshLocation() // store human-readable location to compare it in changeLocationPresentation() mHumanReadableLocation = location_name; setText(location_name); + isHumanReadableLocationVisible = true; + + refreshMaturityIcon(); } // returns new right edge @@ -657,21 +758,47 @@ void LLLocationInputCtrl::refreshParcelIcons() { // Our "cursor" moving right to left S32 x = mAddLandmarkBtn->getRect().mLeft; - - static LLUICachedControl<bool> show_properties("NavBarShowParcelProperties", false); - if (show_properties) - { - LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstance(); - bool allow_buy = vpm->canAgentBuyParcel( vpm->getAgentParcel(), false); - bool allow_voice = vpm->allowAgentVoice(); - bool allow_fly = vpm->allowAgentFly(); - bool allow_push = vpm->allowAgentPush(); - bool allow_build = vpm->allowAgentBuild(); - bool allow_scripts = vpm->allowAgentScripts(); - bool allow_damage = vpm->allowAgentDamage(); - + + 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); + // Most icons are "block this ability" - mForSaleBtn->setVisible(allow_buy); mParcelIcon[VOICE_ICON]->setVisible( !allow_voice ); mParcelIcon[FLY_ICON]->setVisible( !allow_fly ); mParcelIcon[PUSH_ICON]->setVisible( !allow_push ); @@ -679,11 +806,10 @@ void LLLocationInputCtrl::refreshParcelIcons() mParcelIcon[SCRIPTS_ICON]->setVisible( !allow_scripts ); mParcelIcon[DAMAGE_ICON]->setVisible( allow_damage ); mDamageText->setVisible(allow_damage); - - x = layout_widget(mForSaleBtn, x); + // 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) { @@ -695,18 +821,20 @@ void LLLocationInputCtrl::refreshParcelIcons() } else { - mForSaleBtn->setVisible(false); for (S32 i = 0; i < ICON_COUNT; ++i) { mParcelIcon[i]->setVisible(false); } mDamageText->setVisible(false); } - - S32 left_pad, right_pad; - mTextEntry->getTextPadding(&left_pad, &right_pad); - right_pad = mTextEntry->getRect().mRight - x; - mTextEntry->setTextPadding(left_pad, right_pad); + + 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() @@ -725,7 +853,56 @@ void LLLocationInputCtrl::refreshHealth() } } -void LLLocationInputCtrl::rebuildLocationHistory(std::string filter) +void LLLocationInputCtrl::refreshMaturityIcon() +{ + // Updating maturity rating icon. + LLViewerRegion* region = gAgent.getRegion(); + if (!region) + return; + + U8 sim_access = region->getSimAccess(); + switch(sim_access) + { + case SIM_ACCESS_PG: + mMaturityIcon->setValue(mIconMaturityGeneral->getName()); + mMaturityIcon->setVisible(TRUE); + break; + + case SIM_ACCESS_ADULT: + mMaturityIcon->setValue(mIconMaturityAdult->getName()); + mMaturityIcon->setVisible(TRUE); + break; + + default: + mMaturityIcon->setVisible(FALSE); + } + + if (mMaturityIcon->getVisible()) + { + positionMaturityIcon(); + } +} + +void LLLocationInputCtrl::positionMaturityIcon() +{ + 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 = mMaturityIcon->getRect(); + mMaturityIcon->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. + mMaturityIcon->setVisible(rect.mRight < mTextEntry->getRect().getWidth() - right_pad); +} + +void LLLocationInputCtrl::rebuildLocationHistory(const std::string& filter) { LLLocationHistory::location_list_t filtered_items; const LLLocationHistory::location_list_t* itemsp = NULL; @@ -747,7 +924,7 @@ void LLLocationInputCtrl::rebuildLocationHistory(std::string filter) LLSD value; value["tooltip"] = it->getToolTip(); //location history can contain only typed locations - value["item_type"] = TYPED_REGION_SURL; + value["item_type"] = TYPED_REGION_SLURL; value["global_pos"] = it->mGlobalPos.getValue(); add(it->getLocation(), value); } @@ -825,16 +1002,23 @@ void LLLocationInputCtrl::updateWidgetlayout() void LLLocationInputCtrl::changeLocationPresentation() { - //change location presentation only if user does not select/past anything and - //human-readable region name is being displayed + if (!mTextEntry) + return; + + //change location presentation only if user does not select/paste anything and + //human-readable region name is being displayed std::string text = mTextEntry->getText(); LLStringUtil::trim(text); - if(mTextEntry && !mTextEntry->hasSelection() && text == mHumanReadableLocation ) + if(!mTextEntry->hasSelection() && text == mHumanReadableLocation) { //needs unescaped one mTextEntry->setText(LLAgentUI::buildSLURL(false)); mTextEntry->selectAll(); - } + + mMaturityIcon->setVisible(FALSE); + + isHumanReadableLocationVisible = false; + } } void LLLocationInputCtrl::onLocationContextMenuItemClicked(const LLSD& userdata) @@ -849,7 +1033,6 @@ void LLLocationInputCtrl::onLocationContextMenuItemClicked(const LLSD& userdata) { gSavedSettings.setBOOL("NavBarShowParcelProperties", !gSavedSettings.getBOOL("NavBarShowParcelProperties")); - refreshParcelIcons(); } else if (item == "landmark") { @@ -918,3 +1101,45 @@ bool LLLocationInputCtrl::onLocationContextMenuItemEnabled(const LLSD& userdata) return false; } + +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 SCRIPTS_ICON: + { + LLViewerRegion* region = gAgent.getRegion(); + if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS) + { + LLNotificationsUtil::add("ScriptsStopped"); + } + else if(region && region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS) + { + LLNotificationsUtil::add("ScriptsNotRunning"); + } + else + { + LLNotificationsUtil::add("NoOutsideScripts"); + } + break; + } + case DAMAGE_ICON: + LLNotificationsUtil::add("NotSafe"); + break; + case ICON_COUNT: + break; + // no default to get compiler warning when a new icon gets added + } +} |