summaryrefslogtreecommitdiff
path: root/indra/newview/llpanelplaces.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llpanelplaces.cpp')
-rw-r--r--indra/newview/llpanelplaces.cpp227
1 files changed, 173 insertions, 54 deletions
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index a8a9717750..5aed1e55e3 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -2,30 +2,25 @@
* @file llpanelplaces.cpp
* @brief Side Bar "Places" panel
*
- * $LicenseInfo:firstyear=2009&license=viewergpl$
- *
- * Copyright (c) 2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * 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$
*/
@@ -34,7 +29,7 @@
#include "llpanelplaces.h"
#include "llassettype.h"
-#include "llwindow.h"
+#include "lltimer.h"
#include "llinventory.h"
#include "lllandmark.h"
@@ -49,9 +44,12 @@
#include "lltrans.h"
#include "lluictrlfactory.h"
+#include "llwindow.h"
+
#include "llagent.h"
#include "llagentpicksinfo.h"
#include "llavatarpropertiesprocessor.h"
+#include "llcommandhandler.h"
#include "llfloaterworldmap.h"
#include "llinventorybridge.h"
#include "llinventoryobserver.h"
@@ -64,21 +62,59 @@
#include "llpanelplaceprofile.h"
#include "llpanelteleporthistory.h"
#include "llremoteparcelrequest.h"
+#include "llsidetray.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 S32 LANDMARK_FOLDERS_MENU_WIDTH = 250;
+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 LANDMARK_INFO_TYPE = "landmark";
static const std::string REMOTE_PLACE_INFO_TYPE = "remote_place";
static const std::string TELEPORT_HISTORY_INFO_TYPE = "teleport_history";
+// 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,
+ LLMediaCtrl* web)
+ {
+ if (params.size() < 2)
+ {
+ return false;
+ }
+ 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;
+ LLSideTray::getInstance()->showPanel("panel_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);
@@ -102,22 +138,35 @@ private:
LLPanelPlaces* mPlaces;
};
-class LLPlacesInventoryObserver : public LLInventoryObserver
+class LLPlacesInventoryObserver : public LLInventoryAddedObserver
{
public:
LLPlacesInventoryObserver(LLPanelPlaces* places_panel) :
- LLInventoryObserver(),
- mPlaces(places_panel)
+ mPlaces(places_panel),
+ mTabsCreated(false)
{}
/*virtual*/ void changed(U32 mask)
{
- if (mPlaces)
- mPlaces->changedInventory(mask);
+ LLInventoryAddedObserver::changed(mask);
+
+ if (!mTabsCreated && mPlaces)
+ {
+ mPlaces->createTabs();
+ mTabsCreated = true;
+ }
+ }
+
+protected:
+ /*virtual*/ void done()
+ {
+ mPlaces->showAddedLandmarkInfo(mAdded);
+ mAdded.clear();
}
private:
LLPanelPlaces* mPlaces;
+ bool mTabsCreated;
};
class LLPlacesRemoteParcelInfoObserver : public LLRemoteParcelInfoObserver
@@ -235,6 +284,9 @@ BOOL LLPanelPlaces::postBuild()
mOverflowBtn = getChild<LLButton>("overflow_btn");
mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this));
+ mPlaceInfoBtn = getChild<LLButton>("profile_btn");
+ mPlaceInfoBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onProfileButtonClicked, this));
+
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("Places.OverflowMenu.Action", boost::bind(&LLPanelPlaces::onOverflowMenuItemClicked, this, _2));
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
@@ -261,6 +313,11 @@ BOOL LLPanelPlaces::postBuild()
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));
}
@@ -269,11 +326,11 @@ BOOL LLPanelPlaces::postBuild()
if (!mPlaceProfile || !mLandmarkInfo)
return FALSE;
- LLButton* back_btn = mPlaceProfile->getChild<LLButton>("back_btn");
- back_btn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this));
+ mPlaceProfileBackBtn = mPlaceProfile->getChild<LLButton>("back_btn");
+ mPlaceProfileBackBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this));
- back_btn = mLandmarkInfo->getChild<LLButton>("back_btn");
- back_btn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this));
+ mLandmarkInfoBackBtn = mLandmarkInfo->getChild<LLButton>("back_btn");
+ mLandmarkInfoBackBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this));
LLLineEditor* title_editor = mLandmarkInfo->getChild<LLLineEditor>("title_editor");
title_editor->setKeystrokeCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this), NULL);
@@ -324,9 +381,12 @@ void LLPanelPlaces::onOpen(const LLSD& key)
mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal);
- // Disable Save button because there is no item to save yet.
- // The button will be enabled in onLandmarkLoaded callback.
+ // Disabling "Save", "Close" and "Back" buttons to prevent closing "Create Landmark"
+ // panel before created landmark is loaded.
+ // These buttons will be enabled when created landmark is added to inventory.
mSaveBtn->setEnabled(FALSE);
+ mCloseBtn->setEnabled(FALSE);
+ mLandmarkInfoBackBtn->setEnabled(FALSE);
}
else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
{
@@ -434,6 +494,8 @@ void LLPanelPlaces::setItem(LLInventoryItem* item)
mEditBtn->setEnabled(is_landmark_editable);
mSaveBtn->setEnabled(is_landmark_editable);
+ mCloseBtn->setEnabled(TRUE);
+ mLandmarkInfoBackBtn->setEnabled(TRUE);
if (is_landmark_editable)
{
@@ -485,8 +547,6 @@ void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark)
landmark->getGlobalPos(mPosGlobal);
mLandmarkInfo->displayParcelInfo(region_id, mPosGlobal);
- mSaveBtn->setEnabled(TRUE);
-
updateVerbs();
}
@@ -500,8 +560,7 @@ void LLPanelPlaces::onFilterEdit(const std::string& search_string, bool force_fi
std::string string = search_string;
// Searches are case-insensitive
- LLStringUtil::toUpper(string);
- LLStringUtil::trimHead(string);
+ // 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);
}
@@ -526,7 +585,9 @@ void LLPanelPlaces::onTeleportButtonClicked()
{
LLSD payload;
payload["asset_id"] = mItem->getAssetUUID();
- LLNotificationsUtil::add("TeleportFromLandmark", LLSD(), payload);
+ LLSD args;
+ args["LOCATION"] = mItem->getName();
+ LLNotificationsUtil::add("TeleportFromLandmark", args, payload);
}
else if (mPlaceInfoType == AGENT_INFO_TYPE ||
mPlaceInfoType == REMOTE_PLACE_INFO_TYPE ||
@@ -586,8 +647,21 @@ void LLPanelPlaces::onShowOnMapButtonClicked()
}
else
{
- if (mActivePanel)
+ 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");
+ }
+ }
}
}
@@ -676,8 +750,8 @@ void LLPanelPlaces::onOverflowButtonClicked()
bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE;
if ((is_agent_place_info_visible ||
- mPlaceInfoType == "remote_place" ||
- mPlaceInfoType == "teleport_history") && mPlaceMenu != NULL)
+ mPlaceInfoType == REMOTE_PLACE_INFO_TYPE ||
+ mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) && mPlaceMenu != NULL)
{
menu = mPlaceMenu;
@@ -718,6 +792,14 @@ void LLPanelPlaces::onOverflowButtonClicked()
LLMenuGL::showPopup(this, menu, rect.mRight, rect.mTop);
}
+void LLPanelPlaces::onProfileButtonClicked()
+{
+ if (!mActivePanel)
+ return;
+
+ mActivePanel->onShowProfile();
+}
+
bool LLPanelPlaces::onOverflowMenuItemEnable(const LLSD& param)
{
std::string value = param.asString();
@@ -830,6 +912,10 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
{
mPlaceProfile->resetLocation();
+ // Do not reset location info until mResetInfoTimer has expired
+ // to avoid text blinking.
+ mResetInfoTimer.setTimerExpirySec(PLACE_INFO_UPDATE_INTERVAL);
+
LLRect rect = getRect();
LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom);
mPlaceProfile->reshape(new_rect.getWidth(), new_rect.getHeight());
@@ -920,11 +1006,12 @@ void LLPanelPlaces::changedParcelSelection()
}
}
- // Reset location info only if global position is changed
- // to reduce unnecessary text and icons updates.
- if (prev_pos_global != mPosGlobal)
+ // 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);
@@ -932,7 +1019,7 @@ void LLPanelPlaces::changedParcelSelection()
updateVerbs();
}
-void LLPanelPlaces::changedInventory(U32 mask)
+void LLPanelPlaces::createTabs()
{
if (!(gInventory.isInventoryUsable() && LLTeleportHistory::getInstance()))
return;
@@ -968,10 +1055,6 @@ void LLPanelPlaces::changedInventory(U32 mask)
// Filter applied to show all items.
if (mActivePanel)
mActivePanel->onSearchEdit(mActivePanel->getFilterSubString());
-
- // we don't need to monitor inventory changes anymore,
- // so remove the observer
- gInventory.removeObserver(mInventoryObserver);
}
void LLPanelPlaces::changedGlobalPos(const LLVector3d &global_pos)
@@ -980,6 +1063,33 @@ void LLPanelPlaces::changedGlobalPos(const LLVector3d &global_pos)
updateVerbs();
}
+void LLPanelPlaces::showAddedLandmarkInfo(const uuid_vec_t& items)
+{
+ for (uuid_vec_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;
@@ -1000,17 +1110,19 @@ void LLPanelPlaces::updateVerbs()
mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
- mOverflowBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
+ mOverflowBtn->setVisible(is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn);
mEditBtn->setVisible(mPlaceInfoType == LANDMARK_INFO_TYPE && !isLandmarkEditModeOn);
mSaveBtn->setVisible(isLandmarkEditModeOn);
mCancelBtn->setVisible(isLandmarkEditModeOn);
mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn);
+ mPlaceInfoBtn->setVisible(!is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn);
- mShowOnMapBtn->setEnabled(!is_create_landmark_visible && !isLandmarkEditModeOn && have_3d_pos);
- mOverflowBtn->setEnabled(is_place_info_visible && !is_create_landmark_visible);
+ mPlaceInfoBtn->setEnabled(!is_create_landmark_visible && !isLandmarkEditModeOn && have_3d_pos);
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
@@ -1022,6 +1134,13 @@ void LLPanelPlaces::updateVerbs()
{
mTeleportBtn->setEnabled(have_3d_pos);
}
+
+ // Do not enable landmark info Back button when we are waiting
+ // for newly created landmark to load.
+ if (!is_create_landmark_visible)
+ {
+ mLandmarkInfoBackBtn->setEnabled(TRUE);
+ }
}
else
{