diff options
-rw-r--r-- | indra/llui/lldockablefloater.cpp | 10 | ||||
-rw-r--r-- | indra/llui/lldockablefloater.h | 3 | ||||
-rw-r--r-- | indra/llui/lldockcontrol.cpp | 22 | ||||
-rw-r--r-- | indra/newview/llpanelplaceinfo.cpp | 199 | ||||
-rw-r--r-- | indra/newview/llpanelplaceinfo.h | 15 | ||||
-rw-r--r-- | indra/newview/llpanelplaces.cpp | 437 | ||||
-rw-r--r-- | indra/newview/llpanelplaces.h | 25 | ||||
-rw-r--r-- | indra/newview/lltoastalertpanel.cpp | 1 | ||||
-rw-r--r-- | indra/newview/llviewermessage.cpp | 17 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_whitelist_entry.xml | 48 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_places.xml | 52 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/widgets/scroll_list.xml | 2 |
12 files changed, 469 insertions, 362 deletions
diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp index 4525f0a45b..c512ef25be 100644 --- a/indra/llui/lldockablefloater.cpp +++ b/indra/llui/lldockablefloater.cpp @@ -91,6 +91,16 @@ void LLDockableFloater::setVisible(BOOL visible) LLFloater::setVisible(visible); } +void LLDockableFloater::onDockHidden() +{ + setCanDock(FALSE); +} + +void LLDockableFloater::onDockShown() +{ + setCanDock(TRUE); +} + void LLDockableFloater::setDocked(bool docked, bool pop_on_undock) { if (mDockControl.get() != NULL && mDockControl.get()->isDockVisible()) diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h index ed90567ad3..7d91d007ee 100644 --- a/indra/llui/lldockablefloater.h +++ b/indra/llui/lldockablefloater.h @@ -68,6 +68,9 @@ public: */ /*virtual*/ void setVisible(BOOL visible); + virtual void onDockHidden(); + virtual void onDockShown(); + private: /** * Provides unique of dockable floater. diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp index 146c7a969a..cdcd823b1c 100644 --- a/indra/llui/lldockcontrol.cpp +++ b/indra/llui/lldockcontrol.cpp @@ -33,6 +33,7 @@ #include "linden_common.h" #include "lldockcontrol.h" +#include "lldockablefloater.h" LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater, const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) : @@ -91,8 +92,8 @@ void LLDockControl::repositionDockable() // recalculate dockable position if dock position changed, dock visibility changed, // root view rect changed or recalculation is forced - if (mEnabled && (mPrevDockRect != dockRect || prev_visibility != mDockWidget->getVisible() - || mRootRect != rootRect || mRecalculateDocablePosition)) + if (mPrevDockRect != dockRect || prev_visibility != mDockWidget->getVisible() + || mRootRect != rootRect || mRecalculateDocablePosition) { // undock dockable and off() if dock not visible if (!isDockVisible()) @@ -100,10 +101,25 @@ void LLDockControl::repositionDockable() mDockableFloater->setDocked(false); // force off() since dockable may not have dockControll at this time off(); + LLDockableFloater* dockable_floater = + dynamic_cast<LLDockableFloater*> (mDockableFloater); + if(dockable_floater != NULL) + { + dockable_floater->onDockHidden(); + } } else { - moveDockable(); + if(mEnabled) + { + moveDockable(); + } + LLDockableFloater* dockable_floater = + dynamic_cast<LLDockableFloater*> (mDockableFloater); + if(dockable_floater != NULL) + { + dockable_floater->onDockShown(); + } } mPrevDockRect = dockRect; 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" /> |