diff options
Diffstat (limited to 'indra/newview/llpanelplaces.cpp')
| -rw-r--r-- | indra/newview/llpanelplaces.cpp | 2716 | 
1 files changed, 1358 insertions, 1358 deletions
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 2abbcc0c12..6baa223389 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<LLUUID>::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<LLUUID>	mParcelIDs; -	LLPanelPlaces*		mPlaces; -}; - - -static LLPanelInjector<LLPanelPlaces> 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<LLButton>("teleport_btn"); -	mTeleportBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onTeleportButtonClicked, this)); -	 -	mShowOnMapBtn = getChild<LLButton>("map_btn"); -	mShowOnMapBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShowOnMapButtonClicked, this)); - -	mSaveBtn = getChild<LLButton>("save_btn"); -	mSaveBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onSaveButtonClicked, this)); - -	mCancelBtn = getChild<LLButton>("cancel_btn"); -	mCancelBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onCancelButtonClicked, this)); - -	mCloseBtn = getChild<LLButton>("close_btn"); -	mCloseBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); - -	mOverflowBtn = getChild<LLMenuButton>("overflow_btn"); -	mOverflowBtn->setMouseDownCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this)); - -    mGearMenuButton = getChild<LLMenuButton>("options_gear_btn"); -    mGearMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onGearMenuClick, this)); - -    mSortingMenuButton = getChild<LLMenuButton>("sorting_menu_btn"); -    mSortingMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onSortingMenuClick, this)); - -    mAddMenuButton = getChild<LLMenuButton>("add_menu_btn"); -    mAddMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onAddMenuClick, this)); - -    mRemoveSelectedBtn = getChild<LLButton>("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<LLToggleableMenu>("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<LLToggleableMenu>("menu_landmark.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -	if (!mLandmarkMenu) -	{ -		LL_WARNS() << "Error loading Landmark menu" << LL_ENDL; -	} - -	mTabContainer = getChild<LLTabContainer>("Places Tabs"); -	if (mTabContainer) -	{ -		mTabContainer->setCommitCallback(boost::bind(&LLPanelPlaces::onTabSelected, this)); -	} - -    mButtonsContainer = getChild<LLPanel>("button_layout_panel"); -    mButtonsContainer->setVisible(false); -    mFilterContainer = getChild<LLLayoutStack>("top_menu_panel"); - -	mFilterEditor = getChild<LLFilterEditor>("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<LLPanelPlaceProfile>("panel_place_profile"); -	mLandmarkInfo = findChild<LLPanelLandmarkInfo>("panel_landmark_info"); -	if (!mPlaceProfile || !mLandmarkInfo) -		return false; - -	mPlaceProfileBackBtn = mPlaceProfile->getChild<LLButton>("back_btn"); -	mPlaceProfileBackBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); - -	mLandmarkInfo->getChild<LLButton>("back_btn")->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); - -	LLLineEditor* title_editor = mLandmarkInfo->getChild<LLLineEditor>("title_editor"); -	title_editor->setKeystrokeCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this), NULL); - -	LLTextEditor* notes_editor = mLandmarkInfo->getChild<LLTextEditor>("notes_editor"); -	notes_editor->setKeystrokeCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this)); - -	LLComboBox* folder_combo = mLandmarkInfo->getChild<LLComboBox>("folder_combo"); -	folder_combo->setCommitCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this)); - -	LLButton* edit_btn = mLandmarkInfo->getChild<LLButton>("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<LLLandmarksPanel*>(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<LLComboBox>("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<LLPanelPlacesTab*>(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<LLViewerInventoryItem> 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<LLInventoryCallback> 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<LLMenuItemCallGL>("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<LLMenuItemCallGL>("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<LLInventoryCallback>(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<LLLandmarksPanel*>(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<X, Y, Z>, -	// otherwise show region<X, Y, Z> 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<LLPanelPlacesTab*>(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<LLLayoutPanel>("lp_options")->setVisible(show_options_btn); -	getChild<LLLayoutPanel>("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<LLUUID>::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<LLUUID>    mParcelIDs;
 +    LLPanelPlaces*      mPlaces;
 +};
 +
 +
 +static LLPanelInjector<LLPanelPlaces> 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<LLButton>("teleport_btn");
 +    mTeleportBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onTeleportButtonClicked, this));
 +
 +    mShowOnMapBtn = getChild<LLButton>("map_btn");
 +    mShowOnMapBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShowOnMapButtonClicked, this));
 +
 +    mSaveBtn = getChild<LLButton>("save_btn");
 +    mSaveBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onSaveButtonClicked, this));
 +
 +    mCancelBtn = getChild<LLButton>("cancel_btn");
 +    mCancelBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onCancelButtonClicked, this));
 +
 +    mCloseBtn = getChild<LLButton>("close_btn");
 +    mCloseBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this));
 +
 +    mOverflowBtn = getChild<LLMenuButton>("overflow_btn");
 +    mOverflowBtn->setMouseDownCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this));
 +
 +    mGearMenuButton = getChild<LLMenuButton>("options_gear_btn");
 +    mGearMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onGearMenuClick, this));
 +
 +    mSortingMenuButton = getChild<LLMenuButton>("sorting_menu_btn");
 +    mSortingMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onSortingMenuClick, this));
 +
 +    mAddMenuButton = getChild<LLMenuButton>("add_menu_btn");
 +    mAddMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onAddMenuClick, this));
 +
 +    mRemoveSelectedBtn = getChild<LLButton>("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<LLToggleableMenu>("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<LLToggleableMenu>("menu_landmark.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
 +    if (!mLandmarkMenu)
 +    {
 +        LL_WARNS() << "Error loading Landmark menu" << LL_ENDL;
 +    }
 +
 +    mTabContainer = getChild<LLTabContainer>("Places Tabs");
 +    if (mTabContainer)
 +    {
 +        mTabContainer->setCommitCallback(boost::bind(&LLPanelPlaces::onTabSelected, this));
 +    }
 +
 +    mButtonsContainer = getChild<LLPanel>("button_layout_panel");
 +    mButtonsContainer->setVisible(false);
 +    mFilterContainer = getChild<LLLayoutStack>("top_menu_panel");
 +
 +    mFilterEditor = getChild<LLFilterEditor>("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<LLPanelPlaceProfile>("panel_place_profile");
 +    mLandmarkInfo = findChild<LLPanelLandmarkInfo>("panel_landmark_info");
 +    if (!mPlaceProfile || !mLandmarkInfo)
 +        return false;
 +
 +    mPlaceProfileBackBtn = mPlaceProfile->getChild<LLButton>("back_btn");
 +    mPlaceProfileBackBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this));
 +
 +    mLandmarkInfo->getChild<LLButton>("back_btn")->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this));
 +
 +    LLLineEditor* title_editor = mLandmarkInfo->getChild<LLLineEditor>("title_editor");
 +    title_editor->setKeystrokeCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this), NULL);
 +
 +    LLTextEditor* notes_editor = mLandmarkInfo->getChild<LLTextEditor>("notes_editor");
 +    notes_editor->setKeystrokeCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this));
 +
 +    LLComboBox* folder_combo = mLandmarkInfo->getChild<LLComboBox>("folder_combo");
 +    folder_combo->setCommitCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this));
 +
 +    LLButton* edit_btn = mLandmarkInfo->getChild<LLButton>("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<LLLandmarksPanel*>(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<LLComboBox>("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<LLPanelPlacesTab*>(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<LLViewerInventoryItem> 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<LLInventoryCallback> 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<LLMenuItemCallGL>("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<LLMenuItemCallGL>("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<LLInventoryCallback>(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<LLLandmarksPanel*>(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<X, Y, Z>,
 +    // otherwise show region<X, Y, Z> 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<LLPanelPlacesTab*>(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<LLLayoutPanel>("lp_options")->setVisible(show_options_btn);
 +    getChild<LLLayoutPanel>("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);
 +}
  | 
