summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt1
-rw-r--r--indra/newview/lloutfitslist.cpp40
-rw-r--r--indra/newview/llpanellandmarks.cpp46
-rw-r--r--indra/newview/llpanellandmarks.h4
-rw-r--r--indra/newview/llpanelplaceprofile.cpp10
-rw-r--r--indra/newview/llsidepaneliteminfo.cpp69
-rw-r--r--indra/newview/llsidepaneliteminfo.h5
-rw-r--r--indra/newview/llsidetray.cpp16
-rw-r--r--indra/newview/viewer_manifest.py1
9 files changed, 148 insertions, 44 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index d685e6ae36..382bbaeba1 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1485,6 +1485,7 @@ if (WINDOWS)
${GOOGLE_PERF_TOOLS_SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/licenses-win32.txt
${CMAKE_CURRENT_SOURCE_DIR}/featuretable.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/featuretable_xp.txt
${CMAKE_CURRENT_SOURCE_DIR}/dbghelp.dll
${CMAKE_CURRENT_SOURCE_DIR}/fmod.dll
${ARCH_PREBUILT_DIRS_RELEASE}/libeay32.dll
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index cf0b3d94bd..c0f7fa4abf 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -85,7 +85,7 @@ public:
registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenu::onAdd, this));
- enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitsList::isActionEnabled, mOutfitList, _2));
+ enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenu::onEnable, this, _2));
enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenu::onVisible, this, _2));
mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(
@@ -155,27 +155,11 @@ private:
void onTakeOff()
{
- // Take off selected items if there are any
- if (mOutfitList->hasItemSelected())
- {
- uuid_vec_t selected_uuids;
- mOutfitList->getSelectedItemsUUIDs(selected_uuids);
-
- for (uuid_vec_t::const_iterator it=selected_uuids.begin(); it != selected_uuids.end(); ++it)
- {
- if (get_is_item_worn(*it))
- {
- LLAppearanceMgr::instance().removeItemFromAvatar(*it);
- }
- }
- }
- else // or take off the whole selected outfit if no items specified.
+ // Take off selected outfit.
+ const LLUUID& selected_outfit_id = getSelectedOutfitID();
+ if (selected_outfit_id.notNull())
{
- const LLUUID& selected_outfit_id = getSelectedOutfitID();
- if (selected_outfit_id.notNull())
- {
- LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id);
- }
+ LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id);
}
}
@@ -209,6 +193,20 @@ private:
LLAgentWearables::createWearable(type, true);
}
+ bool onEnable(LLSD::String param)
+ {
+ // Handle the "Wear - Replace Current Outfit" menu option specially
+ // because LLOutfitList::isActionEnabled() checks whether it's allowed
+ // to wear selected outfit OR selected items, while we're only
+ // interested in the outfit (STORM-183).
+ if ("wear" == param)
+ {
+ return LLAppearanceMgr::instance().getCanReplaceCOF(mOutfitList->getSelectedOutfitUUID());
+ }
+
+ return mOutfitList->isActionEnabled(param);
+ }
+
bool onVisible(LLSD::String param)
{
const LLUUID& selected_outfit_id = getSelectedOutfitID();
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index ff15e3f08e..24bf67a000 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -965,12 +965,32 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
|| "expand" == command_name
)
{
- return canSelectedBeModified(command_name);
+ if (!root_folder_view) return false;
+
+ std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList();
+
+ // Allow to execute the command only if it can be applied to all selected items.
+ for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
+ {
+ LLFolderViewItem* item = root_folder_view->getItemByID(*iter);
+
+ // If no item is found it might be a folder id.
+ if (!item)
+ {
+ item = root_folder_view->getFolderByID(*iter);
+ }
+ if (!item) return false;
+
+ if (!canItemBeModified(command_name, item)) return false;
+ }
+
+ return true;
}
else if ( "teleport" == command_name
|| "more_info" == command_name
|| "show_on_map" == command_name
|| "copy_slurl" == command_name
+ || "rename" == command_name
)
{
// disable some commands for multi-selection. EXT-1757
@@ -994,13 +1014,16 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
// Disable "Show on Map" if landmark loading is in progress.
return !gLandmarkList.isAssetInLoadedCallbackMap(asset_uuid);
}
+ else if ("rename" == command_name)
+ {
+ LLFolderViewItem* selected_item = getCurSelectedItem();
+ if (!selected_item) return false;
+
+ return canItemBeModified(command_name, selected_item);
+ }
return true;
}
- else if ("rename" == command_name)
- {
- return root_folder_view && root_folder_view->getSelectedCount() == 1 && canSelectedBeModified(command_name);
- }
else if("category" == command_name)
{
// we can add folder only in Landmarks Accordion
@@ -1065,12 +1088,11 @@ Rules:
4. We can not paste folders from Clipboard (processed by LLFolderView::canPaste())
5. Check LLFolderView/Inventory Bridges rules
*/
-bool LLLandmarksPanel::canSelectedBeModified(const std::string& command_name) const
+bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const
{
// validate own rules first
- LLFolderViewItem* selected = getCurSelectedItem();
- if (!selected) return false;
+ if (!item) return false;
// nothing can be modified in Library
if (mLibraryInventoryPanel == mCurrentSelectedList) return false;
@@ -1078,7 +1100,7 @@ bool LLLandmarksPanel::canSelectedBeModified(const std::string& command_name) co
bool can_be_modified = false;
// landmarks can be modified in any other accordion...
- if (isLandmarkSelected())
+ if (item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
{
can_be_modified = true;
@@ -1107,16 +1129,16 @@ bool LLLandmarksPanel::canSelectedBeModified(const std::string& command_name) co
}
else if ("collapse" == command_name)
{
- return selected->isOpen();
+ return item->isOpen();
}
else if ("expand" == command_name)
{
- return !selected->isOpen();
+ return !item->isOpen();
}
if (can_be_modified)
{
- LLFolderViewEventListener* listenerp = selected->getListener();
+ LLFolderViewEventListener* listenerp = item->getListener();
if ("cut" == command_name)
{
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index 2b398decce..0d4402d8cb 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -127,12 +127,12 @@ private:
void onCustomAction(const LLSD& command_name);
/**
- * Determines if selected item can be modified via context/gear menu.
+ * Determines if an item can be modified via context/gear menu.
*
* It validates Places Landmarks rules first. And then LLFolderView permissions.
* For now it checks cut/rename/delete/paste actions.
*/
- bool canSelectedBeModified(const std::string& command_name) const;
+ bool canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const;
void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params);
/**
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index ee30c928c2..801db1e741 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -230,6 +230,11 @@ void LLPanelPlaceProfile::setInfoType(EInfoType type)
break;
}
+ if (mAccordionCtrl != NULL)
+ {
+ mAccordionCtrl->expandDefaultTab();
+ }
+
LLPanelPlaceInfo::setInfoType(type);
}
@@ -274,11 +279,6 @@ void LLPanelPlaceProfile::handleVisibilityChange(BOOL new_visibility)
parcel_mgr->deselectUnused();
}
}
-
- if (mAccordionCtrl != NULL)
- {
- mAccordionCtrl->expandDefaultTab();
- }
}
void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index 731079fb5d..e41bbe43df 100644
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -75,7 +75,40 @@ void LLItemPropertiesObserver::changed(U32 mask)
}
}
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLObjectInventoryObserver
+//
+// Helper class to watch for changes in an object inventory.
+// Used to update item properties in LLSidepanelItemInfo.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLObjectInventoryObserver : public LLVOInventoryListener
+{
+public:
+ LLObjectInventoryObserver(LLSidepanelItemInfo* floater, LLViewerObject* object)
+ : mFloater(floater)
+ {
+ registerVOInventoryListener(object, NULL);
+ }
+ virtual ~LLObjectInventoryObserver()
+ {
+ removeVOInventoryListener();
+ }
+ /*virtual*/ void inventoryChanged(LLViewerObject* object,
+ LLInventoryObject::object_list_t* inventory,
+ S32 serial_num,
+ void* user_data);
+private:
+ LLSidepanelItemInfo* mFloater;
+};
+/*virtual*/
+void LLObjectInventoryObserver::inventoryChanged(LLViewerObject* object,
+ LLInventoryObject::object_list_t* inventory,
+ S32 serial_num,
+ void* user_data)
+{
+ mFloater->dirty();
+}
///----------------------------------------------------------------------------
/// Class LLSidepanelItemInfo
@@ -86,6 +119,7 @@ static LLRegisterPanelClassWrapper<LLSidepanelItemInfo> t_item_info("sidepanel_i
// Default constructor
LLSidepanelItemInfo::LLSidepanelItemInfo()
: mItemID(LLUUID::null)
+ , mObjectInventoryObserver(NULL)
{
mPropertiesObserver = new LLItemPropertiesObserver(this);
@@ -97,6 +131,8 @@ LLSidepanelItemInfo::~LLSidepanelItemInfo()
{
delete mPropertiesObserver;
mPropertiesObserver = NULL;
+
+ stopObjectInventoryObserver();
}
// virtual
@@ -134,6 +170,10 @@ BOOL LLSidepanelItemInfo::postBuild()
void LLSidepanelItemInfo::setObjectID(const LLUUID& object_id)
{
mObjectID = object_id;
+
+ // Start monitoring changes in the object inventory to update
+ // selected inventory item properties in Item Profile panel. See STORM-148.
+ startObjectInventoryObserver();
}
void LLSidepanelItemInfo::setItemID(const LLUUID& item_id)
@@ -147,6 +187,8 @@ void LLSidepanelItemInfo::reset()
mObjectID = LLUUID::null;
mItemID = LLUUID::null;
+
+ stopObjectInventoryObserver();
}
void LLSidepanelItemInfo::refresh()
@@ -600,6 +642,33 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
}
}
+void LLSidepanelItemInfo::startObjectInventoryObserver()
+{
+ if (!mObjectInventoryObserver)
+ {
+ stopObjectInventoryObserver();
+
+ // Previous object observer should be removed before starting to observe a new object.
+ llassert(mObjectInventoryObserver == NULL);
+ }
+
+ if (mObjectID.isNull())
+ {
+ llwarns << "Empty object id passed to inventory observer" << llendl;
+ return;
+ }
+
+ LLViewerObject* object = gObjectList.findObject(mObjectID);
+
+ mObjectInventoryObserver = new LLObjectInventoryObserver(this, object);
+}
+
+void LLSidepanelItemInfo::stopObjectInventoryObserver()
+{
+ delete mObjectInventoryObserver;
+ mObjectInventoryObserver = NULL;
+}
+
void LLSidepanelItemInfo::onClickCreator()
{
LLViewerInventoryItem* item = findItem();
diff --git a/indra/newview/llsidepaneliteminfo.h b/indra/newview/llsidepaneliteminfo.h
index 82ebbfa7ec..10e93dd7de 100644
--- a/indra/newview/llsidepaneliteminfo.h
+++ b/indra/newview/llsidepaneliteminfo.h
@@ -37,6 +37,7 @@
class LLButton;
class LLViewerInventoryItem;
class LLItemPropertiesObserver;
+class LLObjectInventoryObserver;
class LLViewerObject;
class LLPermissions;
@@ -63,9 +64,13 @@ protected:
void refreshFromItem(LLViewerInventoryItem* item);
private:
+ void startObjectInventoryObserver();
+ void stopObjectInventoryObserver();
+
LLUUID mItemID; // inventory UUID for the inventory item.
LLUUID mObjectID; // in-world task UUID, or null if in agent inventory.
LLItemPropertiesObserver* mPropertiesObserver; // for syncing changes to item
+ LLObjectInventoryObserver* mObjectInventoryObserver; // for syncing changes to items inside an object
//
// UI Elements
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 88e37b815f..9ee504cc4c 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -568,8 +568,9 @@ void LLSideTray::toggleTabButton(LLSideTrayTab* tab)
{
LLButton* btn = it->second;
bool new_state = !btn->getToggleState();
- btn->setToggleState(new_state);
- btn->setImageOverlay( new_state ? tab->mImageSelected : tab->mImage );
+ btn->setToggleState(new_state);
+ // Only highlight the tab if side tray is expanded (STORM-157).
+ btn->setImageOverlay( new_state && !getCollapsed() ? tab->mImageSelected : tab->mImage );
}
}
@@ -762,8 +763,15 @@ bool LLSideTray::removeTab(LLSideTrayTab* tab)
// Deselect the tab.
if (mActiveTab == tab)
{
- child_vector_iter_t next_tab_it =
- (tab_it < (mTabs.end() - 1)) ? tab_it + 1 : mTabs.begin();
+ // Select the next tab (or first one, if we're removing the last tab),
+ // skipping the fake open/close tab (STORM-155).
+ child_vector_iter_t next_tab_it = tab_it;
+ do
+ {
+ next_tab_it = (next_tab_it < (mTabs.end() - 1)) ? next_tab_it + 1 : mTabs.begin();
+ }
+ while ((*next_tab_it)->getName() == "sidebar_openclose");
+
selectTabByName((*next_tab_it)->getName(), true); // Don't hide the tab being removed.
}
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 08ba8c13b1..949fa3cc1c 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -310,6 +310,7 @@ class WindowsManifest(ViewerManifest):
self.path(src="licenses-win32.txt", dst="licenses.txt")
self.path("featuretable.txt")
+ self.path("featuretable_xp.txt")
# For use in crash reporting (generates minidumps)
self.path("dbghelp.dll")