diff options
author | angela <angela@lindenlab.com> | 2010-02-23 11:44:56 +0800 |
---|---|---|
committer | angela <angela@lindenlab.com> | 2010-02-23 11:44:56 +0800 |
commit | e98d6a910a39671225f1af627570aee58517ea7f (patch) | |
tree | 9d0d28c80be1fd23166061e20bfce3d15a924e33 /indra/newview | |
parent | 0eea585ef13426bf343fb5bcc3642cdfc769c022 (diff) | |
parent | 37291bea8d9b5a626b449d984856e280e159ac5c (diff) |
merg and resolve conflicts
Diffstat (limited to 'indra/newview')
19 files changed, 542 insertions, 211 deletions
diff --git a/indra/newview/linux_tools/client-readme.txt b/indra/newview/linux_tools/client-readme.txt index 92d321d8c0..e01b9e4bc6 100644 --- a/indra/newview/linux_tools/client-readme.txt +++ b/indra/newview/linux_tools/client-readme.txt @@ -15,7 +15,7 @@ Life itself - please see <http://www.secondlife.com/whatis/>. 5.3. Blank window after minimizing it 5.4. Audio 5.5. 'Alt' key for camera controls doesn't work - 5.6. In-world streaming movie/music playback + 5.6. In-world streaming movie, music and Flash playback 6. Advanced Troubleshooting 6.1. Audio 6.2. OpenGL @@ -169,12 +169,15 @@ SOLUTION:- Some window managers eat the Alt key for their own purposes; you example, the 'Windows' key!) which will allow the Alt key to function properly with mouse actions in Second Life and other applications. -PROBLEM 6:- In-world movie and/or music playback doesn't work for me. +PROBLEM 6:- In-world movie, music, or Flash playback doesn't work for me. SOLUTION:- You need to have a working installation of GStreamer 0.10; this is usually an optional package for most versions of Linux. If you have installed GStreamer 0.10 and you can play some music/movies but not others then you need to install a wider selection of GStreamer plugins, either - from your vendor or an appropriate third party. + from your vendor (i.e. the 'Ugly' plugins) or an appropriate third party. + For Flash playback, you need to have Flash 10 installed for your normal + web browser (for example, Firefox). PulseAudio is required for Flash + volume control / muting to fully function inside Second Life. 6. ADVANCED TROUBLESHOOTING diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index f4bc35002b..08cd101b01 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -286,6 +286,7 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i } if (mTodo & CALL_RECOVERDONE) { + LLAppearanceManager::instance().addCOFItemLink(inv_item,false); gAgentWearables.recoverMissingWearableDone(); } /* @@ -1038,7 +1039,7 @@ void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void* { return; } - + if (wearable) { llassert(type == wearable->getType()); @@ -1057,6 +1058,7 @@ void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void* // Somehow the asset doesn't exist in the database. gAgentWearables.recoverMissingWearable(type,index); } + gInventory.notifyObservers(); @@ -1576,7 +1578,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it const LLDynamicArray< LLWearable* >& wearables, BOOL remove) { - lldebugs << "setWearableOutfit() start" << llendl; + llinfos << "setWearableOutfit() start" << llendl; BOOL wearables_to_remove[WT_COUNT]; wearables_to_remove[WT_SHAPE] = FALSE; @@ -2485,7 +2487,7 @@ class LLFetchAndLinkObserver: public LLInventoryFetchObserver public: LLFetchAndLinkObserver(LLInventoryFetchObserver::item_ref_t& ids): m_ids(ids), - LLInventoryFetchObserver(true) + LLInventoryFetchObserver(true) // retry for missing items { } ~LLFetchAndLinkObserver() @@ -2494,7 +2496,9 @@ public: virtual void done() { gInventory.removeObserver(this); + // Link to all fetched items in COF. + LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy; for (LLInventoryFetchObserver::item_ref_t::iterator it = m_ids.begin(); it != m_ids.end(); ++it) @@ -2506,8 +2510,13 @@ public: llwarns << "fetch failed!" << llendl; continue; } - link_inventory_item(gAgent.getID(), item->getLinkedUUID(), LLAppearanceManager::instance().getCOF(), item->getName(), - LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL)); + + link_inventory_item(gAgent.getID(), + item->getLinkedUUID(), + LLAppearanceManager::instance().getCOF(), + item->getName(), + LLAssetType::AT_LINK, + link_waiter); } } private: @@ -2530,11 +2539,13 @@ void LLInitialWearablesFetch::processWearablesMessage() #ifdef USE_CURRENT_OUTFIT_FOLDER ids.push_back(wearable_data->mItemID); #endif - // Fetch the wearables - LLWearableList::instance().getAsset(wearable_data->mAssetID, - LLStringUtil::null, - LLWearableDictionary::getAssetType(wearable_data->mType), - LLAgentWearables::onInitialWearableAssetArrived, (void*)(wearable_data)); +#if 0 +// // Fetch the wearables +// LLWearableList::instance().getAsset(wearable_data->mAssetID, +// LLStringUtil::null, +// LLWearableDictionary::getAssetType(wearable_data->mType), +// LLAgentWearables::onInitialWearableAssetArrived, (void*)(wearable_data)); +#endif } else { diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index eb4a47664b..c9da08701d 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -301,50 +301,52 @@ void LLOutfitFetch::done() delete this; } -class LLUpdateAppearanceOnDestroy: public LLInventoryCallback +LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(): + mFireCount(0) { -public: - LLUpdateAppearanceOnDestroy(): - mFireCount(0) - { - } +} - virtual ~LLUpdateAppearanceOnDestroy() +LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy() +{ + llinfos << "done update appearance on destroy" << llendl; + + if (!LLApp::isExiting()) { - llinfos << "done update appearance on destroy" << llendl; - - if (!LLApp::isExiting()) - { - LLAppearanceManager::instance().updateAppearanceFromCOF(); - } + LLAppearanceManager::instance().updateAppearanceFromCOF(); } +} - /* virtual */ void fire(const LLUUID& inv_item) - { - llinfos << "callback fired" << llendl; - mFireCount++; - } -private: - U32 mFireCount; -}; +void LLUpdateAppearanceOnDestroy::fire(const LLUUID& inv_item) +{ + llinfos << "callback fired" << llendl; + mFireCount++; +} struct LLFoundData { - LLFoundData() : mAssetType(LLAssetType::AT_NONE), mWearable(NULL) {} + LLFoundData() : + mAssetType(LLAssetType::AT_NONE), + mWearableType(WT_INVALID), + mWearable(NULL) {} + LLFoundData(const LLUUID& item_id, - const LLUUID& asset_id, - const std::string& name, - LLAssetType::EType asset_type) : + const LLUUID& asset_id, + const std::string& name, + const LLAssetType::EType& asset_type, + const EWearableType& wearable_type + ) : mItemID(item_id), mAssetID(asset_id), mName(name), mAssetType(asset_type), + mWearableType(wearable_type), mWearable( NULL ) {} LLUUID mItemID; LLUUID mAssetID; std::string mName; LLAssetType::EType mAssetType; + EWearableType mWearableType; LLWearable* mWearable; }; @@ -355,14 +357,26 @@ public: LLWearableHoldingPattern(); ~LLWearableHoldingPattern(); - bool pollCompletion(); + bool pollFetchCompletion(); + void onFetchCompletion(); bool isFetchCompleted(); bool isTimedOut(); + + void checkMissingWearables(); + bool pollMissingWearables(); + bool isMissingCompleted(); + void recoverMissingWearable(EWearableType type); + void clearCOFLinksForMissingWearables(); + + void onAllComplete(); typedef std::list<LLFoundData> found_list_t; found_list_t mFoundList; LLInventoryModel::item_array_t mObjItems; LLInventoryModel::item_array_t mGestItems; + typedef std::set<S32> type_set_t; + type_set_t mTypesToRecover; + type_set_t mTypesToLink; S32 mResolved; LLTimer mWaitTime; bool mFired; @@ -389,13 +403,99 @@ bool LLWearableHoldingPattern::isTimedOut() return mWaitTime.getElapsedTimeF32() > max_wait_time; } -bool LLWearableHoldingPattern::pollCompletion() +void LLWearableHoldingPattern::checkMissingWearables() +{ + std::vector<S32> found_by_type(WT_COUNT,0); + std::vector<S32> requested_by_type(WT_COUNT,0); + for (found_list_t::iterator it = mFoundList.begin(); it != mFoundList.end(); ++it) + { + LLFoundData &data = *it; + if (data.mWearableType < WT_COUNT) + requested_by_type[data.mWearableType]++; + if (data.mWearable) + found_by_type[data.mWearableType]++; + } + + for (S32 type = 0; type < WT_COUNT; ++type) + { + llinfos << "type " << type << " requested " << requested_by_type[type] << " found " << found_by_type[type] << llendl; + if (found_by_type[type] > 0) + continue; + if ( + // Need to recover if at least one wearable of that type + // was requested but none was found (prevent missing + // pants) + (requested_by_type[type] > 0) || + // or if type is a body part and no wearables were found. + ((type == WT_SHAPE) || (type == WT_SKIN) || (type == WT_HAIR) || (type == WT_EYES))) + { + mTypesToRecover.insert(type); + mTypesToLink.insert(type); + recoverMissingWearable((EWearableType)type); + llwarns << "need to replace " << type << llendl; + } + } + + if (!pollMissingWearables()) + { + mWaitTime.reset(); + doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollMissingWearables,this)); + } +} + +void LLWearableHoldingPattern::onAllComplete() +{ + // Activate all gestures in this folder + if (mGestItems.count() > 0) + { + llinfos << "Activating " << mGestItems.count() << " gestures" << llendl; + + LLGestureManager::instance().activateGestures(mGestItems); + + // Update the inventory item labels to reflect the fact + // they are active. + LLViewerInventoryCategory* catp = + gInventory.getCategory(LLAppearanceManager::instance().getCOF()); + + if (catp) + { + gInventory.updateCategory(catp); + gInventory.notifyObservers(); + } + } + + // Update wearables. + llinfos << "Updating agent wearables with " << mResolved << " wearable items " << llendl; + LLAppearanceManager::instance().updateAgentWearables(this, false); + + // Update attachments to match those requested. + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if( avatar ) + { + llinfos << "Updating " << mObjItems.count() << " attachments" << llendl; + LLAgentWearables::userUpdateAttachments(mObjItems); + } + + if (isFetchCompleted() && isMissingCompleted()) + { + // Only safe to delete if all wearable callbacks and all missing wearables completed. + delete this; + } +} + +void LLWearableHoldingPattern::onFetchCompletion() +{ + checkMissingWearables(); +} + +// Runs as an idle callback until all wearables are fetched (or we time out). +bool LLWearableHoldingPattern::pollFetchCompletion() { bool completed = isFetchCompleted(); bool timed_out = isTimedOut(); bool done = completed || timed_out; - llinfos << "polling, done status: " << completed << " timed out? " << timed_out << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl; + llinfos << "polling, done status: " << completed << " timed out " << timed_out << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl; if (done) { @@ -406,46 +506,184 @@ bool LLWearableHoldingPattern::pollCompletion() llwarns << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl; } - // Activate all gestures in this folder - if (mGestItems.count() > 0) - { - llinfos << "Activating " << mGestItems.count() << " gestures" << llendl; - - LLGestureManager::instance().activateGestures(mGestItems); - - // Update the inventory item labels to reflect the fact - // they are active. - LLViewerInventoryCategory* catp = - gInventory.getCategory(LLAppearanceManager::instance().getCOF()); + onFetchCompletion(); + } + return done; +} - if (catp) - { - gInventory.updateCategory(catp); - gInventory.notifyObservers(); - } - } +class RecoveredItemLinkCB: public LLInventoryCallback +{ +public: + RecoveredItemLinkCB(EWearableType type, LLWearable *wearable, LLWearableHoldingPattern* holder): + mHolder(holder), + mWearable(wearable), + mType(type) + { + } + void fire(const LLUUID& item_id) + { + llinfos << "Recovered item link for type " << mType << llendl; + mHolder->mTypesToLink.erase(mType); + // Add wearable to FoundData for actual wearing + LLViewerInventoryItem *item = gInventory.getItem(item_id); + LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL; - // Update wearables. - llinfos << "Updating agent wearables with " << mResolved << " wearable items " << llendl; - LLAppearanceManager::instance().updateAgentWearables(this, false); - - // Update attachments to match those requested. - LLVOAvatar* avatar = gAgent.getAvatarObject(); - if( avatar ) + gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID()); + + if (item && linked_item) { - llinfos << "Updating " << mObjItems.count() << " attachments" << llendl; - LLAgentWearables::userUpdateAttachments(mObjItems); + LLFoundData found(linked_item->getUUID(), + linked_item->getAssetUUID(), + linked_item->getName(), + linked_item->getType(), + linked_item->isWearableType() ? linked_item->getWearableType() : WT_INVALID + ); + found.mWearable = mWearable; + mHolder->mFoundList.push_front(found); } + else + { + llwarns << "inventory item or link not found for recovered wearable" << llendl; + } + } +private: + LLWearableHoldingPattern* mHolder; + LLWearable *mWearable; + EWearableType mType; +}; - if (completed) +class RecoveredItemCB: public LLInventoryCallback +{ +public: + RecoveredItemCB(EWearableType type, LLWearable *wearable, LLWearableHoldingPattern* holder): + mHolder(holder), + mWearable(wearable), + mType(type) + { + } + void fire(const LLUUID& item_id) + { + llinfos << "Recovered item for type " << mType << llendl; + LLViewerInventoryItem *itemp = gInventory.getItem(item_id); + LLPointer<LLInventoryCallback> cb = new RecoveredItemLinkCB(mType,mWearable,mHolder); + mHolder->mTypesToRecover.erase(mType); + link_inventory_item( gAgent.getID(), + item_id, + LLAppearanceManager::instance().getCOF(), + itemp->getName(), + LLAssetType::AT_LINK, + cb); + } +private: + LLWearableHoldingPattern* mHolder; + LLWearable *mWearable; + EWearableType mType; +}; + +void LLWearableHoldingPattern::recoverMissingWearable(EWearableType type) +{ + // Try to recover by replacing missing wearable with a new one. + LLNotificationsUtil::add("ReplacedMissingWearable"); + lldebugs << "Wearable " << LLWearableDictionary::getTypeLabel(type) + << " could not be downloaded. Replaced inventory item with default wearable." << llendl; + LLWearable* wearable = LLWearableList::instance().createNewWearable(type); + + // Add a new one in the lost and found folder. + const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); + LLPointer<LLInventoryCallback> cb = new RecoveredItemCB(type,wearable,this); + + create_inventory_item(gAgent.getID(), + gAgent.getSessionID(), + lost_and_found_id, + wearable->getTransactionID(), + wearable->getName(), + wearable->getDescription(), + wearable->getAssetType(), + LLInventoryType::IT_WEARABLE, + wearable->getType(), + wearable->getPermissions().getMaskNextOwner(), + cb); +} + +bool LLWearableHoldingPattern::isMissingCompleted() +{ + return mTypesToLink.size()==0 && mTypesToRecover.size()==0; +} + +void LLWearableHoldingPattern::clearCOFLinksForMissingWearables() +{ + for (found_list_t::iterator it = mFoundList.begin(); it != mFoundList.end(); ++it) + { + LLFoundData &data = *it; + if ((data.mWearableType < WT_COUNT) && (!data.mWearable)) { - // Only safe to delete if all wearable callbacks completed. - delete this; + // Wearable link that was never resolved; remove links to it from COF + llinfos << "removing link for unresolved item " << data.mItemID.asString() << llendl; + LLAppearanceManager::instance().removeCOFItemLinks(data.mItemID,false); } } +} + +bool LLWearableHoldingPattern::pollMissingWearables() +{ + bool timed_out = isTimedOut(); + bool missing_completed = isMissingCompleted(); + bool done = timed_out || missing_completed; + + llinfos << "polling missing wearables, waiting for items " << mTypesToRecover.size() + << " links " << mTypesToLink.size() + << " wearables, timed out " << timed_out + << " elapsed " << mWaitTime.getElapsedTimeF32() + << " done " << done << llendl; + + if (done) + { + clearCOFLinksForMissingWearables(); + onAllComplete(); + } return done; } +static void onWearableAssetFetch(LLWearable* wearable, void* data) +{ + LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data; + holder->mResolved += 1; // just counting callbacks, not successes. + llinfos << "onWearableAssetFetch, resolved count " << holder->mResolved << " of requested " << holder->mFoundList.size() << llendl; + if (wearable) + { + llinfos << "wearable found, type " << wearable->getType() << " asset " << wearable->getAssetID() << llendl; + } + else + { + llwarns << "no wearable found" << llendl; + } + + if (holder->mFired) + { + llwarns << "called after holder fired" << llendl; + return; + } + + if (!wearable) + { + return; + } + + for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin(); + iter != holder->mFoundList.end(); ++iter) + { + LLFoundData& data = *iter; + if(wearable->getAssetID() == data.mAssetID) + { + data.mWearable = wearable; + // Failing this means inventory or asset server are corrupted in a way we don't handle. + llassert((data.mWearableType < WT_COUNT) && (wearable->getType() == data.mWearableType)); + break; + } + } +} + + static void removeDuplicateItems(LLInventoryModel::item_array_t& items) { LLInventoryModel::item_array_t new_items; @@ -473,30 +711,6 @@ static void removeDuplicateItems(LLInventoryModel::item_array_t& items) items = new_items; } -static void onWearableAssetFetch(LLWearable* wearable, void* data) -{ - LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data; - if (holder->mFired) - { - llwarns << "called after holder fired" << llendl; - } - - if(wearable) - { - for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin(); - iter != holder->mFoundList.end(); ++iter) - { - LLFoundData& data = *iter; - if(wearable->getAssetID() == data.mAssetID) - { - data.mWearable = wearable; - break; - } - } - } - holder->mResolved += 1; -} - const LLUUID LLAppearanceManager::getCOF() const { return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); @@ -718,7 +932,8 @@ void LLAppearanceManager::linkAll(const LLUUID& category, void LLAppearanceManager::updateCOF(const LLUUID& category, bool append) { - llinfos << "starting" << llendl; + LLViewerInventoryCategory *pcat = gInventory.getCategory(category); + llinfos << "starting, cat " << (pcat ? pcat->getName() : "[UNKNOWN]") << llendl; const LLUUID cof = getCOF(); @@ -893,6 +1108,9 @@ void LLAppearanceManager::updateAppearanceFromCOF() // wearables can be resolved immediately, then the // callback will be called (and this object deleted) // before the final getNextData(). + + // BAP future cleanup - no point having found_container when + // mFoundList already has all the info. LLDynamicArray<LLFoundData> found_container; for(S32 i = 0; i < wear_items.count(); ++i) { @@ -903,7 +1121,21 @@ void LLAppearanceManager::updateAppearanceFromCOF() LLFoundData found(linked_item->getUUID(), linked_item->getAssetUUID(), linked_item->getName(), - linked_item->getType()); + linked_item->getType(), + linked_item->isWearableType() ? linked_item->getWearableType() : WT_INVALID + ); + +#if 0 + // Fault injection: uncomment this block to test asset + // fetch failures (should be replaced by new defaults in + // lost&found). + if (found.mWearableType == WT_SHAPE || found.mWearableType == WT_JACKET) + { + found.mAssetID.generate(); // Replace with new UUID, guaranteed not to exist in DB + + } +#endif + holder->mFoundList.push_front(found); found_container.put(found); } @@ -923,7 +1155,9 @@ void LLAppearanceManager::updateAppearanceFromCOF() for(S32 i = 0; i < found_container.count(); ++i) { LLFoundData& found = found_container.get(i); - + + llinfos << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << llendl; + // Fetch the wearables about to be worn. LLWearableList::instance().getAsset(found.mAssetID, found.mName, @@ -933,9 +1167,9 @@ void LLAppearanceManager::updateAppearanceFromCOF() } - if (!holder->pollCompletion()) + if (!holder->pollFetchCompletion()) { - doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollCompletion,holder)); + doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollFetchCompletion,holder)); } } diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 28b51ee0f6..e7e2f33520 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -151,6 +151,18 @@ public: BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const; }; +class LLUpdateAppearanceOnDestroy: public LLInventoryCallback +{ +public: + LLUpdateAppearanceOnDestroy(); + virtual ~LLUpdateAppearanceOnDestroy(); + /* virtual */ void fire(const LLUUID& inv_item); + +private: + U32 mFireCount; +}; + + #define SUPPORT_ENSEMBLES 0 LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 5b59f52fa5..d0513c35ce 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1925,7 +1925,7 @@ bool LLFindCOFValidItems::operator()(LLInventoryCategory* cat, // - links to attachments // - links to gestures // - links to ensemble folders - LLViewerInventoryItem *linked_item = ((LLViewerInventoryItem*)item)->getLinkedItem(); // BAP - safe? + LLViewerInventoryItem *linked_item = ((LLViewerInventoryItem*)item)->getLinkedItem(); if (linked_item) { LLAssetType::EType type = linked_item->getType(); @@ -1936,7 +1936,7 @@ bool LLFindCOFValidItems::operator()(LLInventoryCategory* cat, } else { - LLViewerInventoryCategory *linked_category = ((LLViewerInventoryItem*)item)->getLinkedCategory(); // BAP - safe? + LLViewerInventoryCategory *linked_category = ((LLViewerInventoryItem*)item)->getLinkedCategory(); // BAP remove AT_NONE support after ensembles are fully working? return (linked_category && ((linked_category->getPreferredType() == LLFolderType::FT_NONE) || @@ -2962,8 +2962,6 @@ void LLFolderBridge::modifyOutfit(BOOL append) LLViewerInventoryCategory* cat = getCategory(); if(!cat) return; - // BAP - was: - // wear_inventory_category_on_avatar( cat, append ); LLAppearanceManager::instance().wearInventoryCategory( cat, FALSE, append ); } diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 61463ed843..706787e824 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -337,7 +337,7 @@ void LLPanelGroup::update(LLGroupChange gc) childSetToolTip("group_name",gdatap->mName); LLGroupData agent_gdatap; - bool is_member = gAgent.getGroupData(mID,agent_gdatap); + bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlike(); bool join_btn_visible = !is_member && gdatap->mOpenEnrollment; mButtonJoin->setVisible(join_btn_visible); @@ -466,7 +466,7 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id) } LLGroupData agent_gdatap; - bool is_member = gAgent.getGroupData(mID,agent_gdatap); + bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlike(); tab_roles->setVisible(is_member); tab_notices->setVisible(is_member); diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 6210973dae..5f913d5469 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -652,6 +652,9 @@ void LLPanelGroupNotices::setGroupID(const LLUUID& id) LLGroupDropTarget* target = getChild<LLGroupDropTarget> ("drop_target"); target->setPanel (this); target->setGroup (mGroupID); + + if(mViewMessage) + mViewMessage->clear(); activate(); } diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index e1676d2299..173ff8d68b 100644 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -535,7 +535,9 @@ void LLPanelNearByMedia::refreshParcelItems() const LLSD &choice_llsd = mShowCtrl->getSelectedValue(); MediaClass choice = (MediaClass)choice_llsd.asInteger(); // Only show "special parcel items" if "All" or "Within" filter - bool should_include = choice == MEDIA_CLASS_ALL || choice == MEDIA_CLASS_WITHIN_PARCEL; + // (and if media is "enabled") + bool should_include = gSavedSettings.getBOOL("AudioStreamingMedia") && + (choice == MEDIA_CLASS_ALL || choice == MEDIA_CLASS_WITHIN_PARCEL); // First Parcel Media: add or remove it as necessary if (should_include && LLViewerMedia::hasParcelMedia()) @@ -579,8 +581,8 @@ void LLPanelNearByMedia::refreshParcelItems() "parcel media"); } - // Next Parcel Audio: add or remove it as necessary - if (should_include && LLViewerMedia::hasParcelAudio()) + // Next Parcel Audio: add or remove it as necessary (don't show if disabled in prefs) + if (should_include && LLViewerMedia::hasParcelAudio() && gSavedSettings.getBOOL("AudioStreamingMusic")) { // Yes, there is parcel audio. if (NULL == mParcelAudioItem) @@ -693,14 +695,16 @@ void LLPanelNearByMedia::refreshList() } } } - mDisableAllCtrl->setEnabled(LLViewerMedia::isAnyMediaShowing() || - LLViewerMedia::isParcelMediaPlaying() || - LLViewerMedia::isParcelAudioPlaying()); - mEnableAllCtrl->setEnabled(disabled_count > 0 || - // parcel media (if we have it, and it isn't playing, enable "start") - (LLViewerMedia::hasParcelMedia() && ! LLViewerMedia::isParcelMediaPlaying()) || - // parcel audio (if we have it, and it isn't playing, enable "start") - (LLViewerMedia::hasParcelAudio() && ! LLViewerMedia::isParcelAudioPlaying())); + mDisableAllCtrl->setEnabled(gSavedSettings.getBOOL("AudioStreamingMedia") && + (LLViewerMedia::isAnyMediaShowing() || + LLViewerMedia::isParcelMediaPlaying() || + LLViewerMedia::isParcelAudioPlaying())); + mEnableAllCtrl->setEnabled(gSavedSettings.getBOOL("AudioStreamingMedia") && + (disabled_count > 0 || + // parcel media (if we have it, and it isn't playing, enable "start") + (LLViewerMedia::hasParcelMedia() && ! LLViewerMedia::isParcelMediaPlaying()) || + // parcel audio (if we have it, and it isn't playing, enable "start") + (LLViewerMedia::hasParcelAudio() && ! LLViewerMedia::isParcelAudioPlaying()))); // Iterate over the rows in the control, updating ones whose impl exists, and deleting ones whose impl has gone away. std::vector<LLScrollListItem*> items = mMediaList->getAllData(); @@ -825,10 +829,7 @@ void LLPanelNearByMedia::onZoomMedia(void* user_data) void LLPanelNearByMedia::onClickParcelMediaPlay() { - if (gSavedSettings.getBOOL("AudioStreamingMedia")) - { - LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); - } + LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); } void LLPanelNearByMedia::onClickParcelMediaStop() @@ -854,8 +855,8 @@ void LLPanelNearByMedia::onClickParcelAudioStart() if (!gAudiop) return; + gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL()); - } void LLPanelNearByMedia::onClickParcelAudioPlay() @@ -957,15 +958,29 @@ void LLPanelNearByMedia::onMoreLess() void LLPanelNearByMedia::updateControls() { + if (! gSavedSettings.getBOOL("AudioStreamingMedia")) + { + // Just show disabled controls + showDisabledControls(); + return; + } + LLUUID selected_media_id = mMediaList->getValue().asUUID(); if (selected_media_id == PARCEL_AUDIO_LIST_ITEM_UUID) { - showTimeBasedControls(LLViewerMedia::isParcelAudioPlaying(), + if (!LLViewerMedia::hasParcelAudio() || !gSavedSettings.getBOOL("AudioStreamingMusic")) + { + // Shouldn't happen, but do this anyway + showDisabledControls(); + } + else { + showTimeBasedControls(LLViewerMedia::isParcelAudioPlaying(), false, // include_zoom false, // is_zoomed gSavedSettings.getBOOL("MuteMusic"), gSavedSettings.getF32("AudioLevelMusic") ); + } } else if (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) { @@ -1079,15 +1094,18 @@ void LLPanelNearByMedia::onClickSelectedMediaPlay() { LLViewerMediaImpl *impl = (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) ? ((LLViewerMediaImpl*)LLViewerParcelMedia::getParcelMedia()) : LLViewerMedia::getMediaImplFromTextureID(selected_media_id); - if (NULL != impl && impl->isMediaTimeBased() && impl->isMediaPaused()) - { - // Aha! It's really time-based media that's paused, so unpause - impl->play(); - return; - } - else if (NULL != impl && impl->isParcelMedia()) + if (NULL != impl) { - LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); + if (impl->isMediaTimeBased() && impl->isMediaPaused()) + { + // Aha! It's really time-based media that's paused, so unpause + impl->play(); + return; + } + else if (impl->isParcelMedia()) + { + LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); + } } } } diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index e83c882866..732c23982b 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -358,8 +358,10 @@ void LLStatusBar::refresh() bool mute_audio = LLAppViewer::instance()->getMasterSystemAudioMute(); mBtnVolume->setToggleState(mute_audio); - // Don't show media toggle if there's no media, parcel media, and no parcel audio - mMediaToggle->setVisible(LLViewerMedia::hasInWorldMedia() || LLViewerMedia::hasParcelMedia() || LLViewerMedia::hasParcelAudio()); + // Disable media toggle if there's no media, parcel media, and no parcel audio + // (or if media is disabled) + mMediaToggle->setEnabled(gSavedSettings.getBOOL("AudioStreamingMedia") && + (LLViewerMedia::hasInWorldMedia() || LLViewerMedia::hasParcelMedia() || LLViewerMedia::hasParcelAudio())); // Note the "sense" of the toggle is opposite whether media is playing or not mMediaToggle->setValue(! (LLViewerMedia::isAnyMediaShowing() || LLViewerMedia::isParcelMediaPlaying() || @@ -547,13 +549,13 @@ void LLStatusBar::onMouseEnterNearbyMedia() LLButton* nearby_media_btn = getChild<LLButton>( "media_toggle_btn" ); LLRect nearby_media_btn_rect = nearby_media_btn->calcScreenRect(); nearby_media_rect.setLeftTopAndSize(nearby_media_btn_rect.mLeft - - (nearby_media_rect.getWidth() - nearby_media_btn_rect.getWidth())/2, - nearby_media_btn_rect.mBottom, - nearby_media_rect.getWidth(), - nearby_media_rect.getHeight()); + (nearby_media_rect.getWidth() - nearby_media_btn_rect.getWidth())/2, + nearby_media_btn_rect.mBottom, + nearby_media_rect.getWidth(), + nearby_media_rect.getHeight()); // force onscreen nearby_media_rect.translate(popup_holder->getRect().getWidth() - nearby_media_rect.mRight, 0); - + // show the master volume pull-down mPanelNearByMedia->setShape(nearby_media_rect); mPanelNearByMedia->setVisible(TRUE); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index f1ca56a8ae..86336e353c 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -952,7 +952,10 @@ void LLViewerMedia::setAllMediaEnabled(bool val) LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); } - if (!LLViewerMedia::isParcelAudioPlaying() && gAudiop && LLViewerMedia::hasParcelAudio()) + if (gSavedSettings.getBOOL("AudioStreamingMusic") && + !LLViewerMedia::isParcelAudioPlaying() && + gAudiop && + LLViewerMedia::hasParcelAudio()) { gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL()); } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 989cfae464..02bde51fb6 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -6897,7 +6897,8 @@ class LLToolsEditLinkedParts : public view_listener_t { bool handleEvent(const LLSD& userdata) { - BOOL select_individuals = gSavedSettings.getBOOL("EditLinkedParts"); + BOOL select_individuals = !gSavedSettings.getBOOL("EditLinkedParts"); + gSavedSettings.setBOOL( "EditLinkedParts", select_individuals ); if (select_individuals) { LLSelectMgr::getInstance()->demoteSelectionToIndividuals(); diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml index 41e53be29e..f913c58cc9 100644 --- a/indra/newview/skins/default/xui/en/panel_group_general.xml +++ b/indra/newview/skins/default/xui/en/panel_group_general.xml @@ -1,9 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel label="General" - follows="all" height="604" - width="303" + width="304" class="panel_group_general" name="general_tab"> <panel.string @@ -26,7 +25,7 @@ Hover your mouse over the options for more help. top="0" left="0" height="129" - width="313" + width="304" layout="topleft"> <texture_picker follows="left|top" diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml index b196d8eeb7..4e57b428bd 100644 --- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml @@ -81,80 +81,129 @@ background_visible="true" width="292" border_size="0"> <layout_panel - bg_alpha_color="DkGray2" - bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" - name="group_accordions" - follows="all" - layout="topleft" - auto_resize="true" - > + bg_alpha_color="DkGray2" + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true" + name="group_accordions" + follows="all" + layout="topleft" + auto_resize="true"> <accordion left="0" top="0" - single_expansion="true" - follows="all" - layout="topleft" - name="groups_accordion"> - <accordion_tab + single_expansion="true" + follows="all" + layout="topleft" + name="groups_accordion"> + <accordion_tab expanded="true" layout="topleft" name="group_general_tab" title="General"> - <panel - border="false" - class="panel_group_general" - filename="panel_group_general.xml" - layout="topleft" - left="0" - follows="all" - help_topic="group_general_tab" - name="group_general_tab_panel" - top="0" /> + <scroll_container + color="DkGray2" + follows="all" + layout="topleft" + left="0" + name="profile_scroll" + opaque="true" + height="604" + width="304" + top="0"> + <panel + border="false" + class="panel_group_general" + filename="panel_group_general.xml" + layout="topleft" + left="0" + follows="left|top|right" + help_topic="group_general_tab" + name="group_general_tab_panel" + top="0" /> + </scroll_container> </accordion_tab> <accordion_tab expanded="false" layout="topleft" name="group_roles_tab" title="Roles"> - <panel - border="false" - class="panel_group_roles" - filename="panel_group_roles.xml" - layout="topleft" - left="0" - name="group_roles_tab_panel" - top="0" /> + <scroll_container + color="DkGray2" + follows="all" + layout="topleft" + left="0" + name="profile_scroll" + opaque="true" + height="680" + width="304" + top="0"> + + <panel + border="false" + class="panel_group_roles" + filename="panel_group_roles.xml" + follows="left|top|right" + layout="topleft" + left="0" + name="group_roles_tab_panel" + top="0" /> + </scroll_container> </accordion_tab> <accordion_tab - expanded="false" + expanded="false" + layout="topleft" + name="group_notices_tab" + title="Notices"> + <scroll_container + color="DkGray2" + follows="all" layout="topleft" - name="group_notices_tab" - title="Notices"> - <panel - border="false" - class="panel_group_notices" - filename="panel_group_notices.xml" - layout="topleft" - left="0" - help_topic="group_notices_tab" - name="group_notices_tab_panel" - top="0" /> + left="0" + name="profile_scroll" + opaque="true" + height="530" + width="304" + top="0"> + + <panel + border="false" + class="panel_group_notices" + filename="panel_group_notices.xml" + follows="left|top|right" + layout="topleft" + left="0" + help_topic="group_notices_tab" + name="group_notices_tab_panel" + top="0" /> + </scroll_container> </accordion_tab> - <accordion_tab - expanded="false" + <accordion_tab + expanded="false" + layout="topleft" + name="group_land_tab" + title="Land/Assets"> + <scroll_container + color="DkGray2" + follows="all" layout="topleft" - name="group_land_tab" - title="Land/Assets"> - <panel - border="false" - class="panel_group_land_money" - filename="panel_group_land_money.xml" - layout="topleft" - left="0" - name="group_land_tab_panel" - top="0" /> + left="0" + name="profile_scroll" + opaque="true" + height="500" + width="304" + top="0"> + + <panel + border="false" + class="panel_group_land_money" + filename="panel_group_land_money.xml" + follows="left|top|right" + layout="topleft" + left="0" + name="group_land_tab_panel" + top="0" /> + </scroll_container> </accordion_tab> </accordion> </layout_panel> diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml index 38b0f234d5..7996a89e72 100644 --- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml @@ -1,14 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel border="false" - follows="all" height="500" label="Land & L$" layout="topleft" left="0" name="land_money_tab" top="0" - width="313"> + width="304"> <panel.string name="help_text"> A warning appears until the Total Land in Use is less than or = to the Total Contribution. diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml index 5f46ad7860..731b3c119c 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml @@ -1,13 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - follows="all" height="530" label="Notices" layout="topleft" left="0" name="notices_tab" top="0" - width="313"> + width="304"> <panel.string name="help_text"> Notices let you send a message and an optionally attached item. @@ -44,7 +43,7 @@ Maximum 200 per group daily right="-1" name="notice_list" top_pad="0" - width="313"> + width="304"> <scroll_list.columns label="" name="icon" diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml index 7557e2cc5e..19c0da4f08 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -1,13 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - follows="all" height="680" label="Members & Roles" layout="topleft" left="0" top="0" name="roles_tab" - width="313"> + width="304"> <panel.string name="default_needs_apply_text"> There are unsaved changes @@ -31,7 +30,7 @@ tab_height="22" tab_min_width="90" top="0" - width="313"> + width="304"> <panel border="false" follows="all" diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml index d72e175bc4..412485e03f 100644 --- a/indra/newview/skins/default/xui/en/panel_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_profile.xml @@ -284,10 +284,11 @@ width="300" /> <expandable_text follows="all" - height="113" + height="103" layout="topleft" left="7" name="sl_groups" + textbox.max_length="512" top_pad="0" translate="false" width="290" diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml index 96c61b69f5..4167401338 100644 --- a/indra/newview/skins/default/xui/en/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml @@ -102,7 +102,7 @@ left_pad="15" top="2" name="media_toggle_btn" - tool_tip="Click to toggle media" + tool_tip="Start/Stop All Media (Music, Video, Web pages)" width="16" > </button> <button diff --git a/indra/newview/skins/default/xui/en/widgets/tab_container.xml b/indra/newview/skins/default/xui/en/widgets/tab_container.xml index 4a163fc1e3..8d6b0c1cfe 100644 --- a/indra/newview/skins/default/xui/en/widgets/tab_container.xml +++ b/indra/newview/skins/default/xui/en/widgets/tab_container.xml @@ -16,17 +16,17 @@ label_pad_left - padding to the left of tab button labels tab_bottom_image_unselected="Toolbar_Left_Off" tab_bottom_image_selected="Toolbar_Left_Selected" tab_left_image_unselected="SegmentedBtn_Left_Disabled" - tab_left_image_selected="SegmentedBtn_Left_Off"/> + tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/> <middle_tab tab_top_image_unselected="TabTop_Middle_Off" tab_top_image_selected="TabTop_Middle_Selected" tab_bottom_image_unselected="Toolbar_Middle_Off" tab_bottom_image_selected="Toolbar_Middle_Selected" tab_left_image_unselected="SegmentedBtn_Left_Disabled" - tab_left_image_selected="SegmentedBtn_Left_Off"/> + tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/> <last_tab tab_top_image_unselected="TabTop_Right_Off" tab_top_image_selected="TabTop_Right_Selected" tab_bottom_image_unselected="Toolbar_Right_Off" tab_bottom_image_selected="Toolbar_Right_Selected" tab_left_image_unselected="SegmentedBtn_Left_Disabled" - tab_left_image_selected="SegmentedBtn_Left_Off"/> + tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/> </tab_container> |