summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorSteven Bennetts <steve@lindenlab.com>2009-10-07 07:09:34 +0000
committerSteven Bennetts <steve@lindenlab.com>2009-10-07 07:09:34 +0000
commitae0827d387dc1e4d0f8a749cab36138f8ac174a0 (patch)
tree35c9d392f91db7a37f709773ab3d065c41538213 /indra/newview
parentcec9edea1e09e9bae2949b61770a9e4016670427 (diff)
merge https://svn.aws.productengine.com/secondlife/export-from-ll/viewer-2-0@1908 https://svn.aws.productengine.com/secondlife/pe/stable-2@1917 -> viewer-2.0.0-3
* Bugs: EXT-1257 EXT-1299 EXT-1149 EXT-1117 EXT-1134 * New Dev: EXT-721
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llpanelplaceinfo.cpp199
-rw-r--r--indra/newview/llpanelplaceinfo.h15
-rw-r--r--indra/newview/llpanelplaces.cpp437
-rw-r--r--indra/newview/llpanelplaces.h25
-rw-r--r--indra/newview/lltoastalertpanel.cpp1
-rw-r--r--indra/newview/llviewermessage.cpp17
-rw-r--r--indra/newview/skins/default/xui/en/floater_whitelist_entry.xml48
-rw-r--r--indra/newview/skins/default/xui/en/panel_places.xml52
-rw-r--r--indra/newview/skins/default/xui/en/widgets/scroll_list.xml2
9 files changed, 437 insertions, 359 deletions
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index eb269fabe3..d6be0a9419 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -44,14 +44,16 @@
#include "llqueryflags.h"
#include "llbutton.h"
+#include "llcombobox.h"
#include "lliconctrl.h"
-#include "lllineeditor.h"
#include "llscrollcontainer.h"
#include "lltextbox.h"
+#include "lltrans.h"
#include "llaccordionctrl.h"
#include "llaccordionctrltab.h"
#include "llagent.h"
+#include "llagentui.h"
#include "llavatarpropertiesprocessor.h"
#include "llfloaterworldmap.h"
#include "llinventorymodel.h"
@@ -64,6 +66,16 @@
#include "llviewertexteditor.h"
#include "llworldmap.h"
+//----------------------------------------------------------------------------
+// Aux types and methods
+//----------------------------------------------------------------------------
+
+typedef std::pair<LLUUID, std::string> folder_pair_t;
+
+static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right);
+static std::string getFullFolderName(const LLViewerInventoryCategory* cat);
+static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
+
static LLRegisterPanelClassWrapper<LLPanelPlaceInfo> t_place_info("panel_place_info");
LLPanelPlaceInfo::LLPanelPlaceInfo()
@@ -141,11 +153,8 @@ BOOL LLPanelPlaceInfo::postBuild()
mCreated = getChild<LLTextBox>("created");
mTitleEditor = getChild<LLLineEditor>("title_editor");
- mTitleEditor->setCommitCallback(boost::bind(&LLPanelPlaceInfo::onCommitTitleOrNote, this, TITLE));
-
mNotesEditor = getChild<LLTextEditor>("notes_editor");
- mNotesEditor->setCommitCallback(boost::bind(&LLPanelPlaceInfo::onCommitTitleOrNote, this, NOTE));
- mNotesEditor->setCommitOnFocusLost(true);
+ mFolderCombo = getChild<LLComboBox>("folder_combo");
LLScrollContainer* scroll_container = getChild<LLScrollContainer>("scroll_container");
scroll_container->setBorderVisible(FALSE);
@@ -316,6 +325,7 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
LLPanel* landmark_edit_panel = getChild<LLPanel>("landmark_edit_panel");
bool is_info_type_agent = type == AGENT;
+ bool is_info_type_create_landmark = type == CREATE_LANDMARK;
bool is_info_type_landmark = type == LANDMARK;
bool is_info_type_teleport_history = type == TELEPORT_HISTORY;
@@ -329,7 +339,10 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
mLastVisited->setVisible(is_info_type_teleport_history);
landmark_info_panel->setVisible(is_info_type_landmark);
- landmark_edit_panel->setVisible(is_info_type_landmark || type == CREATE_LANDMARK);
+ landmark_edit_panel->setVisible(is_info_type_landmark || is_info_type_create_landmark);
+
+ getChild<LLTextBox>("folder_lable")->setVisible(is_info_type_create_landmark);
+ mFolderCombo->setVisible(is_info_type_create_landmark);
getChild<LLAccordionCtrl>("advanced_info_accordion")->setVisible(is_info_type_agent);
@@ -337,6 +350,11 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
{
case CREATE_LANDMARK:
mCurrentTitle = getString("title_create_landmark");
+
+ mTitleEditor->setEnabled(TRUE);
+ mNotesEditor->setEnabled(TRUE);
+
+ populateFoldersList();
break;
case AGENT:
@@ -351,6 +369,11 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
case LANDMARK:
mCurrentTitle = getString("title_landmark");
+
+ mTitleEditor->setEnabled(FALSE);
+ mNotesEditor->setEnabled(FALSE);
+
+ populateFoldersList();
break;
case TELEPORT_HISTORY:
@@ -485,10 +508,9 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
parcel_data.sim_name.c_str(), region_x, region_y, region_z);
mRegionName->setText(name);
}
-
+
if (mInfoType == CREATE_LANDMARK)
{
-
if (parcel_data.name.empty())
{
mTitleEditor->setText(name);
@@ -498,7 +520,15 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
mTitleEditor->setText(parcel_data.name);
}
- mNotesEditor->setText(LLStringUtil::null);
+ // FIXME: Creating landmark works only for current agent location.
+ std::string desc;
+ LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_FULL, gAgent.getPositionAgent());
+ mNotesEditor->setText(desc);
+
+ if (!LLLandmarkActions::landmarkAlreadyExists())
+ {
+ createLandmark(mFolderCombo->getValue().asUUID());
+ }
}
}
@@ -694,7 +724,6 @@ void LLPanelPlaceInfo::displaySelectedParcelInfo(LLParcel* parcel,
&rent_price,
&for_sale,
&dwell);
-
if (for_sale)
{
// Adding "For Sale" flag in remote parcel response format.
@@ -803,52 +832,42 @@ void LLPanelPlaceInfo::updateLastVisitedText(const LLDate &date)
}
}
-void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type)
+void LLPanelPlaceInfo::toggleLandmarkEditMode(BOOL enabled)
{
- LLInventoryItem* item = gInventory.getItem(mLandmarkID);
- if (!item)
- return;
-
- std::string current_value;
- std::string item_value;
- if (type == TITLE)
+ // If switching to edit mode while creating landmark
+ // the "Create Landmark" title remains.
+ if (enabled && mInfoType != CREATE_LANDMARK)
{
- if (mTitleEditor)
- {
- current_value = mTitleEditor->getText();
- item_value = item->getName();
- }
+ mTitle->setText(getString("title_edit_landmark"));
}
else
{
- if (mNotesEditor)
- {
- current_value = mNotesEditor->getText();
- item_value = item->getDescription();
- }
+ mTitle->setText(mCurrentTitle);
}
- LLStringUtil::trim(current_value);
+ mTitleEditor->setEnabled(enabled);
+ mNotesEditor->setReadOnly(!enabled);
+ mFolderCombo->setVisible(enabled);
+ getChild<LLTextBox>("folder_lable")->setVisible(enabled);
- if (!current_value.empty() &&
- item_value != current_value &&
- gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE))
- {
- LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+ // HACK: To change the text color in a text editor
+ // when it was enabled/disabled we set the text once again.
+ mNotesEditor->setText(mNotesEditor->getText());
+}
- if (type == TITLE)
- {
- new_item->rename(current_value);
- }
- else
- {
- new_item->setDescription(current_value);
- }
+const std::string& LLPanelPlaceInfo::getLandmarkTitle() const
+{
+ return mTitleEditor->getText();
+}
- new_item->updateServer(FALSE);
- gInventory.updateItem(new_item);
- gInventory.notifyObservers();
- }
+const std::string LLPanelPlaceInfo::getLandmarkNotes() const
+{
+ return mNotesEditor->getText();
+}
+
+const LLUUID LLPanelPlaceInfo::getLandmarkFolder() const
+{
+ return mFolderCombo->getValue().asUUID();
}
void LLPanelPlaceInfo::createLandmark(const LLUUID& folder_id)
@@ -921,3 +940,91 @@ void LLPanelPlaceInfo::handleVisibilityChange (BOOL new_visibility)
}
}
}
+
+void LLPanelPlaceInfo::populateFoldersList()
+{
+ // Collect all folders that can contain landmarks.
+ LLInventoryModel::cat_array_t cats;
+ collectLandmarkFolders(cats);
+
+ mFolderCombo->removeall();
+
+ // Put the "Landmarks" folder first in list.
+ LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
+ const LLViewerInventoryCategory* cat = gInventory.getCategory(landmarks_id);
+ if (!cat)
+ {
+ llwarns << "Cannot find the landmarks folder" << llendl;
+ }
+ std::string cat_full_name = getFullFolderName(cat);
+ mFolderCombo->add(cat_full_name, cat->getUUID());
+
+ typedef std::vector<folder_pair_t> folder_vec_t;
+ folder_vec_t folders;
+ // Sort the folders by their full name.
+ for (S32 i = 0; i < cats.count(); i++)
+ {
+ cat = cats.get(i);
+ cat_full_name = getFullFolderName(cat);
+ folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name));
+ }
+ sort(folders.begin(), folders.end(), cmp_folders);
+
+ // Finally, populate the combobox.
+ for (folder_vec_t::const_iterator it = folders.begin(); it != folders.end(); it++)
+ mFolderCombo->add(it->second, LLSD(it->first));
+}
+
+static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right)
+{
+ return left.second < right.second;
+}
+
+static std::string getFullFolderName(const LLViewerInventoryCategory* cat)
+{
+ std::string name = cat->getName();
+ LLUUID parent_id;
+
+ // translate category name, if it's right below the root
+ // FIXME: it can throw notification about non existent string in strings.xml
+ if (cat->getParentUUID().notNull() && cat->getParentUUID() == gInventory.getRootFolderID())
+ {
+ LLTrans::findString(name, "InvFolder " + name);
+ }
+
+ // we don't want "My Inventory" to appear in the name
+ while ((parent_id = cat->getParentUUID()).notNull() && parent_id != gInventory.getRootFolderID())
+ {
+ cat = gInventory.getCategory(parent_id);
+ name = cat->getName() + "/" + name;
+ }
+
+ return name;
+}
+
+static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
+{
+ LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
+
+ // Add descendent folders of the "Landmarks" category.
+ LLInventoryModel::item_array_t items; // unused
+ LLIsType is_category(LLAssetType::AT_CATEGORY);
+ gInventory.collectDescendentsIf(
+ landmarks_id,
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ is_category);
+
+ // Add the "My Favorites" category.
+ LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
+ LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id);
+ if (!favorites_cat)
+ {
+ llwarns << "Cannot find the favorites folder" << llendl;
+ }
+ else
+ {
+ cats.put(favorites_cat);
+ }
+}
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 23a845bc20..49aa195490 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -42,6 +42,7 @@
#include "llremoteparcelrequest.h"
class LLButton;
+class LLComboBox;
class LLInventoryItem;
class LLLineEditor;
class LLPanelPick;
@@ -117,18 +118,19 @@ public:
const std::string& first,
const std::string& last);
+ void toggleLandmarkEditMode(BOOL enabled);
+
+ const std::string& getLandmarkTitle() const;
+ const std::string getLandmarkNotes() const;
+ const LLUUID getLandmarkFolder() const;
+
/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
/*virtual*/ void handleVisibilityChange (BOOL new_visibility);
private:
- enum LANDMARK_INFO_TYPE
- {
- TITLE,
- NOTE
- };
- void onCommitTitleOrNote(LANDMARK_INFO_TYPE type);
+ void populateFoldersList();
LLUUID mParcelID;
LLUUID mRequestedID;
@@ -182,6 +184,7 @@ private:
LLTextBox* mCreated;
LLLineEditor* mTitleEditor;
LLTextEditor* mNotesEditor;
+ LLComboBox* mFolderCombo;
LLPanel* mScrollingPanel;
LLPanel* mInfoPanel;
LLMediaPanel* mMediaPanel;
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 80ecc95afb..35206f54c7 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -40,16 +40,19 @@
#include "lllandmark.h"
#include "llparcel.h"
+#include "llcombobox.h"
+#include "llfiltereditor.h"
#include "llfloaterreg.h"
#include "llnotifications.h"
-#include "llfiltereditor.h"
#include "lltabcontainer.h"
+#include "lltexteditor.h"
#include "lltrans.h"
#include "lluictrlfactory.h"
#include "llagent.h"
#include "llavatarpropertiesprocessor.h"
#include "llfloaterworldmap.h"
+#include "llinventorybridge.h"
#include "llinventorymodel.h"
#include "lllandmarkactions.h"
#include "lllandmarklist.h"
@@ -74,9 +77,6 @@ static const std::string TELEPORT_HISTORY_INFO_TYPE = "teleport_history";
// Helper functions
static bool is_agent_in_selected_parcel(LLParcel* parcel);
-static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right);
-static std::string getFullFolderName(const LLViewerInventoryCategory* cat);
-static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
static void onSLURLBuilt(std::string& slurl);
static void setAllChildrenVisible(LLView* view, BOOL visible);
@@ -125,8 +125,8 @@ LLPanelPlaces::LLPanelPlaces()
mItem(NULL),
mPlaceMenu(NULL),
mLandmarkMenu(NULL),
- mLandmarkFoldersMenuHandle(),
- mPosGlobal()
+ mPosGlobal(),
+ isLandmarkEditModeOn(false)
{
mParcelObserver = new LLPlacesParcelObserver(this);
mInventoryObserver = new LLPlacesInventoryObserver(this);
@@ -146,20 +146,12 @@ LLPanelPlaces::~LLPanelPlaces()
LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver);
- LLView::deleteViewByHandle(mLandmarkFoldersMenuHandle);
-
delete mInventoryObserver;
delete mParcelObserver;
}
BOOL LLPanelPlaces::postBuild()
{
- mCreateLandmarkBtn = getChild<LLButton>("create_landmark_btn");
- mCreateLandmarkBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onCreateLandmarkButtonClicked, this, LLUUID()));
-
- mFolderMenuBtn = getChild<LLButton>("folder_menu_btn");
- mFolderMenuBtn->setClickedCallback(boost::bind(&LLPanelPlaces::showLandmarkFoldersMenu, this));
-
mTeleportBtn = getChild<LLButton>("teleport_btn");
mTeleportBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onTeleportButtonClicked, this));
@@ -169,6 +161,18 @@ BOOL LLPanelPlaces::postBuild()
mShareBtn = getChild<LLButton>("share_btn");
//mShareBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShareButtonClicked, this));
+ mEditBtn = getChild<LLButton>("edit_btn");
+ mEditBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, 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<LLButton>("overflow_btn");
mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this));
@@ -200,10 +204,18 @@ BOOL LLPanelPlaces::postBuild()
}
mPlaceInfo = getChild<LLPanelPlaceInfo>("panel_place_info");
-
+
LLButton* back_btn = mPlaceInfo->getChild<LLButton>("back_btn");
back_btn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this));
+ LLLineEditor* title_editor = mPlaceInfo->getChild<LLLineEditor>("title_editor");
+ title_editor->setKeystrokeCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this), NULL);
+
+ LLTextEditor* notes_editor = mPlaceInfo->getChild<LLTextEditor>("notes_editor");
+ notes_editor->setKeystrokeCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this));
+
+ LLComboBox* folder_combo = mPlaceInfo->getChild<LLComboBox>("folder_combo");
+ folder_combo->setSelectionCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this));
return TRUE;
}
@@ -217,6 +229,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)
mPlaceInfoType = key["type"].asString();
mPosGlobal.setZero();
+ mItem = NULL;
togglePlaceInfoPanel(TRUE);
updateVerbs();
@@ -227,11 +240,25 @@ void LLPanelPlaces::onOpen(const LLSD& key)
else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
{
mPlaceInfo->setInfoType(LLPanelPlaceInfo::CREATE_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();
+ }
+
+ mPlaceInfo->displayParcelInfo(LLUUID(), mPosGlobal);
}
else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
{
- LLUUID item_uuid = key["id"].asUUID();
- LLInventoryItem* item = gInventory.getItem(item_uuid);
+ mPlaceInfo->setInfoType(LLPanelPlaceInfo::LANDMARK);
+
+ LLInventoryItem* item = gInventory.getItem(key["id"].asUUID());
if (!item)
return;
@@ -272,8 +299,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)
// 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 ||
- mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
+ if (mPlaceInfoType == AGENT_INFO_TYPE)
{
parcel_mgr->addObserver(mParcelObserver);
parcel_mgr->selectParcelAt(gAgent.getPositionGlobal());
@@ -291,7 +317,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)
void LLPanelPlaces::setItem(LLInventoryItem* item)
{
- if (!mPlaceInfo)
+ if (!item)
return;
mItem = item;
@@ -304,7 +330,9 @@ void LLPanelPlaces::setItem(LLInventoryItem* item)
return;
}
- mPlaceInfo->setInfoType(LLPanelPlaceInfo::LANDMARK);
+ if (!mPlaceInfo)
+ return;
+
mPlaceInfo->displayItemInfo(mItem);
LLLandmark* lm = gLandmarkList.getAsset(mItem->getAssetUUID(),
@@ -324,6 +352,12 @@ void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark)
landmark->getRegionID(region_id);
landmark->getGlobalPos(mPosGlobal);
mPlaceInfo->displayParcelInfo(region_id, mPosGlobal);
+
+ // Check if item is in agent's inventory and he has the permission to modify it.
+ BOOL is_landmark_editable = mItem.notNull() &&
+ gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.getRootFolderID()) &&
+ mItem->getPermissions().allowModifyBy(gAgent.getID());
+ mEditBtn->setEnabled(is_landmark_editable);
}
void LLPanelPlaces::onFilterEdit(const std::string& search_string)
@@ -436,6 +470,136 @@ void LLPanelPlaces::onShowOnMapButtonClicked()
}
}
+void LLPanelPlaces::onEditButtonClicked()
+{
+ if (!mPlaceInfo || isLandmarkEditModeOn)
+ return;
+
+ isLandmarkEditModeOn = true;
+
+ mPlaceInfo->toggleLandmarkEditMode(TRUE);
+
+ updateVerbs();
+}
+
+void LLPanelPlaces::onSaveButtonClicked()
+{
+ if (!mPlaceInfo || mItem.isNull())
+ return;
+
+ LLAssetType::EType item_type = mItem->getType();
+ 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->getAssetUUID());
+ if (mItem.isNull())
+ return;
+ }
+ }
+ else
+ {
+ return;
+ }
+
+ std::string current_title_value = mPlaceInfo->getLandmarkTitle();
+ std::string item_title_value = mItem->getName();
+ std::string current_notes_value = mPlaceInfo->getLandmarkNotes();
+ std::string item_notes_value = mItem->getDescription();
+
+ LLStringUtil::trim(current_title_value);
+ LLStringUtil::trim(current_notes_value);
+
+ bool is_item_update_needed = false;
+
+ if (!current_title_value.empty() &&
+ (item_title_value != current_title_value || item_notes_value != current_notes_value))
+ {
+ is_item_update_needed = true;
+ }
+
+ LLUUID item_id = mItem->getUUID();
+ LLUUID folder_id = mPlaceInfo->getLandmarkFolder();
+
+ // Check if item is in agent's inventory and he has the permission to modify it.
+ if (!gInventory.isObjectDescendentOf(item_id, gInventory.getRootFolderID()) ||
+ !mItem->getPermissions().allowModifyBy(gAgent.getID()))
+ return;
+
+ if(folder_id != mItem->getParentUUID() || is_item_update_needed)
+ {
+ LLViewerInventoryItem* item = (LLViewerInventoryItem*)mItem.get();
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+
+ LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
+
+ // If target is the favorites folder we create link to it.
+ if (favorites_id == folder_id)
+ {
+ if (is_item_update_needed)
+ {
+ new_item->rename(current_title_value);
+ new_item->setDescription(current_notes_value);
+ new_item->updateServer(FALSE);
+
+ gInventory.updateItem(new_item);
+ gInventory.notifyObservers();
+ }
+
+ link_inventory_item(gAgent.getID(),
+ item->getUUID(),
+ folder_id,
+ item->getName(),
+ LLAssetType::AT_LINK,
+ LLPointer<LLInventoryCallback>(NULL));
+ }
+ else
+ {
+ if (is_item_update_needed)
+ {
+ new_item->rename(current_title_value);
+ new_item->setDescription(current_notes_value);
+ new_item->updateServer(FALSE);
+ }
+
+ LLInventoryModel::update_list_t update;
+ LLInventoryModel::LLCategoryUpdate old_folder(item->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 (!mPlaceInfo)
+ return;
+
+ if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
+ {
+ onBackButtonClicked();
+ }
+ else
+ {
+ mPlaceInfo->toggleLandmarkEditMode(FALSE);
+ updateVerbs();
+
+ // Reload the landmark properties.
+ mPlaceInfo->displayItemInfo(mItem);
+ }
+}
+
void LLPanelPlaces::onOverflowButtonClicked()
{
LLToggleableMenu* menu;
@@ -487,7 +651,12 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
std::string item = param.asString();
if (item == "landmark")
{
- onOpen(LLSD().insert("type", CREATE_LANDMARK_INFO_TYPE));
+ 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")
{
@@ -523,20 +692,6 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
}
}
-void LLPanelPlaces::onCreateLandmarkButtonClicked(const LLUUID& folder_id)
-{
- if (!mPlaceInfo)
- return;
-
- // To prevent creating duplicate landmarks
- // disable landmark creating buttons until
- // the information on existing landmarks is reloaded.
- mCreateLandmarkBtn->setEnabled(FALSE);
- mFolderMenuBtn->setEnabled(FALSE);
-
- mPlaceInfo->createLandmark(folder_id);
-}
-
void LLPanelPlaces::onBackButtonClicked()
{
if (!mPlaceInfo)
@@ -697,10 +852,14 @@ void LLPanelPlaces::updateVerbs()
bool is_create_landmark_visible = mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE;
bool is_media_panel_visible = mPlaceInfo->isMediaPanelVisible();
- mTeleportBtn->setVisible(!is_create_landmark_visible);
- mShareBtn->setVisible(!is_create_landmark_visible);
- mCreateLandmarkBtn->setVisible(is_create_landmark_visible);
- mFolderMenuBtn->setVisible(is_create_landmark_visible);
+ mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
+ mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
+ mShareBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
+ mOverflowBtn->setVisible(!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);
mOverflowBtn->setEnabled(is_place_info_visible && !is_media_panel_visible && !is_create_landmark_visible);
@@ -714,15 +873,6 @@ void LLPanelPlaces::updateVerbs()
!mPosGlobal.isExactlyZero() &&
!LLViewerParcelMgr::getInstance()->inAgentParcel(mPosGlobal));
}
- else if (is_create_landmark_visible)
- {
- // Enable "Create Landmark" only if there is no landmark
- // for the current parcel and agent is inside it.
- bool enable = !LLLandmarkActions::landmarkAlreadyExists() &&
- is_agent_in_selected_parcel(mParcel->getParcel());
- mCreateLandmarkBtn->setEnabled(enable);
- mFolderMenuBtn->setEnabled(enable);
- }
else if (mPlaceInfoType == LANDMARK_INFO_TYPE || mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
{
mTeleportBtn->setEnabled(TRUE);
@@ -735,131 +885,8 @@ void LLPanelPlaces::updateVerbs()
if (mActivePanel)
mActivePanel->updateVerbs();
}
-}
-
-void LLPanelPlaces::showLandmarkFoldersMenu()
-{
- if (mLandmarkFoldersMenuHandle.isDead())
- {
- LLToggleableMenu::Params menu_p;
- menu_p.name("landmarks_folders_menu");
- menu_p.can_tear_off(false);
- menu_p.visible(false);
- menu_p.scrollable(true);
- menu_p.max_scrollable_items = 10;
-
- LLToggleableMenu* menu = LLUICtrlFactory::create<LLToggleableMenu>(menu_p);
-
- mLandmarkFoldersMenuHandle = menu->getHandle();
- }
-
- LLToggleableMenu* menu = (LLToggleableMenu*)mLandmarkFoldersMenuHandle.get();
- if(!menu)
- return;
-
- if (!menu->toggleVisibility())
- return;
-
- // Collect all folders that can contain landmarks.
- LLInventoryModel::cat_array_t cats;
- collectLandmarkFolders(cats);
-
- // Sort the folders by their full name.
- folder_vec_t folders;
- S32 count = cats.count();
- for (S32 i = 0; i < count; i++)
- {
- const LLViewerInventoryCategory* cat = cats.get(i);
- std::string cat_full_name = getFullFolderName(cat);
- folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name));
- }
- sort(folders.begin(), folders.end(), cmp_folders);
-
- LLRect btn_rect = mFolderMenuBtn->getRect();
-
- LLRect root_rect = getRootView()->getRect();
-
- // Check it there are changed items or viewer dimensions
- // have changed since last call
- if (mLandmarkFoldersCache.size() == count &&
- mRootViewWidth == root_rect.getWidth() &&
- mRootViewHeight == root_rect.getHeight())
- {
- S32 i;
- for (i = 0; i < count; i++)
- {
- if (mLandmarkFoldersCache[i].second != folders[i].second)
- {
- break;
- }
- }
-
- // Check passed, just show the menu
- if (i == count)
- {
- menu->buildDrawLabels();
- menu->updateParent(LLMenuGL::sMenuContainer);
-
- menu->setButtonRect(btn_rect, this);
- LLMenuGL::showPopup(this, menu, btn_rect.mRight, btn_rect.mTop);
- return;
- }
- }
-
- // If there are changes, store the new viewer dimensions
- // and a list of folders
- mRootViewWidth = root_rect.getWidth();
- mRootViewHeight = root_rect.getHeight();
- mLandmarkFoldersCache = folders;
-
- menu->empty();
-
- // Menu width must not exceed the root view limits,
- // so we assume the space between the left edge of
- // the root view and
- LLRect screen_btn_rect;
- localRectToScreen(btn_rect, &screen_btn_rect);
- S32 free_space = screen_btn_rect.mRight;
- U32 max_width = llmin(LANDMARK_FOLDERS_MENU_WIDTH, free_space);
- for(folder_vec_t::const_iterator it = mLandmarkFoldersCache.begin(); it != mLandmarkFoldersCache.end(); it++)
- {
- const std::string& item_name = it->second;
-
- LLMenuItemCallGL::Params item_params;
- item_params.name(item_name);
- item_params.label(item_name);
-
- item_params.on_click.function(boost::bind(&LLPanelPlaces::onCreateLandmarkButtonClicked, this, it->first));
-
- LLMenuItemCallGL *menu_item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
-
- // *TODO: Use a separate method for menu width calculation.
- // Check whether item name wider than menu
- if (menu_item->getNominalWidth() > max_width)
- {
- S32 chars_total = item_name.length();
- S32 chars_fitted = 1;
- menu_item->setLabel(LLStringExplicit(""));
- S32 label_space = max_width - menu_item->getFont()->getWidth("...") -
- menu_item->getNominalWidth(); // This returns width of menu item with empty label (pad pixels)
-
- while (chars_fitted < chars_total && menu_item->getFont()->getWidth(item_name, 0, chars_fitted) < label_space)
- {
- chars_fitted++;
- }
- chars_fitted--; // Rolling back one char, that doesn't fit
-
- menu_item->setLabel(item_name.substr(0, chars_fitted) + "...");
- }
-
- menu->addChild(menu_item);
- }
-
- menu->buildDrawLabels();
- menu->updateParent(LLMenuGL::sMenuContainer);
- menu->setButtonRect(btn_rect, this);
- LLMenuGL::showPopup(this, menu, btn_rect.mRight, btn_rect.mTop);
+ isLandmarkEditModeOn = false;
}
static bool is_agent_in_selected_parcel(LLParcel* parcel)
@@ -874,70 +901,6 @@ static bool is_agent_in_selected_parcel(LLParcel* parcel)
parcel->getLocalID() == parcel_mgr->getAgentParcel()->getLocalID();
}
-static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right)
-{
- return left.second < right.second;
-}
-
-static std::string getFullFolderName(const LLViewerInventoryCategory* cat)
-{
- std::string name = cat->getName();
- LLUUID parent_id;
-
- // translate category name, if it's right below the root
- // FIXME: it can throw notification about non existent string in strings.xml
- if (cat->getParentUUID().notNull() && cat->getParentUUID() == gInventory.getRootFolderID())
- {
- LLTrans::findString(name, "InvFolder " + name);
- }
-
- // we don't want "My Inventory" to appear in the name
- while ((parent_id = cat->getParentUUID()).notNull() && parent_id != gInventory.getRootFolderID())
- {
- cat = gInventory.getCategory(parent_id);
- name = cat->getName() + "/" + name;
- }
-
- return name;
-}
-
-static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
-{
- // Add the "Landmarks" category itself.
- LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
- LLViewerInventoryCategory* landmarks_cat = gInventory.getCategory(landmarks_id);
- if (!landmarks_cat)
- {
- llwarns << "Cannot find the landmarks folder" << llendl;
- }
- else
- {
- cats.put(landmarks_cat);
- }
-
- // Add descendent folders of the "Landmarks" category.
- LLInventoryModel::item_array_t items; // unused
- LLIsType is_category(LLAssetType::AT_CATEGORY);
- gInventory.collectDescendentsIf(
- landmarks_id,
- cats,
- items,
- LLInventoryModel::EXCLUDE_TRASH,
- is_category);
-
- // Add the "My Favorites" category.
- LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
- LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id);
- if (!favorites_cat)
- {
- llwarns << "Cannot find the favorites folder" << llendl;
- }
- else
- {
- cats.put(favorites_cat);
- }
-}
-
static void onSLURLBuilt(std::string& slurl)
{
LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(slurl));
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index f208e91237..0b3b3b5fc3 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -72,6 +72,9 @@ private:
//void onShareButtonClicked();
void onTeleportButtonClicked();
void onShowOnMapButtonClicked();
+ void onEditButtonClicked();
+ void onSaveButtonClicked();
+ void onCancelButtonClicked();
void onOverflowButtonClicked();
void onOverflowMenuItemClicked(const LLSD& param);
void onCreateLandmarkButtonClicked(const LLUUID& folder_id);
@@ -84,8 +87,6 @@ private:
void onAgentParcelChange();
void updateVerbs();
- void showLandmarkFoldersMenu();
-
LLFilterEditor* mFilterEditor;
LLPanelPlacesTab* mActivePanel;
LLTabContainer* mTabContainer;
@@ -94,11 +95,13 @@ private:
LLToggleableMenu* mPlaceMenu;
LLToggleableMenu* mLandmarkMenu;
- LLButton* mCreateLandmarkBtn;
- LLButton* mFolderMenuBtn;
LLButton* mTeleportBtn;
LLButton* mShowOnMapBtn;
LLButton* mShareBtn;
+ LLButton* mEditBtn;
+ LLButton* mSaveBtn;
+ LLButton* mCancelBtn;
+ LLButton* mCloseBtn;
LLButton* mOverflowBtn;
LLPlacesInventoryObserver* mInventoryObserver;
@@ -118,19 +121,7 @@ private:
// Information type currently shown in Place Information panel
std::string mPlaceInfoType;
- // Menu handle for pop-up menu to chose a landmark saving
- // folder when creating a new landmark
- LLHandle<LLView> mLandmarkFoldersMenuHandle;
-
- typedef std::vector<folder_pair_t> folder_vec_t;
-
- // List of folders to choose from when creating a landmark
- folder_vec_t mLandmarkFoldersCache;
-
- // If root view width or height is changed
- // the pop-up menu must be updated
- S32 mRootViewWidth;
- S32 mRootViewHeight;
+ bool isLandmarkEditModeOn;
LLSafeHandle<LLParcelSelection> mParcel;
};
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index d9be6b172c..e4a3f8603b 100644
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -308,7 +308,6 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
//gFloaterView->adjustToFitScreen(this, FALSE);
if (mLineEditor)
{
- mLineEditor->setFocus(TRUE);
mLineEditor->selectAll();
}
if(mDefaultOption >= 0)
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 2e8580907e..aa662b713e 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -98,6 +98,7 @@
#include "llnotifications.h"
#include "llnotify.h"
#include "llpanelgrouplandmoney.h"
+#include "llpanelplaces.h"
#include "llrecentpeople.h"
#include "llselectmgr.h"
#include "llsidetray.h"
@@ -138,7 +139,6 @@
#include "llkeythrottle.h"
#include "llgroupactions.h"
#include "llagentui.h"
-#include "llsidetray.h"
#include "llpanelblockedlist.h"
#include "llpanelplaceinfo.h"
@@ -907,14 +907,15 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)
LLInventoryCategory* parent_folder = gInventory.getCategory(item->getParentUUID());
LLSD args;
args["LANDMARK_NAME"] = item->getName();
- args["FOLDER_NAME"] = std::string(parent_folder ? parent_folder->getName() : "unnkown");
+ args["FOLDER_NAME"] = std::string(parent_folder ? parent_folder->getName() : "unknown");
LLNotifications::instance().add("LandmarkCreated", args);
-
- // Open new landmark for editing in Places panel.
- LLSD key;
- key["type"] = "landmark";
- key["id"] = item->getUUID();
- LLSideTray::getInstance()->showPanel("panel_places", key);
+
+ // Created landmark is passed to Places panel to allow its editing.
+ LLPanelPlaces *panel = dynamic_cast<LLPanelPlaces*>(LLSideTray::getInstance()->showPanel("panel_places", LLSD()));
+ if (panel)
+ {
+ panel->setItem(item);
+ }
}
break;
case LLAssetType::AT_TEXTURE:
diff --git a/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml
index 0eb2c5e1be..4f501b65f3 100644
--- a/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml
+++ b/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml
@@ -1,24 +1,24 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- can_minimize="false"
- height="108"
- layout="topleft"
- name="whitelist_entry"
- width="390">
-
- <text type="string" length="1" bottom="20" follows="top|left" height="15" layout="topleft"
- left="10" name="media_label" top="20">
- Enter a URL or URL pattern to add to the list of allowed domains
- </text>
-
- <line_editor bottom_delta="40" enabled="true" follows="left|top" font="SansSerif"
- height="20" left="10" name="whitelist_entry"
- tool_tip="Enter a URL or URL pattern to White List"
- width="350" />
-
- <button follows="top|left" height="20" font="SansSerifSmall" label="OK"
- layout="topleft" left="10" name="ok_btn" bottom_delta="28" width="64" />
-
- <button follows="top|left" height="20" font="SansSerifSmall" label="Cancel"
- layout="topleft" left_pad="5" name="cancel_btn" bottom_delta="0" width="64" />
-</floater>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ height="108"
+ layout="topleft"
+ name="whitelist_entry"
+ width="390">
+
+ <text type="string" length="1" bottom="20" follows="top|left" height="15" layout="topleft"
+ left="10" name="media_label" top="20">
+ Enter a URL or URL pattern to add to the list of allowed domains
+ </text>
+
+ <line_editor bottom_delta="40" enabled="true" follows="left|top" font="SansSerif"
+ height="20" left="10" name="whitelist_entry"
+ tool_tip="Enter a URL or URL pattern to White List"
+ width="350" />
+
+ <button follows="top|left" height="20" font="SansSerifSmall" label="OK"
+ layout="topleft" left="10" name="ok_btn" bottom_delta="28" width="64" />
+
+ <button follows="top|left" height="20" font="SansSerifSmall" label="Cancel"
+ layout="topleft" left_pad="5" name="cancel_btn" bottom_delta="0" width="64" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index 8b9fe2cf77..696e0b3c33 100644
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -60,7 +60,7 @@
left="5"
name="teleport_btn"
top="0"
- width="90" />
+ width="70" />
<button
follows="bottom|left"
font="SansSerifSmallBold"
@@ -70,7 +70,7 @@
left_pad="5"
name="map_btn"
top="0"
- width="80" />
+ width="50" />
<button
enabled="false"
follows="bottom|left"
@@ -83,40 +83,54 @@
top="0"
width="60" />
<button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Edit"
+ layout="topleft"
+ left_pad="5"
+ name="edit_btn"
+ top="0"
+ width="50" />
+ <button
follows="bottom|right"
font="SansSerifSmallBold"
height="25"
label="▼"
layout="topleft"
- left_pad="5"
name="overflow_btn"
+ right="-10"
top="0"
width="30" />
<button
- follows="bottom|left"
+ follows="bottom|right"
font="SansSerifSmallBold"
height="25"
- image_disabled="widgets/SegmentedBtn_Left_Disabled.png"
- image_selected="widgets/SegmentedBtn_Left_Selected.png"
- image_unselected="widgets/SegmentedBtn_Left_Off.png"
- label="Create"
+ label="Close"
layout="topleft"
- left="5"
- name="create_landmark_btn"
+ name="close_btn"
+ right="-10"
top="0"
- width="70" />
+ width="60" />
<button
- follows="bottom|left"
+ follows="bottom|right"
font="SansSerifSmallBold"
height="25"
- image_disabled="widgets/ComboButton_Disabled.png"
- image_selected="widgets/ComboButton_Selected.png"
- image_unselected="widgets/ComboButton_Off.png"
- label="▼"
+ label="Cancel"
+ layout="topleft"
+ name="cancel_btn"
+ right="-10"
+ top="0"
+ width="60" />
+ <button
+ follows="bottom|right"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Save"
layout="topleft"
- left_pad="0"
- name="folder_menu_btn"
+ name="save_btn"
+ right="-75"
top="0"
- width="20" />
+ width="60" />
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
index 824a815a99..4520768216 100644
--- a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
@@ -12,7 +12,7 @@
draw_stripes="true"
scroll_bar_bg_visible="false"
scroll_bar_bg_color="black"
- background_visible="false"
+ background_visible="true"
heading_height="23"
draw_border="false"
draw_heading="false" />