diff options
-rw-r--r-- | indra/llcommon/llmd5.cpp | 37 | ||||
-rw-r--r-- | indra/llcommon/llmd5.h | 11 | ||||
-rw-r--r-- | indra/newview/llappearancemgr.cpp | 1 | ||||
-rw-r--r-- | indra/newview/llcofwearables.cpp | 3 | ||||
-rw-r--r-- | indra/newview/llinventorymodel.cpp | 24 | ||||
-rw-r--r-- | indra/newview/llinventorymodel.h | 4 | ||||
-rw-r--r-- | indra/newview/llinventoryobserver.cpp | 25 | ||||
-rw-r--r-- | indra/newview/llinventoryobserver.h | 6 | ||||
-rw-r--r-- | indra/newview/lloutfitobserver.cpp | 20 | ||||
-rw-r--r-- | indra/newview/lloutfitobserver.h | 3 | ||||
-rw-r--r-- | indra/newview/llpaneleditwearable.cpp | 8 | ||||
-rw-r--r-- | indra/newview/llpaneloutfitedit.cpp | 3 |
12 files changed, 110 insertions, 35 deletions
diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp index da9cb94e13..cc73c3e45c 100644 --- a/indra/llcommon/llmd5.cpp +++ b/indra/llcommon/llmd5.cpp @@ -171,11 +171,6 @@ void LLMD5::update(FILE* file){ } - - - - - // MD5 update for istreams. // Like update for files; see above. @@ -192,9 +187,10 @@ void LLMD5::update(std::istream& stream){ } - - - +void LLMD5::update(const std::string& s) +{ + update((unsigned char *)s.c_str(),s.length()); +} // MD5 finalization. Ends an MD5 message-digest operation, writing the // the message digest and zeroizing the context. @@ -277,7 +273,7 @@ LLMD5::LLMD5(const unsigned char *s) finalize(); } -void LLMD5::raw_digest(unsigned char *s) +void LLMD5::raw_digest(unsigned char *s) const { if (!finalized) { @@ -293,7 +289,7 @@ void LLMD5::raw_digest(unsigned char *s) -void LLMD5::hex_digest(char *s) +void LLMD5::hex_digest(char *s) const { int i; @@ -319,6 +315,7 @@ void LLMD5::hex_digest(char *s) + std::ostream& operator<<(std::ostream &stream, LLMD5 context) { char s[33]; /* Flawfinder: ignore */ @@ -327,13 +324,25 @@ std::ostream& operator<<(std::ostream &stream, LLMD5 context) return stream; } +bool operator==(const LLMD5& a, const LLMD5& b) +{ + unsigned char a_guts[16]; + unsigned char b_guts[16]; + a.raw_digest(a_guts); + b.raw_digest(b_guts); + if (memcmp(a_guts,b_guts,16)==0) + return true; + else + return false; +} - +bool operator!=(const LLMD5& a, const LLMD5& b) +{ + return !(a==b); +} // PRIVATE METHODS: - - void LLMD5::init(){ finalized=0; // we just started! @@ -531,3 +540,5 @@ void LLMD5::decode (uint4 *output, const uint1 *input, const uint4 len){ output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); } + + diff --git a/indra/llcommon/llmd5.h b/indra/llcommon/llmd5.h index df9d7324ab..4e68ba0d5e 100644 --- a/indra/llcommon/llmd5.h +++ b/indra/llcommon/llmd5.h @@ -95,6 +95,7 @@ public: void update (const uint1 *input, const uint4 input_length); void update (std::istream& stream); void update (FILE *file); + void update (const std::string& str); void finalize (); // constructors for special circumstances. All these constructors finalize @@ -105,11 +106,10 @@ public: LLMD5 (const unsigned char *string, const unsigned int number); // methods to acquire finalized result - void raw_digest(unsigned char *array); // provide 16-byte array for binary data - void hex_digest(char *string); // provide 33-byte array for ascii-hex string - friend std::ostream& operator<< (std::ostream&, LLMD5 context); - + void raw_digest(unsigned char *array) const; // provide 16-byte array for binary data + void hex_digest(char *string) const; // provide 33-byte array for ascii-hex string + friend std::ostream& operator<< (std::ostream&, LLMD5 context); private: @@ -131,4 +131,7 @@ private: }; +LL_COMMON_API bool operator==(const LLMD5& a, const LLMD5& b); +LL_COMMON_API bool operator!=(const LLMD5& a, const LLMD5& b); + #endif // LL_LLMD5_H diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index a7d90ab8d3..d2449abf08 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -2209,6 +2209,7 @@ void LLAppearanceMgr::updateIsDirty() LLViewerInventoryItem *item2 = outfit_items.get(i); if (item1->getLinkedUUID() != item2->getLinkedUUID() || + item1->getName() != item2->getName() || item1->LLInventoryItem::getDescription() != item2->LLInventoryItem::getDescription()) { mOutfitIsDirty = true; diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index 86d9121213..f75ea23351 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -393,7 +393,8 @@ void LLCOFWearables::refresh() return; } - if (mCOFVersion == catp->getVersion()) return; + // BAP - removed check; does not detect item name changes. + //if (mCOFVersion == catp->getVersion()) return; mCOFVersion = catp->getVersion(); typedef std::vector<LLSD> values_vector_t; diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 13e5cb516e..5a952bb6a8 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -294,6 +294,30 @@ void LLInventoryModel::getDirectDescendentsOf(const LLUUID& cat_id, items = get_ptr_in_map(mParentChildItemTree, cat_id); } +LLMD5 LLInventoryModel::hashDirectDescendentNames(const LLUUID& cat_id) const +{ + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + getDirectDescendentsOf(cat_id,cat_array,item_array); + LLMD5 item_name_hash; + if (!item_array) + { + item_name_hash.finalize(); + return item_name_hash; + } + for (LLInventoryModel::item_array_t::const_iterator iter = item_array->begin(); + iter != item_array->end(); + iter++) + { + const LLViewerInventoryItem *item = (*iter); + if (!item) + continue; + item_name_hash.update(item->getName()); + } + item_name_hash.finalize(); + return item_name_hash; +} + // SJB: Added version to lock the arrays to catch potential logic bugs void LLInventoryModel::lockDirectDescendentArrays(const LLUUID& cat_id, cat_array_t*& categories, diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 7b56d0bdd1..ff8a5bae9b 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -41,6 +41,7 @@ #include "lluuid.h" #include "llpermissionsflags.h" #include "llstring.h" +#include "llmd5.h" #include <map> #include <set> #include <string> @@ -194,6 +195,9 @@ public: void getDirectDescendentsOf(const LLUUID& cat_id, cat_array_t*& categories, item_array_t*& items) const; + + // Compute a hash of direct descendent names (for detecting child name changes) + LLMD5 hashDirectDescendentNames(const LLUUID& cat_id) const; // Starting with the object specified, add its descendents to the // array provided, but do not add the inventory object specified diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index bd6877d9d3..5416f01033 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -676,7 +676,9 @@ void LLInventoryCategoriesObserver::changed(U32 mask) iter != mCategoryMap.end(); ++iter) { - LLViewerInventoryCategory* category = gInventory.getCategory((*iter).first); + const LLUUID& cat_id = (*iter).first; + + LLViewerInventoryCategory* category = gInventory.getCategory(cat_id); if (!category) continue; @@ -691,7 +693,7 @@ void LLInventoryCategoriesObserver::changed(U32 mask) // Check number of known descendents to find out whether it has changed. LLInventoryModel::cat_array_t* cats; LLInventoryModel::item_array_t* items; - gInventory.getDirectDescendentsOf((*iter).first, cats, items); + gInventory.getDirectDescendentsOf(cat_id, cats, items); if (!cats || !items) { llwarns << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << llendl; @@ -703,20 +705,33 @@ void LLInventoryCategoriesObserver::changed(U32 mask) continue; } - + const S32 current_num_known_descendents = cats->count() + items->count(); LLCategoryData cat_data = (*iter).second; + bool cat_changed = false; + // If category version or descendents count has changed - // update category data in mCategoryMap and fire a callback. + // update category data in mCategoryMap if (version != cat_data.mVersion || current_num_known_descendents != cat_data.mDescendentsCount) { cat_data.mVersion = version; cat_data.mDescendentsCount = current_num_known_descendents; + cat_changed = true; + } - cat_data.mCallback(); + // If any item names have changed, update the name hash + LLMD5 item_name_hash = gInventory.hashDirectDescendentNames(cat_id); + if (cat_data.mItemNameHash != item_name_hash) + { + cat_data.mItemNameHash = item_name_hash; + cat_changed = true; } + + // If anything has changed above, fire the callback. + if (cat_changed) + cat_data.mCallback(); } } diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h index 4a88a65bf8..ccd5fa5f4e 100644 --- a/indra/newview/llinventoryobserver.h +++ b/indra/newview/llinventoryobserver.h @@ -34,6 +34,7 @@ #define LL_LLINVENTORYOBSERVERS_H #include "lluuid.h" +#include "llmd5.h" #include <string> #include <vector> @@ -298,11 +299,14 @@ protected: : mCallback(cb) , mVersion(version) , mDescendentsCount(num_descendents) - {} + { + mItemNameHash.finalize(); + } callback_t mCallback; S32 mVersion; S32 mDescendentsCount; + LLMD5 mItemNameHash; }; typedef std::map<LLUUID, LLCategoryData> category_map_t; diff --git a/indra/newview/lloutfitobserver.cpp b/indra/newview/lloutfitobserver.cpp index 03414b9964..60c941b456 100644 --- a/indra/newview/lloutfitobserver.cpp +++ b/indra/newview/lloutfitobserver.cpp @@ -40,6 +40,7 @@ LLOutfitObserver::LLOutfitObserver() : mCOFLastVersion(LLViewerInventoryCategory::VERSION_UNKNOWN) { + mItemNameHash.finalize(); gInventory.addObserver(this); } @@ -87,13 +88,24 @@ bool LLOutfitObserver::checkCOF() if (cof.isNull()) return false; + bool cof_changed = false; + LLMD5 item_name_hash = gInventory.hashDirectDescendentNames(cof); + if (item_name_hash != mItemNameHash) + { + cof_changed = true; + mItemNameHash = item_name_hash; + } + S32 cof_version = getCategoryVersion(cof); + if (cof_version != mCOFLastVersion) + { + cof_changed = true; + mCOFLastVersion = cof_version; + } - if (cof_version == mCOFLastVersion) + if (!cof_changed) return false; - - mCOFLastVersion = cof_version; - + // dirtiness state should be updated before sending signal LLAppearanceMgr::getInstance()->updateIsDirty(); mCOFChanged(); diff --git a/indra/newview/lloutfitobserver.h b/indra/newview/lloutfitobserver.h index 3a66b5ea9f..4bb2b9b5ec 100644 --- a/indra/newview/lloutfitobserver.h +++ b/indra/newview/lloutfitobserver.h @@ -34,6 +34,7 @@ #define LL_OUTFITOBSERVER_H #include "llsingleton.h" +#include "llmd5.h" /** * Outfit observer facade that provides simple possibility to subscribe on @@ -84,6 +85,8 @@ protected: bool mLastOutfitDirtiness; + LLMD5 mItemNameHash; + private: signal_t mBOFReplaced; signal_t mBOFChanged; diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index f7e8a7b1a7..ddb5f49ab0 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -786,7 +786,7 @@ BOOL LLPanelEditWearable::isDirty() const if (mWearablePtr) { if (mWearablePtr->isDirty() || - mWearablePtr->getName().compare(mNameEditor->getText()) != 0) + mWearableItem->getName().compare(mNameEditor->getText()) != 0) { isDirty = TRUE; } @@ -987,7 +987,7 @@ void LLPanelEditWearable::saveChanges(bool force_save_as) // the name of the wearable has changed, re-save wearable with new name LLAppearanceMgr::instance().removeCOFItemLinks(mWearablePtr->getItemID(),false); gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, new_name, FALSE); - mNameEditor->setText(mWearablePtr->getName()); + mNameEditor->setText(mWearableItem->getName()); } else { @@ -1004,7 +1004,7 @@ void LLPanelEditWearable::revertChanges() } mWearablePtr->revertValues(); - mNameEditor->setText(mWearablePtr->getName()); + mNameEditor->setText(mWearableItem->getName()); updatePanelPickerControls(mWearablePtr->getType()); updateTypeSpecificControls(mWearablePtr->getType()); gAgentAvatarp->wearableUpdated(mWearablePtr->getType(), FALSE); @@ -1050,7 +1050,7 @@ void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show) mDescTitle->setText(description_title); // set name - mNameEditor->setText(wearable->getName()); + mNameEditor->setText(mWearableItem->getName()); updatePanelPickerControls(type); updateTypeSpecificControls(type); diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 571261ff5b..767b01f039 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -1102,9 +1102,6 @@ void LLPanelOutfitEdit::getSelectedItemsUUID(uuid_vec_t& uuid_list) void LLPanelOutfitEdit::onCOFChanged() { - //the panel is only updated when is visible to a user - if (!isInVisibleChain()) return; - update(); } |