From 2b31dad40026d8078ea30d0da0656a4078d0f5b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20N=C3=A6sbye=20Christensen?= Date: Fri, 9 Feb 2024 22:26:02 +0100 Subject: miscellaneous: BOOL (int) to real bool --- indra/newview/llpanelplaces.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llpanelplaces.cpp') diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 1d5ed93c4d..b603c361d8 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -831,7 +831,7 @@ void LLPanelPlaces::onSaveButtonClicked() gInventory.accountForUpdate(update); new_item->setParent(folder_id); - new_item->updateParentOnServer(FALSE); + new_item->updateParentOnServer(false); } gInventory.updateItem(new_item); -- cgit v1.2.3 From a5261a5fa8fad810ecb5c260d92c3e771822bf58 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Tue, 20 Feb 2024 23:46:23 +0100 Subject: Convert BOOL to bool in llui --- indra/newview/llpanelplaces.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/newview/llpanelplaces.cpp') diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index b603c361d8..31413900a1 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -275,7 +275,7 @@ LLPanelPlaces::~LLPanelPlaces() } } -BOOL LLPanelPlaces::postBuild() +bool LLPanelPlaces::postBuild() { mTeleportBtn = getChild("teleport_btn"); mTeleportBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onTeleportButtonClicked, this)); @@ -323,7 +323,7 @@ BOOL LLPanelPlaces::postBuild() mPlaceMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_place.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if (mPlaceMenu) { - mPlaceMenu->setAlwaysShowMenu(TRUE); + mPlaceMenu->setAlwaysShowMenu(true); } else { @@ -360,7 +360,7 @@ BOOL LLPanelPlaces::postBuild() mPlaceProfile = findChild("panel_place_profile"); mLandmarkInfo = findChild("panel_landmark_info"); if (!mPlaceProfile || !mLandmarkInfo) - return FALSE; + return false; mPlaceProfileBackBtn = mPlaceProfile->getChild("back_btn"); mPlaceProfileBackBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); @@ -382,7 +382,7 @@ BOOL LLPanelPlaces::postBuild() createTabs(); updateVerbs(); - return TRUE; + return true; } void LLPanelPlaces::onOpen(const LLSD& key) @@ -1107,7 +1107,7 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) } // virtual -void LLPanelPlaces::onVisibilityChange(BOOL new_visibility) +void LLPanelPlaces::onVisibilityChange(bool new_visibility) { LLPanel::onVisibilityChange(new_visibility); -- cgit v1.2.3 From 60d3dd98a44230c21803c1606552ee098ed9fa7c Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 21 Feb 2024 21:05:14 +0100 Subject: Convert remaining BOOL to bool --- indra/newview/llpanelplaces.cpp | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'indra/newview/llpanelplaces.cpp') diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 31413900a1..2abbcc0c12 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -108,7 +108,7 @@ public: } LLUUID parcel_id; - if (!parcel_id.set(params[0], FALSE)) + if (!parcel_id.set(params[0], false)) { return false; } @@ -309,7 +309,7 @@ bool LLPanelPlaces::postBuild() LLDragAndDropButton* trash_btn = (LLDragAndDropButton*)mRemoveSelectedBtn; trash_btn->setDragAndDropHandler(boost::bind(&LLPanelPlaces::handleDragAndDropToTrash, this - , _4 // BOOL drop + , _4 // bool drop , _5 // EDragAndDropType cargo_type , _6 // void* cargo_data , _7 // EAcceptance* accept @@ -343,7 +343,7 @@ bool LLPanelPlaces::postBuild() } mButtonsContainer = getChild("button_layout_panel"); - mButtonsContainer->setVisible(FALSE); + mButtonsContainer->setVisible(false); mFilterContainer = getChild("top_menu_panel"); mFilterEditor = getChild("Filter"); @@ -403,9 +403,9 @@ void LLPanelPlaces::onOpen(const LLSD& key) // The second toggle forces the list to be set to Landmark. // This avoids extracting and duplicating all the state logic from togglePlaceInfoPanel() // here or some specific private method - togglePlaceInfoPanel(FALSE); + togglePlaceInfoPanel(false); mPlaceInfoType = key_type; - togglePlaceInfoPanel(FALSE); + togglePlaceInfoPanel(false); // Update the active tab onTabSelected(); // Update the buttons at the bottom of the panel @@ -435,7 +435,7 @@ void LLPanelPlaces::onOpen(const LLSD& key) mPosGlobal.setZero(); mItem = NULL; mRegionId.setNull(); - togglePlaceInfoPanel(TRUE); + togglePlaceInfoPanel(true); if (mPlaceInfoType == AGENT_INFO_TYPE) { @@ -463,7 +463,7 @@ void LLPanelPlaces::onOpen(const LLSD& key) mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal); - mSaveBtn->setEnabled(FALSE); + mSaveBtn->setEnabled(false); } else if (mPlaceInfoType == LANDMARK_INFO_TYPE) { @@ -474,7 +474,7 @@ void LLPanelPlaces::onOpen(const LLSD& key) if (!item) return; - BOOL is_editable = gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID()) + bool is_editable = gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID()) && item->getPermissions().allowModifyBy(gAgent.getID()); mLandmarkInfo->setCanEdit(is_editable); @@ -574,7 +574,7 @@ void LLPanelPlaces::setItem(LLInventoryItem* item) } // Check if item is in agent's inventory and he has the permission to modify it. - BOOL is_landmark_editable = gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.getRootFolderID()) && + bool is_landmark_editable = gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.getRootFolderID()) && mItem->getPermissions().allowModifyBy(gAgent.getID()); mSaveBtn->setEnabled(is_landmark_editable); @@ -663,7 +663,7 @@ void LLPanelPlaces::onTabSelected() childSetVisible("add_btn_panel", supports_create); // favorites and inventory can remove items, history can clear history - childSetVisible("trash_btn_panel", TRUE); + childSetVisible("trash_btn_panel", true); if (supports_create) { @@ -784,7 +784,7 @@ void LLPanelPlaces::onEditButtonClicked() isLandmarkEditModeOn = true; - mLandmarkInfo->toggleLandmarkEditMode(TRUE); + mLandmarkInfo->toggleLandmarkEditMode(true); updateVerbs(); } @@ -851,7 +851,7 @@ void LLPanelPlaces::onCancelButtonClicked() } else { - mLandmarkInfo->toggleLandmarkEditMode(FALSE); + mLandmarkInfo->toggleLandmarkEditMode(false); isLandmarkEditModeOn = false; updateVerbs(); @@ -898,7 +898,7 @@ void LLPanelPlaces::onOverflowButtonClicked() { menu = mLandmarkMenu; - BOOL is_landmark_removable = FALSE; + bool is_landmark_removable = false; if (mItem.notNull()) { const LLUUID& item_id = mItem->getUUID(); @@ -978,7 +978,7 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param) void LLPanelPlaces::onBackButtonClicked() { - togglePlaceInfoPanel(FALSE); + togglePlaceInfoPanel(false); // Resetting mPlaceInfoType when Place Info panel is closed. mPlaceInfoType = LLStringUtil::null; @@ -1023,7 +1023,7 @@ void LLPanelPlaces::onRemoveButtonClicked() } } -bool LLPanelPlaces::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) +bool LLPanelPlaces::handleDragAndDropToTrash(bool drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) { if (mActivePanel) { @@ -1032,7 +1032,7 @@ bool LLPanelPlaces::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_t return false; } -void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) +void LLPanelPlaces::togglePlaceInfoPanel(bool visible) { if (!mPlaceProfile || !mLandmarkInfo) return; @@ -1055,7 +1055,7 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) // to avoid text blinking. mResetInfoTimer.setTimerExpirySec(PLACE_INFO_UPDATE_INTERVAL); - mLandmarkInfo->setVisible(FALSE); + mLandmarkInfo->setVisible(false); } else if (mPlaceInfoType == AGENT_INFO_TYPE) { @@ -1071,7 +1071,7 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) mPlaceInfoType == LANDMARK_TAB_INFO_TYPE) { mLandmarkInfo->setVisible(visible); - mPlaceProfile->setVisible(FALSE); + mPlaceProfile->setVisible(false); if (visible) { mLandmarkInfo->resetLocation(); @@ -1095,7 +1095,7 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) mTabContainer->selectTabPanel(landmarks_panel); if (mItem.notNull()) { - landmarks_panel->setItemSelected(mItem->getUUID(), TRUE); + landmarks_panel->setItemSelected(mItem->getUUID(), true); } else { @@ -1213,7 +1213,7 @@ void LLPanelPlaces::createTabs() childSetVisible("add_btn_panel", supports_create); // favorites and inventory can remove items, history can clear history - childSetVisible("trash_btn_panel", TRUE); + childSetVisible("trash_btn_panel", true); if (supports_create) { -- cgit v1.2.3 From e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 22 May 2024 21:25:21 +0200 Subject: Fix line endlings --- indra/newview/llpanelplaces.cpp | 2716 +++++++++++++++++++-------------------- 1 file changed, 1358 insertions(+), 1358 deletions(-) (limited to 'indra/newview/llpanelplaces.cpp') diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 6baa223389..7deb1d9fd4 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -1,1358 +1,1358 @@ -/** - * @file llpanelplaces.cpp - * @brief Side Bar "Places" panel - * - * $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" - -#include "llpanelplaces.h" - -#include "llassettype.h" -#include "lltimer.h" - -#include "llinventory.h" -#include "lllandmark.h" -#include "llparcel.h" - -#include "llcombobox.h" -#include "llfiltereditor.h" -#include "llfirstuse.h" -#include "llfloaterreg.h" -#include "llfloatersidepanelcontainer.h" -#include "llmenubutton.h" -#include "llnotificationsutil.h" -#include "lltabcontainer.h" -#include "lltexteditor.h" -#include "lltrans.h" -#include "lluictrlfactory.h" - -#include "llwindow.h" - -#include "llagent.h" -#include "llagentpicksinfo.h" -#include "llavatarpropertiesprocessor.h" -#include "llcommandhandler.h" -#include "lldndbutton.h" -#include "llfloaterworldmap.h" -#include "llinventorybridge.h" -#include "llinventoryobserver.h" -#include "llinventorymodel.h" -#include "lllandmarkactions.h" -#include "lllandmarklist.h" -#include "lllayoutstack.h" -#include "llpanellandmarkinfo.h" -#include "llpanellandmarks.h" -#include "llpanelplaceprofile.h" -#include "llpanelteleporthistory.h" -#include "llremoteparcelrequest.h" -#include "llteleporthistorystorage.h" -#include "lltoggleablemenu.h" -#include "llviewerinventory.h" -#include "llviewermenu.h" -#include "llviewermessage.h" -#include "llviewerparcelmgr.h" -#include "llviewerregion.h" -#include "llviewerwindow.h" - -// Constants -static const F32 PLACE_INFO_UPDATE_INTERVAL = 3.0; -static const std::string AGENT_INFO_TYPE = "agent"; -static const std::string CREATE_LANDMARK_INFO_TYPE = "create_landmark"; -static const std::string CREATE_PICK_TYPE = "create_pick"; -static const std::string LANDMARK_INFO_TYPE = "landmark"; -static const std::string REMOTE_PLACE_INFO_TYPE = "remote_place"; -static const std::string TELEPORT_HISTORY_INFO_TYPE = "teleport_history"; -static const std::string LANDMARK_TAB_INFO_TYPE = "open_landmark_tab"; - -// Support for secondlife:///app/parcel/{UUID}/about SLapps -class LLParcelHandler : public LLCommandHandler -{ -public: - // requires trusted browser to trigger - LLParcelHandler() : LLCommandHandler("parcel", UNTRUSTED_THROTTLE) { } - bool handle(const LLSD& params, - const LLSD& query_map, - const std::string& grid, - LLMediaCtrl* web) - { - if (params.size() < 2) - { - return false; - } - - if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePlaceProfile")) - { - LLNotificationsUtil::add("NoPlaceInfo", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); - return true; - } - - LLUUID parcel_id; - if (!parcel_id.set(params[0], false)) - { - return false; - } - if (params[1].asString() == "about") - { - if (parcel_id.notNull()) - { - LLSD key; - key["type"] = "remote_place"; - key["id"] = parcel_id; - LLFloaterSidePanelContainer::showPanel("places", key); - return true; - } - } - return false; - } -}; -LLParcelHandler gParcelHandler; - -// Helper functions -static bool is_agent_in_selected_parcel(LLParcel* parcel); -static void onSLURLBuilt(std::string& slurl); - -//Observer classes -class LLPlacesParcelObserver : public LLParcelObserver -{ -public: - LLPlacesParcelObserver(LLPanelPlaces* places_panel) : - LLParcelObserver(), - mPlaces(places_panel) - {} - - /*virtual*/ void changed() - { - if (mPlaces) - mPlaces->changedParcelSelection(); - } - -private: - LLPanelPlaces* mPlaces; -}; - -class LLPlacesInventoryObserver : public LLInventoryAddedObserver -{ -public: - LLPlacesInventoryObserver(LLPanelPlaces* places_panel) : - mPlaces(places_panel) - {} - - /*virtual*/ void changed(U32 mask) - { - LLInventoryAddedObserver::changed(mask); - - if (mPlaces && !mPlaces->tabsCreated()) - { - mPlaces->createTabs(); - } - } - -protected: - /*virtual*/ void done() - { - mPlaces->showAddedLandmarkInfo(gInventory.getAddedIDs()); - } - -private: - LLPanelPlaces* mPlaces; -}; - -class LLPlacesRemoteParcelInfoObserver : public LLRemoteParcelInfoObserver -{ -public: - LLPlacesRemoteParcelInfoObserver(LLPanelPlaces* places_panel) : - LLRemoteParcelInfoObserver(), - mPlaces(places_panel) - {} - - ~LLPlacesRemoteParcelInfoObserver() - { - // remove any in-flight observers - std::set::iterator it; - for (it = mParcelIDs.begin(); it != mParcelIDs.end(); ++it) - { - const LLUUID &id = *it; - LLRemoteParcelInfoProcessor::getInstance()->removeObserver(id, this); - } - mParcelIDs.clear(); - } - - /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data) - { - if (mPlaces) - { - mPlaces->changedGlobalPos(LLVector3d(parcel_data.global_x, - parcel_data.global_y, - parcel_data.global_z)); - } - - mParcelIDs.erase(parcel_data.parcel_id); - LLRemoteParcelInfoProcessor::getInstance()->removeObserver(parcel_data.parcel_id, this); - } - /*virtual*/ void setParcelID(const LLUUID& parcel_id) - { - if (!parcel_id.isNull()) - { - mParcelIDs.insert(parcel_id); - LLRemoteParcelInfoProcessor::getInstance()->addObserver(parcel_id, this); - LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id); - } - } - /*virtual*/ void setErrorStatus(S32 status, const std::string& reason) - { - LL_ERRS() << "Can't complete remote parcel request. Http Status: " - << status << ". Reason : " << reason << LL_ENDL; - } - -private: - std::set mParcelIDs; - LLPanelPlaces* mPlaces; -}; - - -static LLPanelInjector t_places("panel_places"); - -LLPanelPlaces::LLPanelPlaces() - : LLPanel(), - mActivePanel(NULL), - mFilterEditor(NULL), - mPlaceProfile(NULL), - mLandmarkInfo(NULL), - mItem(NULL), - mPlaceMenu(NULL), - mLandmarkMenu(NULL), - mPosGlobal(), - isLandmarkEditModeOn(false), - mTabsCreated(false) -{ - mParcelObserver = new LLPlacesParcelObserver(this); - mInventoryObserver = new LLPlacesInventoryObserver(this); - mRemoteParcelObserver = new LLPlacesRemoteParcelInfoObserver(this); - - gInventory.addObserver(mInventoryObserver); - - mAgentParcelChangedConnection = gAgent.addParcelChangedCallback( - boost::bind(&LLPanelPlaces::updateVerbs, this)); - - //buildFromFile( "panel_places.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() -} - -LLPanelPlaces::~LLPanelPlaces() -{ - if (gInventory.containsObserver(mInventoryObserver)) - gInventory.removeObserver(mInventoryObserver); - - LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver); - - delete mInventoryObserver; - delete mParcelObserver; - delete mRemoteParcelObserver; - - if (mAgentParcelChangedConnection.connected()) - { - mAgentParcelChangedConnection.disconnect(); - } -} - -bool LLPanelPlaces::postBuild() -{ - mTeleportBtn = getChild("teleport_btn"); - mTeleportBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onTeleportButtonClicked, this)); - - mShowOnMapBtn = getChild("map_btn"); - mShowOnMapBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShowOnMapButtonClicked, this)); - - mSaveBtn = getChild("save_btn"); - mSaveBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onSaveButtonClicked, this)); - - mCancelBtn = getChild("cancel_btn"); - mCancelBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onCancelButtonClicked, this)); - - mCloseBtn = getChild("close_btn"); - mCloseBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); - - mOverflowBtn = getChild("overflow_btn"); - mOverflowBtn->setMouseDownCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this)); - - mGearMenuButton = getChild("options_gear_btn"); - mGearMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onGearMenuClick, this)); - - mSortingMenuButton = getChild("sorting_menu_btn"); - mSortingMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onSortingMenuClick, this)); - - mAddMenuButton = getChild("add_menu_btn"); - mAddMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onAddMenuClick, this)); - - mRemoveSelectedBtn = getChild("trash_btn"); - mRemoveSelectedBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onRemoveButtonClicked, this)); - - LLDragAndDropButton* trash_btn = (LLDragAndDropButton*)mRemoveSelectedBtn; - trash_btn->setDragAndDropHandler(boost::bind(&LLPanelPlaces::handleDragAndDropToTrash, this - , _4 // bool drop - , _5 // EDragAndDropType cargo_type - , _6 // void* cargo_data - , _7 // EAcceptance* accept - )); - - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - registrar.add("Places.OverflowMenu.Action", boost::bind(&LLPanelPlaces::onOverflowMenuItemClicked, this, _2)); - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; - enable_registrar.add("Places.OverflowMenu.Enable", boost::bind(&LLPanelPlaces::onOverflowMenuItemEnable, this, _2)); - - mPlaceMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_place.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if (mPlaceMenu) - { - mPlaceMenu->setAlwaysShowMenu(true); - } - else - { - LL_WARNS() << "Error loading Place menu" << LL_ENDL; - } - - mLandmarkMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_landmark.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if (!mLandmarkMenu) - { - LL_WARNS() << "Error loading Landmark menu" << LL_ENDL; - } - - mTabContainer = getChild("Places Tabs"); - if (mTabContainer) - { - mTabContainer->setCommitCallback(boost::bind(&LLPanelPlaces::onTabSelected, this)); - } - - mButtonsContainer = getChild("button_layout_panel"); - mButtonsContainer->setVisible(false); - mFilterContainer = getChild("top_menu_panel"); - - mFilterEditor = getChild("Filter"); - if (mFilterEditor) - { - //when list item is being clicked the filter editor looses focus - //committing on focus lost leads to detaching list items - //BUT a detached list item cannot be made selected and must not be clicked onto - mFilterEditor->setCommitOnFocusLost(false); - - mFilterEditor->setCommitCallback(boost::bind(&LLPanelPlaces::onFilterEdit, this, _2, false)); - } - - mPlaceProfile = findChild("panel_place_profile"); - mLandmarkInfo = findChild("panel_landmark_info"); - if (!mPlaceProfile || !mLandmarkInfo) - return false; - - mPlaceProfileBackBtn = mPlaceProfile->getChild("back_btn"); - mPlaceProfileBackBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); - - mLandmarkInfo->getChild("back_btn")->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); - - LLLineEditor* title_editor = mLandmarkInfo->getChild("title_editor"); - title_editor->setKeystrokeCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this), NULL); - - LLTextEditor* notes_editor = mLandmarkInfo->getChild("notes_editor"); - notes_editor->setKeystrokeCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this)); - - LLComboBox* folder_combo = mLandmarkInfo->getChild("folder_combo"); - folder_combo->setCommitCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this)); - - LLButton* edit_btn = mLandmarkInfo->getChild("edit_btn"); - edit_btn->setCommitCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this)); - - createTabs(); - updateVerbs(); - - return true; -} - -void LLPanelPlaces::onOpen(const LLSD& key) -{ - if (!mPlaceProfile || !mLandmarkInfo) - return; - - if (key.size() != 0) - { - isLandmarkEditModeOn = false; - std::string key_type = key["type"].asString(); - if (key_type == LANDMARK_TAB_INFO_TYPE) - { - // Small hack: We need to toggle twice. The first toggle moves from the Landmark - // or Teleport History info panel to the Landmark or Teleport History list panel. - // For this first toggle, the mPlaceInfoType should be the one previously used so - // that the state can be corretly set. - // The second toggle forces the list to be set to Landmark. - // This avoids extracting and duplicating all the state logic from togglePlaceInfoPanel() - // here or some specific private method - togglePlaceInfoPanel(false); - mPlaceInfoType = key_type; - togglePlaceInfoPanel(false); - // Update the active tab - onTabSelected(); - // Update the buttons at the bottom of the panel - updateVerbs(); - } - else if (key_type == CREATE_PICK_TYPE) - { - LLUUID item_id = key["item_id"]; - - LLLandmarksPanel* landmarks_panel = - dynamic_cast(mTabContainer->getPanelByName("Landmarks")); - if (landmarks_panel && item_id.notNull()) - { - LLLandmark* landmark = LLLandmarkActions::getLandmark(item_id, boost::bind(&LLLandmarksPanel::doCreatePick, landmarks_panel, _1, item_id)); - if (landmark) - { - landmarks_panel->doCreatePick(landmark, item_id); - } - } - } - else // "create_landmark" - { - mFilterEditor->clear(); - onFilterEdit("", false); - - mPlaceInfoType = key_type; - mPosGlobal.setZero(); - mItem = NULL; - mRegionId.setNull(); - togglePlaceInfoPanel(true); - - if (mPlaceInfoType == AGENT_INFO_TYPE) - { - mPlaceProfile->setInfoType(LLPanelPlaceInfo::AGENT); - if (gAgent.getRegion()) - { - mRegionId = gAgent.getRegion()->getRegionID(); - } - } - else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE) - { - LLUUID dest_folder = key["dest_folder"]; - mLandmarkInfo->setInfoAndCreateLandmark(dest_folder); - - if (key.has("x") && key.has("y") && key.has("z")) - { - mPosGlobal = LLVector3d(key["x"].asReal(), - key["y"].asReal(), - key["z"].asReal()); - } - else - { - mPosGlobal = gAgent.getPositionGlobal(); - } - - mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal); - - mSaveBtn->setEnabled(false); - } - else if (mPlaceInfoType == LANDMARK_INFO_TYPE) - { - mLandmarkInfo->setInfoType(LLPanelPlaceInfo::LANDMARK); - - LLUUID id = key["id"].asUUID(); - LLInventoryItem* item = gInventory.getItem(id); - if (!item) - return; - - bool is_editable = gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID()) - && item->getPermissions().allowModifyBy(gAgent.getID()); - mLandmarkInfo->setCanEdit(is_editable); - - setItem(item); - } - else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE) - { - if (key.has("id")) - { - LLUUID parcel_id = key["id"].asUUID(); - mPlaceProfile->setParcelID(parcel_id); - - // query the server to get the global 3D position of this - // parcel - we need this for teleport/mapping functions. - mRemoteParcelObserver->setParcelID(parcel_id); - } - else - { - mPosGlobal = LLVector3d(key["x"].asReal(), - key["y"].asReal(), - key["z"].asReal()); - mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal); - } - - mPlaceProfile->setInfoType(LLPanelPlaceInfo::PLACE); - } - else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) - { - S32 index = key["id"].asInteger(); - - const LLTeleportHistoryStorage::slurl_list_t& hist_items = - LLTeleportHistoryStorage::getInstance()->getItems(); - - mPosGlobal = hist_items[index].mGlobalPos; - - mPlaceProfile->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY); - mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal); - } - - updateVerbs(); - } - } - - LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); - if (!parcel_mgr) - return; - - mParcelLocalId = parcel_mgr->getAgentParcel()->getLocalID(); - - // Start using LLViewerParcelMgr for land selection if - // information about nearby land is requested. - // Otherwise stop using land selection and deselect land. - if (mPlaceInfoType == AGENT_INFO_TYPE) - { - // We don't know if we are already added to LLViewerParcelMgr observers list - // so try to remove observer not to add an extra one. - parcel_mgr->removeObserver(mParcelObserver); - - parcel_mgr->addObserver(mParcelObserver); - parcel_mgr->selectParcelAt(gAgent.getPositionGlobal()); - } - else - { - parcel_mgr->removeObserver(mParcelObserver); - - // Clear the reference to selection to allow its removal in deselectUnused(). - mParcel.clear(); - - if (!parcel_mgr->selectionEmpty()) - { - parcel_mgr->deselectUnused(); - } - } -} - -void LLPanelPlaces::setItem(LLInventoryItem* item) -{ - if (!mLandmarkInfo || !item) - return; - - mItem = item; - - LLAssetType::EType item_type = mItem->getActualType(); - if (item_type == LLAssetType::AT_LANDMARK || item_type == LLAssetType::AT_LINK) - { - // If the item is a link get a linked item - if (item_type == LLAssetType::AT_LINK) - { - mItem = gInventory.getItem(mItem->getLinkedUUID()); - if (mItem.isNull()) - return; - } - } - else - { - return; - } - - // Check if item is in agent's inventory and he has the permission to modify it. - bool is_landmark_editable = gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.getRootFolderID()) && - mItem->getPermissions().allowModifyBy(gAgent.getID()); - - mSaveBtn->setEnabled(is_landmark_editable); - - if (is_landmark_editable) - { - if(!mLandmarkInfo->setLandmarkFolder(mItem->getParentUUID()) && !mItem->getParentUUID().isNull()) - { - const LLViewerInventoryCategory* cat = gInventory.getCategory(mItem->getParentUUID()); - if (cat) - { - std::string cat_fullname = LLPanelLandmarkInfo::getFullFolderName(cat); - LLComboBox* folderList = mLandmarkInfo->getChild("folder_combo"); - folderList->add(cat_fullname, cat->getUUID(), ADD_TOP); - } - } - } - - mLandmarkInfo->displayItemInfo(mItem); - - LLLandmark* lm = gLandmarkList.getAsset(mItem->getAssetUUID(), - boost::bind(&LLPanelPlaces::onLandmarkLoaded, this, _1)); - if (lm) - { - onLandmarkLoaded(lm); - } -} - -S32 LLPanelPlaces::notifyParent(const LLSD& info) -{ - if(info.has("update_verbs")) - { - if(mPosGlobal.isExactlyZero()) - { - mPosGlobal.setVec(info["global_x"], info["global_y"], info["global_z"]); - } - - updateVerbs(); - - return 1; - } - return LLPanel::notifyParent(info); -} - -void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark) -{ - if (!mLandmarkInfo) - return; - - LLUUID region_id; - landmark->getRegionID(region_id); - landmark->getGlobalPos(mPosGlobal); - mLandmarkInfo->displayParcelInfo(region_id, mPosGlobal); - - updateVerbs(); -} - -void LLPanelPlaces::onFilterEdit(const std::string& search_string, bool force_filter) -{ - if (!mActivePanel) - return; - - if (force_filter || mActivePanel->getFilterSubString() != search_string) - { - std::string string = search_string; - - // Searches are case-insensitive - // but we don't convert the typed string to upper-case so that it can be fed to the web search as-is. - - mActivePanel->onSearchEdit(string); - } -} - -void LLPanelPlaces::onTabSelected() -{ - mActivePanel = dynamic_cast(mTabContainer->getCurrentPanel()); - if (!mActivePanel) - return; - - onFilterEdit(mActivePanel->getFilterSubString(), true); - mActivePanel->updateVerbs(); - - // History panel does not support deletion nor creation - // Hide menus - bool supports_create = mActivePanel->getCreateMenu() != NULL; - childSetVisible("add_btn_panel", supports_create); - - // favorites and inventory can remove items, history can clear history - childSetVisible("trash_btn_panel", true); - - if (supports_create) - { - mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_items")); - } - else - { - mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_history")); - } -} - -void LLPanelPlaces::onTeleportButtonClicked() -{ - LLPanelPlaceInfo* panel = getCurrentInfoPanel(); - if (panel && panel->getVisible()) - { - if (mPlaceInfoType == LANDMARK_INFO_TYPE) - { - if (mItem.isNull()) - { - LL_WARNS() << "NULL landmark item" << LL_ENDL; - llassert(mItem.notNull()); - return; - } - - LLSD payload; - payload["asset_id"] = mItem->getAssetUUID(); - LLSD args; - args["LOCATION"] = mItem->getName(); - LLNotificationsUtil::add("TeleportFromLandmark", args, payload); - } - else if (mPlaceInfoType == AGENT_INFO_TYPE || - mPlaceInfoType == REMOTE_PLACE_INFO_TYPE || - mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) - { - LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); - if (!mPosGlobal.isExactlyZero() && worldmap_instance) - { - gAgent.teleportViaLocation(mPosGlobal); - worldmap_instance->trackLocation(mPosGlobal); - } - } - } - else - { - if (mActivePanel) - mActivePanel->onTeleport(); - } -} - -void LLPanelPlaces::onShowOnMapButtonClicked() -{ - LLPanelPlaceInfo* panel = getCurrentInfoPanel(); - if (panel && panel->getVisible()) - { - LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); - if(!worldmap_instance) - return; - - if (mPlaceInfoType == AGENT_INFO_TYPE || - mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE || - mPlaceInfoType == REMOTE_PLACE_INFO_TYPE || - mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) - { - if (!mPosGlobal.isExactlyZero()) - { - worldmap_instance->trackLocation(mPosGlobal); - LLFloaterReg::showInstance("world_map", "center"); - } - } - else if (mPlaceInfoType == LANDMARK_INFO_TYPE) - { - if (mItem.isNull()) - { - LL_WARNS() << "NULL landmark item" << LL_ENDL; - llassert(mItem.notNull()); - return; - } - LLLandmark* landmark = gLandmarkList.getAsset(mItem->getAssetUUID()); - if (!landmark) - return; - - LLVector3d landmark_global_pos; - if (!landmark->getGlobalPos(landmark_global_pos)) - return; - - if (!landmark_global_pos.isExactlyZero()) - { - worldmap_instance->trackLocation(landmark_global_pos); - LLFloaterReg::showInstance("world_map", "center"); - } - } - } - else - { - if (mActivePanel && mActivePanel->isSingleItemSelected()) - { - mActivePanel->onShowOnMap(); - } - else - { - LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); - LLVector3d global_pos = gAgent.getPositionGlobal(); - - if (!global_pos.isExactlyZero() && worldmap_instance) - { - worldmap_instance->trackLocation(global_pos); - LLFloaterReg::showInstance("world_map", "center"); - } - } - } -} - -void LLPanelPlaces::onEditButtonClicked() -{ - if (!mLandmarkInfo || isLandmarkEditModeOn) - return; - - isLandmarkEditModeOn = true; - - mLandmarkInfo->toggleLandmarkEditMode(true); - - updateVerbs(); -} - -void LLPanelPlaces::onSaveButtonClicked() -{ - if (!mLandmarkInfo || mItem.isNull()) - return; - - std::string current_title_value = mLandmarkInfo->getLandmarkTitle(); - std::string item_title_value = mItem->getName(); - std::string current_notes_value = mLandmarkInfo->getLandmarkNotes(); - std::string item_notes_value = mItem->getDescription(); - - LLStringUtil::trim(current_title_value); - LLStringUtil::trim(current_notes_value); - - LLUUID folder_id = mLandmarkInfo->getLandmarkFolder(); - bool change_parent = folder_id != mItem->getParentUUID(); - - LLPointer new_item = new LLViewerInventoryItem(mItem); - - if (!current_title_value.empty() && - (item_title_value != current_title_value || item_notes_value != current_notes_value)) - { - new_item->rename(current_title_value); - new_item->setDescription(current_notes_value); - LLPointer cb; - if (change_parent) - { - cb = new LLUpdateLandmarkParent(new_item, folder_id); - } - LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0); - gInventory.accountForUpdate(up); - update_inventory_item(new_item, cb); - } - else if (change_parent) - { - LLInventoryModel::update_list_t update; - LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(),-1); - update.push_back(old_folder); - LLInventoryModel::LLCategoryUpdate new_folder(folder_id, 1); - update.push_back(new_folder); - gInventory.accountForUpdate(update); - - new_item->setParent(folder_id); - new_item->updateParentOnServer(false); - } - - gInventory.updateItem(new_item); - gInventory.notifyObservers(); - - onCancelButtonClicked(); -} - -void LLPanelPlaces::onCancelButtonClicked() -{ - if (!mLandmarkInfo) - return; - - if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE) - { - onBackButtonClicked(); - } - else - { - mLandmarkInfo->toggleLandmarkEditMode(false); - isLandmarkEditModeOn = false; - - updateVerbs(); - - // Reload the landmark properties. - mLandmarkInfo->displayItemInfo(mItem); - } -} - -void LLPanelPlaces::onOverflowButtonClicked() -{ - LLToggleableMenu* menu; - - bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE; - - if ((is_agent_place_info_visible || - mPlaceInfoType == REMOTE_PLACE_INFO_TYPE || - mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) && mPlaceMenu != NULL) - { - menu = mPlaceMenu; - - bool landmark_item_enabled = false; - LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); - if (is_agent_place_info_visible - && gAgent.getRegion() - && mRegionId == gAgent.getRegion()->getRegionID() - && parcel_mgr - && parcel_mgr->getAgentParcel()->getLocalID() == mParcelLocalId) - { - // Floater still shows location identical to agent's position - landmark_item_enabled = !LLLandmarkActions::landmarkAlreadyExists(); - } - - // Enable adding a landmark only for agent current parcel and if - // there is no landmark already pointing to that parcel in agent's inventory. - menu->getChild("landmark")->setEnabled(landmark_item_enabled); - // STORM-411 - // Creating landmarks for remote locations is impossible. - // So hide menu item "Make a Landmark" in "Teleport History Profile" panel. - menu->setItemVisible("landmark", mPlaceInfoType != TELEPORT_HISTORY_INFO_TYPE); - menu->arrangeAndClear(); - } - else if (mPlaceInfoType == LANDMARK_INFO_TYPE && mLandmarkMenu != NULL) - { - menu = mLandmarkMenu; - - bool is_landmark_removable = false; - if (mItem.notNull()) - { - const LLUUID& item_id = mItem->getUUID(); - const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - is_landmark_removable = gInventory.isObjectDescendentOf(item_id, gInventory.getRootFolderID()) && - !gInventory.isObjectDescendentOf(item_id, trash_id); - } - - menu->getChild("delete")->setEnabled(is_landmark_removable); - } - else - { - return; - } - - mOverflowBtn->setMenu(menu, LLMenuButton::MP_TOP_RIGHT); -} - -bool LLPanelPlaces::onOverflowMenuItemEnable(const LLSD& param) -{ - std::string value = param.asString(); - if("can_create_pick" == value) - { - return !LLAgentPicksInfo::getInstance()->isPickLimitReached(); - } - return true; -} - -void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param) -{ - std::string item = param.asString(); - if (item == "landmark") - { - LLSD key; - key["type"] = CREATE_LANDMARK_INFO_TYPE; - key["x"] = mPosGlobal.mdV[VX]; - key["y"] = mPosGlobal.mdV[VY]; - key["z"] = mPosGlobal.mdV[VZ]; - onOpen(key); - } - else if (item == "copy") - { - LLLandmarkActions::getSLURLfromPosGlobal(mPosGlobal, boost::bind(&onSLURLBuilt, _1)); - } - else if (item == "delete") - { - gInventory.removeItem(mItem->getUUID()); - - onBackButtonClicked(); - } - else if (item == "pick") - { - LLPanelPlaceInfo* panel = getCurrentInfoPanel(); - if (panel) - { - panel->createPick(mPosGlobal); - } - } - else if (item == "add_to_favbar") - { - if ( mItem.notNull() ) - { - const LLUUID& favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); - if ( favorites_id.notNull() ) - { - copy_inventory_item(gAgent.getID(), - mItem->getPermissions().getOwner(), - mItem->getUUID(), - favorites_id, - std::string(), - LLPointer(NULL)); - LL_INFOS() << "Copied inventory item #" << mItem->getUUID() << " to favorites." << LL_ENDL; - } - } - } -} - -void LLPanelPlaces::onBackButtonClicked() -{ - togglePlaceInfoPanel(false); - - // Resetting mPlaceInfoType when Place Info panel is closed. - mPlaceInfoType = LLStringUtil::null; - - isLandmarkEditModeOn = false; - - updateVerbs(); -} - -void LLPanelPlaces::onGearMenuClick() -{ - if (mActivePanel) - { - LLToggleableMenu* menu = mActivePanel->getSelectionMenu(); - mGearMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT); - } -} - -void LLPanelPlaces::onSortingMenuClick() -{ - if (mActivePanel) - { - LLToggleableMenu* menu = mActivePanel->getSortingMenu(); - mSortingMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT); - } -} - -void LLPanelPlaces::onAddMenuClick() -{ - if (mActivePanel) - { - LLToggleableMenu* menu = mActivePanel->getCreateMenu(); - mAddMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT); - } -} - -void LLPanelPlaces::onRemoveButtonClicked() -{ - if (mActivePanel) - { - mActivePanel->onRemoveSelected(); - } -} - -bool LLPanelPlaces::handleDragAndDropToTrash(bool drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) -{ - if (mActivePanel) - { - return mActivePanel->handleDragAndDropToTrash(drop, cargo_type, cargo_data, accept); - } - return false; -} - -void LLPanelPlaces::togglePlaceInfoPanel(bool visible) -{ - if (!mPlaceProfile || !mLandmarkInfo) - return; - - mTabContainer->setVisible(!visible); - mButtonsContainer->setVisible(visible); - mFilterContainer->setVisible(!visible); - - if (mPlaceInfoType == AGENT_INFO_TYPE || - mPlaceInfoType == REMOTE_PLACE_INFO_TYPE || - mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) - { - mPlaceProfile->setVisible(visible); - - if (visible) - { - mPlaceProfile->resetLocation(); - - // Do not reset location info until mResetInfoTimer has expired - // to avoid text blinking. - mResetInfoTimer.setTimerExpirySec(PLACE_INFO_UPDATE_INTERVAL); - - mLandmarkInfo->setVisible(false); - } - else if (mPlaceInfoType == AGENT_INFO_TYPE) - { - LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver); - - // Clear reference to parcel selection when closing place profile panel. - // LLViewerParcelMgr removes the selection if it has 1 reference to it. - mParcel.clear(); - } - } - else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE || - mPlaceInfoType == LANDMARK_INFO_TYPE || - mPlaceInfoType == LANDMARK_TAB_INFO_TYPE) - { - mLandmarkInfo->setVisible(visible); - mPlaceProfile->setVisible(false); - if (visible) - { - mLandmarkInfo->resetLocation(); - } - else - { - std::string tab_panel_name("Landmarks"); - if (mItem.notNull()) - { - if (gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE))) - { - tab_panel_name = "Favorites"; - } - } - - LLLandmarksPanel* landmarks_panel = dynamic_cast(mTabContainer->getPanelByName(tab_panel_name)); - if (landmarks_panel) - { - // If a landmark info is being closed we open the landmarks tab - // and set this landmark selected. - mTabContainer->selectTabPanel(landmarks_panel); - if (mItem.notNull()) - { - landmarks_panel->setItemSelected(mItem->getUUID(), true); - } - else - { - landmarks_panel->resetSelection(); - } - } - } - } -} - -// virtual -void LLPanelPlaces::onVisibilityChange(bool new_visibility) -{ - LLPanel::onVisibilityChange(new_visibility); - - if (!new_visibility && mPlaceInfoType == AGENT_INFO_TYPE) - { - LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver); - - // Clear reference to parcel selection when closing places panel. - mParcel.clear(); - } -} - -void LLPanelPlaces::changedParcelSelection() -{ - if (!mPlaceProfile) - return; - - LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); - mParcel = parcel_mgr->getFloatingParcelSelection(); - LLParcel* parcel = mParcel->getParcel(); - LLViewerRegion* region = parcel_mgr->getSelectionRegion(); - if (!region || !parcel) - return; - - LLVector3d prev_pos_global = mPosGlobal; - - // If agent is inside the selected parcel show agent's region, - // otherwise show region of agent's selection point. - bool is_current_parcel = is_agent_in_selected_parcel(parcel); - if (is_current_parcel) - { - mPosGlobal = gAgent.getPositionGlobal(); - } - else - { - LLVector3d pos_global = gViewerWindow->getLastPick().mPosGlobal; - if (!pos_global.isExactlyZero()) - { - mPosGlobal = pos_global; - } - } - - // Reset location info only if global position has changed - // and update timer has expired to reduce unnecessary text and icons updates. - if (prev_pos_global != mPosGlobal && mResetInfoTimer.hasExpired()) - { - mPlaceProfile->resetLocation(); - mResetInfoTimer.setTimerExpirySec(PLACE_INFO_UPDATE_INTERVAL); - } - - mPlaceProfile->displaySelectedParcelInfo(parcel, region, mPosGlobal, is_current_parcel); - - updateVerbs(); -} - -void LLPanelPlaces::createTabs() -{ - if (!(gInventory.isInventoryUsable() && LLTeleportHistory::getInstance() && !mTabsCreated)) - return; - - LLFavoritesPanel* favorites_panel = new LLFavoritesPanel(); - if (favorites_panel) - { - mTabContainer->addTabPanel( - LLTabContainer::TabPanelParams(). - panel(favorites_panel). - label(getString("favorites_tab_title")). - insert_at(LLTabContainer::END)); - } - - LLLandmarksPanel* landmarks_panel = new LLLandmarksPanel(); - if (landmarks_panel) - { - mTabContainer->addTabPanel( - LLTabContainer::TabPanelParams(). - panel(landmarks_panel). - label(getString("landmarks_tab_title")). - insert_at(LLTabContainer::END)); - } - - LLTeleportHistoryPanel* teleport_history_panel = new LLTeleportHistoryPanel(); - if (teleport_history_panel) - { - mTabContainer->addTabPanel( - LLTabContainer::TabPanelParams(). - panel(teleport_history_panel). - label(getString("teleport_history_tab_title")). - insert_at(LLTabContainer::END)); - } - - mTabContainer->selectFirstTab(); - - mActivePanel = dynamic_cast(mTabContainer->getCurrentPanel()); - - if (mActivePanel) - { - // Filter applied to show all items. - mActivePanel->onSearchEdit(mActivePanel->getFilterSubString()); - - // History panel does not support deletion nor creation - // Hide menus - bool supports_create = mActivePanel->getCreateMenu() != NULL; - childSetVisible("add_btn_panel", supports_create); - - // favorites and inventory can remove items, history can clear history - childSetVisible("trash_btn_panel", true); - - if (supports_create) - { - mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_items")); - } - else - { - mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_history")); - } - - mActivePanel->setRemoveBtn(mRemoveSelectedBtn); - mActivePanel->updateVerbs(); - } - - mTabsCreated = true; -} - -void LLPanelPlaces::changedGlobalPos(const LLVector3d &global_pos) -{ - mPosGlobal = global_pos; - updateVerbs(); -} - -void LLPanelPlaces::showAddedLandmarkInfo(const uuid_set_t& items) -{ - for (uuid_set_t::const_iterator item_iter = items.begin(); - item_iter != items.end(); - ++item_iter) - { - const LLUUID& item_id = (*item_iter); - if(!highlight_offered_object(item_id)) - { - continue; - } - - LLInventoryItem* item = gInventory.getItem(item_id); - - llassert(item); - if (item && (LLAssetType::AT_LANDMARK == item->getType()) ) - { - // Created landmark is passed to Places panel to allow its editing. - // If the panel is closed we don't reopen it until created landmark is loaded. - if("create_landmark" == getPlaceInfoType() && !getItem()) - { - setItem(item); - } - } - } -} - -void LLPanelPlaces::updateVerbs() -{ - bool is_place_info_visible; - - LLPanelPlaceInfo* panel = getCurrentInfoPanel(); - if (panel) - { - is_place_info_visible = panel->getVisible(); - } - else - { - is_place_info_visible = false; - } - - bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE; - bool is_create_landmark_visible = mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE; - - bool have_3d_pos = ! mPosGlobal.isExactlyZero(); - - mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn); - mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn); - mSaveBtn->setVisible(isLandmarkEditModeOn); - mCancelBtn->setVisible(isLandmarkEditModeOn); - mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn); - - bool show_options_btn = is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn; - mOverflowBtn->setVisible(show_options_btn); - getChild("lp_options")->setVisible(show_options_btn); - getChild("lp2")->setVisible(!show_options_btn); - - if (is_place_info_visible) - { - mShowOnMapBtn->setEnabled(have_3d_pos); - - if (is_agent_place_info_visible) - { - // We don't need to teleport to the current location - // so check if the location is not within the current parcel. - mTeleportBtn->setEnabled(have_3d_pos && - !LLViewerParcelMgr::getInstance()->inAgentParcel(mPosGlobal)); - } - else if (mPlaceInfoType == LANDMARK_INFO_TYPE || mPlaceInfoType == REMOTE_PLACE_INFO_TYPE) - { - mTeleportBtn->setEnabled(have_3d_pos); - } - } - else - { - if (mActivePanel) - mActivePanel->updateVerbs(); - } -} - -LLPanelPlaceInfo* LLPanelPlaces::getCurrentInfoPanel() -{ - if (mPlaceInfoType == AGENT_INFO_TYPE || - mPlaceInfoType == REMOTE_PLACE_INFO_TYPE || - mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) - { - return mPlaceProfile; - } - else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE || - mPlaceInfoType == LANDMARK_INFO_TYPE || - mPlaceInfoType == LANDMARK_TAB_INFO_TYPE) - { - return mLandmarkInfo; - } - - return NULL; -} - -static bool is_agent_in_selected_parcel(LLParcel* parcel) -{ - LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); - - LLViewerRegion* region = parcel_mgr->getSelectionRegion(); - if (!region || !parcel) - return false; - - return region == gAgent.getRegion() && - parcel->getLocalID() == parcel_mgr->getAgentParcel()->getLocalID(); -} - -static void onSLURLBuilt(std::string& slurl) -{ - LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(slurl)); - - LLSD args; - args["SLURL"] = slurl; - - LLNotificationsUtil::add("CopySLURL", args); -} +/** + * @file llpanelplaces.cpp + * @brief Side Bar "Places" panel + * + * $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" + +#include "llpanelplaces.h" + +#include "llassettype.h" +#include "lltimer.h" + +#include "llinventory.h" +#include "lllandmark.h" +#include "llparcel.h" + +#include "llcombobox.h" +#include "llfiltereditor.h" +#include "llfirstuse.h" +#include "llfloaterreg.h" +#include "llfloatersidepanelcontainer.h" +#include "llmenubutton.h" +#include "llnotificationsutil.h" +#include "lltabcontainer.h" +#include "lltexteditor.h" +#include "lltrans.h" +#include "lluictrlfactory.h" + +#include "llwindow.h" + +#include "llagent.h" +#include "llagentpicksinfo.h" +#include "llavatarpropertiesprocessor.h" +#include "llcommandhandler.h" +#include "lldndbutton.h" +#include "llfloaterworldmap.h" +#include "llinventorybridge.h" +#include "llinventoryobserver.h" +#include "llinventorymodel.h" +#include "lllandmarkactions.h" +#include "lllandmarklist.h" +#include "lllayoutstack.h" +#include "llpanellandmarkinfo.h" +#include "llpanellandmarks.h" +#include "llpanelplaceprofile.h" +#include "llpanelteleporthistory.h" +#include "llremoteparcelrequest.h" +#include "llteleporthistorystorage.h" +#include "lltoggleablemenu.h" +#include "llviewerinventory.h" +#include "llviewermenu.h" +#include "llviewermessage.h" +#include "llviewerparcelmgr.h" +#include "llviewerregion.h" +#include "llviewerwindow.h" + +// Constants +static const F32 PLACE_INFO_UPDATE_INTERVAL = 3.0; +static const std::string AGENT_INFO_TYPE = "agent"; +static const std::string CREATE_LANDMARK_INFO_TYPE = "create_landmark"; +static const std::string CREATE_PICK_TYPE = "create_pick"; +static const std::string LANDMARK_INFO_TYPE = "landmark"; +static const std::string REMOTE_PLACE_INFO_TYPE = "remote_place"; +static const std::string TELEPORT_HISTORY_INFO_TYPE = "teleport_history"; +static const std::string LANDMARK_TAB_INFO_TYPE = "open_landmark_tab"; + +// Support for secondlife:///app/parcel/{UUID}/about SLapps +class LLParcelHandler : public LLCommandHandler +{ +public: + // requires trusted browser to trigger + LLParcelHandler() : LLCommandHandler("parcel", UNTRUSTED_THROTTLE) { } + bool handle(const LLSD& params, + const LLSD& query_map, + const std::string& grid, + LLMediaCtrl* web) + { + if (params.size() < 2) + { + return false; + } + + if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePlaceProfile")) + { + LLNotificationsUtil::add("NoPlaceInfo", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); + return true; + } + + LLUUID parcel_id; + if (!parcel_id.set(params[0], false)) + { + return false; + } + if (params[1].asString() == "about") + { + if (parcel_id.notNull()) + { + LLSD key; + key["type"] = "remote_place"; + key["id"] = parcel_id; + LLFloaterSidePanelContainer::showPanel("places", key); + return true; + } + } + return false; + } +}; +LLParcelHandler gParcelHandler; + +// Helper functions +static bool is_agent_in_selected_parcel(LLParcel* parcel); +static void onSLURLBuilt(std::string& slurl); + +//Observer classes +class LLPlacesParcelObserver : public LLParcelObserver +{ +public: + LLPlacesParcelObserver(LLPanelPlaces* places_panel) : + LLParcelObserver(), + mPlaces(places_panel) + {} + + /*virtual*/ void changed() + { + if (mPlaces) + mPlaces->changedParcelSelection(); + } + +private: + LLPanelPlaces* mPlaces; +}; + +class LLPlacesInventoryObserver : public LLInventoryAddedObserver +{ +public: + LLPlacesInventoryObserver(LLPanelPlaces* places_panel) : + mPlaces(places_panel) + {} + + /*virtual*/ void changed(U32 mask) + { + LLInventoryAddedObserver::changed(mask); + + if (mPlaces && !mPlaces->tabsCreated()) + { + mPlaces->createTabs(); + } + } + +protected: + /*virtual*/ void done() + { + mPlaces->showAddedLandmarkInfo(gInventory.getAddedIDs()); + } + +private: + LLPanelPlaces* mPlaces; +}; + +class LLPlacesRemoteParcelInfoObserver : public LLRemoteParcelInfoObserver +{ +public: + LLPlacesRemoteParcelInfoObserver(LLPanelPlaces* places_panel) : + LLRemoteParcelInfoObserver(), + mPlaces(places_panel) + {} + + ~LLPlacesRemoteParcelInfoObserver() + { + // remove any in-flight observers + std::set::iterator it; + for (it = mParcelIDs.begin(); it != mParcelIDs.end(); ++it) + { + const LLUUID &id = *it; + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(id, this); + } + mParcelIDs.clear(); + } + + /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data) + { + if (mPlaces) + { + mPlaces->changedGlobalPos(LLVector3d(parcel_data.global_x, + parcel_data.global_y, + parcel_data.global_z)); + } + + mParcelIDs.erase(parcel_data.parcel_id); + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(parcel_data.parcel_id, this); + } + /*virtual*/ void setParcelID(const LLUUID& parcel_id) + { + if (!parcel_id.isNull()) + { + mParcelIDs.insert(parcel_id); + LLRemoteParcelInfoProcessor::getInstance()->addObserver(parcel_id, this); + LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id); + } + } + /*virtual*/ void setErrorStatus(S32 status, const std::string& reason) + { + LL_ERRS() << "Can't complete remote parcel request. Http Status: " + << status << ". Reason : " << reason << LL_ENDL; + } + +private: + std::set mParcelIDs; + LLPanelPlaces* mPlaces; +}; + + +static LLPanelInjector t_places("panel_places"); + +LLPanelPlaces::LLPanelPlaces() + : LLPanel(), + mActivePanel(NULL), + mFilterEditor(NULL), + mPlaceProfile(NULL), + mLandmarkInfo(NULL), + mItem(NULL), + mPlaceMenu(NULL), + mLandmarkMenu(NULL), + mPosGlobal(), + isLandmarkEditModeOn(false), + mTabsCreated(false) +{ + mParcelObserver = new LLPlacesParcelObserver(this); + mInventoryObserver = new LLPlacesInventoryObserver(this); + mRemoteParcelObserver = new LLPlacesRemoteParcelInfoObserver(this); + + gInventory.addObserver(mInventoryObserver); + + mAgentParcelChangedConnection = gAgent.addParcelChangedCallback( + boost::bind(&LLPanelPlaces::updateVerbs, this)); + + //buildFromFile( "panel_places.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() +} + +LLPanelPlaces::~LLPanelPlaces() +{ + if (gInventory.containsObserver(mInventoryObserver)) + gInventory.removeObserver(mInventoryObserver); + + LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver); + + delete mInventoryObserver; + delete mParcelObserver; + delete mRemoteParcelObserver; + + if (mAgentParcelChangedConnection.connected()) + { + mAgentParcelChangedConnection.disconnect(); + } +} + +bool LLPanelPlaces::postBuild() +{ + mTeleportBtn = getChild("teleport_btn"); + mTeleportBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onTeleportButtonClicked, this)); + + mShowOnMapBtn = getChild("map_btn"); + mShowOnMapBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShowOnMapButtonClicked, this)); + + mSaveBtn = getChild("save_btn"); + mSaveBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onSaveButtonClicked, this)); + + mCancelBtn = getChild("cancel_btn"); + mCancelBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onCancelButtonClicked, this)); + + mCloseBtn = getChild("close_btn"); + mCloseBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); + + mOverflowBtn = getChild("overflow_btn"); + mOverflowBtn->setMouseDownCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this)); + + mGearMenuButton = getChild("options_gear_btn"); + mGearMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onGearMenuClick, this)); + + mSortingMenuButton = getChild("sorting_menu_btn"); + mSortingMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onSortingMenuClick, this)); + + mAddMenuButton = getChild("add_menu_btn"); + mAddMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onAddMenuClick, this)); + + mRemoveSelectedBtn = getChild("trash_btn"); + mRemoveSelectedBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onRemoveButtonClicked, this)); + + LLDragAndDropButton* trash_btn = (LLDragAndDropButton*)mRemoveSelectedBtn; + trash_btn->setDragAndDropHandler(boost::bind(&LLPanelPlaces::handleDragAndDropToTrash, this + , _4 // bool drop + , _5 // EDragAndDropType cargo_type + , _6 // void* cargo_data + , _7 // EAcceptance* accept + )); + + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + registrar.add("Places.OverflowMenu.Action", boost::bind(&LLPanelPlaces::onOverflowMenuItemClicked, this, _2)); + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + enable_registrar.add("Places.OverflowMenu.Enable", boost::bind(&LLPanelPlaces::onOverflowMenuItemEnable, this, _2)); + + mPlaceMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_place.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (mPlaceMenu) + { + mPlaceMenu->setAlwaysShowMenu(true); + } + else + { + LL_WARNS() << "Error loading Place menu" << LL_ENDL; + } + + mLandmarkMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_landmark.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (!mLandmarkMenu) + { + LL_WARNS() << "Error loading Landmark menu" << LL_ENDL; + } + + mTabContainer = getChild("Places Tabs"); + if (mTabContainer) + { + mTabContainer->setCommitCallback(boost::bind(&LLPanelPlaces::onTabSelected, this)); + } + + mButtonsContainer = getChild("button_layout_panel"); + mButtonsContainer->setVisible(false); + mFilterContainer = getChild("top_menu_panel"); + + mFilterEditor = getChild("Filter"); + if (mFilterEditor) + { + //when list item is being clicked the filter editor looses focus + //committing on focus lost leads to detaching list items + //BUT a detached list item cannot be made selected and must not be clicked onto + mFilterEditor->setCommitOnFocusLost(false); + + mFilterEditor->setCommitCallback(boost::bind(&LLPanelPlaces::onFilterEdit, this, _2, false)); + } + + mPlaceProfile = findChild("panel_place_profile"); + mLandmarkInfo = findChild("panel_landmark_info"); + if (!mPlaceProfile || !mLandmarkInfo) + return false; + + mPlaceProfileBackBtn = mPlaceProfile->getChild("back_btn"); + mPlaceProfileBackBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); + + mLandmarkInfo->getChild("back_btn")->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); + + LLLineEditor* title_editor = mLandmarkInfo->getChild("title_editor"); + title_editor->setKeystrokeCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this), NULL); + + LLTextEditor* notes_editor = mLandmarkInfo->getChild("notes_editor"); + notes_editor->setKeystrokeCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this)); + + LLComboBox* folder_combo = mLandmarkInfo->getChild("folder_combo"); + folder_combo->setCommitCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this)); + + LLButton* edit_btn = mLandmarkInfo->getChild("edit_btn"); + edit_btn->setCommitCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this)); + + createTabs(); + updateVerbs(); + + return true; +} + +void LLPanelPlaces::onOpen(const LLSD& key) +{ + if (!mPlaceProfile || !mLandmarkInfo) + return; + + if (key.size() != 0) + { + isLandmarkEditModeOn = false; + std::string key_type = key["type"].asString(); + if (key_type == LANDMARK_TAB_INFO_TYPE) + { + // Small hack: We need to toggle twice. The first toggle moves from the Landmark + // or Teleport History info panel to the Landmark or Teleport History list panel. + // For this first toggle, the mPlaceInfoType should be the one previously used so + // that the state can be corretly set. + // The second toggle forces the list to be set to Landmark. + // This avoids extracting and duplicating all the state logic from togglePlaceInfoPanel() + // here or some specific private method + togglePlaceInfoPanel(false); + mPlaceInfoType = key_type; + togglePlaceInfoPanel(false); + // Update the active tab + onTabSelected(); + // Update the buttons at the bottom of the panel + updateVerbs(); + } + else if (key_type == CREATE_PICK_TYPE) + { + LLUUID item_id = key["item_id"]; + + LLLandmarksPanel* landmarks_panel = + dynamic_cast(mTabContainer->getPanelByName("Landmarks")); + if (landmarks_panel && item_id.notNull()) + { + LLLandmark* landmark = LLLandmarkActions::getLandmark(item_id, boost::bind(&LLLandmarksPanel::doCreatePick, landmarks_panel, _1, item_id)); + if (landmark) + { + landmarks_panel->doCreatePick(landmark, item_id); + } + } + } + else // "create_landmark" + { + mFilterEditor->clear(); + onFilterEdit("", false); + + mPlaceInfoType = key_type; + mPosGlobal.setZero(); + mItem = NULL; + mRegionId.setNull(); + togglePlaceInfoPanel(true); + + if (mPlaceInfoType == AGENT_INFO_TYPE) + { + mPlaceProfile->setInfoType(LLPanelPlaceInfo::AGENT); + if (gAgent.getRegion()) + { + mRegionId = gAgent.getRegion()->getRegionID(); + } + } + else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE) + { + LLUUID dest_folder = key["dest_folder"]; + mLandmarkInfo->setInfoAndCreateLandmark(dest_folder); + + if (key.has("x") && key.has("y") && key.has("z")) + { + mPosGlobal = LLVector3d(key["x"].asReal(), + key["y"].asReal(), + key["z"].asReal()); + } + else + { + mPosGlobal = gAgent.getPositionGlobal(); + } + + mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal); + + mSaveBtn->setEnabled(false); + } + else if (mPlaceInfoType == LANDMARK_INFO_TYPE) + { + mLandmarkInfo->setInfoType(LLPanelPlaceInfo::LANDMARK); + + LLUUID id = key["id"].asUUID(); + LLInventoryItem* item = gInventory.getItem(id); + if (!item) + return; + + bool is_editable = gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID()) + && item->getPermissions().allowModifyBy(gAgent.getID()); + mLandmarkInfo->setCanEdit(is_editable); + + setItem(item); + } + else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE) + { + if (key.has("id")) + { + LLUUID parcel_id = key["id"].asUUID(); + mPlaceProfile->setParcelID(parcel_id); + + // query the server to get the global 3D position of this + // parcel - we need this for teleport/mapping functions. + mRemoteParcelObserver->setParcelID(parcel_id); + } + else + { + mPosGlobal = LLVector3d(key["x"].asReal(), + key["y"].asReal(), + key["z"].asReal()); + mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal); + } + + mPlaceProfile->setInfoType(LLPanelPlaceInfo::PLACE); + } + else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) + { + S32 index = key["id"].asInteger(); + + const LLTeleportHistoryStorage::slurl_list_t& hist_items = + LLTeleportHistoryStorage::getInstance()->getItems(); + + mPosGlobal = hist_items[index].mGlobalPos; + + mPlaceProfile->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY); + mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal); + } + + updateVerbs(); + } + } + + LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); + if (!parcel_mgr) + return; + + mParcelLocalId = parcel_mgr->getAgentParcel()->getLocalID(); + + // Start using LLViewerParcelMgr for land selection if + // information about nearby land is requested. + // Otherwise stop using land selection and deselect land. + if (mPlaceInfoType == AGENT_INFO_TYPE) + { + // We don't know if we are already added to LLViewerParcelMgr observers list + // so try to remove observer not to add an extra one. + parcel_mgr->removeObserver(mParcelObserver); + + parcel_mgr->addObserver(mParcelObserver); + parcel_mgr->selectParcelAt(gAgent.getPositionGlobal()); + } + else + { + parcel_mgr->removeObserver(mParcelObserver); + + // Clear the reference to selection to allow its removal in deselectUnused(). + mParcel.clear(); + + if (!parcel_mgr->selectionEmpty()) + { + parcel_mgr->deselectUnused(); + } + } +} + +void LLPanelPlaces::setItem(LLInventoryItem* item) +{ + if (!mLandmarkInfo || !item) + return; + + mItem = item; + + LLAssetType::EType item_type = mItem->getActualType(); + if (item_type == LLAssetType::AT_LANDMARK || item_type == LLAssetType::AT_LINK) + { + // If the item is a link get a linked item + if (item_type == LLAssetType::AT_LINK) + { + mItem = gInventory.getItem(mItem->getLinkedUUID()); + if (mItem.isNull()) + return; + } + } + else + { + return; + } + + // Check if item is in agent's inventory and he has the permission to modify it. + bool is_landmark_editable = gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.getRootFolderID()) && + mItem->getPermissions().allowModifyBy(gAgent.getID()); + + mSaveBtn->setEnabled(is_landmark_editable); + + if (is_landmark_editable) + { + if(!mLandmarkInfo->setLandmarkFolder(mItem->getParentUUID()) && !mItem->getParentUUID().isNull()) + { + const LLViewerInventoryCategory* cat = gInventory.getCategory(mItem->getParentUUID()); + if (cat) + { + std::string cat_fullname = LLPanelLandmarkInfo::getFullFolderName(cat); + LLComboBox* folderList = mLandmarkInfo->getChild("folder_combo"); + folderList->add(cat_fullname, cat->getUUID(), ADD_TOP); + } + } + } + + mLandmarkInfo->displayItemInfo(mItem); + + LLLandmark* lm = gLandmarkList.getAsset(mItem->getAssetUUID(), + boost::bind(&LLPanelPlaces::onLandmarkLoaded, this, _1)); + if (lm) + { + onLandmarkLoaded(lm); + } +} + +S32 LLPanelPlaces::notifyParent(const LLSD& info) +{ + if(info.has("update_verbs")) + { + if(mPosGlobal.isExactlyZero()) + { + mPosGlobal.setVec(info["global_x"], info["global_y"], info["global_z"]); + } + + updateVerbs(); + + return 1; + } + return LLPanel::notifyParent(info); +} + +void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark) +{ + if (!mLandmarkInfo) + return; + + LLUUID region_id; + landmark->getRegionID(region_id); + landmark->getGlobalPos(mPosGlobal); + mLandmarkInfo->displayParcelInfo(region_id, mPosGlobal); + + updateVerbs(); +} + +void LLPanelPlaces::onFilterEdit(const std::string& search_string, bool force_filter) +{ + if (!mActivePanel) + return; + + if (force_filter || mActivePanel->getFilterSubString() != search_string) + { + std::string string = search_string; + + // Searches are case-insensitive + // but we don't convert the typed string to upper-case so that it can be fed to the web search as-is. + + mActivePanel->onSearchEdit(string); + } +} + +void LLPanelPlaces::onTabSelected() +{ + mActivePanel = dynamic_cast(mTabContainer->getCurrentPanel()); + if (!mActivePanel) + return; + + onFilterEdit(mActivePanel->getFilterSubString(), true); + mActivePanel->updateVerbs(); + + // History panel does not support deletion nor creation + // Hide menus + bool supports_create = mActivePanel->getCreateMenu() != NULL; + childSetVisible("add_btn_panel", supports_create); + + // favorites and inventory can remove items, history can clear history + childSetVisible("trash_btn_panel", true); + + if (supports_create) + { + mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_items")); + } + else + { + mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_history")); + } +} + +void LLPanelPlaces::onTeleportButtonClicked() +{ + LLPanelPlaceInfo* panel = getCurrentInfoPanel(); + if (panel && panel->getVisible()) + { + if (mPlaceInfoType == LANDMARK_INFO_TYPE) + { + if (mItem.isNull()) + { + LL_WARNS() << "NULL landmark item" << LL_ENDL; + llassert(mItem.notNull()); + return; + } + + LLSD payload; + payload["asset_id"] = mItem->getAssetUUID(); + LLSD args; + args["LOCATION"] = mItem->getName(); + LLNotificationsUtil::add("TeleportFromLandmark", args, payload); + } + else if (mPlaceInfoType == AGENT_INFO_TYPE || + mPlaceInfoType == REMOTE_PLACE_INFO_TYPE || + mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) + { + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if (!mPosGlobal.isExactlyZero() && worldmap_instance) + { + gAgent.teleportViaLocation(mPosGlobal); + worldmap_instance->trackLocation(mPosGlobal); + } + } + } + else + { + if (mActivePanel) + mActivePanel->onTeleport(); + } +} + +void LLPanelPlaces::onShowOnMapButtonClicked() +{ + LLPanelPlaceInfo* panel = getCurrentInfoPanel(); + if (panel && panel->getVisible()) + { + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if(!worldmap_instance) + return; + + if (mPlaceInfoType == AGENT_INFO_TYPE || + mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE || + mPlaceInfoType == REMOTE_PLACE_INFO_TYPE || + mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) + { + if (!mPosGlobal.isExactlyZero()) + { + worldmap_instance->trackLocation(mPosGlobal); + LLFloaterReg::showInstance("world_map", "center"); + } + } + else if (mPlaceInfoType == LANDMARK_INFO_TYPE) + { + if (mItem.isNull()) + { + LL_WARNS() << "NULL landmark item" << LL_ENDL; + llassert(mItem.notNull()); + return; + } + LLLandmark* landmark = gLandmarkList.getAsset(mItem->getAssetUUID()); + if (!landmark) + return; + + LLVector3d landmark_global_pos; + if (!landmark->getGlobalPos(landmark_global_pos)) + return; + + if (!landmark_global_pos.isExactlyZero()) + { + worldmap_instance->trackLocation(landmark_global_pos); + LLFloaterReg::showInstance("world_map", "center"); + } + } + } + else + { + if (mActivePanel && mActivePanel->isSingleItemSelected()) + { + mActivePanel->onShowOnMap(); + } + else + { + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + LLVector3d global_pos = gAgent.getPositionGlobal(); + + if (!global_pos.isExactlyZero() && worldmap_instance) + { + worldmap_instance->trackLocation(global_pos); + LLFloaterReg::showInstance("world_map", "center"); + } + } + } +} + +void LLPanelPlaces::onEditButtonClicked() +{ + if (!mLandmarkInfo || isLandmarkEditModeOn) + return; + + isLandmarkEditModeOn = true; + + mLandmarkInfo->toggleLandmarkEditMode(true); + + updateVerbs(); +} + +void LLPanelPlaces::onSaveButtonClicked() +{ + if (!mLandmarkInfo || mItem.isNull()) + return; + + std::string current_title_value = mLandmarkInfo->getLandmarkTitle(); + std::string item_title_value = mItem->getName(); + std::string current_notes_value = mLandmarkInfo->getLandmarkNotes(); + std::string item_notes_value = mItem->getDescription(); + + LLStringUtil::trim(current_title_value); + LLStringUtil::trim(current_notes_value); + + LLUUID folder_id = mLandmarkInfo->getLandmarkFolder(); + bool change_parent = folder_id != mItem->getParentUUID(); + + LLPointer new_item = new LLViewerInventoryItem(mItem); + + if (!current_title_value.empty() && + (item_title_value != current_title_value || item_notes_value != current_notes_value)) + { + new_item->rename(current_title_value); + new_item->setDescription(current_notes_value); + LLPointer cb; + if (change_parent) + { + cb = new LLUpdateLandmarkParent(new_item, folder_id); + } + LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0); + gInventory.accountForUpdate(up); + update_inventory_item(new_item, cb); + } + else if (change_parent) + { + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(),-1); + update.push_back(old_folder); + LLInventoryModel::LLCategoryUpdate new_folder(folder_id, 1); + update.push_back(new_folder); + gInventory.accountForUpdate(update); + + new_item->setParent(folder_id); + new_item->updateParentOnServer(false); + } + + gInventory.updateItem(new_item); + gInventory.notifyObservers(); + + onCancelButtonClicked(); +} + +void LLPanelPlaces::onCancelButtonClicked() +{ + if (!mLandmarkInfo) + return; + + if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE) + { + onBackButtonClicked(); + } + else + { + mLandmarkInfo->toggleLandmarkEditMode(false); + isLandmarkEditModeOn = false; + + updateVerbs(); + + // Reload the landmark properties. + mLandmarkInfo->displayItemInfo(mItem); + } +} + +void LLPanelPlaces::onOverflowButtonClicked() +{ + LLToggleableMenu* menu; + + bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE; + + if ((is_agent_place_info_visible || + mPlaceInfoType == REMOTE_PLACE_INFO_TYPE || + mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) && mPlaceMenu != NULL) + { + menu = mPlaceMenu; + + bool landmark_item_enabled = false; + LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); + if (is_agent_place_info_visible + && gAgent.getRegion() + && mRegionId == gAgent.getRegion()->getRegionID() + && parcel_mgr + && parcel_mgr->getAgentParcel()->getLocalID() == mParcelLocalId) + { + // Floater still shows location identical to agent's position + landmark_item_enabled = !LLLandmarkActions::landmarkAlreadyExists(); + } + + // Enable adding a landmark only for agent current parcel and if + // there is no landmark already pointing to that parcel in agent's inventory. + menu->getChild("landmark")->setEnabled(landmark_item_enabled); + // STORM-411 + // Creating landmarks for remote locations is impossible. + // So hide menu item "Make a Landmark" in "Teleport History Profile" panel. + menu->setItemVisible("landmark", mPlaceInfoType != TELEPORT_HISTORY_INFO_TYPE); + menu->arrangeAndClear(); + } + else if (mPlaceInfoType == LANDMARK_INFO_TYPE && mLandmarkMenu != NULL) + { + menu = mLandmarkMenu; + + bool is_landmark_removable = false; + if (mItem.notNull()) + { + const LLUUID& item_id = mItem->getUUID(); + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + is_landmark_removable = gInventory.isObjectDescendentOf(item_id, gInventory.getRootFolderID()) && + !gInventory.isObjectDescendentOf(item_id, trash_id); + } + + menu->getChild("delete")->setEnabled(is_landmark_removable); + } + else + { + return; + } + + mOverflowBtn->setMenu(menu, LLMenuButton::MP_TOP_RIGHT); +} + +bool LLPanelPlaces::onOverflowMenuItemEnable(const LLSD& param) +{ + std::string value = param.asString(); + if("can_create_pick" == value) + { + return !LLAgentPicksInfo::getInstance()->isPickLimitReached(); + } + return true; +} + +void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param) +{ + std::string item = param.asString(); + if (item == "landmark") + { + LLSD key; + key["type"] = CREATE_LANDMARK_INFO_TYPE; + key["x"] = mPosGlobal.mdV[VX]; + key["y"] = mPosGlobal.mdV[VY]; + key["z"] = mPosGlobal.mdV[VZ]; + onOpen(key); + } + else if (item == "copy") + { + LLLandmarkActions::getSLURLfromPosGlobal(mPosGlobal, boost::bind(&onSLURLBuilt, _1)); + } + else if (item == "delete") + { + gInventory.removeItem(mItem->getUUID()); + + onBackButtonClicked(); + } + else if (item == "pick") + { + LLPanelPlaceInfo* panel = getCurrentInfoPanel(); + if (panel) + { + panel->createPick(mPosGlobal); + } + } + else if (item == "add_to_favbar") + { + if ( mItem.notNull() ) + { + const LLUUID& favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); + if ( favorites_id.notNull() ) + { + copy_inventory_item(gAgent.getID(), + mItem->getPermissions().getOwner(), + mItem->getUUID(), + favorites_id, + std::string(), + LLPointer(NULL)); + LL_INFOS() << "Copied inventory item #" << mItem->getUUID() << " to favorites." << LL_ENDL; + } + } + } +} + +void LLPanelPlaces::onBackButtonClicked() +{ + togglePlaceInfoPanel(false); + + // Resetting mPlaceInfoType when Place Info panel is closed. + mPlaceInfoType = LLStringUtil::null; + + isLandmarkEditModeOn = false; + + updateVerbs(); +} + +void LLPanelPlaces::onGearMenuClick() +{ + if (mActivePanel) + { + LLToggleableMenu* menu = mActivePanel->getSelectionMenu(); + mGearMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT); + } +} + +void LLPanelPlaces::onSortingMenuClick() +{ + if (mActivePanel) + { + LLToggleableMenu* menu = mActivePanel->getSortingMenu(); + mSortingMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT); + } +} + +void LLPanelPlaces::onAddMenuClick() +{ + if (mActivePanel) + { + LLToggleableMenu* menu = mActivePanel->getCreateMenu(); + mAddMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT); + } +} + +void LLPanelPlaces::onRemoveButtonClicked() +{ + if (mActivePanel) + { + mActivePanel->onRemoveSelected(); + } +} + +bool LLPanelPlaces::handleDragAndDropToTrash(bool drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) +{ + if (mActivePanel) + { + return mActivePanel->handleDragAndDropToTrash(drop, cargo_type, cargo_data, accept); + } + return false; +} + +void LLPanelPlaces::togglePlaceInfoPanel(bool visible) +{ + if (!mPlaceProfile || !mLandmarkInfo) + return; + + mTabContainer->setVisible(!visible); + mButtonsContainer->setVisible(visible); + mFilterContainer->setVisible(!visible); + + if (mPlaceInfoType == AGENT_INFO_TYPE || + mPlaceInfoType == REMOTE_PLACE_INFO_TYPE || + mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) + { + mPlaceProfile->setVisible(visible); + + if (visible) + { + mPlaceProfile->resetLocation(); + + // Do not reset location info until mResetInfoTimer has expired + // to avoid text blinking. + mResetInfoTimer.setTimerExpirySec(PLACE_INFO_UPDATE_INTERVAL); + + mLandmarkInfo->setVisible(false); + } + else if (mPlaceInfoType == AGENT_INFO_TYPE) + { + LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver); + + // Clear reference to parcel selection when closing place profile panel. + // LLViewerParcelMgr removes the selection if it has 1 reference to it. + mParcel.clear(); + } + } + else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE || + mPlaceInfoType == LANDMARK_INFO_TYPE || + mPlaceInfoType == LANDMARK_TAB_INFO_TYPE) + { + mLandmarkInfo->setVisible(visible); + mPlaceProfile->setVisible(false); + if (visible) + { + mLandmarkInfo->resetLocation(); + } + else + { + std::string tab_panel_name("Landmarks"); + if (mItem.notNull()) + { + if (gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE))) + { + tab_panel_name = "Favorites"; + } + } + + LLLandmarksPanel* landmarks_panel = dynamic_cast(mTabContainer->getPanelByName(tab_panel_name)); + if (landmarks_panel) + { + // If a landmark info is being closed we open the landmarks tab + // and set this landmark selected. + mTabContainer->selectTabPanel(landmarks_panel); + if (mItem.notNull()) + { + landmarks_panel->setItemSelected(mItem->getUUID(), true); + } + else + { + landmarks_panel->resetSelection(); + } + } + } + } +} + +// virtual +void LLPanelPlaces::onVisibilityChange(bool new_visibility) +{ + LLPanel::onVisibilityChange(new_visibility); + + if (!new_visibility && mPlaceInfoType == AGENT_INFO_TYPE) + { + LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver); + + // Clear reference to parcel selection when closing places panel. + mParcel.clear(); + } +} + +void LLPanelPlaces::changedParcelSelection() +{ + if (!mPlaceProfile) + return; + + LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); + mParcel = parcel_mgr->getFloatingParcelSelection(); + LLParcel* parcel = mParcel->getParcel(); + LLViewerRegion* region = parcel_mgr->getSelectionRegion(); + if (!region || !parcel) + return; + + LLVector3d prev_pos_global = mPosGlobal; + + // If agent is inside the selected parcel show agent's region, + // otherwise show region of agent's selection point. + bool is_current_parcel = is_agent_in_selected_parcel(parcel); + if (is_current_parcel) + { + mPosGlobal = gAgent.getPositionGlobal(); + } + else + { + LLVector3d pos_global = gViewerWindow->getLastPick().mPosGlobal; + if (!pos_global.isExactlyZero()) + { + mPosGlobal = pos_global; + } + } + + // Reset location info only if global position has changed + // and update timer has expired to reduce unnecessary text and icons updates. + if (prev_pos_global != mPosGlobal && mResetInfoTimer.hasExpired()) + { + mPlaceProfile->resetLocation(); + mResetInfoTimer.setTimerExpirySec(PLACE_INFO_UPDATE_INTERVAL); + } + + mPlaceProfile->displaySelectedParcelInfo(parcel, region, mPosGlobal, is_current_parcel); + + updateVerbs(); +} + +void LLPanelPlaces::createTabs() +{ + if (!(gInventory.isInventoryUsable() && LLTeleportHistory::getInstance() && !mTabsCreated)) + return; + + LLFavoritesPanel* favorites_panel = new LLFavoritesPanel(); + if (favorites_panel) + { + mTabContainer->addTabPanel( + LLTabContainer::TabPanelParams(). + panel(favorites_panel). + label(getString("favorites_tab_title")). + insert_at(LLTabContainer::END)); + } + + LLLandmarksPanel* landmarks_panel = new LLLandmarksPanel(); + if (landmarks_panel) + { + mTabContainer->addTabPanel( + LLTabContainer::TabPanelParams(). + panel(landmarks_panel). + label(getString("landmarks_tab_title")). + insert_at(LLTabContainer::END)); + } + + LLTeleportHistoryPanel* teleport_history_panel = new LLTeleportHistoryPanel(); + if (teleport_history_panel) + { + mTabContainer->addTabPanel( + LLTabContainer::TabPanelParams(). + panel(teleport_history_panel). + label(getString("teleport_history_tab_title")). + insert_at(LLTabContainer::END)); + } + + mTabContainer->selectFirstTab(); + + mActivePanel = dynamic_cast(mTabContainer->getCurrentPanel()); + + if (mActivePanel) + { + // Filter applied to show all items. + mActivePanel->onSearchEdit(mActivePanel->getFilterSubString()); + + // History panel does not support deletion nor creation + // Hide menus + bool supports_create = mActivePanel->getCreateMenu() != NULL; + childSetVisible("add_btn_panel", supports_create); + + // favorites and inventory can remove items, history can clear history + childSetVisible("trash_btn_panel", true); + + if (supports_create) + { + mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_items")); + } + else + { + mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_history")); + } + + mActivePanel->setRemoveBtn(mRemoveSelectedBtn); + mActivePanel->updateVerbs(); + } + + mTabsCreated = true; +} + +void LLPanelPlaces::changedGlobalPos(const LLVector3d &global_pos) +{ + mPosGlobal = global_pos; + updateVerbs(); +} + +void LLPanelPlaces::showAddedLandmarkInfo(const uuid_set_t& items) +{ + for (uuid_set_t::const_iterator item_iter = items.begin(); + item_iter != items.end(); + ++item_iter) + { + const LLUUID& item_id = (*item_iter); + if(!highlight_offered_object(item_id)) + { + continue; + } + + LLInventoryItem* item = gInventory.getItem(item_id); + + llassert(item); + if (item && (LLAssetType::AT_LANDMARK == item->getType()) ) + { + // Created landmark is passed to Places panel to allow its editing. + // If the panel is closed we don't reopen it until created landmark is loaded. + if("create_landmark" == getPlaceInfoType() && !getItem()) + { + setItem(item); + } + } + } +} + +void LLPanelPlaces::updateVerbs() +{ + bool is_place_info_visible; + + LLPanelPlaceInfo* panel = getCurrentInfoPanel(); + if (panel) + { + is_place_info_visible = panel->getVisible(); + } + else + { + is_place_info_visible = false; + } + + bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE; + bool is_create_landmark_visible = mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE; + + bool have_3d_pos = ! mPosGlobal.isExactlyZero(); + + mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn); + mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn); + mSaveBtn->setVisible(isLandmarkEditModeOn); + mCancelBtn->setVisible(isLandmarkEditModeOn); + mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn); + + bool show_options_btn = is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn; + mOverflowBtn->setVisible(show_options_btn); + getChild("lp_options")->setVisible(show_options_btn); + getChild("lp2")->setVisible(!show_options_btn); + + if (is_place_info_visible) + { + mShowOnMapBtn->setEnabled(have_3d_pos); + + if (is_agent_place_info_visible) + { + // We don't need to teleport to the current location + // so check if the location is not within the current parcel. + mTeleportBtn->setEnabled(have_3d_pos && + !LLViewerParcelMgr::getInstance()->inAgentParcel(mPosGlobal)); + } + else if (mPlaceInfoType == LANDMARK_INFO_TYPE || mPlaceInfoType == REMOTE_PLACE_INFO_TYPE) + { + mTeleportBtn->setEnabled(have_3d_pos); + } + } + else + { + if (mActivePanel) + mActivePanel->updateVerbs(); + } +} + +LLPanelPlaceInfo* LLPanelPlaces::getCurrentInfoPanel() +{ + if (mPlaceInfoType == AGENT_INFO_TYPE || + mPlaceInfoType == REMOTE_PLACE_INFO_TYPE || + mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) + { + return mPlaceProfile; + } + else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE || + mPlaceInfoType == LANDMARK_INFO_TYPE || + mPlaceInfoType == LANDMARK_TAB_INFO_TYPE) + { + return mLandmarkInfo; + } + + return NULL; +} + +static bool is_agent_in_selected_parcel(LLParcel* parcel) +{ + LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); + + LLViewerRegion* region = parcel_mgr->getSelectionRegion(); + if (!region || !parcel) + return false; + + return region == gAgent.getRegion() && + parcel->getLocalID() == parcel_mgr->getAgentParcel()->getLocalID(); +} + +static void onSLURLBuilt(std::string& slurl) +{ + LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(slurl)); + + LLSD args; + args["SLURL"] = slurl; + + LLNotificationsUtil::add("CopySLURL", args); +} -- cgit v1.2.3