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.cpp319
1 files changed, 216 insertions, 103 deletions
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index b037674c37..51a11e97e4 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -34,7 +34,7 @@
#include "llpanelplaces.h"
#include "llassettype.h"
-#include "llwindow.h"
+#include "lltimer.h"
#include "llinventory.h"
#include "lllandmark.h"
@@ -49,6 +49,8 @@
#include "lltrans.h"
#include "lluictrlfactory.h"
+#include "llwindow.h"
+
#include "llagent.h"
#include "llagentpicksinfo.h"
#include "llavatarpropertiesprocessor.h"
@@ -68,11 +70,13 @@
#include "lltoggleablemenu.h"
#include "llviewerinventory.h"
#include "llviewermenu.h"
+#include "llviewermessage.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"
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";
@@ -102,22 +106,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 +252,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 +281,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 +294,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);
@@ -289,89 +314,95 @@ BOOL LLPanelPlaces::postBuild()
void LLPanelPlaces::onOpen(const LLSD& key)
{
- if(!mPlaceProfile || !mLandmarkInfo || key.size() == 0)
+ if (!mPlaceProfile || !mLandmarkInfo)
return;
- mFilterEditor->clear();
- onFilterEdit("", false);
-
- mPlaceInfoType = key["type"].asString();
- mPosGlobal.setZero();
- mItem = NULL;
- isLandmarkEditModeOn = false;
- togglePlaceInfoPanel(TRUE);
-
- if (mPlaceInfoType == AGENT_INFO_TYPE)
- {
- mPlaceProfile->setInfoType(LLPanelPlaceInfo::AGENT);
- }
- else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
+ if (key.size() != 0)
{
- mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK);
+ mFilterEditor->clear();
+ onFilterEdit("", false);
- if (key.has("x") && key.has("y") && key.has("z"))
+ mPlaceInfoType = key["type"].asString();
+ mPosGlobal.setZero();
+ mItem = NULL;
+ isLandmarkEditModeOn = false;
+ togglePlaceInfoPanel(TRUE);
+
+ if (mPlaceInfoType == AGENT_INFO_TYPE)
{
- mPosGlobal = LLVector3d(key["x"].asReal(),
- key["y"].asReal(),
- key["z"].asReal());
+ mPlaceProfile->setInfoType(LLPanelPlaceInfo::AGENT);
}
- else
+ else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
{
- mPosGlobal = gAgent.getPositionGlobal();
- }
-
- mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal);
+ mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK);
- // Disable Save button because there is no item to save yet.
- // The button will be enabled in onLandmarkLoaded callback.
- mSaveBtn->setEnabled(FALSE);
- }
- else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
- {
- mLandmarkInfo->setInfoType(LLPanelPlaceInfo::LANDMARK);
+ 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();
+ }
- LLInventoryItem* item = gInventory.getItem(key["id"].asUUID());
- if (!item)
- return;
+ mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal);
- setItem(item);
- }
- else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
- {
- if (key.has("id"))
+ // 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)
{
- LLUUID parcel_id = key["id"].asUUID();
- mPlaceProfile->setParcelID(parcel_id);
+ mLandmarkInfo->setInfoType(LLPanelPlaceInfo::LANDMARK);
- // query the server to get the global 3D position of this
- // parcel - we need this for teleport/mapping functions.
- mRemoteParcelObserver->setParcelID(parcel_id);
+ LLInventoryItem* item = gInventory.getItem(key["id"].asUUID());
+ if (!item)
+ return;
+
+ setItem(item);
}
- else
+ else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
{
- mPosGlobal = LLVector3d(key["x"].asReal(),
- key["y"].asReal(),
- key["z"].asReal());
- mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
+ 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();
- 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();
- const LLTeleportHistoryStorage::slurl_list_t& hist_items =
- LLTeleportHistoryStorage::getInstance()->getItems();
+ mPosGlobal = hist_items[index].mGlobalPos;
- mPosGlobal = hist_items[index].mGlobalPos;
+ mPlaceProfile->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
+ mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
+ }
- mPlaceProfile->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
- mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
+ updateVerbs();
}
- updateVerbs();
-
LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
if (!parcel_mgr)
return;
@@ -381,6 +412,10 @@ void LLPanelPlaces::onOpen(const LLSD& key)
// 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());
}
@@ -388,9 +423,12 @@ void LLPanelPlaces::onOpen(const LLSD& key)
{
parcel_mgr->removeObserver(mParcelObserver);
+ // Clear the reference to selection to allow its removal in deselectUnused().
+ mParcel.clear();
+
if (!parcel_mgr->selectionEmpty())
{
- parcel_mgr->deselectLand();
+ parcel_mgr->deselectUnused();
}
}
}
@@ -424,6 +462,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)
{
@@ -475,8 +515,6 @@ void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark)
landmark->getGlobalPos(mPosGlobal);
mLandmarkInfo->displayParcelInfo(region_id, mPosGlobal);
- mSaveBtn->setEnabled(TRUE);
-
updateVerbs();
}
@@ -490,8 +528,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);
}
@@ -516,7 +553,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 ||
@@ -708,6 +747,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();
@@ -765,23 +812,23 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
mPickPanel->reshape(rect.getWidth(), rect.getHeight());
mPickPanel->setRect(rect);
}
- 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));
- llinfos << "Copied inventory item #" << mItem->getUUID() << " to favorites." << llendl;
- }
- }
- }
+ 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));
+ llinfos << "Copied inventory item #" << mItem->getUUID() << " to favorites." << llendl;
+ }
+ }
+ }
}
void LLPanelPlaces::onBackButtonClicked()
@@ -820,12 +867,24 @@ 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());
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)
@@ -858,6 +917,20 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
}
}
+// virtual
+void LLPanelPlaces::handleVisibilityChange(BOOL new_visibility)
+{
+ LLPanel::handleVisibilityChange(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)
@@ -870,6 +943,8 @@ void LLPanelPlaces::changedParcelSelection()
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);
@@ -886,13 +961,20 @@ void LLPanelPlaces::changedParcelSelection()
}
}
- mPlaceProfile->resetLocation();
+ // 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::changedInventory(U32 mask)
+void LLPanelPlaces::createTabs()
{
if (!(gInventory.isInventoryUsable() && LLTeleportHistory::getInstance()))
return;
@@ -928,10 +1010,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)
@@ -940,6 +1018,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_item(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;
@@ -960,14 +1065,15 @@ 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)
{
@@ -982,6 +1088,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
{