diff options
Diffstat (limited to 'indra/newview')
124 files changed, 3050 insertions, 2382 deletions
diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index 14025c8061..0805e94b10 100644 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -268,8 +268,8 @@ ATTACH_LHIP Passed to llAttachToAvatar to attach task to left hip ATTACH_LULEG Passed to llAttachToAvatar to attach task to left upper leg ATTACH_LLLEG Passed to llAttachToAvatar to attach task to left lower leg ATTACH_BELLY Passed to llAttachToAvatar to attach task to belly -ATTACH_RPEC Passed to llAttachToAvatar to attach task to right pectoral -ATTACH_LPEC Passed to llAttachToAvatar to attach task to left pectoral +ATTACH_LEFT_PEC Passed to llAttachToAvatar to attach task to left pectoral +ATTACH_RIGHT_PEC Passed to llAttachToAvatar to attach task to right pectoral LAND_LEVEL Passed to llModifyLand to level terrain LAND_RAISE Passed to llModifyLand to raise terrain diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 91126cb0fc..ffe8762f03 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1145,17 +1145,6 @@ <key>Value</key> <integer>5</integer> </map> - <key>CallFloaterMaxItems</key> - <map> - <key>Comment</key> - <string>Max number of visible participants in voice controls window</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>1</integer> - </map> <key>CameraAngle</key> <map> <key>Comment</key> @@ -3629,7 +3618,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>http://int.searchwww-phx0.damballah.lindenlab.com/viewer/[CATEGORY]?q=[QUERY]&p=[AUTH_TOKEN]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]</string> + <string>http://search.secondlife.com/viewer/[CATEGORY]?q=[QUERY]&p=[AUTH_TOKEN]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]</string> </map> <key>HighResSnapshot</key> <map> @@ -10104,6 +10093,18 @@ <key>Value</key> <integer>0</integer> </map> + <key>SpeakerParticipantRemoveDelay</key> + <map> + <key>Comment</key> + <string>Timeout to remove participants who is not in channel before removed from list of active speakers (text/voice chat)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>10.0</real> + </map> + <key>UseStartScreen</key> <map> <key>Comment</key> diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 748d8bdfbf..03180b6a9d 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -274,6 +274,7 @@ private: struct LLFoundData { + LLFoundData() {} LLFoundData(const LLUUID& item_id, const LLUUID& asset_id, const std::string& name, @@ -292,20 +293,94 @@ struct LLFoundData }; -struct LLWearableHoldingPattern +class LLWearableHoldingPattern { - LLWearableHoldingPattern() : mResolved(0) {} - ~LLWearableHoldingPattern() - { - for_each(mFoundList.begin(), mFoundList.end(), DeletePointer()); - mFoundList.clear(); - } - typedef std::list<LLFoundData*> found_list_t; +public: + LLWearableHoldingPattern(); + ~LLWearableHoldingPattern(); + + bool pollCompletion(); + bool isDone(); + bool isTimedOut(); + + typedef std::list<LLFoundData> found_list_t; found_list_t mFoundList; + LLInventoryModel::item_array_t mObjItems; + LLInventoryModel::item_array_t mGestItems; S32 mResolved; - bool append; + LLTimer mWaitTime; }; +LLWearableHoldingPattern::LLWearableHoldingPattern(): + mResolved(0) +{ +} + +LLWearableHoldingPattern::~LLWearableHoldingPattern() +{ +} + +bool LLWearableHoldingPattern::isDone() +{ + if (mResolved >= (S32)mFoundList.size()) + return true; // have everything we were waiting for + else if (isTimedOut()) + { + llwarns << "Exceeded max wait time, updating appearance based on what has arrived" << llendl; + return true; + } + return false; + +} + +bool LLWearableHoldingPattern::isTimedOut() +{ + static F32 max_wait_time = 15.0; // give up if wearable fetches haven't completed in max_wait_time seconds. + return mWaitTime.getElapsedTimeF32() > max_wait_time; +} + +bool LLWearableHoldingPattern::pollCompletion() +{ + bool done = isDone(); + llinfos << "polling, done status: " << done << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl; + if (done) + { + // 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); + } + + delete this; + } + return done; +} + static void removeDuplicateItems(LLInventoryModel::item_array_t& items) { LLInventoryModel::item_array_t new_items; @@ -336,29 +411,24 @@ static void removeDuplicateItems(LLInventoryModel::item_array_t& items) static void onWearableAssetFetch(LLWearable* wearable, void* data) { LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data; - bool append = holder->append; 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) + LLFoundData& data = *iter; + if(wearable->getAssetID() == data.mAssetID) { - data->mWearable = wearable; + data.mWearable = wearable; break; } } } holder->mResolved += 1; - if(holder->mResolved >= (S32)holder->mFoundList.size()) - { - LLAppearanceManager::instance().updateAgentWearables(holder, append); - } } -LLUUID LLAppearanceManager::getCOF() +const LLUUID LLAppearanceManager::getCOF() const { return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); } @@ -662,12 +732,12 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder, for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin(); iter != holder->mFoundList.end(); ++iter) { - LLFoundData* data = *iter; - LLWearable* wearable = data->mWearable; + LLFoundData& data = *iter; + LLWearable* wearable = data.mWearable; if( wearable && ((S32)wearable->getType() == i) ) { LLViewerInventoryItem* item; - item = (LLViewerInventoryItem*)gInventory.getItem(data->mItemID); + item = (LLViewerInventoryItem*)gInventory.getItem(data.mItemID); if( item && (item->getAssetUUID() == wearable->getAssetID()) ) { items.put(item); @@ -683,8 +753,6 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder, gAgentWearables.setWearableOutfit(items, wearables, !append); } - delete holder; - // dec_busy_count(); } @@ -706,86 +774,66 @@ void LLAppearanceManager::updateAppearanceFromCOF() LLInventoryModel::item_array_t gest_items; getUserDescendents(current_outfit_id, wear_items, obj_items, gest_items, follow_folder_links); - if( !wear_items.count() && !obj_items.count() && !gest_items.count()) + if(!wear_items.count()) { LLNotificationsUtil::add("CouldNotPutOnOutfit"); return; } - - // Processes that take time should show the busy cursor - //inc_busy_count(); // BAP this is currently a no-op in llinventorybridge.cpp - do we need it? - - // Activate all gestures in this folder - if (gest_items.count() > 0) - { - llinfos << "Activating " << gest_items.count() << " gestures" << llendl; - LLGestureManager::instance().activateGestures(gest_items); + LLWearableHoldingPattern* holder = new LLWearableHoldingPattern; - // Update the inventory item labels to reflect the fact - // they are active. - LLViewerInventoryCategory* catp = gInventory.getCategory(current_outfit_id); - if (catp) + holder->mObjItems = obj_items; + holder->mGestItems = gest_items; + + // Note: can't do normal iteration, because if all the + // wearables can be resolved immediately, then the + // callback will be called (and this object deleted) + // before the final getNextData(). + LLDynamicArray<LLFoundData> found_container; + for(S32 i = 0; i < wear_items.count(); ++i) + { + LLViewerInventoryItem *item = wear_items.get(i); + LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL; + if (item && linked_item) { - gInventory.updateCategory(catp); - gInventory.notifyObservers(); + LLFoundData found(linked_item->getUUID(), + linked_item->getAssetUUID(), + linked_item->getName(), + linked_item->getType()); + holder->mFoundList.push_front(found); + found_container.put(found); } - } - - if(wear_items.count() > 0) - { - // Note: can't do normal iteration, because if all the - // wearables can be resolved immediately, then the - // callback will be called (and this object deleted) - // before the final getNextData(). - LLWearableHoldingPattern* holder = new LLWearableHoldingPattern; - LLFoundData* found; - LLDynamicArray<LLFoundData*> found_container; - for(S32 i = 0; i < wear_items.count(); ++i) + else { - LLViewerInventoryItem *item = wear_items.get(i); - LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL; - if (item && linked_item) + if (!item) { - found = new LLFoundData(linked_item->getUUID(), - linked_item->getAssetUUID(), - linked_item->getName(), - linked_item->getType()); - holder->mFoundList.push_front(found); - found_container.put(found); + llwarns << "attempt to wear a null item " << llendl; } - else + else if (!linked_item) { - if (!item) - { - llwarns << "attempt to wear a null item " << llendl; - } - else if (!linked_item) - { - llwarns << "attempt to wear a broken link " << item->getName() << llendl; - } + llwarns << "attempt to wear a broken link " << item->getName() << llendl; } } - for(S32 i = 0; i < found_container.count(); ++i) - { - holder->append = false; - found = found_container.get(i); + } + + for(S32 i = 0; i < found_container.count(); ++i) + { + LLFoundData& found = found_container.get(i); - // Fetch the wearables about to be worn. - LLWearableList::instance().getAsset(found->mAssetID, - found->mName, - found->mAssetType, - onWearableAssetFetch, - (void*)holder); - } + // Fetch the wearables about to be worn. + LLWearableList::instance().getAsset(found.mAssetID, + found.mName, + found.mAssetType, + onWearableAssetFetch, + (void*)holder); + } - // Update attachments to match those requested. - LLVOAvatar* avatar = gAgent.getAvatarObject(); - if( avatar ) + if (!holder->pollCompletion()) { - LLAgentWearables::userUpdateAttachments(obj_items); + doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollCompletion,holder)); } + } void LLAppearanceManager::getDescendentsOfAssetType(const LLUUID& category, @@ -1263,3 +1311,23 @@ void LLAppearanceManager::linkRegisteredAttachments() } mRegisteredAttachments.clear(); } + +BOOL LLAppearanceManager::getIsInCOF(const LLUUID& obj_id) const +{ + return gInventory.isObjectDescendentOf(obj_id, getCOF()); +} + +BOOL LLAppearanceManager::getIsProtectedCOFItem(const LLUUID& obj_id) const +{ + if (!getIsInCOF(obj_id)) return FALSE; + const LLInventoryObject *obj = gInventory.getObject(obj_id); + if (!obj) return FALSE; + + // Can't delete bodyparts, since this would be equivalent to removing the item. + if (obj->getType() == LLAssetType::AT_BODYPART) return TRUE; + + // Can't delete the folder link, since this is saved for bookkeeping. + if (obj->getActualType() == LLAssetType::AT_LINK_FOLDER) return TRUE; + + return FALSE; +} diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 20745b70e4..dd50b482cf 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -39,7 +39,7 @@ #include "llcallbacklist.h" class LLWearable; -struct LLWearableHoldingPattern; +class LLWearableHoldingPattern; class LLAppearanceManager: public LLSingleton<LLAppearanceManager> { @@ -59,7 +59,7 @@ public: LLPointer<LLInventoryCallback> cb); // Find the Current Outfit folder. - LLUUID getCOF(); + const LLUUID getCOF() const; // Finds the folder link to the currently worn outfit const LLViewerInventoryItem *getBaseOutfitLink(); @@ -132,6 +132,14 @@ private: std::set<LLUUID> mRegisteredAttachments; bool mAttachmentInvLinkEnabled; bool mOutfitIsDirty; + + ////////////////////////////////////////////////////////////////////////////////// + // Item-specific convenience functions +public: + // Is this in the COF? + BOOL getIsInCOF(const LLUUID& obj_id) const; + // Is this in the COF and can the user delete it from the COF? + BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const; }; #define SUPPORT_ENSEMBLES 0 @@ -168,4 +176,40 @@ void doOnIdle(T callable) gIdleCallbacks.addFunction(&OnIdleCallback<T>::onIdle,cb_functor); } +// Shim class and template function to allow arbitrary boost::bind +// expressions to be run as recurring idle callbacks. +template <typename T> +class OnIdleCallbackRepeating +{ +public: + OnIdleCallbackRepeating(T callable): + mCallable(callable) + { + } + // Will keep getting called until the callable returns false. + static void onIdle(void *data) + { + OnIdleCallbackRepeating<T>* self = reinterpret_cast<OnIdleCallbackRepeating<T>*>(data); + bool done = self->call(); + if (done) + { + gIdleCallbacks.deleteFunction(onIdle, data); + delete self; + } + } + bool call() + { + return mCallable(); + } +private: + T mCallable; +}; + +template <typename T> +void doOnIdleRepeating(T callable) +{ + OnIdleCallbackRepeating<T>* cb_functor = new OnIdleCallbackRepeating<T>(callable); + gIdleCallbacks.addFunction(&OnIdleCallbackRepeating<T>::onIdle,cb_functor); +} + #endif diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 87be68d0e2..b4a3cd2079 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -930,7 +930,6 @@ bool LLAppViewer::mainLoop() { LLMemType mt1(LLMemType::MTYPE_MAIN); mMainloopTimeout = new LLWatchdogTimeout(); - // *FIX:Mani - Make this a setting, once new settings exist in this branch. //------------------------------------------- // Run main loop until time to quit @@ -940,12 +939,13 @@ bool LLAppViewer::mainLoop() gServicePump = new LLPumpIO(gAPRPoolp); LLHTTPClient::setPump(*gServicePump); LLCurl::setCAFile(gDirUtilp->getCAFile()); + LLCurl::setSSLVerify(! gSavedSettings.getBOOL("NoVerifySSLCert")); // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated. LLVoiceChannel::initClass(); LLVoiceClient::init(gServicePump); - + LLTimer frameTimer,idleTimer; LLTimer debugTime; LLViewerJoystick* joystick(LLViewerJoystick::getInstance()); diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 988867ef84..bd68d52868 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -322,7 +322,7 @@ void LLBottomTray::setVisible(BOOL visible) // Chat bar and gesture button are shown even in mouselook mode. // But the move, camera and snapshot buttons shouldn't be displayed. See EXT-3988. - if ("chat_bar" == name || "gesture_panel" == name) + if ("chat_bar" == name || "gesture_panel" == name || (visibility && ("movement_panel" == name || "cam_panel" == name || "snapshot_panel" == name))) continue; else { diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index 6317a6a392..d4c8adadc6 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -51,9 +51,9 @@ #include "lltransientfloatermgr.h" #include "llviewerwindow.h" #include "llvoicechannel.h" -#include "lllayoutstack.h" static void get_voice_participants_uuids(std::vector<LLUUID>& speakers_uuids); +void reshape_floater(LLCallFloater* floater, S32 delta_height); class LLNonAvatarCaller : public LLAvatarListItem { @@ -93,22 +93,6 @@ static void* create_non_avatar_caller(void*) return new LLNonAvatarCaller; } -LLCallFloater::LLAvatarListItemRemoveTimer::LLAvatarListItemRemoveTimer(callback_t remove_cb, F32 period, const LLUUID& speaker_id) -: LLEventTimer(period) -, mRemoveCallback(remove_cb) -, mSpeakerId(speaker_id) -{ -} - -BOOL LLCallFloater::LLAvatarListItemRemoveTimer::tick() -{ - if (mRemoveCallback) - { - mRemoveCallback(mSpeakerId); - } - return TRUE; -} - LLVoiceChannel* LLCallFloater::sCurrentVoiceCanel = NULL; LLCallFloater::LLCallFloater(const LLSD& key) @@ -122,10 +106,9 @@ LLCallFloater::LLCallFloater(const LLSD& key) , mSpeakingIndicator(NULL) , mIsModeratorMutedVoice(false) , mInitParticipantsVoiceState(false) -, mVoiceLeftRemoveDelay(10) { static LLUICachedControl<S32> voice_left_remove_delay ("VoiceParticipantLeftRemoveDelay", 10); - mVoiceLeftRemoveDelay = voice_left_remove_delay; + mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLCallFloater::removeVoiceLeftParticipant, this, _1), voice_left_remove_delay); mFactoryMap["non_avatar_caller"] = LLCallbackMap(create_non_avatar_caller, NULL); LLVoiceClient::getInstance()->addObserver(this); @@ -135,6 +118,7 @@ LLCallFloater::LLCallFloater(const LLSD& key) LLCallFloater::~LLCallFloater() { resetVoiceRemoveTimers(); + delete mSpeakerDelayRemover; delete mParticipants; mParticipants = NULL; @@ -225,16 +209,6 @@ void LLCallFloater::onChange() } } -S32 LLCallFloater::notifyParent(const LLSD& info) -{ - if("size_changes" == info["action"]) - { - reshapeToFitContent(); - return 1; - } - return LLDockableFloater::notifyParent(info); -} - ////////////////////////////////////////////////////////////////////////// /// PRIVATE SECTION ////////////////////////////////////////////////////////////////////////// @@ -316,7 +290,7 @@ void LLCallFloater::updateSession() //hide "Leave Call" button for nearby chat bool is_local_chat = mVoiceType == VC_LOCAL_CHAT; childSetVisible("leave_call_btn_panel", !is_local_chat); - + refreshParticipantList(); updateAgentModeratorState(); @@ -658,33 +632,11 @@ void LLCallFloater::setState(LLAvatarListItem* item, ESpeakerState state) void LLCallFloater::setVoiceRemoveTimer(const LLUUID& voice_speaker_id) { - - // If there is already a started timer for the current panel don't do anything. - bool no_timer_for_current_panel = true; - if (mVoiceLeftTimersMap.size() > 0) - { - timers_map::iterator found_it = mVoiceLeftTimersMap.find(voice_speaker_id); - if (found_it != mVoiceLeftTimersMap.end()) - { - no_timer_for_current_panel = false; - } - } - - if (no_timer_for_current_panel) - { - // Starting a timer to remove an avatar row panel after timeout - mVoiceLeftTimersMap.insert(timer_pair(voice_speaker_id, - new LLAvatarListItemRemoveTimer(boost::bind(&LLCallFloater::removeVoiceLeftParticipant, this, _1), mVoiceLeftRemoveDelay, voice_speaker_id))); - } + mSpeakerDelayRemover->setActionTimer(voice_speaker_id); } -void LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id) +bool LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id) { - if (mVoiceLeftTimersMap.size() > 0) - { - mVoiceLeftTimersMap.erase(mVoiceLeftTimersMap.find(voice_speaker_id)); - } - LLAvatarList::uuid_vector_t& speaker_uuids = mAvatarList->getIDs(); LLAvatarList::uuid_vector_t::iterator pos = std::find(speaker_uuids.begin(), speaker_uuids.end(), voice_speaker_id); if(pos != speaker_uuids.end()) @@ -692,34 +644,19 @@ void LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id) speaker_uuids.erase(pos); mAvatarList->setDirty(); } + + return false; } void LLCallFloater::resetVoiceRemoveTimers() { - if (mVoiceLeftTimersMap.size() > 0) - { - for (timers_map::iterator iter = mVoiceLeftTimersMap.begin(); - iter != mVoiceLeftTimersMap.end(); ++iter) - { - delete iter->second; - } - } - mVoiceLeftTimersMap.clear(); + mSpeakerDelayRemover->removeAllTimers(); } void LLCallFloater::removeVoiceRemoveTimer(const LLUUID& voice_speaker_id) { - // Remove the timer if it has been already started - if (mVoiceLeftTimersMap.size() > 0) - { - timers_map::iterator found_it = mVoiceLeftTimersMap.find(voice_speaker_id); - if (found_it != mVoiceLeftTimersMap.end()) - { - delete found_it->second; - mVoiceLeftTimersMap.erase(found_it); - } - } + mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id); } bool LLCallFloater::validateSpeaker(const LLUUID& speaker_id) @@ -798,90 +735,4 @@ void LLCallFloater::reset() mSpeakerManager = NULL; } -void reshape_floater(LLCallFloater* floater, S32 delta_height) -{ - // Try to update floater top side if it is docked(to bottom bar). - // Try to update floater bottom side or top side if it is un-docked. - // If world rect is too small, floater will not be reshaped at all. - - LLRect floater_rect = floater->getRect(); - LLRect world_rect = gViewerWindow->getWorldViewRectScaled(); - - // floater is docked to bottom bar - if(floater->isDocked()) - { - // can update floater top side - if(floater_rect.mTop + delta_height < world_rect.mTop) - { - floater_rect.set(floater_rect.mLeft, floater_rect.mTop + delta_height, - floater_rect.mRight, floater_rect.mBottom); - } - } - // floater is un-docked - else - { - // can update floater bottom side - if( floater_rect.mBottom - delta_height >= world_rect.mBottom ) - { - floater_rect.set(floater_rect.mLeft, floater_rect.mTop, - floater_rect.mRight, floater_rect.mBottom - delta_height); - } - // could not update floater bottom side, check if we can update floater top side - else if( floater_rect.mTop + delta_height < world_rect.mTop ) - { - floater_rect.set(floater_rect.mLeft, floater_rect.mTop + delta_height, - floater_rect.mRight, floater_rect.mBottom); - } - } - - floater->setShape(floater_rect); - floater->getChild<LLLayoutStack>("my_call_stack")->updateLayout(FALSE); -} - -void LLCallFloater::reshapeToFitContent() -{ - const S32 ITEM_HEIGHT = getParticipantItemHeight(); - static const S32 MAX_VISIBLE_ITEMS = getMaxVisibleItems(); - - static S32 items_pad = mAvatarList->getItemsPad(); - S32 list_height = mAvatarList->getRect().getHeight(); - S32 items_height = mAvatarList->getItemsRect().getHeight(); - if(items_height <= 0) - { - // make "no one near" text visible - items_height = ITEM_HEIGHT + items_pad; - } - S32 max_list_height = MAX_VISIBLE_ITEMS * ITEM_HEIGHT + items_pad * (MAX_VISIBLE_ITEMS - 1); - max_list_height += 2* mAvatarList->getBorderWidth(); - - S32 delta = items_height - list_height; - // too many items, don't reshape floater anymore, let scroll bar appear. - if(items_height > max_list_height) - { - delta = max_list_height - list_height; - } - - reshape_floater(this, delta); -} - -S32 LLCallFloater::getParticipantItemHeight() -{ - std::vector<LLPanel*> items; - mAvatarList->getItems(items); - if(items.size() > 0) - { - return items[0]->getRect().getHeight(); - } - else - { - return getChild<LLPanel>("non_avatar_caller")->getRect().getHeight(); - } -} - -S32 LLCallFloater::getMaxVisibleItems() -{ - static LLCachedControl<S32> max_visible_items(*LLUI::sSettingGroups["config"],"CallFloaterMaxItems"); - return max_visible_items; -} - //EOF diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h index 2b40225906..eded3a426b 100644 --- a/indra/newview/llcallfloater.h +++ b/indra/newview/llcallfloater.h @@ -44,6 +44,8 @@ class LLNonAvatarCaller; class LLOutputMonitorCtrl; class LLParticipantList; class LLSpeakerMgr; +class LLSpeakersDelayActionsStorage; + /** * The Voice Control Panel is an ambient window summoned by clicking the flyout chevron on the Speak button. * It can be torn-off and freely positioned onscreen. @@ -75,11 +77,6 @@ public: */ /*virtual*/ void onChange(); - /** - * Will reshape floater when participant list size changes - */ - /*virtual*/ S32 notifyParent(const LLSD& info); - static void sOnCurrentChannelChanged(const LLUUID& session_id); private: @@ -174,7 +171,7 @@ private: * * @param voice_speaker_id LLUUID of Avatar List item to be removed from the list. */ - void removeVoiceLeftParticipant(const LLUUID& voice_speaker_id); + bool removeVoiceLeftParticipant(const LLUUID& voice_speaker_id); /** * Deletes all timers from the list to prevent started timers from ticking after destruction @@ -221,21 +218,6 @@ private: */ void reset(); - /** - * Reshapes floater to fit participant list height - */ - void reshapeToFitContent(); - - /** - * Returns height of participant list item - */ - S32 getParticipantItemHeight(); - - /** - * Returns predefined max visible participants. - */ - S32 getMaxVisibleItems(); - private: speaker_state_map_t mSpeakerStateMap; LLSpeakerMgr* mSpeakerManager; @@ -260,32 +242,11 @@ private: boost::signals2::connection mAvatarListRefreshConnection; + /** - * class LLAvatarListItemRemoveTimer - * - * Implements a timer that removes avatar list item of a participant - * who has left the call. + * time out speakers when they are not part of current session */ - class LLAvatarListItemRemoveTimer : public LLEventTimer - { - public: - typedef boost::function<void(const LLUUID&)> callback_t; - - LLAvatarListItemRemoveTimer(callback_t remove_cb, F32 period, const LLUUID& speaker_id); - virtual ~LLAvatarListItemRemoveTimer() {}; - - virtual BOOL tick(); - - private: - callback_t mRemoveCallback; - LLUUID mSpeakerId; - }; - - typedef std::pair<LLUUID, LLAvatarListItemRemoveTimer*> timer_pair; - typedef std::map<LLUUID, LLAvatarListItemRemoveTimer*> timers_map; - - timers_map mVoiceLeftTimersMap; - S32 mVoiceLeftRemoveDelay; + LLSpeakersDelayActionsStorage* mSpeakerDelayRemover; /** * Stores reference to current voice channel. diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 5497d6121f..f1de4e2982 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -47,6 +47,7 @@ #include "llnotificationsutil.h" #include "lloutputmonitorctrl.h" #include "llscriptfloater.h" +#include "llspeakers.h" #include "lltextbox.h" #include "llvoiceclient.h" #include "llgroupmgr.h" @@ -1271,6 +1272,7 @@ bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index) chiclet->setChicletSizeChangedCallback(boost::bind(&LLChicletPanel::onChicletSizeChanged, this, _1, index)); arrange(); + LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, chiclet); return true; } @@ -1298,6 +1300,7 @@ void LLChicletPanel::removeChiclet(chiclet_list_t::iterator it) mChicletList.erase(it); arrange(); + LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, chiclet); chiclet->die(); } diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index fb94657278..0e42ff09d8 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -51,6 +51,7 @@ #include "llinventorymodel.h" #include "llfloaterworldmap.h" #include "lllandmarkactions.h" +#include "llnotificationsutil.h" #include "llsidetray.h" #include "lltoggleablemenu.h" #include "llviewerinventory.h" @@ -975,6 +976,10 @@ BOOL LLFavoritesBarCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) void copy_slurl_to_clipboard_cb(std::string& slurl) { gClipboard.copyFromString(utf8str_to_wstring(slurl)); + + LLSD args; + args["SLURL"] = slurl; + LLNotificationsUtil::add("CopySLURL", args); } diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index e0f2fca580..2efae0c8db 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -277,13 +277,8 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id) { object_owner.append("Unknown"); } - childSetText("object_name", object_owner); - std::string owner_link = - LLSLURL::buildCommand("agent", mObjectID, "inspect"); - childSetText("owner_name", owner_link); - childSetText("abuser_name_edit", object_owner); - mAbuserID = object_id; - mOwnerName = object_owner; + + setFromAvatar(object_id, object_owner); } else { @@ -305,7 +300,6 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id) } } - void LLFloaterReporter::onClickSelectAbuser() { gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE )); @@ -323,6 +317,17 @@ void LLFloaterReporter::callbackAvatarID(const std::vector<std::string>& names, } +void LLFloaterReporter::setFromAvatar(const LLUUID& avatar_id, const std::string& avatar_name) +{ + mAbuserID = mObjectID = avatar_id; + mOwnerName = avatar_name; + + std::string avatar_link = LLSLURL::buildCommand("agent", mObjectID, "inspect"); + childSetText("owner_name", avatar_link); + childSetText("object_name", avatar_name); // name + childSetText("abuser_name_edit", avatar_name); +} + // static void LLFloaterReporter::onClickSend(void *userdata) { @@ -458,9 +463,8 @@ void LLFloaterReporter::showFromMenu(EReportType report_type) } } - // static -void LLFloaterReporter::showFromObject(const LLUUID& object_id) +void LLFloaterReporter::show(const LLUUID& object_id, const std::string& avatar_name) { LLFloaterReporter* f = LLFloaterReg::showTypedInstance<LLFloaterReporter>("reporter"); @@ -469,8 +473,11 @@ void LLFloaterReporter::showFromObject(const LLUUID& object_id) LLAgentUI::buildFullname(fullname); f->childSetText("reporter_field", fullname); - // Request info for this object - f->getObjectInfo(object_id); + if (avatar_name.empty()) + // Request info for this object + f->getObjectInfo(object_id); + else + f->setFromAvatar(object_id, avatar_name); // Need to deselect on close f->mDeselectOnClose = TRUE; @@ -479,6 +486,18 @@ void LLFloaterReporter::showFromObject(const LLUUID& object_id) } +// static +void LLFloaterReporter::showFromObject(const LLUUID& object_id) +{ + show(object_id); +} + +// static +void LLFloaterReporter::showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name) +{ + show(avatar_id, avatar_name); +} + void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id) { childSetText("object_name", object_name); diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index cc2dfb2f98..7c6473f975 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -93,6 +93,7 @@ public: static void showFromMenu(EReportType report_type); static void showFromObject(const LLUUID& object_id); + static void showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name); static void onClickSend (void *userdata); static void onClickCancel (void *userdata); @@ -109,6 +110,8 @@ public: void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id); private: + static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null); + void takeScreenshot(); void sendReportViaCaps(std::string url); void uploadImage(); @@ -121,6 +124,7 @@ private: void enableControls(BOOL own_avatar); void getObjectInfo(const LLUUID& object_id); void callbackAvatarID(const std::vector<std::string>& names, const std::vector<LLUUID>& ids); + void setFromAvatar(const LLUUID& avatar_id, const std::string& avatar_name = LLStringUtil::null); private: EReportType mReportType; diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index a63fb73032..b833c611bf 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -1391,6 +1391,7 @@ void LLFolderView::startRenamingSelectedItem( void ) // set focus will fail unless item is visible mRenamer->setFocus( TRUE ); mRenamer->setTopLostCallback(boost::bind(onRenamerLost, _1)); + mRenamer->setFocusLostCallback(boost::bind(onRenamerLost, _1)); gFocusMgr.setTopCtrl( mRenamer ); } } diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 82293b4aa0..0ba7bdf613 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -98,6 +98,41 @@ void LLGestureManager::init() // TODO } +void LLGestureManager::changed(U32 mask) +{ + LLInventoryFetchObserver::changed(mask); + + if (mask & LLInventoryObserver::GESTURE) + { + // If there was a gesture label changed, update all the names in the + // active gestures and then notify observers + if (mask & LLInventoryObserver::LABEL) + { + for(item_map_t::iterator it = mActive.begin(); it != mActive.end(); ++it) + { + if(it->second) + { + LLViewerInventoryItem* item = gInventory.getItem(it->first); + if(item) + { + it->second->mName = item->getName(); + } + } + } + notifyObservers(); + } + // If there was a gesture added or removed notify observers + // STRUCTURE denotes that the inventory item has been moved + // In the case of deleting gesture, it is moved to the trash + else if(mask & LLInventoryObserver::ADD || + mask & LLInventoryObserver::REMOVE || + mask & LLInventoryObserver::STRUCTURE) + { + notifyObservers(); + } + } +} + // Use this version when you have the item_id but not the asset_id, // and you KNOW the inventory is loaded. diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h index c562587c6f..3dd184ddc7 100644 --- a/indra/newview/llgesturemgr.h +++ b/indra/newview/llgesturemgr.h @@ -140,6 +140,9 @@ public: void removeObserver(LLGestureManagerObserver* observer); void notifyObservers(); + // Overriding so we can update active gesture names and notify observers + void changed(U32 mask); + BOOL matchPrefix(const std::string& in_str, std::string* out_str); // Copy item ids into the vector diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index d7c60ff34e..73597e7de3 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -58,6 +58,7 @@ #include "llinventorymodel.h" #include "llrootview.h" +#include "llspeakers.h" LLIMFloater::LLIMFloater(const LLUUID& session_id) @@ -109,6 +110,8 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id) } } setOverlapsScreenChannel(true); + + LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this); } void LLIMFloater::onFocusLost() @@ -227,6 +230,7 @@ void LLIMFloater::sendMsg() LLIMFloater::~LLIMFloater() { + LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this); } //virtual @@ -350,13 +354,15 @@ void* LLIMFloater::createPanelAdHocControl(void* userdata) void LLIMFloater::onSlide() { - LLPanel* im_control_panel = getChild<LLPanel>("panel_im_control_panel"); - im_control_panel->setVisible(!im_control_panel->getVisible()); + mControlPanel->setVisible(!mControlPanel->getVisible()); + + gSavedSettings.setBOOL("IMShowControlPanel", mControlPanel->getVisible()); - gSavedSettings.setBOOL("IMShowControlPanel", im_control_panel->getVisible()); + getChild<LLButton>("slide_left_btn")->setVisible(mControlPanel->getVisible()); + getChild<LLButton>("slide_right_btn")->setVisible(!mControlPanel->getVisible()); - getChild<LLButton>("slide_left_btn")->setVisible(im_control_panel->getVisible()); - getChild<LLButton>("slide_right_btn")->setVisible(!im_control_panel->getVisible()); + LLLayoutStack* stack = getChild<LLLayoutStack>("im_panels"); + if (stack) stack->setAnimate(true); } //static @@ -510,14 +516,14 @@ bool LLIMFloater::toggle(const LLUUID& session_id) if(!isChatMultiTab()) { LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id); - if (floater && floater->getVisible()) + if (floater && floater->getVisible() && floater->hasFocus()) { // clicking on chiclet to close floater just hides it to maintain existing // scroll/text entry state floater->setVisible(false); return false; } - else if(floater && !floater->isDocked()) + else if(floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus())) { floater->setVisible(TRUE); floater->setFocus(TRUE); diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index d9db385d06..0ca0325451 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -116,6 +116,8 @@ public: static void onIMChicletCreated(const LLUUID& session_id); + virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; } + private: // process focus events to set a currently active session /* virtual */ void onFocusLost(); diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp index 6cc985aef4..06a7b4a29c 100644 --- a/indra/newview/llimfloatercontainer.cpp +++ b/indra/newview/llimfloatercontainer.cpp @@ -35,19 +35,22 @@ #include "llimfloatercontainer.h" #include "llfloaterreg.h" +#include "llimview.h" +#include "llavatariconctrl.h" +#include "llagent.h" // // LLIMFloaterContainer // LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed) -: LLMultiFloater(seed), - mActiveVoiceFloater(NULL) +: LLMultiFloater(seed) { mAutoResize = FALSE; } LLIMFloaterContainer::~LLIMFloaterContainer() { + LLGroupMgr::getInstance()->removeObserver(this); } BOOL LLIMFloaterContainer::postBuild() @@ -87,13 +90,84 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp, LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point); - // make sure active voice icon shows up for new tab - if (floaterp == mActiveVoiceFloater) + LLUUID session_id = floaterp->getKey(); + + if(gAgent.isInGroup(session_id)) + { + mSessions[session_id] = floaterp; + mID = session_id; + mGroupID.push_back(session_id); + LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(session_id); + LLGroupMgr* gm = LLGroupMgr::getInstance(); + gm->addObserver(this); + + if (group_data && group_data->mInsigniaID.notNull()) + { + mTabContainer->setTabImage(get_ptr_in_map(mSessions, session_id), group_data->mInsigniaID); + } + else + { + gm->sendGroupPropertiesRequest(session_id); + } + } + else + { + LLUUID avatar_id = LLIMModel::getInstance()->getOtherParticipantID(session_id); + LLAvatarPropertiesProcessor& app = LLAvatarPropertiesProcessor::instance(); + app.addObserver(avatar_id, this); + floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, avatar_id)); + mSessions[avatar_id] = floaterp; + + LLUUID* icon_id_ptr = LLAvatarIconIDCache::getInstance()->get(avatar_id); + if(!icon_id_ptr) + { + app.sendAvatarPropertiesRequest(avatar_id); + } + else + { + mTabContainer->setTabImage(floaterp, *icon_id_ptr); + } + } +} + +void LLIMFloaterContainer::processProperties(void* data, enum EAvatarProcessorType type) +{ + if (APT_PROPERTIES == type) + { + LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data); + if (avatar_data) + { + LLUUID avatar_id = avatar_data->avatar_id; + if(avatar_data->image_id != *LLAvatarIconIDCache::getInstance()->get(avatar_id)) + { + LLAvatarIconIDCache::getInstance()->add(avatar_id,avatar_data->image_id); + } + mTabContainer->setTabImage(get_ptr_in_map(mSessions, avatar_id), avatar_data->image_id); + } + } +} + +void LLIMFloaterContainer::changed(LLGroupChange gc) +{ + if (GC_PROPERTIES == gc) { - mTabContainer->setTabImage(floaterp, "active_voice_tab.tga"); + for(groupIDs_t::iterator it = mGroupID.begin(); it!=mGroupID.end(); it++) + { + LLUUID group_id = *it; + LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(group_id); + if (group_data && group_data->mInsigniaID.notNull()) + { + mTabContainer->setTabImage(get_ptr_in_map(mSessions, group_id), group_data->mInsigniaID); + } + } } } +void LLIMFloaterContainer::onCloseFloater(LLUUID id) +{ + LLAvatarPropertiesProcessor::instance().removeObserver(id, this); +} + LLIMFloaterContainer* LLIMFloaterContainer::findInstance() { return LLFloaterReg::findTypedInstance<LLIMFloaterContainer>("im_container"); diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h index d4a542dfc2..1333b098bc 100644 --- a/indra/newview/llimfloatercontainer.h +++ b/indra/newview/llimfloatercontainer.h @@ -33,12 +33,17 @@ #ifndef LL_LLIMFLOATERCONTAINER_H #define LL_LLIMFLOATERCONTAINER_H +#include <map> +#include <vector> + #include "llfloater.h" #include "llmultifloater.h" +#include "llavatarpropertiesprocessor.h" +#include "llgroupmgr.h" class LLTabContainer; -class LLIMFloaterContainer : public LLMultiFloater +class LLIMFloaterContainer : public LLMultiFloater, public LLAvatarPropertiesObserver, public LLGroupMgrObserver { public: LLIMFloaterContainer(const LLSD& seed); @@ -51,15 +56,23 @@ public: BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END); + void processProperties(void* data, EAvatarProcessorType type); + void changed(LLGroupChange gc); + static LLFloater* getCurrentVoiceFloater(); static LLIMFloaterContainer* findInstance(); static LLIMFloaterContainer* getInstance(); -protected: - - LLFloater* mActiveVoiceFloater; +private: + typedef std::map<LLUUID,LLPanel*> avatarID_panel_map_t; + avatarID_panel_map_t mSessions; + + typedef std::vector<LLUUID> groupIDs_t; + groupIDs_t mGroupID; + + void onCloseFloater(LLUUID avatar_id); }; #endif // LL_LLIMFLOATERCONTAINER_H diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 9a6115dd63..4bdf5f42dc 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -40,6 +40,7 @@ #include "llfontgl.h" #include "llrect.h" #include "llerror.h" +#include "llmultifloater.h" #include "llstring.h" #include "message.h" #include "lltextbox.h" diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 3ff156eca3..c2a7969c0d 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -42,47 +42,31 @@ #include "llhttpclient.h" #include "llsdutil_math.h" #include "llstring.h" +#include "lltrans.h" #include "lluictrlfactory.h" #include "llagent.h" +#include "llagentui.h" #include "llappviewer.h" #include "llavatariconctrl.h" #include "llbottomtray.h" #include "llcallingcard.h" #include "llchat.h" -#include "llchiclet.h" -#include "llresmgr.h" #include "llfloaterchatterbox.h" -#include "llavataractions.h" -#include "llhttpnode.h" #include "llimfloater.h" -#include "llimpanel.h" #include "llgroupiconctrl.h" -#include "llresizebar.h" -#include "lltabcontainer.h" -#include "llviewercontrol.h" -#include "llfloater.h" +#include "llmd5.h" #include "llmutelist.h" -#include "llresizehandle.h" -#include "llkeyboard.h" -#include "llui.h" -#include "llviewermenu.h" -#include "llcallingcard.h" -#include "lltoolbar.h" +#include "llrecentpeople.h" #include "llviewermessage.h" #include "llviewerwindow.h" #include "llnotifications.h" #include "llnotificationsutil.h" #include "llnearbychat.h" -#include "llviewerregion.h" -#include "llvoicechannel.h" -#include "lltrans.h" -#include "llrecentpeople.h" -#include "llsyswellwindow.h" - -//#include "llfirstuse.h" -#include "llagentui.h" +#include "llspeakers.h" //for LLIMSpeakerMgr #include "lltextutil.h" +#include "llviewercontrol.h" + const static std::string IM_TIME("time"); const static std::string IM_TEXT("message"); @@ -232,12 +216,14 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionID); } + buildHistoryFileName(); + if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") ) { std::list<LLSD> chat_history; //involves parsing of a chat history - LLLogChat::loadAllHistory(mName, chat_history); + LLLogChat::loadAllHistory(mHistoryFileName, chat_history); addMessagesFromHistory(chat_history); } } @@ -484,6 +470,44 @@ bool LLIMModel::LLIMSession::isOtherParticipantAvaline() return !mOtherParticipantIsAvatar; } +void LLIMModel::LLIMSession::buildHistoryFileName() +{ + mHistoryFileName = mName; + + //ad-hoc requires sophisticated chat history saving schemes + if (isAdHoc()) + { + //in case of outgoing ad-hoc sessions + if (mInitialTargetIDs.size()) + { + std::set<LLUUID> sorted_uuids(mInitialTargetIDs.begin(), mInitialTargetIDs.end()); + mHistoryFileName = mName + " hash" + generateHash(sorted_uuids); + return; + } + + //in case of incoming ad-hoc sessions + mHistoryFileName = mName + " " + LLLogChat::timestamp(true) + " " + mSessionID.asString().substr(0, 4); + } +} + +//static +std::string LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_uuids) +{ + LLMD5 md5_uuid; + + std::set<LLUUID>::const_iterator it = sorted_uuids.begin(); + while (it != sorted_uuids.end()) + { + md5_uuid.update((unsigned char*)(*it).mData, 16); + it++; + } + md5_uuid.finalize(); + + LLUUID participants_md5_hash; + md5_uuid.raw_digest((unsigned char*) participants_md5_hash.mData); + return participants_md5_hash.asString(); +} + void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, const LLUUID& new_session_id) { @@ -631,11 +655,11 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, return true; } -bool LLIMModel::logToFile(const std::string& session_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) +bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) { if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")) { - LLLogChat::saveHistory(session_name, from, from_id, utf8_text); + LLLogChat::saveHistory(file_name, from, from_id, utf8_text); return true; } else @@ -646,15 +670,7 @@ bool LLIMModel::logToFile(const std::string& session_name, const std::string& fr bool LLIMModel::logToFile(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) { - if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")) - { - LLLogChat::saveHistory(LLIMModel::getInstance()->getName(session_id), from, from_id, utf8_text); - return true; - } - else - { - return false; - } + return logToFile(LLIMModel::getInstance()->getHistoryFileName(session_id), from, from_id, utf8_text); } bool LLIMModel::proccessOnlineOfflineNotification( @@ -799,6 +815,18 @@ LLIMSpeakerMgr* LLIMModel::getSpeakerManager( const LLUUID& session_id ) const return session->mSpeakers; } +const std::string& LLIMModel::getHistoryFileName(const LLUUID& session_id) const +{ + LLIMSession* session = findIMSession(session_id); + if (!session) + { + llwarns << "session " << session_id << " does not exist " << llendl; + return LLStringUtil::null; + } + + return session->mHistoryFileName; +} + // TODO get rid of other participant ID void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing) diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index e72bda6c2b..a3b4f78af0 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -33,22 +33,19 @@ #ifndef LL_LLIMVIEW_H #define LL_LLIMVIEW_H -#include "lldarray.h" -#include "lldockablefloater.h" -#include "llspeakers.h" //for LLIMSpeakerMgr -#include "llimpanel.h" //for voice channels -#include "llmodaldialog.h" #include "lldockablefloater.h" #include "llinstantmessage.h" -#include "lluuid.h" -#include "llmultifloater.h" + #include "lllogchat.h" +#include "llvoicechannel.h" class LLFloaterChatterBox; class LLUUID; class LLFloaterIMPanel; class LLFriendObserver; class LLCallDialogManager; +class LLIMSpeakerMgr; + class LLIMModel : public LLSingleton<LLIMModel> { @@ -72,6 +69,8 @@ public: void addMessagesFromHistory(const std::list<LLSD>& history); void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time); void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction); + + /** @deprecated */ static void chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata); bool isAdHoc(); @@ -83,12 +82,20 @@ public: bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;} bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;} + //*TODO make private + /** ad-hoc sessions involve sophisticated chat history file naming schemes */ + void buildHistoryFileName(); + + //*TODO make private + static std::string generateHash(const std::set<LLUUID>& sorted_uuids); + LLUUID mSessionID; std::string mName; EInstantMessage mType; SType mSessionType; LLUUID mOtherParticipantID; std::vector<LLUUID> mInitialTargetIDs; + std::string mHistoryFileName; // connection to voice channel state change signal boost::signals2::connection mVoiceChannelStateChangeConnection; @@ -234,6 +241,8 @@ public: */ LLIMSpeakerMgr* getSpeakerManager(const LLUUID& session_id) const; + const std::string& getHistoryFileName(const LLUUID& session_id) const; + static void sendLeaveSession(const LLUUID& session_id, const LLUUID& other_participant_id); static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id, const std::vector<LLUUID>& ids, EInstantMessage dialog); @@ -246,7 +255,7 @@ public: /** * Saves an IM message into a file */ - bool logToFile(const std::string& session_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text); + bool logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text); private: diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 0374a1d25b..4b0539337b 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -689,7 +689,7 @@ void LLInspectAvatar::onToggleMute() void LLInspectAvatar::onClickReport() { - LLFloaterReporter::showFromObject(mAvatarID); + LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName); closeFloater(); } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index ab3e60b2fa..42bb62ad47 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -187,6 +187,11 @@ BOOL LLInvFVBridge::isItemRemovable() { return FALSE; } + if (LLAppearanceManager::instance().getIsProtectedCOFItem(mUUID)) + { + return FALSE; + } + const LLInventoryObject *obj = model->getItem(mUUID); if (obj && obj->getIsLinkType()) { @@ -576,8 +581,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Paste As Link")); } } - items.push_back(std::string("Paste Separator")); + items.push_back(std::string("Paste Separator")); if (obj && obj->getIsLinkType() && !get_is_item_worn(mUUID)) { @@ -714,14 +719,7 @@ BOOL LLInvFVBridge::isAgentInventory() const BOOL LLInvFVBridge::isCOFFolder() const { - const LLInventoryModel* model = getInventoryModel(); - if(!model) return TRUE; - const LLUUID cof_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); - if (mUUID == cof_id || model->isObjectDescendentOf(mUUID, cof_id)) - { - return TRUE; - } - return FALSE; + return LLAppearanceManager::instance().getIsInCOF(mUUID); } BOOL LLInvFVBridge::isItemPermissive() const @@ -3702,18 +3700,6 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop, return rv; } -BOOL LLCallingCardBridge::removeItem() -{ - if (LLFriendCardsManager::instance().isItemInAnyFriendsList(getItem())) - { - LLAvatarActions::removeFriendDialog(getItem()->getCreatorUUID()); - return FALSE; - } - else - { - return LLItemBridge::removeItem(); - } -} // +=================================================+ // | LLNotecardBridge | // +=================================================+ @@ -3825,8 +3811,25 @@ void LLGestureBridge::openItem() BOOL LLGestureBridge::removeItem() { - // Force close the preview window, if it exists - LLGestureManager::instance().deactivateGesture(mUUID); + // Grab class information locally since *this may be deleted + // within this function. Not a great pattern... + const LLInventoryModel* model = getInventoryModel(); + if(!model) + { + return FALSE; + } + const LLUUID item_id = mUUID; + + // This will also force close the preview window, if it exists. + // This may actually delete *this, if mUUID is in the COF. + LLGestureManager::instance().deactivateGesture(item_id); + + // If deactivateGesture deleted *this, then return out immediately. + if (!model->getObject(item_id)) + { + return TRUE; + } + return LLItemBridge::removeItem(); } @@ -4620,7 +4623,10 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) getClipboardEntries(true, items, disabled_items, flags); - items.push_back(std::string("Wearable Separator")); + if (!is_sidepanel) + { + items.push_back(std::string("Wearable Separator")); + } items.push_back(std::string("Wearable Edit")); @@ -5150,8 +5156,12 @@ void LLLandmarkBridgeAction::doIt() // Opening (double-clicking) a landmark immediately teleports, // but warns you the first time. LLSD payload; - payload["asset_id"] = item->getAssetUUID(); - LLNotificationsUtil::add("TeleportFromLandmark", LLSD(), payload); + payload["asset_id"] = item->getAssetUUID(); + + LLSD args; + args["LOCATION"] = item->getDisplayName(); + + LLNotificationsUtil::add("TeleportFromLandmark", args, payload); } LLInvFVBridgeAction::doIt(); diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 5565fd7182..3acf8e5072 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -450,7 +450,6 @@ public: EDragAndDropType cargo_type, void* cargo_data); void refreshFolderViewItem(); - BOOL removeItem(); protected: LLCallingCardBridge( LLInventoryPanel* inventory, const LLUUID& uuid ); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index e44adfb511..961f7adc0a 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -755,6 +755,10 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item) gCacheName->get(id, FALSE, boost::bind(&LLViewerInventoryItem::onCallingCardNameLookup, new_item.get(), _1, _2, _3)); } } + else if (new_item->getType() == LLAssetType::AT_GESTURE) + { + mask |= LLInventoryObserver::GESTURE; + } addChangedMask(mask, new_item->getUUID()); return mask; } diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h index c1f192e2bf..d6dded52d4 100644 --- a/indra/newview/llinventoryobserver.h +++ b/indra/newview/llinventoryobserver.h @@ -61,8 +61,9 @@ public: REMOVE = 8, // something deleted STRUCTURE = 16, // structural change (eg item or folder moved) CALLING_CARD = 32, // (eg online, grant status, cancel) - REBUILD = 64, // item UI changed (eg item type different) - SORT = 128, // folder needs to be resorted. + GESTURE = 64, + REBUILD = 128, // item UI changed (eg item type different) + SORT = 256, // folder needs to be resorted. ALL = 0xffffffff }; LLInventoryObserver(); diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 9141d50829..7e71ac90b4 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -682,6 +682,14 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc mFolders->setSelectionByID(obj_id, take_keyboard_focus); } +void LLInventoryPanel::setSelectCallback(const LLFolderView::signal_t::slot_type& cb) +{ + if (mFolders) + { + mFolders->setSelectCallback(cb); + } +} + void LLInventoryPanel::clearSelection() { mFolders->clearSelection(); diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 09533b52f1..ccff795a51 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -123,7 +123,7 @@ public: // Call this method to set the selection. void openAllFolders(); void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus); - void setSelectCallback(const LLFolderView::signal_t::slot_type& cb) { if (mFolders) mFolders->setSelectCallback(cb); } + void setSelectCallback(const LLFolderView::signal_t::slot_type& cb); void clearSelection(); LLInventoryFilter* getFilter(); void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT); diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 404e266806..7f49a7defb 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -43,8 +43,11 @@ #include "lltrans.h" #include "lluictrlfactory.h" #include "lltooltip.h" +#include "llnotificationsutil.h" +#include "llregionflags.h" // newview includes +#include "llagent.h" #include "llinventoryobserver.h" #include "lllandmarkactions.h" #include "lllandmarklist.h" @@ -56,6 +59,7 @@ #include "lltrans.h" #include "llviewerinventory.h" #include "llviewerparcelmgr.h" +#include "llviewerregion.h" #include "llviewercontrol.h" #include "llviewermenu.h" #include "llurllineeditorctrl.h" @@ -256,36 +260,42 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) voice_icon.tool_tip = LLTrans::getString("LocationCtrlVoiceTooltip"); voice_icon.mouse_opaque = true; mParcelIcon[VOICE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(voice_icon); + mParcelIcon[VOICE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, VOICE_ICON)); addChild(mParcelIcon[VOICE_ICON]); LLIconCtrl::Params fly_icon = p.fly_icon; fly_icon.tool_tip = LLTrans::getString("LocationCtrlFlyTooltip"); fly_icon.mouse_opaque = true; mParcelIcon[FLY_ICON] = LLUICtrlFactory::create<LLIconCtrl>(fly_icon); + mParcelIcon[FLY_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, FLY_ICON)); addChild(mParcelIcon[FLY_ICON]); LLIconCtrl::Params push_icon = p.push_icon; push_icon.tool_tip = LLTrans::getString("LocationCtrlPushTooltip"); push_icon.mouse_opaque = true; mParcelIcon[PUSH_ICON] = LLUICtrlFactory::create<LLIconCtrl>(push_icon); + mParcelIcon[PUSH_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PUSH_ICON)); addChild(mParcelIcon[PUSH_ICON]); LLIconCtrl::Params build_icon = p.build_icon; build_icon.tool_tip = LLTrans::getString("LocationCtrlBuildTooltip"); build_icon.mouse_opaque = true; mParcelIcon[BUILD_ICON] = LLUICtrlFactory::create<LLIconCtrl>(build_icon); + mParcelIcon[BUILD_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, BUILD_ICON)); addChild(mParcelIcon[BUILD_ICON]); LLIconCtrl::Params scripts_icon = p.scripts_icon; scripts_icon.tool_tip = LLTrans::getString("LocationCtrlScriptsTooltip"); scripts_icon.mouse_opaque = true; mParcelIcon[SCRIPTS_ICON] = LLUICtrlFactory::create<LLIconCtrl>(scripts_icon); + mParcelIcon[SCRIPTS_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, SCRIPTS_ICON)); addChild(mParcelIcon[SCRIPTS_ICON]); LLIconCtrl::Params damage_icon = p.damage_icon; damage_icon.tool_tip = LLTrans::getString("LocationCtrlDamageTooltip"); damage_icon.mouse_opaque = true; mParcelIcon[DAMAGE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(damage_icon); + mParcelIcon[DAMAGE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, DAMAGE_ICON)); addChild(mParcelIcon[DAMAGE_ICON]); LLTextBox::Params damage_text = p.damage_text; @@ -918,3 +928,45 @@ bool LLLocationInputCtrl::onLocationContextMenuItemEnabled(const LLSD& userdata) return false; } + +void LLLocationInputCtrl::onParcelIconClick(EParcelIcon icon) +{ + switch (icon) + { + case VOICE_ICON: + LLNotificationsUtil::add("NoVoice"); + break; + case FLY_ICON: + LLNotificationsUtil::add("NoFly"); + break; + case PUSH_ICON: + LLNotificationsUtil::add("PushRestricted"); + break; + case BUILD_ICON: + LLNotificationsUtil::add("NoBuild"); + break; + case SCRIPTS_ICON: + { + LLViewerRegion* region = gAgent.getRegion(); + if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS) + { + LLNotificationsUtil::add("ScriptsStopped"); + } + else if(region && region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS) + { + LLNotificationsUtil::add("ScriptsNotRunning"); + } + else + { + LLNotificationsUtil::add("NoOutsideScripts"); + } + break; + } + case DAMAGE_ICON: + LLNotificationsUtil::add("NotSafe"); + break; + case ICON_COUNT: + break; + // no default to get compiler warning when a new icon gets added + } +} diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h index 7959fab2de..607ccd4da6 100644 --- a/indra/newview/lllocationinputctrl.h +++ b/indra/newview/lllocationinputctrl.h @@ -102,6 +102,18 @@ public: void handleLoginComplete(); private: + + enum EParcelIcon + { + VOICE_ICON = 0, + FLY_ICON, + PUSH_ICON, + BUILD_ICON, + SCRIPTS_ICON, + DAMAGE_ICON, + ICON_COUNT + }; + friend class LLUICtrlFactory; LLLocationInputCtrl(const Params&); virtual ~LLLocationInputCtrl(); @@ -138,6 +150,7 @@ private: // callbacks bool onLocationContextMenuItemEnabled(const LLSD& userdata); void onLocationContextMenuItemClicked(const LLSD& userdata); + void onParcelIconClick(EParcelIcon icon); LLMenuGL* mLocationContextMenu; LLButton* mAddLandmarkBtn; @@ -146,16 +159,6 @@ private: S32 mIconHPad; // pad between all icons S32 mAddLandmarkHPad; // pad to left of landmark star - enum EParcelIcon - { - VOICE_ICON = 0, - FLY_ICON, - PUSH_ICON, - BUILD_ICON, - SCRIPTS_ICON, - DAMAGE_ICON, - ICON_COUNT - }; LLIconCtrl* mParcelIcon[ICON_COUNT]; LLTextBox* mDamageText; diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 4e5aaeb66a..dc187bf36c 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -237,15 +237,15 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line) messages.back()[IM_TEXT] = im_text; } -void LLLogChat::loadAllHistory(const std::string& session_name, std::list<LLSD>& messages) +void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& messages) { - if (session_name.empty()) + if (file_name.empty()) { llwarns << "Session name is Empty!" << llendl; return ; } - LLFILE* fptr = LLFile::fopen(makeLogFileName(session_name), "r"); /*Flawfinder: ignore*/ + LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r"); /*Flawfinder: ignore*/ if (!fptr) return; //No previous conversation with this name. char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/ diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index 3d3f5c4458..4290e4bbc0 100644 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -56,7 +56,7 @@ public: void (*callback)(ELogLineType, const LLSD&, void*), void* userdata); - static void loadAllHistory(const std::string& session_name, std::list<LLSD>& messages); + static void loadAllHistory(const std::string& file_name, std::list<LLSD>& messages); private: static std::string cleanFileName(std::string filename); }; diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 87ebce1d34..d464862eed 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -870,38 +870,6 @@ void LLMediaCtrl::convertInputCoords(S32& x, S32& y) } //////////////////////////////////////////////////////////////////////////////// -// static -bool LLMediaCtrl::onClickLinkExternalTarget(const LLSD& notification, const LLSD& response ) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if ( 0 == option ) - { - LLSD payload = notification["payload"]; - std::string url = payload["url"].asString(); - S32 target_type = payload["target_type"].asInteger(); - - switch (target_type) - { - case LLPluginClassMedia::TARGET_EXTERNAL: - // load target in an external browser - LLWeb::loadURLExternal(url); - break; - - case LLPluginClassMedia::TARGET_BLANK: - // load target in the user's preferred browser - LLWeb::loadURL(url); - break; - - default: - // unsupported link target - shouldn't happen - LL_WARNS("LinkTarget") << "Unsupported link target type" << LL_ENDL; - break; - } - } - return false; -} - -//////////////////////////////////////////////////////////////////////////////// // inherited from LLViewerMediaObserver //virtual void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) @@ -1014,44 +982,83 @@ void LLMediaCtrl::onClickLinkHref( LLPluginClassMedia* self ) U32 target_type = self->getClickTargetType(); // is there is a target specified for the link? - if (target_type == LLPluginClassMedia::TARGET_EXTERNAL || - target_type == LLPluginClassMedia::TARGET_BLANK) + if (gSavedSettings.getBOOL("UseExternalBrowser") || target_type == LLPluginClassMedia::TARGET_EXTERNAL) { LLSD payload; payload["url"] = url; payload["target_type"] = LLSD::Integer(target_type); LLNotificationsUtil::add( "WebLaunchExternalTarget", LLSD(), payload, onClickLinkExternalTarget); - return; } - - const std::string protocol1( "http://" ); - const std::string protocol2( "https://" ); - if( mOpenLinksInExternalBrowser ) + else if (target_type == LLPluginClassMedia::TARGET_BLANK) { - if ( !url.empty() ) + clickLinkWithTarget(url, target_type); + } + else { + const std::string protocol1( "http://" ); + const std::string protocol2( "https://" ); + if( mOpenLinksInExternalBrowser ) { - if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 || - LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 ) + if ( !url.empty() ) { - LLWeb::loadURLExternal( url ); + if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 || + LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 ) + { + LLWeb::loadURLExternal( url ); + } } } - } - else - if( mOpenLinksInInternalBrowser ) - { - if ( !url.empty() ) + else + if( mOpenLinksInInternalBrowser ) { - if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 || - LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 ) + if ( !url.empty() ) { - llwarns << "Dead, unimplemented path that we used to send to the built-in browser long ago." << llendl; + if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 || + LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 ) + { + llwarns << "Dead, unimplemented path that we used to send to the built-in browser long ago." << llendl; + } } } } } //////////////////////////////////////////////////////////////////////////////// +// static +bool LLMediaCtrl::onClickLinkExternalTarget(const LLSD& notification, const LLSD& response ) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if ( 0 == option ) + { + LLSD payload = notification["payload"]; + std::string url = payload["url"].asString(); + S32 target_type = payload["target_type"].asInteger(); + clickLinkWithTarget(url, target_type); + } + return false; +} + + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLMediaCtrl::clickLinkWithTarget(const std::string& url, const S32& target_type ) +{ + if (gSavedSettings.getBOOL("UseExternalBrowser") || target_type == LLPluginClassMedia::TARGET_EXTERNAL) + { + // load target in an external browser + LLWeb::loadURLExternal(url); + } + else if (target_type == LLPluginClassMedia::TARGET_BLANK) + { + // load target in the user's preferred browser + LLWeb::loadURL(url); + } + else { + // unsupported link target - shouldn't happen + LL_WARNS("LinkTarget") << "Unsupported link target type" << LL_ENDL; + } +} + +//////////////////////////////////////////////////////////////////////////////// // void LLMediaCtrl::onClickLinkNoFollow( LLPluginClassMedia* self ) { diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index b0aca3cfa4..60e0c4073b 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -172,6 +172,7 @@ public: private: void onVisibilityChange ( const LLSD& new_visibility ); static bool onClickLinkExternalTarget( const LLSD&, const LLSD& ); + static void clickLinkWithTarget(const std::string& url, const S32& target_type ); const S32 mTextureDepthBytes; LLUUID mMediaTextureID; diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index cf4a08ce76..7ee4c64f8f 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -64,6 +64,7 @@ #include "llviewerwindow.h" #include "llworld.h" //for particle system banning #include "llchat.h" +#include "llimpanel.h" #include "llimview.h" #include "llnotifications.h" #include "lluistring.h" diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index ee0426c7df..8c5208678e 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -65,6 +65,7 @@ #include "llvovolume.h" #include "lluictrlfactory.h" #include "llpluginclassmedia.h" +#include "llviewertexturelist.h" // // Methods @@ -406,14 +407,40 @@ void LLPanelFace::getState() LLUUID id; struct f1 : public LLSelectedTEGetFunctor<LLUUID> { - LLUUID get(LLViewerObject* object, S32 te) + LLUUID get(LLViewerObject* object, S32 te_index) { - LLViewerTexture* image = object->getTEImage(te); - return image ? image->getID() : LLUUID::null; + LLUUID id; + + LLViewerTexture* image = object->getTEImage(te_index); + if (image) id = image->getID(); + + if (!id.isNull() && LLViewerMedia::textureHasMedia(id)) + { + LLTextureEntry *te = object->getTE(te_index); + if (te) + { + LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL ; + if(!tex) + { + tex = LLViewerFetchedTexture::sDefaultImagep; + } + if (tex) + { + id = tex->getID(); + } + } + } + return id; } } func; identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id ); + if(LLViewerMedia::textureHasMedia(id)) + { + childSetEnabled("textbox autofix",editable); + childSetEnabled("button align",editable); + } + if (identical) { // All selected have the same texture @@ -444,13 +471,6 @@ void LLPanelFace::getState() } } } - - if(LLViewerMedia::textureHasMedia(id)) - { - childSetEnabled("textbox autofix",editable); - childSetEnabled("button align",editable); - } - } diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 01291c4012..c30ef3221d 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -356,13 +356,6 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id) for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it) (*it)->setGroupID(group_id); - LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID); - if(gdatap) - { - childSetValue("group_name", gdatap->mName); - childSetToolTip("group_name",gdatap->mName); - } - LLButton* button_apply = findChild<LLButton>("btn_apply"); LLButton* button_refresh = findChild<LLButton>("btn_refresh"); LLButton* button_create = findChild<LLButton>("btn_create"); @@ -425,6 +418,11 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id) getChild<LLUICtrl>("group_name")->setVisible(false); getChild<LLUICtrl>("group_name_editor")->setVisible(true); + + if(button_call) + button_call->setVisible(false); + if(button_chat) + button_chat->setVisible(false); } else { @@ -452,9 +450,24 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id) if(button_apply) button_apply->setVisible(is_member); + if(button_call) + button_call->setVisible(is_member); + if(button_chat) + button_chat->setVisible(is_member); } reposButtons(); + + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID); + + if(gdatap) + { + childSetValue("group_name", gdatap->mName); + childSetToolTip("group_name",gdatap->mName); + + //group data is already present, call update manually + update(GC_ALL); + } } bool LLPanelGroup::apply(LLPanelGroupTab* tab) diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 0e55ff3214..45f0381d6f 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -452,6 +452,7 @@ LLPanelGroupSubTab::LLPanelGroupSubTab() : LLPanelGroupTab(), mHeader(NULL), mFooter(NULL), + mActivated(false), mSearchEditor(NULL) { } @@ -504,13 +505,14 @@ void LLPanelGroupSubTab::setGroupID(const LLUUID& id) mSearchEditor->clear(); setSearchFilter(""); } + + mActivated = false; } void LLPanelGroupSubTab::setSearchFilter(const std::string& filter) { if(mSearchFilter == filter) return; - lldebugs << "LLPanelGroupSubTab::setSearchFilter() ==> '" << filter << "'" << llendl; mSearchFilter = filter; LLStringUtil::toLower(mSearchFilter); update(GC_ALL); @@ -518,13 +520,11 @@ void LLPanelGroupSubTab::setSearchFilter(const std::string& filter) void LLPanelGroupSubTab::activate() { - lldebugs << "LLPanelGroupSubTab::activate()" << llendl; setOthersVisible(TRUE); } void LLPanelGroupSubTab::deactivate() { - lldebugs << "LLPanelGroupSubTab::deactivate()" << llendl; setOthersVisible(FALSE); } @@ -534,19 +534,11 @@ void LLPanelGroupSubTab::setOthersVisible(BOOL b) { mHeader->setVisible( b ); } - else - { - llwarns << "LLPanelGroupSubTab missing header!" << llendl; - } if (mFooter) { mFooter->setVisible( b ); } - else - { - llwarns << "LLPanelGroupSubTab missing footer!" << llendl; - } } bool LLPanelGroupSubTab::matchesActionSearchFilter(std::string action) @@ -875,10 +867,12 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() for (itor = selection.begin(); itor != selection.end(); ++itor) { - selected_members.push_back( (*itor)->getUUID() ); + LLUUID member_id = (*itor)->getValue()["uuid"]; + + selected_members.push_back( member_id ); // Get this member's power mask including any unsaved changes - U64 powers = getAgentPowersBasedOnRoleChanges((*itor)->getUUID()); + U64 powers = getAgentPowersBasedOnRoleChanges( member_id ); allowed_by_all &= powers; allowed_by_some |= powers; @@ -1022,6 +1016,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() //last owner. We should check for this special case // -jwolk check->setEnabled(cb_enable); + item->setEnabled(cb_enable); } } else @@ -1098,7 +1093,8 @@ void LLPanelGroupMembersSubTab::handleEjectMembers() for (itor = selection.begin() ; itor != selection.end(); ++itor) { - selected_members.push_back((*itor)->getUUID()); + LLUUID member_id = (*itor)->getValue()["uuid"]; + selected_members.push_back( member_id ); } mMembersList->deleteSelectedItems(); @@ -1154,7 +1150,8 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id, for (std::vector<LLScrollListItem*>::iterator itor = selection.begin() ; itor != selection.end(); ++itor) { - member_id = (*itor)->getUUID(); + + member_id = (*itor)->getValue()["uuid"]; //see if we requested a change for this member before if ( mMemberRoleChangeData.find(member_id) == mMemberRoleChangeData.end() ) @@ -1245,15 +1242,19 @@ void LLPanelGroupMembersSubTab::handleMemberDoubleClick() LLScrollListItem* selected = mMembersList->getFirstSelected(); if (selected) { - LLAvatarActions::showProfile(selected->getUUID()); + LLUUID member_id = selected->getValue()["uuid"]; + LLAvatarActions::showProfile( member_id ); } } void LLPanelGroupMembersSubTab::activate() { LLPanelGroupSubTab::activate(); - - update(GC_ALL); + if(!mActivated) + { + update(GC_ALL); + mActivated = true; + } } void LLPanelGroupMembersSubTab::deactivate() @@ -1629,7 +1630,9 @@ void LLPanelGroupMembersSubTab::updateMembers() row["columns"][2]["value"] = mMemberProgress->second->getOnlineStatus(); row["columns"][2]["font"] = "SANSSERIF_SMALL"; - mMembersList->addElement(row);//, ADD_SORTED); + LLScrollListItem* member = mMembersList->addElement(row);//, ADD_SORTED); + + LLUUID id = member->getValue()["uuid"]; mHasMatch = TRUE; } } diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index 2f81900e60..eac22a6338 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -149,6 +149,8 @@ protected: icon_map_t mActionIcons; + bool mActivated; + void setOthersVisible(BOOL b); }; diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index 0cfe501fab..a334eb9d68 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -46,6 +46,7 @@ #include "llimview.h" #include "llvoicechannel.h" #include "llsidetray.h" +#include "llspeakers.h" #include "lltrans.h" void LLPanelChatControlPanel::onCallButtonClicked() @@ -244,7 +245,6 @@ void LLPanelIMControlPanel::nameUpdatedCallback(const LLUUID& id, const std::str LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id): mParticipantList(NULL) { - mSpeakerManager = LLIMModel::getInstance()->getSpeakerManager(session_id); } BOOL LLPanelGroupControlPanel::postBuild() @@ -263,9 +263,6 @@ LLPanelGroupControlPanel::~LLPanelGroupControlPanel() // virtual void LLPanelGroupControlPanel::draw() { - //Remove event does not raised until speakerp->mActivityTimer.hasExpired() is false, see LLSpeakerManager::update() - //so we need update it to raise needed event - mSpeakerManager->update(true); // Need to resort the participant list if it's in sort by recent speaker order. if (mParticipantList) mParticipantList->updateRecentSpeakersOrder(); @@ -306,7 +303,10 @@ void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id) // for group and Ad-hoc chat we need to include agent into list if(!mParticipantList) - mParticipantList = new LLParticipantList(mSpeakerManager, getChild<LLAvatarList>("speakers_list"), true,false); + { + LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(session_id); + mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true,false); + } } diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h index c18be5a6df..25fdf944c9 100644 --- a/indra/newview/llpanelimcontrolpanel.h +++ b/indra/newview/llpanelimcontrolpanel.h @@ -37,8 +37,6 @@ #include "llvoicechannel.h" #include "llcallingcard.h" -class LLSpeakerMgr; -class LLAvatarList; class LLParticipantList; class LLPanelChatControlPanel : public LLPanel @@ -110,7 +108,6 @@ public: protected: LLUUID mGroupID; - LLSpeakerMgr* mSpeakerManager; LLParticipantList* mParticipantList; diff --git a/indra/newview/llpanellandaudio.cpp b/indra/newview/llpanellandaudio.cpp index 920fca66f2..6a4c909759 100644 --- a/indra/newview/llpanellandaudio.cpp +++ b/indra/newview/llpanellandaudio.cpp @@ -37,6 +37,7 @@ // viewer includes #include "llmimetypes.h" #include "llviewerparcelmgr.h" +#include "llviewerregion.h" #include "lluictrlfactory.h" // library includes @@ -83,8 +84,14 @@ BOOL LLPanelLandAudio::postBuild() mCheckSoundLocal = getChild<LLCheckBoxCtrl>("check sound local"); childSetCommitCallback("check sound local", onCommitAny, this); - mRadioVoiceChat = getChild<LLRadioGroup>("parcel_voice_channel"); - childSetCommitCallback("parcel_voice_channel", onCommitAny, this); + mCheckParcelEnableVoice = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel"); + childSetCommitCallback("parcel_enable_voice_channel", onCommitAny, this); + + // This one is always disabled so no need for a commit callback + mCheckEstateDisabledVoice = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel_is_estate_disabled"); + + mCheckParcelVoiceLocal = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel_local"); + childSetCommitCallback("parcel_enable_voice_channel_local", onCommitAny, this); mMusicURLEdit = getChild<LLLineEditor>("music_url"); childSetCommitCallback("music_url", onCommitAny, this); @@ -118,19 +125,33 @@ void LLPanelLandAudio::refresh() mMusicUrlCheck->set( parcel->getObscureMusic() ); mMusicUrlCheck->setEnabled( can_change_media ); - if(parcel->getParcelFlagAllowVoice()) + bool allow_voice = parcel->getParcelFlagAllowVoice(); + + LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); + if (region && region->isVoiceEnabled()) { - if(parcel->getParcelFlagUseEstateVoiceChannel()) - mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate); - else - mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatPrivate); + mCheckEstateDisabledVoice->setVisible(false); + + mCheckParcelEnableVoice->setVisible(true); + mCheckParcelEnableVoice->setEnabled( can_change_media ); + mCheckParcelEnableVoice->set(allow_voice); + + mCheckParcelVoiceLocal->setEnabled( can_change_media && allow_voice ); } else { - mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatDisable); + // Voice disabled at estate level, overrides parcel settings + // Replace the parcel voice checkbox with a disabled one + // labelled with an explanatory message + mCheckEstateDisabledVoice->setVisible(true); + + mCheckParcelEnableVoice->setVisible(false); + mCheckParcelEnableVoice->setEnabled(false); + mCheckParcelVoiceLocal->setEnabled(false); } - mRadioVoiceChat->setEnabled( can_change_media ); + mCheckParcelEnableVoice->set(allow_voice); + mCheckParcelVoiceLocal->set(!parcel->getParcelFlagUseEstateVoiceChannel()); mMusicURLEdit->setText(parcel->getMusicURL()); mMusicURLEdit->setEnabled( can_change_media ); @@ -149,30 +170,11 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata) // Extract data from UI BOOL sound_local = self->mCheckSoundLocal->get(); - int voice_setting = self->mRadioVoiceChat->getSelectedIndex(); std::string music_url = self->mMusicURLEdit->getText(); U8 obscure_music = self->mMusicUrlCheck->get(); - - BOOL voice_enabled; - BOOL voice_estate_chan; - - switch(voice_setting) - { - default: - case kRadioVoiceChatEstate: - voice_enabled = TRUE; - voice_estate_chan = TRUE; - break; - case kRadioVoiceChatPrivate: - voice_enabled = TRUE; - voice_estate_chan = FALSE; - break; - case kRadioVoiceChatDisable: - voice_enabled = FALSE; - voice_estate_chan = FALSE; - break; - } + BOOL voice_enabled = self->mCheckParcelEnableVoice->get(); + BOOL voice_estate_chan = !self->mCheckParcelVoiceLocal->get(); // Remove leading/trailing whitespace (common when copying/pasting) LLStringUtil::trim(music_url); diff --git a/indra/newview/llpanellandaudio.h b/indra/newview/llpanellandaudio.h index de5da95fa4..19766a40b6 100644 --- a/indra/newview/llpanellandaudio.h +++ b/indra/newview/llpanellandaudio.h @@ -52,7 +52,9 @@ private: private: LLCheckBoxCtrl* mCheckSoundLocal; - LLRadioGroup* mRadioVoiceChat; + LLCheckBoxCtrl* mCheckParcelEnableVoice; + LLCheckBoxCtrl* mCheckEstateDisabledVoice; + LLCheckBoxCtrl* mCheckParcelVoiceLocal; LLLineEditor* mMusicURLEdit; LLCheckBoxCtrl* mMusicUrlCheck; diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index d6e407a0ed..47feef496a 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -305,6 +305,29 @@ void LLLandmarksPanel::updateShowFolderState() ); } +void LLLandmarksPanel::setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus) +{ + if (selectItemInAccordionTab(mFavoritesInventoryPanel, "tab_favorites", obj_id, take_keyboard_focus)) + { + return; + } + + if (selectItemInAccordionTab(mLandmarksInventoryPanel, "tab_landmarks", obj_id, take_keyboard_focus)) + { + return; + } + + if (selectItemInAccordionTab(mMyInventoryPanel, "tab_inventory", obj_id, take_keyboard_focus)) + { + return; + } + + if (selectItemInAccordionTab(mLibraryInventoryPanel, "tab_library", obj_id, take_keyboard_focus)) + { + return; + } +} + ////////////////////////////////////////////////////////////////////////// // PROTECTED METHODS ////////////////////////////////////////////////////////////////////////// @@ -350,6 +373,36 @@ LLFolderViewItem* LLLandmarksPanel::getCurSelectedItem() const return mCurrentSelectedList ? mCurrentSelectedList->getRootFolder()->getCurSelectedItem() : NULL; } +LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list, + const std::string& tab_name, + const LLUUID& obj_id, + BOOL take_keyboard_focus) const +{ + if (!inventory_list) + return NULL; + + LLFolderView* folder_view = inventory_list->getRootFolder(); + + LLFolderViewItem* item = folder_view->getItemByID(obj_id); + if (!item) + return NULL; + + LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(tab_name); + if (!tab->isExpanded()) + { + tab->changeOpenClose(false); + } + + folder_view->setSelection(item, FALSE, take_keyboard_focus); + + LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion"); + LLRect screen_rc; + localRectToScreen(item->getRect(), &screen_rc); + accordion->notifyParent(LLSD().with("scrollToShowRect", screen_rc.getValue())); + + return item; +} + void LLLandmarksPanel::updateSortOrder(LLInventoryPanel* panel, bool byDate) { if(!panel) return; diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 569739237d..96b790844c 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -73,6 +73,11 @@ public: */ void updateShowFolderState(); + /** + * Selects item with "obj_id" in one of accordion tabs. + */ + void setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus); + protected: /** * @return true - if current selected panel is not null and selected item is a landmark @@ -81,6 +86,17 @@ protected: bool isReceivedFolderSelected() const; void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb); LLFolderViewItem* getCurSelectedItem() const; + + /** + * Selects item with "obj_id" in "inventory_list" and scrolls accordion + * scrollbar to show the item. + * Returns pointer to the item if it is found in "inventory_list", otherwise NULL. + */ + LLFolderViewItem* selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list, + const std::string& tab_name, + const LLUUID& obj_id, + BOOL take_keyboard_focus) const; + void updateSortOrder(LLInventoryPanel* panel, bool byDate); //LLRemoteParcelInfoObserver interface diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index fd5ce7a46d..cf903958ee 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -61,6 +61,9 @@ #include "llviewercontrol.h" +static const std::string OUTFITS_TAB_NAME = "outfitslist_tab"; +static const std::string COF_TAB_NAME = "cof_tab"; + static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory"); bool LLPanelOutfitsInventory::sShowDebugEditor = false; @@ -267,7 +270,7 @@ void LLPanelOutfitsInventory::onSaveCommit(const std::string& outfit_name) if (mAppearanceTabs) { - mAppearanceTabs->selectTabByName("outfitslist_tab"); + mAppearanceTabs->selectTabByName(OUTFITS_TAB_NAME); } } @@ -503,8 +506,7 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata) if (command_name == "wear") { - const BOOL is_my_outfits = (mActivePanel->getName() == "outfitslist_tab"); - if (!is_my_outfits) + if (isCOFPanelActive()) { return FALSE; } @@ -558,17 +560,15 @@ bool LLPanelOutfitsInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropTy void LLPanelOutfitsInventory::initTabPanels() { - mTabPanels.resize(2); - - LLInventoryPanel *cof_panel = getChild<LLInventoryPanel>("cof_tab"); + LLInventoryPanel *cof_panel = getChild<LLInventoryPanel>(COF_TAB_NAME); cof_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); - mTabPanels[0] = cof_panel; - - LLInventoryPanel *myoutfits_panel = getChild<LLInventoryPanel>("outfitslist_tab"); + mTabPanels.push_back(cof_panel); + + LLInventoryPanel *myoutfits_panel = getChild<LLInventoryPanel>(OUTFITS_TAB_NAME); myoutfits_panel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, LLInventoryFilter::FILTERTYPE_CATEGORY); myoutfits_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); - mTabPanels[1] = myoutfits_panel; - + mTabPanels.push_back(myoutfits_panel); + for (tabpanels_vec_t::iterator iter = mTabPanels.begin(); iter != mTabPanels.end(); ++iter) @@ -615,19 +615,19 @@ void LLPanelOutfitsInventory::onTabChange() updateVerbs(); } -LLInventoryPanel* LLPanelOutfitsInventory::getActivePanel() -{ - return mActivePanel; -} - -bool LLPanelOutfitsInventory::isTabPanel(LLInventoryPanel *panel) +BOOL LLPanelOutfitsInventory::isTabPanel(LLInventoryPanel *panel) const { - for(tabpanels_vec_t::iterator it = mTabPanels.begin(); + for(tabpanels_vec_t::const_iterator it = mTabPanels.begin(); it != mTabPanels.end(); ++it) { if (*it == panel) - return true; + return TRUE; } - return false; + return FALSE; +} + +BOOL LLPanelOutfitsInventory::isCOFPanelActive() const +{ + return (getActivePanel()->getName() == COF_TAB_NAME); } diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h index 76110e2a3f..ab25ef0a49 100644 --- a/indra/newview/llpaneloutfitsinventory.h +++ b/indra/newview/llpaneloutfitsinventory.h @@ -78,24 +78,26 @@ protected: bool getIsCorrectType(const LLFolderViewEventListener *listenerp) const; private: - LLSidepanelAppearance* mParent; - LLSaveFolderState* mSavedFolderState; - LLTabContainer* mAppearanceTabs; - std::string mFilterSubString; + LLSidepanelAppearance* mParent; + LLSaveFolderState* mSavedFolderState; + LLTabContainer* mAppearanceTabs; + std::string mFilterSubString; public: ////////////////////////////////////////////////////////////////////////////////// // tab panels - LLInventoryPanel* getActivePanel(); - bool isTabPanel(LLInventoryPanel *panel); + LLInventoryPanel* getActivePanel() { return mActivePanel; } + const LLInventoryPanel* getActivePanel() const { return mActivePanel; } + BOOL isTabPanel(LLInventoryPanel *panel) const; protected: - void initTabPanels(); - void onTabSelectionChange(LLInventoryPanel* tab_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action); - void onTabChange(); - + void initTabPanels(); + void onTabSelectionChange(LLInventoryPanel* tab_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action); + void onTabChange(); + BOOL isCOFPanelActive() const; + private: - LLInventoryPanel* mActivePanel; + LLInventoryPanel* mActivePanel; typedef std::vector<LLInventoryPanel *> tabpanels_vec_t; tabpanels_vec_t mTabPanels; diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index b80eb9db38..0c10f11bfc 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -34,26 +34,20 @@ #include "llpanelplaceinfo.h" -#include "roles_constants.h" #include "llsdutil.h" -#include "llsecondlifeurls.h" #include "llsdutil_math.h" + #include "llregionhandle.h" -#include "message.h" #include "lliconctrl.h" #include "lltextbox.h" #include "llagent.h" -#include "llavatarpropertiesprocessor.h" #include "llexpandabletextbox.h" #include "llpanelpick.h" #include "lltexturectrl.h" -#include "llviewerinventory.h" -#include "llviewerparcelmgr.h" #include "llviewerregion.h" -#include "llviewertexteditor.h" LLPanelPlaceInfo::LLPanelPlaceInfo() : LLPanel(), @@ -265,25 +259,6 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent) } } -// virtual -void LLPanelPlaceInfo::handleVisibilityChange(BOOL new_visibility) -{ - LLPanel::handleVisibilityChange(new_visibility); - - LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); - if (!parcel_mgr) - return; - - // Remove land selection when panel hides. - if (!new_visibility) - { - if (!parcel_mgr->selectionEmpty()) - { - parcel_mgr->deselectLand(); - } - } -} - void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel) { std::string region_name = mRegionName->getText(); diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index 7dfc7b2444..3091f7ed24 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -94,7 +94,6 @@ public: /*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); // Create a pick for the location specified // by global_pos. diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 402d50ba9c..d892e2885b 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -257,6 +257,25 @@ void LLPanelPlaceProfile::processParcelInfo(const LLParcelData& parcel_data) } } +// virtual +void LLPanelPlaceProfile::handleVisibilityChange(BOOL new_visibility) +{ + LLPanel::handleVisibilityChange(new_visibility); + + LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); + if (!parcel_mgr) + return; + + // Remove land selection when panel hides. + if (!new_visibility) + { + if (!parcel_mgr->selectionEmpty()) + { + parcel_mgr->deselectUnused(); + } + } +} + void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, LLViewerRegion* region, const LLVector3d& pos_global, diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h index 8c30ca92fb..8ca9526875 100644 --- a/indra/newview/llpanelplaceprofile.h +++ b/indra/newview/llpanelplaceprofile.h @@ -52,6 +52,8 @@ public: /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); + /*virtual*/ void handleVisibilityChange(BOOL new_visibility); + // Displays information about the currently selected parcel // without sending a request to the server. // If is_current_parcel true shows "You Are Here" banner. diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index a71c8d8958..a4f0e55a93 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -289,89 +289,92 @@ BOOL LLPanelPlaces::postBuild() void LLPanelPlaces::onOpen(const LLSD& key) { - if(!mPlaceProfile || !mLandmarkInfo || key.size() == 0) + if (!mPlaceProfile || !mLandmarkInfo) return; - mFilterEditor->clear(); - onFilterEdit("", false); - - mPlaceInfoType = key["type"].asString(); - mPosGlobal.setZero(); - mItem = NULL; - isLandmarkEditModeOn = false; - togglePlaceInfoPanel(TRUE); - - if (mPlaceInfoType == AGENT_INFO_TYPE) - { - mPlaceProfile->setInfoType(LLPanelPlaceInfo::AGENT); - } - else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE) + if (key.size() != 0) { - mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK); + mFilterEditor->clear(); + onFilterEdit("", false); + + mPlaceInfoType = key["type"].asString(); + mPosGlobal.setZero(); + mItem = NULL; + isLandmarkEditModeOn = false; + togglePlaceInfoPanel(TRUE); - if (key.has("x") && key.has("y") && key.has("z")) + if (mPlaceInfoType == AGENT_INFO_TYPE) { - mPosGlobal = LLVector3d(key["x"].asReal(), - key["y"].asReal(), - key["z"].asReal()); + mPlaceProfile->setInfoType(LLPanelPlaceInfo::AGENT); } - else + else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE) { - mPosGlobal = gAgent.getPositionGlobal(); - } - - mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal); + mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK); - // Disable Save button because there is no item to save yet. - // The button will be enabled in onLandmarkLoaded callback. - mSaveBtn->setEnabled(FALSE); - } - else if (mPlaceInfoType == LANDMARK_INFO_TYPE) - { - mLandmarkInfo->setInfoType(LLPanelPlaceInfo::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(); + } - LLInventoryItem* item = gInventory.getItem(key["id"].asUUID()); - if (!item) - return; + mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal); - setItem(item); - } - else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE) - { - if (key.has("id")) + // Disable Save button because there is no item to save yet. + // The button will be enabled in onLandmarkLoaded callback. + mSaveBtn->setEnabled(FALSE); + } + else if (mPlaceInfoType == LANDMARK_INFO_TYPE) { - LLUUID parcel_id = key["id"].asUUID(); - mPlaceProfile->setParcelID(parcel_id); + mLandmarkInfo->setInfoType(LLPanelPlaceInfo::LANDMARK); + + LLInventoryItem* item = gInventory.getItem(key["id"].asUUID()); + if (!item) + return; - // query the server to get the global 3D position of this - // parcel - we need this for teleport/mapping functions. - mRemoteParcelObserver->setParcelID(parcel_id); + setItem(item); } - else + else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE) { - mPosGlobal = LLVector3d(key["x"].asReal(), - key["y"].asReal(), - key["z"].asReal()); - mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal); + if (key.has("id")) + { + LLUUID parcel_id = key["id"].asUUID(); + mPlaceProfile->setParcelID(parcel_id); + + // query the server to get the global 3D position of this + // parcel - we need this for teleport/mapping functions. + mRemoteParcelObserver->setParcelID(parcel_id); + } + else + { + mPosGlobal = LLVector3d(key["x"].asReal(), + key["y"].asReal(), + key["z"].asReal()); + mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal); + } + + mPlaceProfile->setInfoType(LLPanelPlaceInfo::PLACE); } + else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) + { + S32 index = key["id"].asInteger(); - mPlaceProfile->setInfoType(LLPanelPlaceInfo::PLACE); - } - else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE) - { - S32 index = key["id"].asInteger(); + const LLTeleportHistoryStorage::slurl_list_t& hist_items = + LLTeleportHistoryStorage::getInstance()->getItems(); - const LLTeleportHistoryStorage::slurl_list_t& hist_items = - LLTeleportHistoryStorage::getInstance()->getItems(); + mPosGlobal = hist_items[index].mGlobalPos; - mPosGlobal = hist_items[index].mGlobalPos; + mPlaceProfile->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY); + mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal); + } - mPlaceProfile->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY); - mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal); + updateVerbs(); } - updateVerbs(); - LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); if (!parcel_mgr) return; @@ -388,9 +391,12 @@ void LLPanelPlaces::onOpen(const LLSD& key) { parcel_mgr->removeObserver(mParcelObserver); + // Clear the reference to selection to allow its removal in deselectUnused(). + mParcel.clear(); + if (!parcel_mgr->selectionEmpty()) { - parcel_mgr->deselectLand(); + parcel_mgr->deselectUnused(); } } } @@ -765,23 +771,23 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param) mPickPanel->reshape(rect.getWidth(), rect.getHeight()); mPickPanel->setRect(rect); } - else if (item == "add_to_favbar") - { - if ( mItem.notNull() ) - { - const LLUUID& favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); - if ( favorites_id.notNull() ) - { - copy_inventory_item(gAgent.getID(), - mItem->getPermissions().getOwner(), - mItem->getUUID(), - favorites_id, - std::string(), - LLPointer<LLInventoryCallback>(NULL)); - llinfos << "Copied inventory item #" << mItem->getUUID() << " to favorites." << llendl; - } - } - } + else if (item == "add_to_favbar") + { + if ( mItem.notNull() ) + { + const LLUUID& favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); + if ( favorites_id.notNull() ) + { + copy_inventory_item(gAgent.getID(), + mItem->getPermissions().getOwner(), + mItem->getUUID(), + favorites_id, + std::string(), + LLPointer<LLInventoryCallback>(NULL)); + llinfos << "Copied inventory item #" << mItem->getUUID() << " to favorites." << llendl; + } + } + } } void LLPanelPlaces::onBackButtonClicked() @@ -826,6 +832,14 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) mLandmarkInfo->setVisible(FALSE); } + else if (mPlaceInfoType == AGENT_INFO_TYPE) + { + LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver); + + // Clear reference to parcel selection when closing place profile panel. + // LLViewerParcelMgr removes the selection if it has 1 reference to it. + mParcel.clear(); + } } else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE || mPlaceInfoType == LANDMARK_INFO_TYPE) @@ -842,6 +856,33 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) mPlaceProfile->setVisible(FALSE); } + else + { + LLLandmarksPanel* landmarks_panel = + dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName("Landmarks")); + if (landmarks_panel && mItem.notNull()) + { + // If a landmark info is being closed we open the landmarks tab + // and set this landmark selected. + mTabContainer->selectTabPanel(landmarks_panel); + + landmarks_panel->setItemSelected(mItem->getUUID(), TRUE); + } + } + } +} + +// virtual +void LLPanelPlaces::handleVisibilityChange(BOOL new_visibility) +{ + LLPanel::handleVisibilityChange(new_visibility); + + if (!new_visibility && mPlaceInfoType == AGENT_INFO_TYPE) + { + LLViewerParcelMgr::getInstance()->removeObserver(mParcelObserver); + + // Clear reference to parcel selection when closing places panel. + mParcel.clear(); } } diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 27b5911ebb..0eba7f3afc 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -97,6 +97,8 @@ private: void togglePickPanel(BOOL visible); void togglePlaceInfoPanel(BOOL visible); + /*virtual*/ void handleVisibilityChange(BOOL new_visibility); + void updateVerbs(); LLPanelPlaceInfo* getCurrentInfoPanel(); diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 571745ee02..1b8fb49641 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -1036,7 +1036,7 @@ void LLTeleportHistoryPanel::setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool bool LLTeleportHistoryPanel::isAccordionCollapsedByUser(LLUICtrl* acc_tab) { LLSD param = acc_tab->getValue(); - if(!param.has("acc_collapsed")) + if(!param.has(COLLAPSED_BY_USER)) { return false; } diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index b049f914ad..88b706fb6b 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -125,6 +125,8 @@ LLParticipantList::~LLParticipantList() delete mParticipantListMenu; mParticipantListMenu = NULL; } + + mAvatarList->setContextMenu(NULL); } void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible) @@ -431,6 +433,10 @@ LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu() LLContextMenu* main_menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( "menu_participant_list.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); + // Don't show sort options for P2P chat + bool is_sort_visible = (mParent.mAvatarList && mParent.mAvatarList->size() > 1); + main_menu->setItemVisible("SortByName", is_sort_visible); + main_menu->setItemVisible("SortByRecentSpeakers", is_sort_visible); main_menu->setItemVisible("Moderator Options", isGroupModerator()); main_menu->arrangeAndClear(); @@ -456,11 +462,6 @@ void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const LLMenuGL::sMenuContainer->childSetVisible("ModerateVoiceUnMuteSelected", false); LLMenuGL::sMenuContainer->childSetVisible("ModerateVoiceUnMuteOthers", false); } - - // Don't show sort options for P2P chat - bool is_sort_visible = (mParent.mAvatarList && mParent.mAvatarList->size() > 1); - LLMenuGL::sMenuContainer->childSetVisible("SortByName", is_sort_visible); - LLMenuGL::sMenuContainer->childSetVisible("SortByRecentSpeakers", is_sort_visible); } void LLParticipantList::LLParticipantListMenu::sortParticipantList(const LLSD& userdata) diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index a857e30d4f..028807a6bd 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -380,138 +380,53 @@ void LLPreviewTexture::updateDimensions() mUpdateDimensions = FALSE; - S32 image_height = llmax(1, mImage->getFullHeight()); - S32 image_width = llmax(1, mImage->getFullWidth()); - // Attempt to make the image 1:1 on screen. - // If that fails, cut width by half. - S32 client_width = image_width; - S32 client_height = image_height; - S32 horiz_pad = 2 * (LLPANEL_BORDER_WIDTH + PREVIEW_PAD) + PREVIEW_RESIZE_HANDLE_SIZE; - S32 vert_pad = PREVIEW_HEADER_SIZE + 2 * CLIENT_RECT_VPAD + LLPANEL_BORDER_WIDTH; - S32 max_client_width = gViewerWindow->getWindowWidthScaled() - horiz_pad; - S32 max_client_height = gViewerWindow->getWindowHeightScaled() - vert_pad; - - if (mAspectRatio > 0.f) - { - client_height = llceil((F32)client_width / mAspectRatio); - } - - while ((client_width > max_client_width) || - (client_height > max_client_height )) - { - client_width /= 2; - client_height /= 2; - } - - S32 view_width = client_width + horiz_pad; - S32 view_height = client_height + vert_pad; - // set text on dimensions display (should be moved out of here and into a callback of some sort) childSetTextArg("dimensions", "[WIDTH]", llformat("%d", mImage->getFullWidth())); childSetTextArg("dimensions", "[HEIGHT]", llformat("%d", mImage->getFullHeight())); - + + LLRect dim_rect; + childGetRect("dimensions", dim_rect); + + S32 horiz_pad = 2 * (LLPANEL_BORDER_WIDTH + PREVIEW_PAD) + PREVIEW_RESIZE_HANDLE_SIZE; + // add space for dimensions and aspect ratio - S32 info_height = 0; - LLRect aspect_rect; - childGetRect("combo_aspect_ratio", aspect_rect); - S32 aspect_height = aspect_rect.getHeight(); - info_height += aspect_height + CLIENT_RECT_VPAD; - view_height += info_height; - - S32 button_height = 0; - - // add space for buttons - view_height += (BTN_HEIGHT + CLIENT_RECT_VPAD) * 3; - button_height = (BTN_HEIGHT + PREVIEW_PAD) * 3; + S32 info_height = dim_rect.mTop + CLIENT_RECT_VPAD; - view_width = llmax(view_width, getMinWidth()); - view_height = llmax(view_height, getMinHeight()); - - if (view_height != mLastHeight || view_width != mLastWidth) - { - if (getHost()) - { - getHost()->growToFit(view_width, view_height); - reshape( view_width, view_height ); - setOrigin( 0, getHost()->getRect().getHeight() - (view_height + PREVIEW_HEADER_SIZE) ); - } - else - { - S32 old_top = getRect().mTop; - S32 old_left = getRect().mLeft; - reshape( view_width, view_height ); - S32 new_bottom = old_top - getRect().getHeight(); - setOrigin( old_left, new_bottom ); - } - - // Try to keep whole view onscreen, don't allow partial offscreen. - if (getHost()) - gFloaterView->adjustToFitScreen(getHost(), FALSE); - else - gFloaterView->adjustToFitScreen(this, FALSE); - - if (image_height > 1 && image_width > 1) - { - // Resize until we know the image's height - mLastWidth = view_width; - mLastHeight = view_height; - } - } - - if (!mUserResized) - { - // clamp texture size to fit within actual size of floater after attempting resize - client_width = llmin(client_width, getRect().getWidth() - horiz_pad); - client_height = llmin(client_height, getRect().getHeight() - PREVIEW_HEADER_SIZE - - (2 * CLIENT_RECT_VPAD) - LLPANEL_BORDER_WIDTH - info_height); + LLRect client_rect(horiz_pad, getRect().getHeight(), getRect().getWidth() - horiz_pad, 0); + client_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD); + client_rect.mBottom += PREVIEW_BORDER + CLIENT_RECT_VPAD + info_height ; - - } - else + S32 client_width = client_rect.getWidth(); + S32 client_height = client_rect.getHeight(); + + if (mAspectRatio > 0.f) { - client_width = getRect().getWidth() - horiz_pad; - if (mAspectRatio > 0) + if(mAspectRatio > 1.f) { - client_height = llround(client_width / mAspectRatio); + client_height = llceil((F32)client_width / mAspectRatio); + if(client_height > client_rect.getHeight()) + { + client_height = client_rect.getHeight(); + client_width = llceil((F32)client_height * mAspectRatio); + } } else { - client_height = getRect().getHeight() - vert_pad; - } - } - - S32 max_height = getRect().getHeight() - PREVIEW_BORDER - button_height - - CLIENT_RECT_VPAD - info_height - CLIENT_RECT_VPAD - PREVIEW_HEADER_SIZE; - - if (mAspectRatio > 0.f) - { - max_height = llmax(max_height, 1); - - if (client_height > max_height) - { - client_height = max_height; - client_width = llround(client_height * mAspectRatio); + client_width = llceil((F32)client_height * mAspectRatio); + if(client_width > client_rect.getWidth()) + { + client_width = client_rect.getWidth(); + client_height = llceil((F32)client_width / mAspectRatio); + } } } - else - { - S32 max_width = getRect().getWidth() - horiz_pad; - client_height = llclamp(client_height, 1, max_height); - client_width = llclamp(client_width, 1, max_width); - } - - LLRect window_rect(0, getRect().getHeight(), getRect().getWidth(), 0); - window_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD); - window_rect.mBottom += PREVIEW_BORDER + button_height + CLIENT_RECT_VPAD + info_height + CLIENT_RECT_VPAD; + mClientRect.setLeftTopAndSize(client_rect.getCenterX() - (client_width / 2), client_rect.getCenterY() + (client_height / 2), client_width, client_height); - mClientRect.setLeftTopAndSize(window_rect.getCenterX() - (client_width / 2), window_rect.mTop, client_width, client_height); - // Hide the aspect ratio label if the window is too narrow // Assumes the label should be to the right of the dimensions - LLRect dim_rect, aspect_label_rect; + LLRect aspect_label_rect; childGetRect("aspect_ratio", aspect_label_rect); - childGetRect("dimensions", dim_rect); childSetVisible("aspect_ratio", dim_rect.mRight < aspect_label_rect.mLeft); } diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 0dd9203c6d..9608cd1263 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -44,7 +44,6 @@ #include "llvoavatar.h" #include "llworld.h" -const F32 SPEAKER_TIMEOUT = 10.f; // seconds of not being on voice channel before removed from list of active speakers const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f); const LLColor4 ACTIVE_COLOR(0.5f, 0.5f, 0.5f, 1.f); @@ -73,8 +72,6 @@ LLSpeaker::LLSpeaker(const LLUUID& id, const std::string& name, const ESpeakerTy } gVoiceClient->setUserVolume(id, LLMuteList::getInstance()->getSavedResidentVolume(id)); - - mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT); } @@ -164,6 +161,89 @@ bool LLSortRecentSpeakers::operator()(const LLPointer<LLSpeaker> lhs, const LLPo return( lhs->mDisplayName.compare(rhs->mDisplayName) < 0 ); } +LLSpeakerActionTimer::LLSpeakerActionTimer(action_callback_t action_cb, F32 action_period, const LLUUID& speaker_id) +: LLEventTimer(action_period) +, mActionCallback(action_cb) +, mSpeakerId(speaker_id) +{ +} + +BOOL LLSpeakerActionTimer::tick() +{ + if (mActionCallback) + { + return (BOOL)mActionCallback(mSpeakerId); + } + return TRUE; +} + +LLSpeakersDelayActionsStorage::LLSpeakersDelayActionsStorage(LLSpeakerActionTimer::action_callback_t action_cb, F32 action_delay) +: mActionCallback(action_cb) +, mActionDelay(action_delay) +{ +} + +LLSpeakersDelayActionsStorage::~LLSpeakersDelayActionsStorage() +{ + removeAllTimers(); +} + +void LLSpeakersDelayActionsStorage::setActionTimer(const LLUUID& speaker_id) +{ + bool not_found = true; + if (mActionTimersMap.size() > 0) + { + not_found = mActionTimersMap.find(speaker_id) == mActionTimersMap.end(); + } + + // If there is already a started timer for the passed UUID don't do anything. + if (not_found) + { + // Starting a timer to remove an participant after delay is completed + mActionTimersMap.insert(LLSpeakerActionTimer::action_value_t(speaker_id, + new LLSpeakerActionTimer( + boost::bind(&LLSpeakersDelayActionsStorage::onTimerActionCallback, this, _1), + mActionDelay, speaker_id))); + } +} + +void LLSpeakersDelayActionsStorage::unsetActionTimer(const LLUUID& speaker_id) +{ + if (mActionTimersMap.size() == 0) return; + + LLSpeakerActionTimer::action_timer_iter_t it_speaker = mActionTimersMap.find(speaker_id); + + if (it_speaker != mActionTimersMap.end()) + { + delete it_speaker->second; + mActionTimersMap.erase(it_speaker); + } +} + +void LLSpeakersDelayActionsStorage::removeAllTimers() +{ + LLSpeakerActionTimer::action_timer_iter_t iter = mActionTimersMap.begin(); + for (; iter != mActionTimersMap.end(); ++iter) + { + delete iter->second; + } + mActionTimersMap.clear(); +} + +bool LLSpeakersDelayActionsStorage::onTimerActionCallback(const LLUUID& speaker_id) +{ + unsetActionTimer(speaker_id); + + if (mActionCallback) + { + mActionCallback(speaker_id); + } + + // do not return true to avoid deleting of an timer twice: + // in LLSpeakersDelayActionsStorage::unsetActionTimer() & LLEventTimer::updateClass() + return false; +} + // // LLSpeakerMgr @@ -172,10 +252,14 @@ bool LLSortRecentSpeakers::operator()(const LLPointer<LLSpeaker> lhs, const LLPo LLSpeakerMgr::LLSpeakerMgr(LLVoiceChannel* channelp) : mVoiceChannel(channelp) { + static LLUICachedControl<F32> remove_delay ("SpeakerParticipantRemoveDelay", 10.0); + + mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLSpeakerMgr::removeSpeaker, this, _1), remove_delay); } LLSpeakerMgr::~LLSpeakerMgr() { + delete mSpeakerDelayRemover; } LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::string& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type) @@ -198,7 +282,6 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin { // keep highest priority status (lowest value) instead of overriding current value speakerp->mStatus = llmin(speakerp->mStatus, status); - speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT); // RN: due to a weird behavior where IMs from attached objects come from the wearer's agent_id // we need to override speakers that we think are objects when we find out they are really // residents @@ -210,6 +293,8 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin } } + mSpeakerDelayRemover->unsetActionTimer(speakerp->mID); + return speakerp; } @@ -314,7 +399,7 @@ void LLSpeakerMgr::update(BOOL resort_ok) S32 sort_index = 0; speaker_list_t::iterator sorted_speaker_it; for(sorted_speaker_it = mSpeakersSorted.begin(); - sorted_speaker_it != mSpeakersSorted.end(); ) + sorted_speaker_it != mSpeakersSorted.end(); ++sorted_speaker_it) { LLPointer<LLSpeaker> speakerp = *sorted_speaker_it; @@ -327,19 +412,6 @@ void LLSpeakerMgr::update(BOOL resort_ok) // stuff sort ordinal into speaker so the ui can sort by this value speakerp->mSortIndex = sort_index++; - - // remove speakers that have been gone too long - if (speakerp->mStatus == LLSpeaker::STATUS_NOT_IN_CHANNEL && speakerp->mActivityTimer.hasExpired()) - { - fireEvent(new LLSpeakerListChangeEvent(this, speakerp->mID), "remove"); - - mSpeakers.erase(speakerp->mID); - sorted_speaker_it = mSpeakersSorted.erase(sorted_speaker_it); - } - else - { - ++sorted_speaker_it; - } } } @@ -363,6 +435,35 @@ void LLSpeakerMgr::updateSpeakerList() } } +void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp) +{ + speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL; + speakerp->mDotColor = INACTIVE_COLOR; + mSpeakerDelayRemover->setActionTimer(speakerp->mID); +} + +bool LLSpeakerMgr::removeSpeaker(const LLUUID& speaker_id) +{ + mSpeakers.erase(speaker_id); + + speaker_list_t::iterator sorted_speaker_it = mSpeakersSorted.begin(); + + for(; sorted_speaker_it != mSpeakersSorted.end(); ++sorted_speaker_it) + { + if (speaker_id == (*sorted_speaker_it)->mID) + { + mSpeakersSorted.erase(sorted_speaker_it); + break; + } + } + + fireEvent(new LLSpeakerListChangeEvent(this, speaker_id), "remove"); + + update(TRUE); + + return false; +} + LLPointer<LLSpeaker> LLSpeakerMgr::findSpeaker(const LLUUID& speaker_id) { //In some conditions map causes crash if it is empty(Windows only), adding check (EK) @@ -511,9 +612,7 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update) { if (agent_data["transition"].asString() == "LEAVE" && speakerp.notNull()) { - speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL; - speakerp->mDotColor = INACTIVE_COLOR; - speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT); + setSpeakerNotInChannel(speakerp); } else if (agent_data["transition"].asString() == "ENTER") { @@ -563,9 +662,7 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update) std::string agent_transition = update_it->second.asString(); if (agent_transition == "LEAVE" && speakerp.notNull()) { - speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL; - speakerp->mDotColor = INACTIVE_COLOR; - speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT); + setSpeakerNotInChannel(speakerp); } else if ( agent_transition == "ENTER") { @@ -734,12 +831,13 @@ void LLActiveSpeakerMgr::updateSpeakerList() mVoiceChannel = LLVoiceChannel::getCurrentVoiceChannel(); // always populate from active voice channel - if (LLVoiceChannel::getCurrentVoiceChannel() != mVoiceChannel) + if (LLVoiceChannel::getCurrentVoiceChannel() != mVoiceChannel) //MA: seems this is always false { fireEvent(new LLSpeakerListChangeEvent(this, LLUUID::null), "clear"); mSpeakers.clear(); mSpeakersSorted.clear(); mVoiceChannel = LLVoiceChannel::getCurrentVoiceChannel(); + mSpeakerDelayRemover->removeAllTimers(); } LLSpeakerMgr::updateSpeakerList(); @@ -800,9 +898,7 @@ void LLLocalSpeakerMgr::updateSpeakerList() LLVOAvatar* avatarp = (LLVOAvatar*)gObjectList.findObject(speaker_id); if (!avatarp || dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS) { - speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL; - speakerp->mDotColor = INACTIVE_COLOR; - speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT); + setSpeakerNotInChannel(speakerp); } } } diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h index da8dfdf548..63237204c8 100644 --- a/indra/newview/llspeakers.h +++ b/indra/newview/llspeakers.h @@ -73,7 +73,6 @@ public: F32 mLastSpokeTime; // timestamp when this speaker last spoke F32 mSpeechVolume; // current speech amplitude (timea average rms amplitude?) std::string mDisplayName; // cache user name for this speaker - LLFrameTimer mActivityTimer; // time out speakers when they are not part of current voice channel BOOL mHasSpoken; // has this speaker said anything this session? BOOL mHasLeftCurrentCall; // has this speaker left the current voice call? LLColor4 mDotColor; @@ -120,6 +119,92 @@ private: const LLUUID& mSpeakerID; }; +/** + * class LLSpeakerActionTimer + * + * Implements a timer that calls stored callback action for stored speaker after passed period. + * + * Action is called until callback returns "true". + * In this case the timer will be removed via LLEventTimer::updateClass(). + * Otherwise it should be deleted manually in place where it is used. + * If action callback is not set timer will tick only once and deleted. + */ +class LLSpeakerActionTimer : public LLEventTimer +{ +public: + typedef boost::function<bool(const LLUUID&)> action_callback_t; + typedef std::map<LLUUID, LLSpeakerActionTimer*> action_timers_map_t; + typedef action_timers_map_t::value_type action_value_t; + typedef action_timers_map_t::const_iterator action_timer_const_iter_t; + typedef action_timers_map_t::iterator action_timer_iter_t; + + /** + * Constructor. + * + * @param action_cb - callback which will be called each time after passed action period. + * @param action_period - time in seconds timer should tick. + * @param speaker_id - LLUUID of speaker which will be passed into action callback. + */ + LLSpeakerActionTimer(action_callback_t action_cb, F32 action_period, const LLUUID& speaker_id); + virtual ~LLSpeakerActionTimer() {}; + + /** + * Implements timer "tick". + * + * If action callback is not specified returns true. Instance will be deleted by LLEventTimer::updateClass(). + */ + virtual BOOL tick(); + +private: + action_callback_t mActionCallback; + LLUUID mSpeakerId; +}; + +/** + * Represents a functionality to store actions for speakers with delay. + * Is based on LLSpeakerActionTimer. + */ +class LLSpeakersDelayActionsStorage +{ +public: + LLSpeakersDelayActionsStorage(LLSpeakerActionTimer::action_callback_t action_cb, F32 action_delay); + ~LLSpeakersDelayActionsStorage(); + + /** + * Sets new LLSpeakerActionTimer with passed speaker UUID. + */ + void setActionTimer(const LLUUID& speaker_id); + + /** + * Removes stored LLSpeakerActionTimer for passed speaker UUID from internal map and deletes it. + * + * @see onTimerActionCallback() + */ + void unsetActionTimer(const LLUUID& speaker_id); + + void removeAllTimers(); +private: + /** + * Callback of the each instance of LLSpeakerActionTimer. + * + * Unsets an appropriate timer instance and calls action callback for specified speacker_id. + * It always returns false to not use LLEventTimer::updateClass functionality of timer deleting. + * + * @see unsetActionTimer() + */ + bool onTimerActionCallback(const LLUUID& speaker_id); + + LLSpeakerActionTimer::action_timers_map_t mActionTimersMap; + LLSpeakerActionTimer::action_callback_t mActionCallback; + + /** + * Delay to call action callback for speakers after timer was set. + */ + F32 mActionDelay; + +}; + + class LLSpeakerMgr : public LLOldEvents::LLObservable { public: @@ -144,6 +229,8 @@ public: protected: virtual void updateSpeakerList(); + void setSpeakerNotInChannel(LLSpeaker* speackerp); + bool removeSpeaker(const LLUUID& speaker_id); typedef std::map<LLUUID, LLPointer<LLSpeaker> > speaker_map_t; speaker_map_t mSpeakers; @@ -151,6 +238,11 @@ protected: speaker_list_t mSpeakersSorted; LLFrameTimer mSpeechTimer; LLVoiceChannel* mVoiceChannel; + + /** + * time out speakers when they are not part of current session + */ + LLSpeakersDelayActionsStorage* mSpeakerDelayRemover; }; class LLIMSpeakerMgr : public LLSpeakerMgr diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 4a7d784c3e..84c8b9d5f0 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -1140,6 +1140,10 @@ LLTexLayerInterface::LLTexLayerInterface(const LLTexLayerInterface &layer, LLWea BOOL LLTexLayerInterface::setInfo(const LLTexLayerInfo *info, LLWearable* wearable ) // This sets mInfo and calls initialization functions { //llassert(mInfo == NULL); // nyx says this is probably bogus but needs investigating + if (mInfo != NULL) // above llassert(), but softened into a warning + { + llwarns << "BAD STUFF! mInfo != NULL" << llendl; + } mInfo = info; //mID = info->mID; // No ID diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index a65e990ef8..60ac701b15 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -1103,7 +1103,10 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op) { if (op == TEXTURE_CANCEL) mViewModel->resetDirty(); - else + // If the "no_commit_on_selection" parameter is set + // we get dirty only when user presses OK in the picker + // (i.e. op == TEXTURE_SELECT) or texture changes via DnD. + else if (mCommitOnSelection || op == TEXTURE_SELECT) mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? if( floaterp->isDirty() ) @@ -1125,7 +1128,7 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op) { // If the "no_commit_on_selection" parameter is set // we commit only when user presses OK in the picker - // (i.e. op == TEXTURE_SELECT) or changes texture via DnD. + // (i.e. op == TEXTURE_SELECT) or texture changes via DnD. if (mCommitOnSelection || op == TEXTURE_SELECT) onCommit(); } @@ -1167,6 +1170,9 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, { if(doDrop(item)) { + if (!mCommitOnSelection) + mViewModel->setDirty(); + // This removes the 'Multiple' overlay, since // there is now only one texture selected. setTentative( FALSE ); diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 023329a9b2..8ca92c3d87 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -74,7 +74,8 @@ public: Optional<std::string> default_image_name; Optional<bool> allow_no_texture; Optional<bool> can_apply_immediately; - Optional<bool> no_commit_on_selection; // don't commit unless it's DnD or OK button press + Optional<bool> no_commit_on_selection; // alternative mode: commit occurs and the widget gets dirty + // only on DnD or when OK is pressed in the picker Optional<S32> label_width; Optional<LLUIColor> border_color; diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index da68af1597..a08e77e3d8 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -661,341 +661,352 @@ static bool needs_tooltip(LLSelectNode* nodep) return false; } -BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask) -{ - if (!LLUI::sSettingGroups["config"]->getBOOL("ShowHoverTips")) return TRUE; - if (!mHoverPick.isValid()) return TRUE; - - LLViewerObject* hover_object = mHoverPick.getObject(); - - // update hover object and hover parcel - LLSelectMgr::getInstance()->setHoverObject(hover_object, mHoverPick.mObjectFace); - if (mHoverPick.mPickType == LLPickInfo::PICK_LAND) +BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg) +{ + LLViewerParcelMgr::getInstance()->setHoverParcel( mHoverPick.mPosGlobal ); + // + // Do not show hover for land unless prefs are set to allow it. + // + + if (!gSavedSettings.getBOOL("ShowLandHoverTip")) return TRUE; + + // Didn't hit an object, but since we have a land point we + // must be hovering over land. + + LLParcel* hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel(); + LLUUID owner; + S32 width = 0; + S32 height = 0; + + if ( hover_parcel ) { - LLViewerParcelMgr::getInstance()->setHoverParcel( mHoverPick.mPosGlobal ); + owner = hover_parcel->getOwnerID(); + width = S32(LLViewerParcelMgr::getInstance()->getHoverParcelWidth()); + height = S32(LLViewerParcelMgr::getInstance()->getHoverParcelHeight()); } - - std::string tooltip_msg; - std::string line; - - if ( hover_object ) + + // Line: "Land" + line.clear(); + line.append(LLTrans::getString("TooltipLand")); + if (hover_parcel) + { + line.append(hover_parcel->getName()); + } + tooltip_msg.append(line); + tooltip_msg.push_back('\n'); + + // Line: "Owner: James Linden" + line.clear(); + line.append(LLTrans::getString("TooltipOwner") + " "); + + if ( hover_parcel ) { - if ( hover_object->isHUDAttachment() ) + std::string name; + if (LLUUID::null == owner) { - // no hover tips for HUD elements, since they can obscure - // what the HUD is displaying - return TRUE; + line.append(LLTrans::getString("TooltipPublic")); } - - if ( hover_object->isAttachment() ) + else if (hover_parcel->getIsGroupOwned()) { - // get root of attachment then parent, which is avatar - LLViewerObject* root_edit = hover_object->getRootEdit(); - if (!root_edit) + if (gCacheName->getGroupName(owner, name)) { - // Strange parenting issue, don't show any text - return TRUE; + line.append(name); + line.append(LLTrans::getString("TooltipIsGroup")); } - hover_object = (LLViewerObject*)root_edit->getParent(); - if (!hover_object) + else { - // another strange parenting issue, bail out - return TRUE; + line.append(LLTrans::getString("RetrievingData")); } } - - line.clear(); - if (hover_object->isAvatar()) + else if(gCacheName->getFullName(owner, name)) { - // only show tooltip if same inspector not already open - LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_avatar"); - if (!existing_inspector - || !existing_inspector->getVisible() - || existing_inspector->getKey()["avatar_id"].asUUID() != hover_object->getID()) - { - std::string avatar_name; - LLNameValue* firstname = hover_object->getNVPair("FirstName"); - LLNameValue* lastname = hover_object->getNVPair("LastName"); - if (firstname && lastname) - { - avatar_name = llformat("%s %s", firstname->getString(), lastname->getString()); - } - else - { - avatar_name = LLTrans::getString("TooltipPerson"); - } - - // *HACK: We may select this object, so pretend it was clicked - mPick = mHoverPick; - LLInspector::Params p; - p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>()); - p.message(avatar_name); - p.image.name("Inspector_I"); - p.click_callback(boost::bind(showAvatarInspector, hover_object->getID())); - p.visible_time_near(6.f); - p.visible_time_far(3.f); - p.delay_time(0.35f); - p.wrap(false); - - LLToolTipMgr::instance().show(p); - } + line.append(name); } else { - // - // We have hit a regular object (not an avatar or attachment) - // - - // - // Default prefs will suppress display unless the object is interactive - // - bool show_all_object_tips = - (bool)gSavedSettings.getBOOL("ShowAllObjectHoverTip"); - LLSelectNode *nodep = LLSelectMgr::getInstance()->getHoverNode(); - - // only show tooltip if same inspector not already open - LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_object"); - if (nodep && - (!existing_inspector - || !existing_inspector->getVisible() - || existing_inspector->getKey()["object_id"].asUUID() != hover_object->getID())) - { - if (nodep->mName.empty()) - { - tooltip_msg.append(LLTrans::getString("TooltipNoName")); - } - else - { - tooltip_msg.append( nodep->mName ); - } - - bool is_time_based_media = false; - bool is_web_based_media = false; - bool is_media_playing = false; - - // Does this face have media? - const LLTextureEntry* tep = hover_object->getTE(mHoverPick.mObjectFace); - - if(tep) - { - const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL; - if (mep) - { - viewer_media_t media_impl = mep ? LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()) : NULL; - LLPluginClassMedia* media_plugin = NULL; - - if (media_impl.notNull() && (media_impl->hasMedia())) - { - LLStringUtil::format_map_t args; - - media_plugin = media_impl->getMediaPlugin(); - if(media_plugin) - { if(media_plugin->pluginSupportsMediaTime()) - { - is_time_based_media = true; - is_web_based_media = false; - //args["[CurrentURL]"] = media_impl->getMediaURL(); - is_media_playing = media_impl->isMediaPlaying(); - } - else - { - is_time_based_media = false; - is_web_based_media = true; - //args["[CurrentURL]"] = media_plugin->getLocation(); - } - //tooltip_msg.append(LLTrans::getString("CurrentURL", args)); - } - } - } - } - - // also check the primary node since sometimes it can have an action even though - // the root node doesn't - bool needs_tip = needs_tooltip(nodep) || - needs_tooltip(LLSelectMgr::getInstance()->getPrimaryHoverNode()); - - if (show_all_object_tips || needs_tip) - { - // We may select this object, so pretend it was clicked - mPick = mHoverPick; - LLInspector::Params p; - p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>()); - p.message(tooltip_msg); - p.image.name("Inspector_I"); - p.click_callback(boost::bind(showObjectInspector, hover_object->getID(), mHoverPick.mObjectFace)); - p.time_based_media(is_time_based_media); - p.web_based_media(is_web_based_media); - p.media_playing(is_media_playing); - p.click_playmedia_callback(boost::bind(playCurrentMedia, mHoverPick)); - p.click_homepage_callback(boost::bind(VisitHomePage, mHoverPick)); - p.visible_time_near(6.f); - p.visible_time_far(3.f); - p.delay_time(0.35f); - p.wrap(false); - - LLToolTipMgr::instance().show(p); - } - } + line.append(LLTrans::getString("RetrievingData")); } } - else if ( mHoverPick.mPickType == LLPickInfo::PICK_LAND ) + else { - // - // Do not show hover for land unless prefs are set to allow it. - // + line.append(LLTrans::getString("RetrievingData")); + } + tooltip_msg.append(line); + tooltip_msg.push_back('\n'); + + // Line: "no fly, not safe, no build" + + // Don't display properties for your land. This is just + // confusing, because you can do anything on your own land. + if ( hover_parcel && owner != gAgent.getID() ) + { + S32 words = 0; - if (!gSavedSettings.getBOOL("ShowLandHoverTip")) return TRUE; - - // Didn't hit an object, but since we have a land point we - // must be hovering over land. - - LLParcel* hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel(); - LLUUID owner; - S32 width = 0; - S32 height = 0; - - if ( hover_parcel ) - { - owner = hover_parcel->getOwnerID(); - width = S32(LLViewerParcelMgr::getInstance()->getHoverParcelWidth()); - height = S32(LLViewerParcelMgr::getInstance()->getHoverParcelHeight()); - } - - // Line: "Land" - line.clear(); - line.append(LLTrans::getString("TooltipLand")); - if (hover_parcel) - { - line.append(hover_parcel->getName()); - } - tooltip_msg.append(line); - tooltip_msg.push_back('\n'); - - // Line: "Owner: James Linden" line.clear(); - line.append(LLTrans::getString("TooltipOwner") + " "); - - if ( hover_parcel ) + // JC - Keep this in the same order as the checkboxes + // on the land info panel + if ( !hover_parcel->getAllowModify() ) { - std::string name; - if (LLUUID::null == owner) + if ( hover_parcel->getAllowGroupModify() ) { - line.append(LLTrans::getString("TooltipPublic")); + line.append(LLTrans::getString("TooltipFlagGroupBuild")); } - else if (hover_parcel->getIsGroupOwned()) + else { - if (gCacheName->getGroupName(owner, name)) - { - line.append(name); - line.append(LLTrans::getString("TooltipIsGroup")); - } - else - { - line.append(LLTrans::getString("RetrievingData")); - } + line.append(LLTrans::getString("TooltipFlagNoBuild")); } - else if(gCacheName->getFullName(owner, name)) + words++; + } + + if ( !hover_parcel->getAllowTerraform() ) + { + if (words) line.append(", "); + line.append(LLTrans::getString("TooltipFlagNoEdit")); + words++; + } + + if ( hover_parcel->getAllowDamage() ) + { + if (words) line.append(", "); + line.append(LLTrans::getString("TooltipFlagNotSafe")); + words++; + } + + // Maybe we should reflect the estate's block fly bit here as well? DK 12/1/04 + if ( !hover_parcel->getAllowFly() ) + { + if (words) line.append(", "); + line.append(LLTrans::getString("TooltipFlagNoFly")); + words++; + } + + if ( !hover_parcel->getAllowOtherScripts() ) + { + if (words) line.append(", "); + if ( hover_parcel->getAllowGroupScripts() ) { - line.append(name); + line.append(LLTrans::getString("TooltipFlagGroupScripts")); } else { - line.append(LLTrans::getString("RetrievingData")); + line.append(LLTrans::getString("TooltipFlagNoScripts")); } + + words++; } - else + + if (words) { - line.append(LLTrans::getString("RetrievingData")); + tooltip_msg.append(line); + tooltip_msg.push_back('\n'); } + } + + if (hover_parcel && hover_parcel->getParcelFlag(PF_FOR_SALE)) + { + LLStringUtil::format_map_t args; + args["[AMOUNT]"] = llformat("%d", hover_parcel->getSalePrice()); + line = LLTrans::getString("TooltipForSaleL$", args); tooltip_msg.append(line); tooltip_msg.push_back('\n'); + } + + // trim last newlines + if (!tooltip_msg.empty()) + { + tooltip_msg.erase(tooltip_msg.size() - 1); + LLToolTipMgr::instance().show(tooltip_msg); + } + + return TRUE; +} - // Line: "no fly, not safe, no build" - - // Don't display properties for your land. This is just - // confusing, because you can do anything on your own land. - if ( hover_parcel && owner != gAgent.getID() ) +BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string line, std::string tooltip_msg) +{ + if ( hover_object->isHUDAttachment() ) + { + // no hover tips for HUD elements, since they can obscure + // what the HUD is displaying + return TRUE; + } + + if ( hover_object->isAttachment() ) + { + // get root of attachment then parent, which is avatar + LLViewerObject* root_edit = hover_object->getRootEdit(); + if (!root_edit) { - S32 words = 0; - - line.clear(); - // JC - Keep this in the same order as the checkboxes - // on the land info panel - if ( !hover_parcel->getAllowModify() ) + // Strange parenting issue, don't show any text + return TRUE; + } + hover_object = (LLViewerObject*)root_edit->getParent(); + if (!hover_object) + { + // another strange parenting issue, bail out + return TRUE; + } + } + + line.clear(); + if (hover_object->isAvatar()) + { + // only show tooltip if same inspector not already open + LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_avatar"); + if (!existing_inspector + || !existing_inspector->getVisible() + || existing_inspector->getKey()["avatar_id"].asUUID() != hover_object->getID()) + { + std::string avatar_name; + LLNameValue* firstname = hover_object->getNVPair("FirstName"); + LLNameValue* lastname = hover_object->getNVPair("LastName"); + if (firstname && lastname) { - if ( hover_parcel->getAllowGroupModify() ) - { - line.append(LLTrans::getString("TooltipFlagGroupBuild")); - } - else - { - line.append(LLTrans::getString("TooltipFlagNoBuild")); - } - words++; + avatar_name = llformat("%s %s", firstname->getString(), lastname->getString()); } - - if ( !hover_parcel->getAllowTerraform() ) + else { - if (words) line.append(", "); - line.append(LLTrans::getString("TooltipFlagNoEdit")); - words++; + avatar_name = LLTrans::getString("TooltipPerson"); } - - if ( hover_parcel->getAllowDamage() ) + + // *HACK: We may select this object, so pretend it was clicked + mPick = mHoverPick; + LLInspector::Params p; + p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>()); + p.message(avatar_name); + p.image.name("Inspector_I"); + p.click_callback(boost::bind(showAvatarInspector, hover_object->getID())); + p.visible_time_near(6.f); + p.visible_time_far(3.f); + p.delay_time(0.35f); + p.wrap(false); + + LLToolTipMgr::instance().show(p); + } + } + else + { + // + // We have hit a regular object (not an avatar or attachment) + // + + // + // Default prefs will suppress display unless the object is interactive + // + bool show_all_object_tips = + (bool)gSavedSettings.getBOOL("ShowAllObjectHoverTip"); + LLSelectNode *nodep = LLSelectMgr::getInstance()->getHoverNode(); + + // only show tooltip if same inspector not already open + LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_object"); + if (nodep && + (!existing_inspector + || !existing_inspector->getVisible() + || existing_inspector->getKey()["object_id"].asUUID() != hover_object->getID())) + { + if (nodep->mName.empty()) { - if (words) line.append(", "); - line.append(LLTrans::getString("TooltipFlagNotSafe")); - words++; + tooltip_msg.append(LLTrans::getString("TooltipNoName")); } - - // Maybe we should reflect the estate's block fly bit here as well? DK 12/1/04 - if ( !hover_parcel->getAllowFly() ) + else { - if (words) line.append(", "); - line.append(LLTrans::getString("TooltipFlagNoFly")); - words++; + tooltip_msg.append( nodep->mName ); } - - if ( !hover_parcel->getAllowOtherScripts() ) + + bool is_time_based_media = false; + bool is_web_based_media = false; + bool is_media_playing = false; + + // Does this face have media? + const LLTextureEntry* tep = hover_object->getTE(mHoverPick.mObjectFace); + + if(tep) { - if (words) line.append(", "); - if ( hover_parcel->getAllowGroupScripts() ) + const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL; + if (mep) { - line.append(LLTrans::getString("TooltipFlagGroupScripts")); - } - else - { - line.append(LLTrans::getString("TooltipFlagNoScripts")); + viewer_media_t media_impl = mep ? LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()) : NULL; + LLPluginClassMedia* media_plugin = NULL; + + if (media_impl.notNull() && (media_impl->hasMedia())) + { + LLStringUtil::format_map_t args; + + media_plugin = media_impl->getMediaPlugin(); + if(media_plugin) + { if(media_plugin->pluginSupportsMediaTime()) + { + is_time_based_media = true; + is_web_based_media = false; + //args["[CurrentURL]"] = media_impl->getMediaURL(); + is_media_playing = media_impl->isMediaPlaying(); + } + else + { + is_time_based_media = false; + is_web_based_media = true; + //args["[CurrentURL]"] = media_plugin->getLocation(); + } + //tooltip_msg.append(LLTrans::getString("CurrentURL", args)); + } + } } - - words++; } - - if (words) + + // also check the primary node since sometimes it can have an action even though + // the root node doesn't + bool needs_tip = needs_tooltip(nodep) || + needs_tooltip(LLSelectMgr::getInstance()->getPrimaryHoverNode()); + + if (show_all_object_tips || needs_tip) { - tooltip_msg.append(line); - tooltip_msg.push_back('\n'); + // We may select this object, so pretend it was clicked + mPick = mHoverPick; + LLInspector::Params p; + p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>()); + p.message(tooltip_msg); + p.image.name("Inspector_I"); + p.click_callback(boost::bind(showObjectInspector, hover_object->getID(), mHoverPick.mObjectFace)); + p.time_based_media(is_time_based_media); + p.web_based_media(is_web_based_media); + p.media_playing(is_media_playing); + p.click_playmedia_callback(boost::bind(playCurrentMedia, mHoverPick)); + p.click_homepage_callback(boost::bind(VisitHomePage, mHoverPick)); + p.visible_time_near(6.f); + p.visible_time_far(3.f); + p.delay_time(0.35f); + p.wrap(false); + + LLToolTipMgr::instance().show(p); } } + } + + return TRUE; +} - if (hover_parcel && hover_parcel->getParcelFlag(PF_FOR_SALE)) - { - LLStringUtil::format_map_t args; - args["[AMOUNT]"] = llformat("%d", hover_parcel->getSalePrice()); - line = LLTrans::getString("TooltipForSaleL$", args); - tooltip_msg.append(line); - tooltip_msg.push_back('\n'); - } +BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask) +{ + if (!LLUI::sSettingGroups["config"]->getBOOL("ShowHoverTips")) return TRUE; + if (!mHoverPick.isValid()) return TRUE; - // trim last newlines - if (!tooltip_msg.empty()) - { - tooltip_msg.erase(tooltip_msg.size() - 1); - LLToolTipMgr::instance().show(tooltip_msg); - } - } + LLViewerObject* hover_object = mHoverPick.getObject(); + + // update hover object and hover parcel + LLSelectMgr::getInstance()->setHoverObject(hover_object, mHoverPick.mObjectFace); + + + std::string tooltip_msg; + std::string line; + if ( hover_object ) + { + handleTooltipObject(hover_object, line, tooltip_msg ); + } + else if (mHoverPick.mPickType == LLPickInfo::PICK_LAND) + { + handleTooltipLand(line, tooltip_msg); + } return TRUE; } diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h index 5f0e28fa95..8a4c949aef 100644 --- a/indra/newview/lltoolpie.h +++ b/indra/newview/lltoolpie.h @@ -89,7 +89,9 @@ private: bool handleMediaClick(const LLPickInfo& info); bool handleMediaHover(const LLPickInfo& info); - bool handleMediaMouseUp(); + bool handleMediaMouseUp(); + BOOL handleTooltipLand(std::string line, std::string tooltip_msg); + BOOL handleTooltipObject( LLViewerObject* hover_object, std::string line, std::string tooltip_msg); private: BOOL mGrabMouseButtonDown; diff --git a/indra/newview/lltransientdockablefloater.cpp b/indra/newview/lltransientdockablefloater.cpp index 7e4d4988d1..c9bfe178ce 100644 --- a/indra/newview/lltransientdockablefloater.cpp +++ b/indra/newview/lltransientdockablefloater.cpp @@ -42,6 +42,7 @@ LLTransientDockableFloater::LLTransientDockableFloater(LLDockControl* dockContro LLDockableFloater(dockControl, uniqueDocking, key, params) { LLTransientFloaterMgr::getInstance()->registerTransientFloater(this); + LLTransientFloater::init(this); } LLTransientDockableFloater::~LLTransientDockableFloater() diff --git a/indra/newview/lltransientdockablefloater.h b/indra/newview/lltransientdockablefloater.h index 6e8a3afd22..e0541d6597 100644 --- a/indra/newview/lltransientdockablefloater.h +++ b/indra/newview/lltransientdockablefloater.h @@ -37,12 +37,13 @@ #include "llfloater.h" #include "lldockcontrol.h" #include "lldockablefloater.h" +#include "lltransientfloatermgr.h" /** * Represents floater that can dock and managed by transient floater manager. * Transient floaters should be hidden if user click anywhere except defined view list. */ -class LLTransientDockableFloater : public LLDockableFloater +class LLTransientDockableFloater : public LLDockableFloater, LLTransientFloater { public: LOG_CLASS(LLTransientDockableFloater); @@ -52,6 +53,7 @@ public: /*virtual*/ void setVisible(BOOL visible); /* virtual */void setDocked(bool docked, bool pop_on_undock = true); + virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; } }; #endif /* LL_TRANSIENTDOCKABLEFLOATER_H */ diff --git a/indra/newview/lltransientfloatermgr.cpp b/indra/newview/lltransientfloatermgr.cpp index 347399f239..8f1a738453 100644 --- a/indra/newview/lltransientfloatermgr.cpp +++ b/indra/newview/lltransientfloatermgr.cpp @@ -44,57 +44,68 @@ LLTransientFloaterMgr::LLTransientFloaterMgr() { gViewerWindow->getRootView()->addMouseDownCallback(boost::bind( &LLTransientFloaterMgr::leftMouseClickCallback, this, _1, _2, _3)); + + mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(GLOBAL, std::set<LLView*>())); + mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(IM, std::set<LLView*>())); } -void LLTransientFloaterMgr::registerTransientFloater(LLFloater* floater) +void LLTransientFloaterMgr::registerTransientFloater(LLTransientFloater* floater) { mTransSet.insert(floater); } -void LLTransientFloaterMgr::unregisterTransientFloater(LLFloater* floater) +void LLTransientFloaterMgr::unregisterTransientFloater(LLTransientFloater* floater) { mTransSet.erase(floater); } +void LLTransientFloaterMgr::addControlView(ETransientGroup group, LLView* view) +{ + mGroupControls.find(group)->second.insert(view); +} + +void LLTransientFloaterMgr::removeControlView(ETransientGroup group, LLView* view) +{ + mGroupControls.find(group)->second.erase(view); +} + void LLTransientFloaterMgr::addControlView(LLView* view) { - mControlsSet.insert(view); + addControlView(GLOBAL, view); } void LLTransientFloaterMgr::removeControlView(LLView* view) { // we will still get focus lost callbacks on this view, but that's ok // since we run sanity checking logic every time - mControlsSet.erase(view); + removeControlView(GLOBAL, view); } -void LLTransientFloaterMgr::hideTransientFloaters() +void LLTransientFloaterMgr::hideTransientFloaters(S32 x, S32 y) { - for (std::set<LLFloater*>::iterator it = mTransSet.begin(); it + for (std::set<LLTransientFloater*>::iterator it = mTransSet.begin(); it != mTransSet.end(); it++) { - LLFloater* floater = *it; - if (floater->isDocked()) + LLTransientFloater* floater = *it; + if (floater->isTransientDocked()) { - floater->setVisible(FALSE); + ETransientGroup group = floater->getGroup(); + + bool hide = isControlClicked(mGroupControls.find(group)->second, x, y); + if (hide) + { + floater->setTransientVisible(FALSE); + } } } } -void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y, - MASK mask) +bool LLTransientFloaterMgr::isControlClicked(std::set<LLView*>& set, S32 x, S32 y) { - bool hide = true; - for (controls_set_t::iterator it = mControlsSet.begin(); it - != mControlsSet.end(); it++) + bool res = true; + for (controls_set_t::iterator it = set.begin(); it + != set.end(); it++) { - // don't hide transient floater if any context menu opened - if (LLMenuGL::sMenuContainer->getVisibleMenu() != NULL) - { - hide = false; - break; - } - LLView* control_view = *it; if (!control_view->getVisible()) { @@ -105,14 +116,32 @@ void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y, // if click inside view rect if (rect.pointInRect(x, y)) { - hide = false; + res = false; break; } } + return res; +} + +void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y, + MASK mask) +{ + // don't hide transient floater if any context menu opened + if (LLMenuGL::sMenuContainer->getVisibleMenu() != NULL) + { + return; + } + bool hide = isControlClicked(mGroupControls.find(GLOBAL)->second, x, y); if (hide) { - hideTransientFloaters(); + hideTransientFloaters(x, y); } } +void LLTransientFloater::init(LLFloater* thiz) +{ + // used since LLTransientFloater(this) can't be used in descendant constructor parameter initialization. + mFloater = thiz; +} + diff --git a/indra/newview/lltransientfloatermgr.h b/indra/newview/lltransientfloatermgr.h index cef6e1fe45..1f99325a7f 100644 --- a/indra/newview/lltransientfloatermgr.h +++ b/indra/newview/lltransientfloatermgr.h @@ -37,27 +37,60 @@ #include "llsingleton.h" #include "llfloater.h" +class LLTransientFloater; /** * Provides functionality to hide transient floaters. */ class LLTransientFloaterMgr: public LLSingleton<LLTransientFloaterMgr> { -public: +protected: LLTransientFloaterMgr(); - void registerTransientFloater(LLFloater* floater); - void unregisterTransientFloater(LLFloater* floater); + friend class LLSingleton<LLTransientFloaterMgr>; + +public: + enum ETransientGroup + { + GLOBAL, IM + }; + + void registerTransientFloater(LLTransientFloater* floater); + void unregisterTransientFloater(LLTransientFloater* floater); + void addControlView(ETransientGroup group, LLView* view); + void removeControlView(ETransientGroup group, LLView* view); void addControlView(LLView* view); void removeControlView(LLView* view); private: - void hideTransientFloaters(); + void hideTransientFloaters(S32 x, S32 y); void leftMouseClickCallback(S32 x, S32 y, MASK mask); - + bool isControlClicked(std::set<LLView*>& set, S32 x, S32 y); private: - std::set<LLFloater*> mTransSet; + std::set<LLTransientFloater*> mTransSet; + typedef std::set<LLView*> controls_set_t; - controls_set_t mControlsSet; + typedef std::map<ETransientGroup, std::set<LLView*> > group_controls_t; + group_controls_t mGroupControls; +}; + +/** + * An abstract class declares transient floater interfaces. + */ +class LLTransientFloater +{ +protected: + /** + * Class initialization method. + * Should be called from descendant constructor. + */ + void init(LLFloater* thiz); +public: + virtual LLTransientFloaterMgr::ETransientGroup getGroup() = 0; + bool isTransientDocked() { return mFloater->isDocked(); }; + void setTransientVisible(BOOL visible) {mFloater->setVisible(visible); } + +private: + LLFloater* mFloater; }; #endif // LL_LLTRANSIENTFLOATERMGR_H diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 2477eca16d..f0f1c0cfab 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -483,7 +483,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected"); render_ui(); - render_disconnected_background(); } ////////////////////////// @@ -1135,6 +1134,10 @@ void render_ui(F32 zoom_factor, int subfield) render_ui_3d(); LLGLState::checkStates(); } + else + { + render_disconnected_background(); + } render_ui_2d(); LLGLState::checkStates(); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 04d67fe750..d712446d83 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -752,6 +752,11 @@ void LLViewerMedia::updateMedia(void *dummy_arg) new_priority = LLPluginClassMedia::PRIORITY_NORMAL; impl_count_interest_normal++; } + else if(pimpl->isParcelMedia()) + { + new_priority = LLPluginClassMedia::PRIORITY_NORMAL; + impl_count_interest_normal++; + } else { // Look at interest and CPU usage for instances that aren't in any of the above states. diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 692474cb2d..79aae9463b 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -6099,7 +6099,8 @@ class LLAttachmentEnableDrop : public view_listener_t LLViewerJointAttachment* attachment = NULL; LLInventoryItem* item = NULL; - if (object) + // Do not enable drop if all faces of object are not enabled + if (object && LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES )) { S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getState()); attachment = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL); @@ -6141,8 +6142,14 @@ class LLAttachmentEnableDrop : public view_listener_t BOOL enable_detach(const LLSD&) { LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (!object) return FALSE; - if (!object->isAttachment()) return FALSE; + + // Only enable detach if all faces of object are selected + if (!object || + !object->isAttachment() || + !LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES )) + { + return FALSE; + } // Find the avatar who owns this attachment LLViewerObject* avatar = object; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index d6f0afff88..c463beb375 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -78,6 +78,7 @@ #include "llstatenums.h" #include "llstatusbar.h" #include "llimview.h" +#include "llspeakers.h" #include "lltrans.h" #include "llviewerfoldertype.h" #include "lluri.h" @@ -1471,7 +1472,12 @@ void inventory_offer_handler(LLOfferInfo* info) { LLStringUtil::truncate(msg, indx); } - + + if(LLAssetType::AT_LANDMARK == info->mType) + { + msg = LLViewerInventoryItem::getDisplayName(msg); + } + LLSD args; args["[OBJECTNAME]"] = msg; @@ -2008,7 +2014,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // Someone has offered us some inventory. { LLOfferInfo* info = new LLOfferInfo; - bool mute_im = false; if (IM_INVENTORY_OFFERED == dialog) { struct offer_agent_bucket_t @@ -2025,11 +2030,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0]; info->mType = (LLAssetType::EType) bucketp->asset_type; info->mObjectID = bucketp->object_id; - - if(accept_im_from_only_friend&&!is_friend) - { - mute_im = true; - } } else { @@ -2060,7 +2060,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) info->mDesc = message; info->mHost = msg->getSender(); //if (((is_busy && !is_owned_by_me) || is_muted)) - if ( is_muted || mute_im) + if (is_muted) { // Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331) LLInventoryFetchObserver::item_ref_t items; diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index e8b435fc8f..e87dbe5c07 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -212,22 +212,15 @@ void LLViewerParcelMedia::play(LLParcel* parcel) else { // Since the texture id is different, we need to generate a new impl - LL_DEBUGS("Media") << "new media impl with mime type " << mime_type << ", url " << media_url << LL_ENDL; // Delete the old one first so they don't fight over the texture. sMediaImpl = NULL; - - sMediaImpl = LLViewerMedia::newMediaImpl( - placeholder_texture_id, - media_width, - media_height, - media_auto_scale, - media_loop); - sMediaImpl->setIsParcelMedia(true); - sMediaImpl->navigateTo(media_url, mime_type, true); + + // A new impl will be created below. } } - else + + if(!sMediaImpl) { LL_DEBUGS("Media") << "new media impl with mime type " << mime_type << ", url " << media_url << LL_ENDL; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index ee89a000ab..73dc9745cb 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1560,7 +1560,11 @@ F32 LLViewerFetchedTexture::calcDecodePriority() void LLViewerFetchedTexture::setDecodePriority(F32 priority) { - llassert(!mInImageList); + //llassert(!mInImageList); // firing a lot, figure out why + if (mInImageList) // above llassert() softened to a warning + { + llwarns << "BAD STUFF! mInImageList" << llendl; + } mDecodePriority = priority; } diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 6bb547373c..ee934ab9c5 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -502,7 +502,10 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image) { llerrs << "LLViewerTextureList::addImageToList - Image already in list" << llendl; } - llverify((mImageList.insert(image)).second == true); + if ((mImageList.insert(image)).second != true) + { + llwarns << "BAD STUFF! (mImageList.insert(image)).second != true" << llendl; + } image->setInImageList(TRUE) ; } @@ -519,7 +522,10 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) } llerrs << "LLViewerTextureList::removeImageFromList - Image not in list" << llendl; } - llverify(mImageList.erase(image) == 1); + if (mImageList.erase(image) != 1) + { + llwarns << "BAD STUFF! mImageList.erase(image) != 1" << llendl; + } image->setInImageList(FALSE) ; } diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 51a75b5825..c84afa5af1 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -63,6 +63,7 @@ #include "llparcel.h" #include "llviewerparcelmgr.h" //#include "llfirstuse.h" +#include "llspeakers.h" #include "lltrans.h" #include "llviewerwindow.h" #include "llviewercamera.h" diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 70859e8ea5..c19be37e75 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -252,9 +252,8 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip) // mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // usefull for debugging mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1); mCurlRequest->setWriteCallback(&curlDownloadCallback, (void*)this); - BOOL vefifySSLCert = !gSavedSettings.getBOOL("NoVerifySSLCert"); - mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, vefifySSLCert); - mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, vefifySSLCert ? 2 : 0); + mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, LLCurl::getSSLVerify()); + mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, LLCurl::getSSLVerify() ? 2 : 0); // Be a little impatient about establishing connections. mCurlRequest->setopt(CURLOPT_CONNECTTIMEOUT, 40L); diff --git a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png Binary files differindex 661d1c5611..6cb33efb93 100644 --- a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png +++ b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png diff --git a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png Binary files differindex f927fd3989..6cb33efb93 100644 --- a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png +++ b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml index faa24b5877..eb63b5c975 100644 --- a/indra/newview/skins/default/xui/da/floater_about.xml +++ b/indra/newview/skins/default/xui/da/floater_about.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_about" title="OM [APP_NAME]"> +<floater name="floater_about" title="OM [CAPITALIZED_APP_NAME]"> <floater.string name="AboutHeader"> [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2] ([VIEWER_VERSION_3]) [BUILD_DATE] [BUILD_TIME] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml index 664c6e3072..0beb54032f 100644 --- a/indra/newview/skins/default/xui/de/floater_about.xml +++ b/indra/newview/skins/default/xui/de/floater_about.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_about" title="INFO ÜBER [APP_NAME]"> +<floater name="floater_about" title="INFO ÜBER [CAPITALIZED_APP_NAME]"> <floater.string name="AboutHeader"> [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2] ([VIEWER_VERSION_3]) [BUILD_DATE] [BUILD_TIME] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] diff --git a/indra/newview/skins/default/xui/de/panel_edit_profile.xml b/indra/newview/skins/default/xui/de/panel_edit_profile.xml index 1c53ca64dd..811ca118d6 100644 --- a/indra/newview/skins/default/xui/de/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/de/panel_edit_profile.xml @@ -39,7 +39,7 @@ <line_editor name="homepage_edit" value="http://"/> <check_box label="In Suchergebnissen anzeigen" name="show_in_search_checkbox"/> <text name="title_acc_status_text" value="Mein Konto:"/> - <text name="my_account_link" value="Meine Startseite aufrufen"/> + <text name="my_account_link" value="[[URL] Meine Startseite aufrufen]"/> <text name="acc_status_text" value="Einwohner. Keine Zahlungsinfo archiviert."/> <text name="title_partner_text" value="Mein Partner:"/> <text name="partner_edit_link" value="[[URL] bearbeiten]"/> diff --git a/indra/newview/skins/default/xui/en/favorites_bar_button.xml b/indra/newview/skins/default/xui/en/favorites_bar_button.xml index dfb0695ec3..b365040c20 100644 --- a/indra/newview/skins/default/xui/en/favorites_bar_button.xml +++ b/indra/newview/skins/default/xui/en/favorites_bar_button.xml @@ -3,7 +3,6 @@ <!-- All buttons in the Favorites bar will be created from this one --> <button follows="left|bottom" - font_halign="center" halign="center" height="15" image_disabled="transparent.j2c" @@ -11,6 +10,8 @@ image_selected="transparent.j2c" image_unselected="transparent.j2c" image_pressed="Favorite_Link_Over" + image_hover_selected="Favorite_Link_Over" + image_hover_unselected="Favorite_Link_Over" hover_glow_amount="0.15" label_shadow="false" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index c58c1f00b9..61ca783d14 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1871,13 +1871,14 @@ Only large parcels can be listed in search. layout="topleft" left="110" name="parcel_enable_voice_channel_is_estate_disabled" + top_delta="0" width="300" /> <check_box height="16" label="Restrict Voice to this parcel" layout="topleft" left="110" - name="parcel_enable_voice_channel_parcel" + name="parcel_enable_voice_channel_local" width="300" /> </panel> <panel diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml index d202bf1b9f..8f67f564a2 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml @@ -304,7 +304,7 @@ Re-enter amount to see the latest exchange rate. </text> <text type="string" - width="175" + width="176" height="125" top="60" left="165" diff --git a/indra/newview/skins/default/xui/en/floater_customize.xml b/indra/newview/skins/default/xui/en/floater_customize.xml index ddc0d9af72..b048eeceb6 100644 --- a/indra/newview/skins/default/xui/en/floater_customize.xml +++ b/indra/newview/skins/default/xui/en/floater_customize.xml @@ -3,7 +3,7 @@ legacy_header_height="18" can_minimize="false" follows="left|top" - height="607" + height="583" layout="topleft" left_delta="-3" name="floater customize" @@ -20,7 +20,7 @@ tab_min_width="96" tab_position="left" tab_height="50" - top="50" + top="26" width="506"> <text type="string" @@ -184,7 +184,6 @@ layout="topleft" name="radio2" value="1" - top="32" width="82" /> </radio_group> <text @@ -270,9 +269,9 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="no modify instructions" - top_delta="0" + top="31" word_wrap="true" width="373"> You do not have permission to modify this wearable. @@ -473,9 +472,9 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="no modify instructions" - top_delta="0" + top="31" word_wrap="true" width="373"> You do not have permission to modify this wearable. @@ -723,9 +722,9 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="no modify instructions" - top_delta="0" + top="31" word_wrap="true" width="373"> You do not have permission to modify this wearable. @@ -798,16 +797,16 @@ width="82" /> </panel> <panel - border="true" + border="false" + background_visible="true" + bg_alpha_color="DkGray2" follows="left|top|right|bottom" - height="481" + height="508" label="Eyes" layout="topleft" - left_delta="0" name="Eyes" help_topic="customize_eyes_tab" - top_delta="0" - width="389"> + width="400"> <icon follows="top|right" height="18" @@ -820,10 +819,10 @@ width="18" /> <icon height="16" + top="10" + left="10" layout="topleft" - left_delta="-325" mouse_opaque="true" - top_delta="3" width="16" /> <text type="string" @@ -832,9 +831,9 @@ font="SansSerif" height="16" layout="topleft" - left_pad="2" + left="31" name="title" - top_delta="0" + top="10" width="355"> [DESC] </text> @@ -845,9 +844,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_no_modify" - top_delta="0" + top="10" width="355"> [DESC]: cannot modify </text> @@ -858,9 +857,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_loading" - top_delta="0" + top="10" width="355"> [DESC]: loading... </text> @@ -871,21 +870,21 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_not_worn" - top_delta="0" + top="10" width="355"> [DESC]: not worn </text> <text type="string" length="1" - follows="left|top|right" - height="14" + follows="left|top" + height="16" layout="topleft" - left="8" + left="10" name="path" - top="24" + top="36" width="373"> Located in [PATH] </text> @@ -895,9 +894,9 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="not worn instructions" - top_pad="8" + top="31" word_wrap="true" width="373"> Put on a new set of eyes by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. @@ -908,9 +907,9 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="no modify instructions" - top_delta="0" + top="31" word_wrap="true" width="373"> You do not have permission to modify this wearable. @@ -918,14 +917,14 @@ <text type="string" length="1" - bottom="486" - follows="left|top|right" + bottom="4" + follows="left|bottom|right" font="SansSerif" halign="right" - height="28" - layout="topleft" + height="23" + layout="bottomleft" name="Item Action Label" - right="117" + right="132" width="100"> Eyes: </text> @@ -933,23 +932,22 @@ can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" + height="108" label="Iris" layout="topleft" - left="8" + left="10" name="Iris" tool_tip="Click to choose a picture" - top="65" - width="64" /> + top="66" + width="82" /> <button follows="left|top" height="23" label="Create New Eyes" label_selected="Create New Eyes" layout="topleft" - left_delta="0" name="Create New" - top_delta="39" + top="66" width="160" /> <button follows="right|bottom" @@ -957,9 +955,9 @@ label="Save" label_selected="Save" layout="topleft" - left="123" + right="218" name="Save" - top="458" + top="477" width="82" /> <button follows="right|bottom" @@ -967,9 +965,9 @@ label="Save As..." label_selected="Save As..." layout="topleft" - left_pad="6" + right="304" name="Save As" - top_delta="0" + top="477" width="82" /> <button follows="right|bottom" @@ -977,9 +975,9 @@ label="Revert" label_selected="Revert" layout="topleft" - left_pad="6" + right="390" name="Revert" - top_delta="0" + top="477" width="82" /> </panel> <text @@ -997,85 +995,83 @@ </text> <placeholder /> <panel - border="true" + border="false" + background_visible="true" + bg_alpha_color="DkGray2" follows="left|top|right|bottom" - height="481" + height="508" label="Shirt" layout="topleft" - left_delta="0" name="Shirt" help_topic="customize_shirt_tab" top_delta="0" - width="389"> + width="400"> <icon - follows="top|right" + follows="top|left" height="18" image_name="Lock" layout="topleft" - left="315" + left="10" mouse_opaque="true" name="square" - top="4" + top="10" width="18" /> <icon height="16" + top="10" + left="10" layout="topleft" - left="8" mouse_opaque="true" - top_delta="3" width="16" /> <texture_picker can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" + height="108" label="Fabric" layout="topleft" - left_delta="0" + left="10" name="Fabric" tool_tip="Click to choose a picture" - top_pad="41" - width="64" /> + top="66" + width="82" /> <color_swatch can_apply_immediately="true" follows="left|top" - height="80" + height="108" label="Color/Tint" layout="topleft" - left_delta="0" name="Color/Tint" tool_tip="Click to open color picker" - top_delta="80" - width="64" /> - <button - follows="left|top" - height="23" - label="Create New Shirt" - label_selected="Create New Shirt" - layout="topleft" - left_delta="0" - name="Create New" - top_delta="-41" - width="160" /> + top_delta="102" + width="82" /> <button follows="left|top" height="23" label="Take Off" label_selected="Take Off" layout="topleft" - left_delta="0" name="Take Off" - top_pad="102" + top_pad="4" width="82" /> <button + follows="left|top" + height="23" + label="Create New Shirt" + label_selected="Create New Shirt" + layout="topleft" + name="Create New" + top="66" + width="160" /> + <button follows="right|bottom" height="23" label="Save" label_selected="Save" layout="topleft" - left="123" + right="218" name="Save" - top="458" + top="477" width="82" /> <button follows="right|bottom" @@ -1083,9 +1079,9 @@ label="Save As..." label_selected="Save As..." layout="topleft" - left_pad="6" + right="304" name="Save As" - top_delta="0" + top="477" width="82" /> <button follows="right|bottom" @@ -1093,9 +1089,9 @@ label="Revert" label_selected="Revert" layout="topleft" - left_pad="6" + right="390" name="Revert" - top_delta="0" + top="477" width="82" /> <text type="string" @@ -1104,9 +1100,9 @@ font="SansSerif" height="16" layout="topleft" - left="8" + left="31" name="title" - top="8" + top="10" width="355"> [DESC] </text> @@ -1117,9 +1113,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_no_modify" - top_delta="0" + top="10" width="355"> [DESC]: cannot modify </text> @@ -1130,9 +1126,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_loading" - top_delta="0" + top="10" width="355"> [DESC]: loading... </text> @@ -1143,21 +1139,21 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_not_worn" - top_delta="0" + top="10" width="355"> [DESC]: not worn </text> <text type="string" length="1" - follows="left|top|right" - height="14" + follows="left|top" + height="16" layout="topleft" - left="8" + left="10" name="path" - top="24" + top="36" width="373"> Located in [PATH] </text> @@ -1167,9 +1163,9 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="not worn instructions" - top_pad="8" + top="31" word_wrap="true" width="373"> Put on a new shirt by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. @@ -1180,9 +1176,9 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="no modify instructions" - top_delta="0" + top="31" word_wrap="true" width="373"> You do not have permission to modify this wearable. @@ -1190,98 +1186,95 @@ <text type="string" length="1" - bottom="486" - follows="left|top|right" + bottom="4" + follows="left|bottom|right" font="SansSerif" halign="right" - height="28" - layout="topleft" + height="23" + layout="bottomleft" name="Item Action Label" - right="117" + right="132" width="100"> Shirt: </text> </panel> <panel - border="true" + border="false" + background_visible="true" + bg_alpha_color="DkGray2" follows="left|top|right|bottom" - height="481" + height="508" label="Pants" layout="topleft" - left_delta="0" name="Pants" help_topic="customize_pants_tab" - top_delta="0" - width="389"> + width="400"> <icon - follows="top|right" + follows="top|left" height="18" image_name="Lock" layout="topleft" - left="315" + left="10" mouse_opaque="true" name="square" - top="4" + top="10" width="18" /> <icon height="16" layout="topleft" - left="8" + left="10" mouse_opaque="true" - top_delta="3" + top="10" width="16" /> <texture_picker can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" + height="108" label="Fabric" layout="topleft" - left_delta="0" + left="10" name="Fabric" tool_tip="Click to choose a picture" - top_pad="41" - width="64" /> + top="66" + width="82" /> <color_swatch can_apply_immediately="true" follows="left|top" - height="80" + height="108" label="Color/Tint" layout="topleft" - left_delta="0" name="Color/Tint" tool_tip="Click to open color picker" - top_delta="80" - width="64" /> - <button - follows="left|top" - height="23" - label="Create New Pants" - label_selected="Create New Pants" - layout="topleft" - left_delta="0" - name="Create New" - top_delta="-41" - width="160" /> + top_delta="102" + width="82" /> <button follows="left|top" height="23" label="Take Off" label_selected="Take Off" layout="topleft" - left_delta="0" name="Take Off" - top_pad="102" + top_pad="4" width="82" /> <button + follows="left|top" + height="23" + label="Create New Pants" + label_selected="Create New Pants" + layout="topleft" + name="Create New" + top="66" + width="160" /> + <button follows="right|bottom" height="23" label="Save" label_selected="Save" layout="topleft" - left="123" + right="218" name="Save" - top="458" + top="477" width="82" /> <button follows="right|bottom" @@ -1289,9 +1282,9 @@ label="Save As..." label_selected="Save As..." layout="topleft" - left_pad="6" + right="304" name="Save As" - top_delta="0" + top="477" width="82" /> <button follows="right|bottom" @@ -1299,9 +1292,9 @@ label="Revert" label_selected="Revert" layout="topleft" - left_pad="6" + right="390" name="Revert" - top_delta="0" + top="477" width="82" /> <text type="string" @@ -1310,9 +1303,9 @@ font="SansSerif" height="16" layout="topleft" - left="8" + left="31" name="title" - top="8" + top="10" width="355"> [DESC] </text> @@ -1323,9 +1316,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_no_modify" - top_delta="0" + top="10" width="355"> [DESC]: cannot modify </text> @@ -1336,9 +1329,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_loading" - top_delta="0" + top="10" width="355"> [DESC]: loading... </text> @@ -1349,9 +1342,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_not_worn" - top_delta="0" + top="10" width="355"> [DESC]: not worn </text> @@ -1361,9 +1354,9 @@ follows="left|top|right" height="14" layout="topleft" - left="8" + left="10" name="path" - top="24" + top="36" width="373"> Located in [PATH] </text> @@ -1373,9 +1366,9 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="not worn instructions" - top_pad="8" + top="31" word_wrap="true" width="373"> Put on new pants by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. @@ -1386,9 +1379,9 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="no modify instructions" - top_delta="0" + top="31" word_wrap="true" width="373"> You do not have permission to modify this wearable. @@ -1396,45 +1389,45 @@ <text type="string" length="1" - bottom="486" - follows="left|top|right" + bottom="4" + follows="left|bottom|right" font="SansSerif" halign="right" - height="28" - layout="topleft" + height="23" + layout="bottomleft" name="Item Action Label" - right="117" + right="132" width="100"> Pants: </text> </panel> <panel - border="true" + border="false" + background_visible="true" + bg_alpha_color="DkGray2" follows="left|top|right|bottom" - height="481" + height="508" label="Shoes" layout="topleft" - left_delta="0" name="Shoes" help_topic="customize_shoes_tab" - top_delta="0" - width="389"> + width="400"> <icon - follows="top|right" + follows="top|left" height="18" image_name="Lock" layout="topleft" - left="315" + left="10" mouse_opaque="true" name="square" - top="4" + top="10" width="18" /> <icon height="16" layout="topleft" - left_delta="-325" + left="10" mouse_opaque="true" - top_delta="3" + top="10" width="16" /> <text type="string" @@ -1443,9 +1436,9 @@ font="SansSerif" height="16" layout="topleft" - left_pad="2" + left="31" name="title" - top_delta="0" + top="10" width="355"> [DESC] </text> @@ -1456,9 +1449,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_no_modify" - top_delta="0" + top="10" width="355"> [DESC]: cannot modify </text> @@ -1469,9 +1462,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_loading" - top_delta="0" + top="10" width="355"> [DESC]: loading... </text> @@ -1482,9 +1475,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_not_worn" - top_delta="0" + top="10" width="355"> [DESC]: not worn </text> @@ -1494,9 +1487,9 @@ follows="left|top|right" height="14" layout="topleft" - left="8" + left="10" name="path" - top="24" + top="36" width="373"> Located in [PATH] </text> @@ -1506,22 +1499,31 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="not worn instructions" - top_pad="8" + top="31" word_wrap="true" width="373"> Put on a new pair of shoes by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. </text> + <button + follows="left|top" + height="23" + label="Create New Shoes" + label_selected="Create New Shoes" + layout="topleft" + name="Create New" + top_pad="18" + width="160" /> <text type="string" length="1" follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="no modify instructions" - top_delta="0" + top="31" word_wrap="true" width="373"> You do not have permission to modify this wearable. @@ -1529,14 +1531,14 @@ <text type="string" length="1" - bottom="486" - follows="left|top|right" + bottom="4" + follows="left|bottom|right" font="SansSerif" halign="right" - height="28" - layout="topleft" + height="23" + layout="bottomleft" name="Item Action Label" - right="117" + right="132" width="100"> Shoes: </text> @@ -1544,44 +1546,32 @@ can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" + height="108" label="Fabric" layout="topleft" - left="8" + left="10" name="Fabric" tool_tip="Click to choose a picture" - top="65" - width="64" /> + top="66" + width="82" /> <color_swatch can_apply_immediately="true" follows="left|top" - height="80" + height="108" label="Color/Tint" layout="topleft" - left_delta="0" name="Color/Tint" tool_tip="Click to open color picker" - top_delta="80" - width="64" /> - <button - follows="left|top" - height="23" - label="Create New Shoes" - label_selected="Create New Shoes" - layout="topleft" - left_delta="0" - name="Create New" - top_delta="-41" - width="160" /> + top_delta="102" + width="82" /> <button follows="left|top" height="23" label="Take Off" label_selected="Take Off" layout="topleft" - left_delta="0" name="Take Off" - top_pad="102" + top_pad="4" width="82" /> <button follows="right|bottom" @@ -1589,9 +1579,9 @@ label="Save" label_selected="Save" layout="topleft" - left="123" + right="218" name="Save" - top="458" + top="477" width="82" /> <button follows="right|bottom" @@ -1599,9 +1589,9 @@ label="Save As..." label_selected="Save As..." layout="topleft" - left_pad="6" + right="304" name="Save As" - top_delta="0" + top="477" width="82" /> <button follows="right|bottom" @@ -1609,38 +1599,38 @@ label="Revert" label_selected="Revert" layout="topleft" - left_pad="6" + right="390" name="Revert" - top_delta="0" + top="477" width="82" /> </panel> <panel - border="true" + border="false" + background_visible="true" + bg_alpha_color="DkGray2" follows="left|top|right|bottom" - height="481" + height="508" label="Socks" layout="topleft" - left_delta="0" name="Socks" help_topic="customize_socks_tab" - top_delta="0" - width="389"> + width="400"> <icon - follows="top|right" + follows="top|left" height="18" image_name="Lock" layout="topleft" - left="315" + left="10" mouse_opaque="true" name="square" - top="4" + top="10" width="18" /> <icon height="16" layout="topleft" - left_delta="-325" + left="10" mouse_opaque="true" - top_delta="3" + top="10" width="16" /> <text type="string" @@ -1649,9 +1639,9 @@ font="SansSerif" height="16" layout="topleft" - left_pad="2" + left="31" name="title" - top_delta="0" + top="10" width="355"> [DESC] </text> @@ -1662,9 +1652,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_no_modify" - top_delta="0" + top="10" width="355"> [DESC]: cannot modify </text> @@ -1675,9 +1665,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_loading" - top_delta="0" + top="10" width="355"> [DESC]: loading... </text> @@ -1688,9 +1678,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_not_worn" - top_delta="0" + top="10" width="355"> [DESC]: not worn </text> @@ -1700,9 +1690,9 @@ follows="left|top|right" height="14" layout="topleft" - left="8" + left="10" name="path" - top="24" + top="36" width="373"> Located in [PATH] </text> @@ -1712,22 +1702,31 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="not worn instructions" - top_pad="8" + top="31" word_wrap="true" width="373"> Put on new socks by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. </text> + <button + follows="left|top" + height="23" + label="Create New Socks" + label_selected="Create New Socks" + layout="topleft" + name="Create New" + top_pad="7" + width="160" /> <text type="string" length="1" follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="no modify instructions" - top_delta="0" + top="31" word_wrap="true" width="373"> You do not have permission to modify this wearable. @@ -1735,14 +1734,14 @@ <text type="string" length="1" - bottom="486" - follows="left|top|right" + bottom="4" + follows="left|bottom|right" font="SansSerif" halign="right" - height="28" - layout="topleft" + height="23" + layout="bottomleft" name="Item Action Label" - right="117" + right="132" width="100"> Socks: </text> @@ -1750,44 +1749,32 @@ can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" + height="108" label="Fabric" layout="topleft" - left="8" + left="10" name="Fabric" tool_tip="Click to choose a picture" - top="65" - width="64" /> + top="66" + width="82" /> <color_swatch can_apply_immediately="true" follows="left|top" - height="80" + height="108" label="Color/Tint" layout="topleft" - left_delta="0" name="Color/Tint" tool_tip="Click to open color picker" - top_delta="80" - width="64" /> - <button - follows="left|top" - height="23" - label="Create New Socks" - label_selected="Create New Socks" - layout="topleft" - left_delta="0" - name="Create New" - top_delta="-41" - width="160" /> + top_delta="102" + width="82" /> <button follows="left|top" height="23" label="Take Off" label_selected="Take Off" layout="topleft" - left_delta="0" name="Take Off" - top_pad="102" + top_pad="4" width="82" /> <button follows="right|bottom" @@ -1795,9 +1782,9 @@ label="Save" label_selected="Save" layout="topleft" - left="123" + right="218" name="Save" - top="458" + top="477" width="82" /> <button follows="right|bottom" @@ -1805,9 +1792,9 @@ label="Save As..." label_selected="Save As..." layout="topleft" - left_pad="6" + right="304" name="Save As" - top_delta="0" + top="477" width="82" /> <button follows="right|bottom" @@ -1815,38 +1802,38 @@ label="Revert" label_selected="Revert" layout="topleft" - left_pad="6" + right="390" name="Revert" - top_delta="0" + top="477" width="82" /> </panel> <panel - border="true" + border="false" + background_visible="true" + bg_alpha_color="DkGray2" follows="left|top|right|bottom" - height="481" + height="508" label="Jacket" layout="topleft" - left_delta="0" name="Jacket" help_topic="customize_jacket_tab" - top_delta="0" - width="389"> + width="400"> <icon - follows="top|right" + follows="top|left" height="18" image_name="Lock" layout="topleft" - left="315" + left="10" mouse_opaque="true" name="square" - top="4" + top="10" width="18" /> <icon height="16" layout="topleft" - left_delta="-325" + left="10" mouse_opaque="true" - top_delta="3" + top="10" width="16" /> <text type="string" @@ -1855,9 +1842,9 @@ font="SansSerif" height="16" layout="topleft" - left_pad="2" + left="31" name="title" - top_delta="0" + top="10" width="355"> [DESC] </text> @@ -1868,9 +1855,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_no_modify" - top_delta="0" + top="10" width="355"> [DESC]: cannot modify </text> @@ -1881,9 +1868,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_loading" - top_delta="0" + top="10" width="355"> [DESC]: loading... </text> @@ -1894,9 +1881,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_not_worn" - top_delta="0" + top="10" width="355"> [DESC]: not worn </text> @@ -1906,9 +1893,9 @@ follows="left|top|right" height="14" layout="topleft" - left="8" + left="10" name="path" - top="24" + top="36" width="373"> Located in [PATH] </text> @@ -1918,22 +1905,31 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="not worn instructions" - top_pad="8" + top="31" word_wrap="true" width="373"> Put on a new jacket by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. </text> + <button + follows="left|top" + height="23" + label="Create New Jacket" + label_selected="Create New Jacket" + layout="topleft" + name="Create New" + top_pad="7" + width="160" /> <text type="string" length="1" follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="no modify instructions" - top_delta="0" + top="31" word_wrap="true" width="373"> You do not have permission to modify this wearable. @@ -1941,14 +1937,14 @@ <text type="string" length="1" - bottom="486" - follows="left|top|right" + bottom="4" + follows="left|bottom|right" font="SansSerif" halign="right" - height="28" - layout="topleft" + height="23" + layout="bottomleft" name="Item Action Label" - right="117" + right="132" width="100"> Jacket: </text> @@ -1956,56 +1952,43 @@ can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" + height="108" label="Upper Fabric" layout="topleft" - left="8" + left="10" name="Upper Fabric" tool_tip="Click to choose a picture" - top="65" - width="64" /> + top="66" + width="82" /> <texture_picker can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" + height="108" label="Lower Fabric" layout="topleft" - left_delta="0" name="Lower Fabric" tool_tip="Click to choose a picture" - top_delta="80" - width="64" /> + top_delta="102" + width="82" /> <color_swatch can_apply_immediately="true" follows="left|top" - height="80" + height="108" label="Color/Tint" layout="topleft" - left_delta="0" name="Color/Tint" tool_tip="Click to open color picker" - top_delta="80" - width="64" /> - <button - follows="left|top" - height="23" - label="Create New Jacket" - label_selected="Create New Jacket" - layout="topleft" - left_delta="0" - name="Create New" - top_delta="-121" - width="160" /> + top_delta="102" + width="82" /> <button follows="left|top" height="23" label="Take Off" label_selected="Take Off" layout="topleft" - left_delta="0" name="Take Off" - top_pad="182" + top_pad="4" width="82" /> <button follows="right|bottom" @@ -2013,9 +1996,9 @@ label="Save" label_selected="Save" layout="topleft" - left="123" + right="218" name="Save" - top="458" + top="477" width="82" /> <button follows="right|bottom" @@ -2023,9 +2006,9 @@ label="Save As..." label_selected="Save As..." layout="topleft" - left_pad="6" + right="304" name="Save As" - top_delta="0" + top="477" width="82" /> <button follows="right|bottom" @@ -2033,38 +2016,38 @@ label="Revert" label_selected="Revert" layout="topleft" - left_pad="6" + right="390" name="Revert" - top_delta="0" + top="477" width="82" /> </panel> <panel - border="true" + border="false" + background_visible="true" + bg_alpha_color="DkGray2" follows="left|top|right|bottom" - height="481" + height="508" label="Gloves" layout="topleft" - left_delta="0" name="Gloves" help_topic="customize_gloves_tab" - top_delta="0" - width="389"> + width="400"> <icon - follows="top|right" + follows="top|left" height="18" image_name="Lock" layout="topleft" - left="315" + left="10" mouse_opaque="true" name="square" - top="4" + top="10" width="18" /> <icon height="16" layout="topleft" - left_delta="-325" + left="10" mouse_opaque="true" - top_delta="3" + top="10" width="16" /> <text type="string" @@ -2073,9 +2056,9 @@ font="SansSerif" height="16" layout="topleft" - left_pad="2" + left="31" name="title" - top_delta="0" + top="10" width="355"> [DESC] </text> @@ -2086,9 +2069,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_no_modify" - top_delta="0" + top="10" width="355"> [DESC]: cannot modify </text> @@ -2099,9 +2082,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_loading" - top_delta="0" + top="10" width="355"> [DESC]: loading... </text> @@ -2112,9 +2095,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_not_worn" - top_delta="0" + top="10" width="355"> [DESC]: not worn </text> @@ -2124,9 +2107,9 @@ follows="left|top|right" height="14" layout="topleft" - left="8" + left="10" name="path" - top="24" + top="36" width="373"> Located in [PATH] </text> @@ -2136,22 +2119,31 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="not worn instructions" - top_pad="8" + top="31" word_wrap="true" width="373"> Put on new gloves by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. </text> + <button + follows="left|top" + height="23" + label="Create New Gloves" + label_selected="Create New Gloves" + layout="topleft" + name="Create New" + top_pad="7" + width="160" /> <text type="string" length="1" follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="no modify instructions" - top_delta="0" + top="31" word_wrap="true" width="373"> You do not have permission to modify this wearable. @@ -2159,14 +2151,14 @@ <text type="string" length="1" - bottom="486" - follows="left|top|right" + bottom="4" + follows="left|bottom|right" font="SansSerif" halign="right" - height="28" - layout="topleft" + height="23" + layout="bottomleft" name="Item Action Label" - right="117" + right="132" width="100"> Gloves: </text> @@ -2174,44 +2166,32 @@ can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" + height="108" label="Fabric" layout="topleft" - left="8" + left="10" name="Fabric" tool_tip="Click to choose a picture" - top="65" - width="64" /> + top="66" + width="82" /> <color_swatch can_apply_immediately="true" follows="left|top" - height="80" + height="108" label="Color/Tint" layout="topleft" - left_delta="0" name="Color/Tint" tool_tip="Click to open color picker" - top_delta="80" - width="64" /> - <button - follows="left|top" - height="23" - label="Create New Gloves" - label_selected="Create New Gloves" - layout="topleft" - left_delta="0" - name="Create New" - top_delta="-41" - width="160" /> + top_delta="102" + width="82" /> <button follows="left|top" height="23" label="Take Off" label_selected="Take Off" layout="topleft" - left_delta="0" name="Take Off" - top_pad="102" + top_pad="4" width="82" /> <button follows="right|bottom" @@ -2219,9 +2199,9 @@ label="Save" label_selected="Save" layout="topleft" - left="123" + right="218" name="Save" - top="458" + top="477" width="82" /> <button follows="right|bottom" @@ -2229,9 +2209,9 @@ label="Save As..." label_selected="Save As..." layout="topleft" - left_pad="6" + right="304" name="Save As" - top_delta="0" + top="477" width="82" /> <button follows="right|bottom" @@ -2239,38 +2219,38 @@ label="Revert" label_selected="Revert" layout="topleft" - left_pad="6" + right="390" name="Revert" - top_delta="0" + top="477" width="82" /> </panel> <panel - border="true" + border="false" + background_visible="true" + bg_alpha_color="DkGray2" follows="left|top|right|bottom" - height="481" + height="508" label="Undershirt" layout="topleft" - left_delta="0" name="Undershirt" help_topic="customize_undershirt_tab" - top_delta="0" - width="389"> + width="400"> <icon - follows="top|right" + follows="top|left" height="18" image_name="Lock" layout="topleft" - left="315" + left="10" mouse_opaque="true" name="square" - top="4" + top="10" width="18" /> <icon height="16" layout="topleft" - left_delta="-325" + left="10" mouse_opaque="true" - top_delta="3" + top="10" width="16" /> <text type="string" @@ -2279,9 +2259,9 @@ font="SansSerif" height="16" layout="topleft" - left_pad="2" + left="31" name="title" - top_delta="0" + top="10" width="355"> [DESC] </text> @@ -2292,9 +2272,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_no_modify" - top_delta="0" + top="10" width="355"> [DESC]: cannot modify </text> @@ -2305,9 +2285,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_loading" - top_delta="0" + top="10" width="355"> [DESC]: loading... </text> @@ -2318,9 +2298,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_not_worn" - top_delta="0" + top="10" width="355"> [DESC]: not worn </text> @@ -2330,9 +2310,9 @@ follows="left|top|right" height="14" layout="topleft" - left="8" + left="10" name="path" - top="24" + top="36" width="373"> Located in [PATH] </text> @@ -2342,22 +2322,31 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="not worn instructions" - top_pad="8" + top="31" word_wrap="true" width="373"> Put on a new undershirt by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. </text> + <button + follows="left|top" + height="23" + label="Create New Undershirt" + label_selected="Create New Undershirt" + layout="topleft" + name="Create New" + top_pad="7" + width="160" /> <text type="string" length="1" follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="no modify instructions" - top_delta="0" + top="31" word_wrap="true" width="373"> You do not have permission to modify this wearable. @@ -2365,14 +2354,14 @@ <text type="string" length="1" - bottom="486" - follows="left|top|right" + bottom="4" + follows="left|bottom|right" font="SansSerif" halign="right" - height="28" - layout="topleft" + height="23" + layout="bottomleft" name="Item Action Label" - right="117" + right="132" width="100"> Undershirt: </text> @@ -2380,44 +2369,32 @@ can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" + height="108" label="Fabric" layout="topleft" - left="8" + left="10" name="Fabric" tool_tip="Click to choose a picture" - top="65" - width="64" /> + top="66" + width="82" /> <color_swatch can_apply_immediately="true" follows="left|top" - height="80" + height="108" label="Color/Tint" layout="topleft" - left_delta="0" name="Color/Tint" tool_tip="Click to open color picker" - top_delta="80" - width="64" /> - <button - follows="left|top" - height="23" - label="Create New Undershirt" - label_selected="Create New Undershirt" - layout="topleft" - left_delta="0" - name="Create New" - top_delta="-41" - width="160" /> + top_delta="102" + width="82" /> <button follows="left|top" height="23" label="Take Off" label_selected="Take Off" layout="topleft" - left_delta="0" name="Take Off" - top_pad="102" + top_pad="4" width="82" /> <button follows="right|bottom" @@ -2425,9 +2402,9 @@ label="Save" label_selected="Save" layout="topleft" - left="123" + right="218" name="Save" - top="458" + top="477" width="82" /> <button follows="right|bottom" @@ -2435,9 +2412,9 @@ label="Save As..." label_selected="Save As..." layout="topleft" - left_pad="6" + right="304" name="Save As" - top_delta="0" + top="477" width="82" /> <button follows="right|bottom" @@ -2445,38 +2422,38 @@ label="Revert" label_selected="Revert" layout="topleft" - left_pad="6" + right="390" name="Revert" - top_delta="0" + top="477" width="82" /> </panel> <panel - border="true" + border="false" + background_visible="true" + bg_alpha_color="DkGray2" follows="left|top|right|bottom" - height="481" + height="508" label="Underpants" layout="topleft" - left_delta="0" name="Underpants" help_topic="customize_underpants_tab" - top_delta="0" - width="389"> + width="400"> <icon - follows="top|right" + follows="top|left" height="18" image_name="Lock" layout="topleft" - left="315" + left="10" mouse_opaque="true" name="square" - top="4" + top="10" width="18" /> <icon height="16" layout="topleft" - left_delta="-325" + left="10" mouse_opaque="true" - top_delta="3" + top="10" width="16" /> <text type="string" @@ -2485,9 +2462,9 @@ font="SansSerif" height="16" layout="topleft" - left_pad="2" + left="31" name="title" - top_delta="0" + top="10" width="355"> [DESC] </text> @@ -2498,9 +2475,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_no_modify" - top_delta="0" + top="10" width="355"> [DESC]: cannot modify </text> @@ -2511,9 +2488,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_loading" - top_delta="0" + top="10" width="355"> [DESC]: loading... </text> @@ -2524,9 +2501,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_not_worn" - top_delta="0" + top="10" width="355"> [DESC]: not worn </text> @@ -2536,9 +2513,9 @@ follows="left|top|right" height="14" layout="topleft" - left="8" + left="10" name="path" - top="24" + top="36" width="373"> Located in [PATH] </text> @@ -2548,22 +2525,31 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="not worn instructions" - top_pad="8" + top="31" word_wrap="true" width="373"> Put on new underpants by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. </text> + <button + follows="left|top" + height="23" + label="Create New Underpants" + label_selected="Create New Underpants" + layout="topleft" + name="Create New" + top_pad="7" + width="160" /> <text type="string" length="1" follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="no modify instructions" - top_delta="0" + top="31" word_wrap="true" width="373"> You do not have permission to modify this wearable. @@ -2571,14 +2557,14 @@ <text type="string" length="1" - bottom="486" - follows="left|top|right" + bottom="4" + follows="left|bottom|right" font="SansSerif" halign="right" - height="28" - layout="topleft" + height="23" + layout="bottomleft" name="Item Action Label" - right="117" + right="132" width="100"> Underpants: </text> @@ -2586,44 +2572,32 @@ can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" + height="108" label="Fabric" layout="topleft" - left="8" + left="10" name="Fabric" tool_tip="Click to choose a picture" - top="65" - width="64" /> + top="66" + width="82" /> <color_swatch can_apply_immediately="true" follows="left|top" - height="80" + height="108" label="Color/Tint" layout="topleft" - left_delta="0" name="Color/Tint" tool_tip="Click to open color picker" - top_delta="80" - width="64" /> - <button - follows="left|top" - height="23" - label="Create New Underpants" - label_selected="Create New Underpants" - layout="topleft" - left_delta="0" - name="Create New" - top_delta="-41" - width="160" /> + top_delta="102" + width="82" /> <button follows="left|top" height="23" label="Take Off" label_selected="Take Off" layout="topleft" - left_delta="0" name="Take Off" - top_pad="102" + top_pad="4" width="82" /> <button follows="right|bottom" @@ -2631,9 +2605,9 @@ label="Save" label_selected="Save" layout="topleft" - left="123" + right="218" name="Save" - top="458" + top="477" width="82" /> <button follows="right|bottom" @@ -2641,9 +2615,9 @@ label="Save As..." label_selected="Save As..." layout="topleft" - left_pad="6" + right="304" name="Save As" - top_delta="0" + top="477" width="82" /> <button follows="right|bottom" @@ -2651,38 +2625,38 @@ label="Revert" label_selected="Revert" layout="topleft" - left_pad="6" + right="390" name="Revert" - top_delta="0" + top="477" width="82" /> </panel> <panel - border="true" + border="false" + background_visible="true" + bg_alpha_color="DkGray2" follows="left|top|right|bottom" - height="481" + height="508" label="Skirt" layout="topleft" - left_delta="0" name="Skirt" help_topic="customize_skirt_tab" - top_delta="0" - width="389"> + width="400"> <icon - follows="top|right" + follows="top|left" height="18" image_name="Lock" layout="topleft" - left="315" + left="10" mouse_opaque="true" name="square" - top="4" + top="10" width="18" /> <icon height="16" layout="topleft" - left_delta="-325" + left="10" mouse_opaque="true" - top_delta="3" + top="10" width="16" /> <text type="string" @@ -2691,9 +2665,9 @@ font="SansSerif" height="16" layout="topleft" - left_pad="2" + left="31" name="title" - top_delta="0" + top="10" width="355"> [DESC] </text> @@ -2704,9 +2678,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_no_modify" - top_delta="0" + top="10" width="355"> [DESC]: cannot modify </text> @@ -2717,9 +2691,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_loading" - top_delta="0" + top="10" width="355"> [DESC]: loading... </text> @@ -2730,9 +2704,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_not_worn" - top_delta="0" + top="10" width="355"> [DESC]: not worn </text> @@ -2742,9 +2716,9 @@ follows="left|top|right" height="14" layout="topleft" - left="8" + left="10" name="path" - top="24" + top="36" width="373"> Located in [PATH] </text> @@ -2754,22 +2728,31 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="not worn instructions" - top_pad="8" + top="31" word_wrap="true" width="373"> Put on a new skirt by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. </text> + <button + follows="left|top" + height="23" + label="Create New Skirt" + label_selected="Create New Skirt" + layout="topleft" + name="Create New" + top_pad="7" + width="160" /> <text type="string" length="1" follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="no modify instructions" - top_delta="0" + top="31" word_wrap="true" width="373"> You do not have permission to modify this wearable. @@ -2777,14 +2760,14 @@ <text type="string" length="1" - bottom="486" - follows="left|top|right" + bottom="4" + follows="left|bottom|right" font="SansSerif" halign="right" - height="28" - layout="topleft" + height="23" + layout="bottomleft" name="Item Action Label" - right="117" + right="132" width="100"> Skirt: </text> @@ -2792,44 +2775,32 @@ can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" + height="108" label="Fabric" layout="topleft" - left="8" + left="10" name="Fabric" tool_tip="Click to choose a picture" - top="65" - width="64" /> + top="66" + width="82" /> <color_swatch can_apply_immediately="true" follows="left|top" - height="80" + height="108" label="Color/Tint" layout="topleft" - left_delta="0" name="Color/Tint" tool_tip="Click to open color picker" - top_delta="80" - width="64" /> - <button - follows="left|top" - height="23" - label="Create New Skirt" - label_selected="Create New Skirt" - layout="topleft" - left_delta="0" - name="Create New" - top_delta="-41" - width="160" /> + top_delta="102" + width="82" /> <button follows="left|top" height="23" label="Take Off" label_selected="Take Off" layout="topleft" - left_delta="0" name="Take Off" - top_pad="102" + top_pad="4" width="82" /> <button follows="right|bottom" @@ -2837,9 +2808,9 @@ label="Save" label_selected="Save" layout="topleft" - left="123" + right="218" name="Save" - top="458" + top="477" width="82" /> <button follows="right|bottom" @@ -2847,9 +2818,9 @@ label="Save As..." label_selected="Save As..." layout="topleft" - left_pad="6" + right="304" name="Save As" - top_delta="0" + top="477" width="82" /> <button follows="right|bottom" @@ -2857,38 +2828,38 @@ label="Revert" label_selected="Revert" layout="topleft" - left_pad="6" + right="390" name="Revert" - top_delta="0" + top="477" width="82" /> </panel> <panel - border="true" + border="false" + background_visible="true" + bg_alpha_color="DkGray2" follows="left|top|right|bottom" - height="481" - label="Alpha" + height="508" + label="Tattoo" layout="topleft" - left_delta="0" - name="Alpha" - help_topic="customize_alpha_tab" - top_delta="0" - width="389"> + name="Tattoo" + help_topic="customize_tattoo_tab" + width="400"> <icon - follows="top|right" + follows="top|left" height="18" image_name="Lock" layout="topleft" - left="315" + left="10" mouse_opaque="true" name="square" - top="4" + top="10" width="18" /> <icon height="16" layout="topleft" - left_delta="-325" + left="10" mouse_opaque="true" - top_delta="3" + top="10" width="16" /> <text type="string" @@ -2897,9 +2868,9 @@ font="SansSerif" height="16" layout="topleft" - left_pad="2" + left="31" name="title" - top_delta="0" + top="10" width="355"> [DESC] </text> @@ -2910,9 +2881,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_no_modify" - top_delta="0" + top="10" width="355"> [DESC]: cannot modify </text> @@ -2923,9 +2894,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_loading" - top_delta="0" + top="10" width="355"> [DESC]: loading... </text> @@ -2936,9 +2907,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_not_worn" - top_delta="0" + top="10" width="355"> [DESC]: not worn </text> @@ -2948,9 +2919,9 @@ follows="left|top|right" height="14" layout="topleft" - left="8" + left="10" name="path" - top="24" + top="36" width="373"> Located in [PATH] </text> @@ -2960,22 +2931,31 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="-2" + left="10" name="not worn instructions" - top_pad="8" + top="31" word_wrap="true" width="373"> - Put on a new alpha mask by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. + Put on a new tattoo by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. </text> + <button + follows="left|top" + height="23" + label="Create New Tattoo" + label_selected="Create New Tattoo" + layout="topleft" + name="Create New" + top_pad="7" + width="160" /> <text type="string" length="1" follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="no modify instructions" - top_delta="0" + top="31" word_wrap="true" width="373"> You do not have permission to modify this wearable. @@ -2983,141 +2963,60 @@ <text type="string" length="1" - bottom="486" - follows="left|top|right" + bottom="4" + follows="left|bottom|right" font="SansSerif" halign="right" - height="28" - layout="topleft" + height="23" + layout="bottomleft" name="Item Action Label" - right="119" + right="132" width="100"> - Alpha: + Tattoo: </text> <texture_picker can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" - label="Lower Alpha" - layout="topleft" - left="8" - name="Lower Alpha" - tool_tip="Click to choose a picture" - top="65" - width="64" /> - <check_box - control_name="LowerAlphaTextureInvisible" - follows="left" - height="16" - layout="topleft" - left_pad="6" - name="lower alpha texture invisible" - top_delta="4" - width="16" /> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="80" - label="Upper Alpha" - layout="topleft" - left="8" - name="Upper Alpha" - tool_tip="Click to choose a picture" - top="145" - width="64" /> - <check_box - control_name="UpperAlphaTextureInvisible" - follows="left" - height="16" - layout="topleft" - left_pad="6" - name="upper alpha texture invisible" - top_delta="4" - width="16" /> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="80" - label="Head Alpha" + height="108" + label="Head Tattoo" layout="topleft" - left="8" - name="Head Alpha" + left="10" + name="Head Tattoo" tool_tip="Click to choose a picture" - top="225" - width="64" /> - <check_box - control_name="HeadAlphaTextureInvisible" - follows="left" - height="16" - layout="topleft" - left_pad="6" - name="head alpha texture invisible" - top_delta="4" - width="16" /> + top="66" + width="82" /> <texture_picker can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" - label="Eye Alpha" + height="108" + label="Upper Tattoo" layout="topleft" - left="8" - name="Eye Alpha" + name="Upper Tattoo" tool_tip="Click to choose a picture" - top="305" - width="64" /> - <check_box - control_name="Eye AlphaTextureInvisible" - follows="left" - height="16" - layout="topleft" - left_pad="6" - name="eye alpha texture invisible" - top_delta="4" - width="16" /> + left_delta="90" + width="82" /> <texture_picker can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" - label="Hair Alpha" + height="108" + label="Lower Tattoo" layout="topleft" - left="8" - name="Hair Alpha" + name="Lower Tattoo" tool_tip="Click to choose a picture" - top="385" - width="64" /> - <check_box - control_name="HairAlphaTextureInvisible" - follows="left" - height="16" - layout="topleft" - left_pad="6" - name="hair alpha texture invisible" - top_delta="4" - width="16" /> - <button - follows="left|top" - height="23" - label="Create New Alpha" - label_selected="Create New Alpha" - layout="topleft" - left="8" - name="Create New" - top="104" - width="160" /> + left_delta="90" + width="82" /> <button follows="left|top" height="23" label="Take Off" label_selected="Take Off" layout="topleft" - left_delta="-4" name="Take Off" - top_pad="332" + top_pad="4" + left="10" width="82" /> <button follows="right|bottom" @@ -3125,9 +3024,9 @@ label="Save" label_selected="Save" layout="topleft" - left_pad="37" + right="218" name="Save" - top_delta="-2" + top="477" width="82" /> <button follows="right|bottom" @@ -3135,9 +3034,9 @@ label="Save As..." label_selected="Save As..." layout="topleft" - left_pad="6" + right="304" name="Save As" - top_delta="0" + top="477" width="82" /> <button follows="right|bottom" @@ -3145,38 +3044,38 @@ label="Revert" label_selected="Revert" layout="topleft" - left_pad="6" + right="390" name="Revert" - top_delta="0" + top="477" width="82" /> </panel> <panel - border="true" + border="false" + background_visible="true" + bg_alpha_color="DkGray2" follows="left|top|right|bottom" - height="481" - label="Tattoo" + height="508" + label="Alpha" layout="topleft" - left_delta="0" - name="Tattoo" - help_topic="customize_tattoo_tab" - top_delta="0" - width="389"> + name="Alpha" + help_topic="customize_alpha_tab" + width="400"> <icon - follows="top|right" + follows="top|left" height="18" image_name="Lock" layout="topleft" - left="315" + left="10" mouse_opaque="true" name="square" - top="4" + top="10" width="18" /> <icon height="16" layout="topleft" - left_delta="-325" + left="10" mouse_opaque="true" - top_delta="3" + top="10" width="16" /> <text type="string" @@ -3185,9 +3084,9 @@ font="SansSerif" height="16" layout="topleft" - left_pad="2" + left="31" name="title" - top_delta="0" + top="10" width="355"> [DESC] </text> @@ -3198,9 +3097,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_no_modify" - top_delta="0" + top="10" width="355"> [DESC]: cannot modify </text> @@ -3211,9 +3110,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_loading" - top_delta="0" + top="10" width="355"> [DESC]: loading... </text> @@ -3224,9 +3123,9 @@ font="SansSerif" height="16" layout="topleft" - left_delta="0" + left="31" name="title_not_worn" - top_delta="0" + top="10" width="355"> [DESC]: not worn </text> @@ -3236,9 +3135,9 @@ follows="left|top|right" height="14" layout="topleft" - left="8" + left="10" name="path" - top="24" + top="36" width="373"> Located in [PATH] </text> @@ -3248,22 +3147,31 @@ follows="left|top|right" height="28" layout="topleft" - left_delta="-2" + left="10" name="not worn instructions" - top_pad="8" + top="31" word_wrap="true" width="373"> - Put on a new tattoo by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. + Put on a new alpha mask by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. </text> + <button + follows="left|top" + height="23" + label="Create New Alpha" + label_selected="Create New Alpha" + layout="topleft" + name="Create New" + top_pad="18" + width="160" /> <text type="string" length="1" follows="left|top|right" height="28" layout="topleft" - left_delta="0" + left="10" name="no modify instructions" - top_delta="0" + top="31" word_wrap="true" width="373"> You do not have permission to modify this wearable. @@ -3271,72 +3179,125 @@ <text type="string" length="1" - bottom="486" - follows="left|top|right" + bottom="4" + follows="left|bottom|right" font="SansSerif" halign="right" - height="28" - layout="topleft" + height="23" + layout="bottomleft" name="Item Action Label" - right="119" + right="132" width="100"> - Tattoo: + Alpha: </text> <texture_picker can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" - label="Head Tattoo" + height="108" + label="Lower Alpha" layout="topleft" - left="8" - name="Head Tattoo" + left="10" + name="Lower Alpha" tool_tip="Click to choose a picture" - top="65" - width="64" /> + top="66" + width="82" /> <texture_picker can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" - label="Upper Tattoo" + height="108" + label="Upper Alpha" layout="topleft" - left_delta="0" - name="Upper Tattoo" + name="Upper Alpha" tool_tip="Click to choose a picture" - top_delta="80" - width="64" /> + left_delta="90" + width="82" /> <texture_picker can_apply_immediately="true" default_image_name="Default" follows="left|top" - height="80" - label="Lower Tattoo" + height="108" + label="Head Alpha" layout="topleft" - left_delta="0" - name="Lower Tattoo" + name="Head Alpha" tool_tip="Click to choose a picture" - top_delta="80" - width="64" /> - <button + left_delta="90" + width="82" /> + <check_box + control_name="LowerAlphaTextureInvisible" + follows="left" + height="16" + layout="topleft" + left="43" + name="lower alpha texture invisible" + top_delta="96" + width="16" /> + <check_box + control_name="UpperAlphaTextureInvisible" + follows="left" + height="16" + layout="topleft" + left_pad="72" + name="upper alpha texture invisible" + width="16" /> + <check_box + control_name="HeadAlphaTextureInvisible" + follows="left" + height="16" + layout="topleft" + left_pad="72" + name="head alpha texture invisible" + width="16" /> + <texture_picker + can_apply_immediately="true" + default_image_name="Default" follows="left|top" - height="23" - label="Create New Tattoo" - label_selected="Create New Tattoo" + height="108" + label="Eye Alpha" layout="topleft" - left_delta="0" - name="Create New" - top_delta="-121" - width="160" /> + name="Eye Alpha" + tool_tip="Click to choose a picture" + left="10" + top_pad="20" + width="82" /> + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="108" + label="Hair Alpha" + layout="topleft" + name="Hair Alpha" + left_delta="90" + tool_tip="Click to choose a picture" + width="82" /> + <check_box + control_name="Eye AlphaTextureInvisible" + follows="left" + height="16" + layout="topleft" + left="43" + name="eye alpha texture invisible" + top_delta="96" + width="16" /> + <check_box + control_name="HairAlphaTextureInvisible" + follows="left" + height="16" + layout="topleft" + left_pad="72" + name="hair alpha texture invisible" + width="16" /> <button follows="left|top" height="23" label="Take Off" label_selected="Take Off" layout="topleft" - left_delta="-4" name="Take Off" - top_pad="332" + left="10" + top_pad="20" width="82" /> <button follows="right|bottom" @@ -3344,9 +3305,9 @@ label="Save" label_selected="Save" layout="topleft" - left_pad="37" + right="218" name="Save" - top_delta="-2" + top="477" width="82" /> <button follows="right|bottom" @@ -3354,9 +3315,9 @@ label="Save As..." label_selected="Save As..." layout="topleft" - left_pad="6" + right="304" name="Save As" - top_delta="0" + top="477" width="82" /> <button follows="right|bottom" @@ -3364,9 +3325,9 @@ label="Revert" label_selected="Revert" layout="topleft" - left_pad="6" + right="390" name="Revert" - top_delta="0" + top="477" width="82" /> </panel> </tab_container> @@ -3377,7 +3338,7 @@ left="211" mouse_opaque="false" name="panel_container" - top="116" + top="92" width="292"> <scrolling_panel_list follows="left|bottom" @@ -3385,17 +3346,18 @@ name="panel_list" /> </scroll_container> <button - bottom="598" + bottom="460" follows="right|left" - height="20" + height="23" label="Script Info" label_selected="Script Info" layout="topleft" name="script_info" - left="2" - width="98" /> + tool_tip="Show scripts attached to your avatar" + left="13" + width="90" /> <button - bottom="598" + bottom="574" follows="right|bottom" height="23" label="Make Outfit" @@ -3405,7 +3367,7 @@ right="-218" width="100" /> <button - bottom="598" + bottom="574" follows="right|bottom" height="23" label="Cancel" @@ -3415,7 +3377,7 @@ right="-10" width="100" /> <button - bottom="598" + bottom="574" follows="right|bottom" height="23" label="OK" diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml index 1d51d19a4a..bd25288a9e 100644 --- a/indra/newview/skins/default/xui/en/floater_im_container.xml +++ b/indra/newview/skins/default/xui/en/floater_im_container.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <multi_floater - can_minimize="false" + can_close="false" + can_minimize="true" can_resize="true" height="390" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index 243b63db00..613530b7aa 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -17,6 +17,7 @@ min_width="250" min_height="190"> <layout_stack + animate="false" follows="all" height="320" width="360" diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml index 3fc57372de..005952f3f2 100644 --- a/indra/newview/skins/default/xui/en/floater_sys_well.xml +++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml @@ -3,13 +3,13 @@ legacy_header_height="18" bevel_style="in" left="0" - top="0" + top="0" follows="right|bottom" layout="topleft" name="sys_well_window" help_topic="notification_chiclet" save_rect="true" - title="NOTIFICATIONS" + title="NOTIFICATIONS" width="320" min_width="320" height="23" @@ -23,13 +23,13 @@ > <string name="title_im_well_window"> - IM SESSIONS + CONVERSATIONS </string> <string name="title_notification_well_window"> NOTIFICATIONS </string> - + <flat_list_view color="FloaterDefaultBackgroundColor" follows="all" diff --git a/indra/newview/skins/default/xui/en/floater_test_checkbox.xml b/indra/newview/skins/default/xui/en/floater_test_checkbox.xml index 9977e85a9d..042b4226c3 100644 --- a/indra/newview/skins/default/xui/en/floater_test_checkbox.xml +++ b/indra/newview/skins/default/xui/en/floater_test_checkbox.xml @@ -71,4 +71,83 @@ name="font_checkbox" top_pad="14" width="150" /> + +<chiclet_im_p2p + height="25" + name="im_p2p_chiclet" + show_speaker="false" + width="25"> + <chiclet_im_p2p.chiclet_button + height="25" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + name="chiclet_button" + tab_stop="false" + width="25"/> + <chiclet_im_p2p.speaker + auto_update="true" + draw_border="false" + height="25" + left="25" + name="speaker" + visible="false" + width="20" /> + <chiclet_im_p2p.avatar_icon + bottom="3" + follows="left|top|bottom" + height="20" + left="2" + mouse_opaque="false" + name="avatar_icon" + width="21" /> + <chiclet_im_p2p.unread_notifications + height="25" + font_halign="center" + left="25" + mouse_opaque="false" + name="unread" + text_color="white" + v_pad="5" + visible="false" + width="20"/> + <chiclet_im_p2p.new_message_icon + bottom="11" + height="14" + image_name="Unread_Chiclet" + left="12" + name="new_message_icon" + visible="false" + width="14" /> +</chiclet_im_p2p> + + +<chiclet_offer + height="25" + name="offer_chiclet" + width="25"> + <chiclet_offer.chiclet_button + height="25" + image_selected="PushButton_Selected" + image_unselected="PushButton_Off" + name="chiclet_button" + tab_stop="false" + width="25"/> + <chiclet_offer.icon + bottom="3" + default_icon="Generic_Object_Small" + follows="all" + height="19" + left="3" + mouse_opaque="false" + name="chiclet_icon" + width="19" /> + <chiclet_offer.new_message_icon + bottom="11" + height="14" + image_name="Unread_Chiclet" + left="12" + name="new_message_icon" + visible="false" + width="14" /> +</chiclet_offer> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index aad333facc..5ada9c0f71 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -1687,6 +1687,7 @@ even though the user gets a free copy. Taper </text> <text + visible="false" type="string" length="1" follows="left|top" @@ -1769,6 +1770,7 @@ even though the user gets a free copy. top_delta="0" width="68" /> <text + visible="false" type="string" length="1" follows="left|top" @@ -1781,6 +1783,7 @@ even though the user gets a free copy. Profile Cut (begin/end) </text> <text + visible="false" type="string" length="1" follows="left|top" @@ -1831,6 +1834,7 @@ even though the user gets a free copy. top_delta="0" width="68" /> <text + visible="false" type="string" length="1" follows="left|top" @@ -1843,6 +1847,7 @@ even though the user gets a free copy. Taper </text> <spinner + visible="false" decimal_digits="2" follows="left|top" height="19" @@ -1857,6 +1862,7 @@ even though the user gets a free copy. top_pad="3" width="68" /> <spinner + visible="false" decimal_digits="2" follows="left|top" height="19" @@ -1871,6 +1877,7 @@ even though the user gets a free copy. top_delta="0" width="68" /> <text + visible="false" type="string" length="1" follows="left|top" @@ -1883,6 +1890,7 @@ even though the user gets a free copy. Radius </text> <text + visible="false" type="string" length="1" follows="left|top" @@ -1894,6 +1902,7 @@ even though the user gets a free copy. Revolutions </text> <spinner + visible="false" follows="left|top" height="19" increment="0.05" @@ -1905,6 +1914,7 @@ even though the user gets a free copy. top_pad="4" width="68" /> <spinner + visible="false" decimal_digits="2" follows="left|top" height="19" diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml index ae198d69a3..f473a51ff6 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml @@ -3,9 +3,9 @@ can_resize="true" can_minimize="true" can_close="false" - height="275" + height="202" layout="topleft" - min_height="100" + min_height="124" min_width="190" name="floater_voice_controls" help_topic="floater_voice_controls" @@ -36,7 +36,7 @@ <layout_stack clip="false" follows="all" - height="262" + height="189" layout="topleft" left="10" mouse_opaque="false" @@ -105,13 +105,13 @@ layout="topleft" left="2" top_pad="0" - height="205" + height="132" name="callers_panel" user_resize="false" width="280"> <avatar_list follows="all" - height="205" + height="132" ignore_online_status="true" layout="topleft" multi_select="true" diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml index a666b8a427..9796f7b5b6 100644 --- a/indra/newview/skins/default/xui/en/inspect_avatar.xml +++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml @@ -58,8 +58,10 @@ height="35" left="8" name="user_details" + right="-10" word_wrap="true" top_pad="6" + use_ellipses="true" width="220">This is my second life description and I really think it is great. </text> <slider diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml index 861eb9009a..1d4377e339 100644 --- a/indra/newview/skins/default/xui/en/main_view.xml +++ b/indra/newview/skins/default/xui/en/main_view.xml @@ -5,6 +5,7 @@ layout="topleft" left="0" mouse_opaque="false" + tab_stop="false" name="main_view" width="1024"> <layout_stack border_size="0" @@ -18,6 +19,7 @@ height="60" mouse_opaque="false" name="nav_bar_container" + tab_stop="false" width="1024" user_resize="false" visible="false"> @@ -27,6 +29,7 @@ height="500" layout="topleft" mouse_opaque="false" + tab_stop="false" name="hud" width="1024"> <layout_stack border_size="0" @@ -38,11 +41,12 @@ orientation="horizontal" top="0" width="1024"> - <panel auto_resize="true" + <layout_panel auto_resize="true" follows="all" height="500" layout="topleft" mouse_opaque="false" + tab_stop="false" name="non_side_tray_view" user_resize="false" width="500"> @@ -60,19 +64,22 @@ left="0" mouse_opaque="false" name="world_stack" - orientation="vertical"> + orientation="vertical" + tab_stop="false"> <panel auto_resize="true" follows="all" height="500" layout="topleft" + tab_stop="false" mouse_opaque="false" - name="hud container" + name="hud container" width="500"> <panel follows="right|top|bottom" height="500" mouse_opaque="false" name="side_bar_tabs" right="500" + tab_stop="false" top="0" width="32"/> <panel bottom="500" @@ -80,6 +87,7 @@ height="25" left="0" mouse_opaque="false" + tab_stop="false" name="stand_stop_flying_container" visible="false" width="500"/> @@ -91,13 +99,14 @@ name="bottom_tray_container" visible="false"/> </layout_stack> - </panel> + </layout_panel> <!-- side tray --> <layout_panel auto_resize="false" follows="all" height="500" min_width="333" mouse_opaque="false" + tab_stop="false" name="side_tray_container" user_resize="false" visible="false" @@ -132,8 +141,9 @@ </layout_panel> </layout_stack> <panel mouse_opaque="false" - follows="left|right|top" + follows="left|right|top" name="status_bar_container" + tab_stop="false" height="19" left="0" top="0" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 30d176c242..4279097f62 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3078,7 +3078,7 @@ Join me in [REGION] icon="alertmodal.tga" name="TeleportFromLandmark" type="alertmodal"> -Are you sure you want to teleport? +Are you sure you want to teleport to [LOCATION]? <usetemplate ignoretext="Confirm that I want to teleport to a landmark" name="okcancelignore" diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index de3de45718..09ec2137b7 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -265,7 +265,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly. left="1" min_width="110" name="chiclet_list" - top="6" + top="8" chiclet_padding="4" scrolling_offset="40" width="189"> @@ -284,7 +284,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly. name="chicklet_left_scroll_button" scale_image="true" tab_stop="false" - top="-2" + top="-4" right_pad="2" visible="false" width="7" /> @@ -303,7 +303,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly. name="chicklet_right_scroll_button" scale_image="true" tab_stop="false" - top="-2" + top="-4" visible="false" width="7" /> </chiclet_panel> @@ -334,11 +334,11 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly. max_displayed_count="99" flash_period="0.3" follows="right" - height="23" + height="28" layout="topleft" left="0" name="im_well" - top="5" + top="0" width="35"> <!-- Emulate 4 states of button by background images, see details in EXT-3147. The same should be for notification_well button @@ -350,7 +350,6 @@ image_pressed_selected "Lit" + "Selected" - there are new messages and the Well --> <button auto_resize="true" - flash_color="ChicletFlashColor" follows="right" halign="center" height="23" @@ -358,12 +357,12 @@ image_pressed_selected "Lit" + "Selected" - there are new messages and the Well image_overlay_alignment="center" image_pressed="WellButton_Lit" image_pressed_selected="WellButton_Lit_Selected" - image_selected="PushButton_Selected_Press" + image_selected="PushButton_Press" label_color="Black" left="0" name="Unread IM messages" tool_tip="Conversations" - width="35" > + width="34" > <button.init_callback function="Button.SetDockableFloaterToggle" parameter="im_well_window" /> @@ -407,25 +406,23 @@ image_pressed_selected "Lit" + "Selected" - there are new messages and the Well bottom_pad="3" image_pressed="WellButton_Lit" image_pressed_selected="WellButton_Lit_Selected" - image_selected="PushButton_Selected_Press" + image_selected="PushButton_Press" auto_resize="true" halign="center" height="23" follows="right" - flash_color="ChicletFlashColor" label_color="Black" left="0" name="Unread" image_overlay="Notices_Unread" image_overlay_alignment="center" - pad_right="15" tool_tip="Notifications" - width="35" > + width="34" > <button.init_callback function="Button.SetDockableFloaterToggle" parameter="notification_well_window" /> </button> - <icon + <icon auto_resize="false" color="0 0 0 0" follows="left|right" 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 673052c3b5..0893c204e7 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 @@ -67,6 +67,7 @@ background_visible="true" layout="topleft" left="20" name="insignia" + no_commit_on_selection="true" tool_tip="Click to choose a picture" top_pad="5" width="100" /> 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 6b3fb04549..618d2f3b8e 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -49,6 +49,18 @@ Select multiple Members by holding the Ctrl key and clicking on their names. </panel.string> + <panel.string + name="power_folder_icon"> + Inv_FolderClosed + </panel.string> + <panel.string + name="power_all_have_icon"> + Checkbox_On + </panel.string> + <panel.string + name="power_partial_icon"> + Checkbox_Off + </panel.string> <filter_editor layout="topleft" top="5" @@ -310,7 +322,7 @@ things in this group. There's a broad variety of Abilities. width="285"> Allowed Abilities </text> - <scroll_list + <scroll_list draw_stripes="true" height="90" layout="topleft" @@ -322,8 +334,16 @@ things in this group. There's a broad variety of Abilities. width="300"> <scroll_list.columns label="" + name="icon" + width="2" /> + <scroll_list.columns + label="" + name="checkbox" + width="20" /> + <scroll_list.columns + label="" name="action" - width="300" /> + width="270" /> </scroll_list> </panel> <panel diff --git a/indra/newview/skins/default/xui/en/panel_my_profile.xml b/indra/newview/skins/default/xui/en/panel_my_profile.xml index 2659156ba8..4894ae01da 100644 --- a/indra/newview/skins/default/xui/en/panel_my_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_my_profile.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel follows="all" - height="535" + height="500" label="Profile" layout="topleft" left="0" @@ -41,7 +41,7 @@ layout="topleft" left="0" top="0" - height="535" + height="480" width="313" border_size="0"> <layout_panel @@ -50,7 +50,8 @@ layout="topleft" top="0" left="0" - height="505" + height="480" + user_resize="false" width="313"> <scroll_container color="DkGray2" @@ -59,7 +60,7 @@ left="0" name="profile_scroll" opaque="true" - height="505" + height="480" width="313" top="0"> <panel @@ -365,6 +366,7 @@ top_pad="0" name="profile_me_buttons_panel" visible="false" + user_resize="false" auto_resize="false" height="28" width="313"> @@ -372,8 +374,9 @@ follows="bottom|right" height="23" left="20" - top="0" + top="5" label="Edit Profile" + layout="topleft" name="edit_profile_btn" tool_tip="Edit your personal information" width="130" /> @@ -382,7 +385,9 @@ height="23" label="Edit Appearance" left_pad="10" + layout="topleft" name="edit_appearance_btn" + top="5" tool_tip="Create/edit your appearance: physical data, clothes and etc." width="130" /> </layout_panel> diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml index bfc97ed5da..baa6c2e51f 100644 --- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml @@ -142,8 +142,8 @@ left="0" name="favorite" image_drag_indication="Accordion_ArrowOpened_Off" - bottom="55" - width="590"> + bottom="55" + width="590"> <chevron_button name=">>" image_unselected="TabIcon_Close_Off" image_selected="TabIcon_Close_Off" diff --git a/indra/newview/skins/default/xui/en/panel_notes.xml b/indra/newview/skins/default/xui/en/panel_notes.xml index 45b64d5e26..ac100a2c06 100644 --- a/indra/newview/skins/default/xui/en/panel_notes.xml +++ b/indra/newview/skins/default/xui/en/panel_notes.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel follows="all" - height="535" + height="540" label="Notes & Privacy" layout="topleft" left="0" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml index 8895484326..710ca733e0 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml @@ -45,7 +45,7 @@ left="0" top="0" mouse_opaque="true" - name="cof_accordionpanel" + name="cof_tab" start_folder="Current Outfit" width="313" /> </tab_container> diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 8a02637817..da3a2274c9 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -3,7 +3,7 @@ <panel background_visible="true" follows="all" - height="570" + height="575" label="People" layout="topleft" min_height="350" @@ -337,7 +337,7 @@ background_visible="true" </tab_container> <panel follows="bottom|left" - height="25" + height="35" layout="topleft" left="10" name="button_bar" diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml index 822e049eec..65ccd10cf0 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml @@ -39,7 +39,7 @@ height="500" layout="topleft" left="10" - top_pad="10" + top_pad="5" name="profile_scroll" width="313"> <panel @@ -102,7 +102,7 @@ </scroll_container> <panel follows="left|right|bottom" - height="20" + height="35" layout="topleft" top_pad="8" left="10" diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml index a2b0adf9d9..d31f4d039f 100644 --- a/indra/newview/skins/default/xui/en/panel_picks.xml +++ b/indra/newview/skins/default/xui/en/panel_picks.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel follows="all" - height="535" + height="540" label="Picks" layout="topleft" left="0" @@ -121,7 +121,7 @@ <panel layout="topleft" left="0" - height="25" + height="30" top_pad="10" name="buttons_cucks" width="313"> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml index f6900cc31c..17ababe854 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml @@ -9,64 +9,64 @@ name="Input panel" top="1" width="517"> - <button - height="23" - label="Other Devices" - layout="topleft" - left="30" - name="joystick_setup_button" - top="10" - width="155"> - <button.commit_callback - function="Floater.Show" - parameter="pref_joystick" /> - </button> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="30" - name="Mouselook:" - top_pad="10" - width="300"> - Mouselook: - </text> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left_delta="50" - name=" Mouse Sensitivity" - top_pad="10" - width="150"> - Mouse sensitivity - </text> - <slider - control_name="MouseSensitivity" - follows="left|top" - height="15" - initial_value="2" - layout="topleft" - show_text="false" - left_delta="150" - max_val="15" - name="mouse_sensitivity" - top_delta="0" - width="145" /> - <check_box - control_name="InvertMouse" - height="16" - label="Invert" - layout="topleft" - left_pad="2" - name="invert_mouse" - top_delta="0" - width="128" /> - <text + <button + height="23" + label="Other Devices" + layout="topleft" + left="30" + name="joystick_setup_button" + top="10" + width="155"> + <button.commit_callback + function="Floater.Show" + parameter="pref_joystick" /> + </button> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left="30" + name="Mouselook:" + top_pad="10" + width="300"> + Mouselook: + </text> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_delta="50" + name=" Mouse Sensitivity" + top_pad="10" + width="150"> + Mouse sensitivity + </text> + <slider + control_name="MouseSensitivity" + follows="left|top" + height="15" + initial_value="2" + layout="topleft" + show_text="false" + left_delta="150" + max_val="15" + name="mouse_sensitivity" + top_delta="0" + width="145" /> + <check_box + control_name="InvertMouse" + height="16" + label="Invert" + layout="topleft" + left_pad="2" + name="invert_mouse" + top_delta="0" + width="128" /> + <text type="string" length="1" follows="left|top" @@ -77,266 +77,270 @@ mouse_opaque="false" top_pad="4" width="300"> - Network: - </text> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left_delta="50" - name="Maximum bandwidth" - mouse_opaque="false" - top_pad="10" - width="200"> - Maximum bandwidth - </text> - <slider - can_edit_text="true" - control_name="ThrottleBandwidthKBPS" - decimal_digits="0" - follows="left|top" - height="15" - increment="100" - initial_value="500" - layout="topleft" - left_delta="150" - max_val="10000" - min_val="100" - name="max_bandwidth" - top_delta="0" - width="180" /> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left_pad="6" - mouse_opaque="false" - name="text_box2" - top_delta="1" - width="200"> - kbps - </text> - <check_box - control_name="ConnectionPortEnabled" - height="16" - label="Custom port" - layout="topleft" - left="77" - name="connection_port_enabled" - top_pad="20" - width="256"> - <check_box.commit_callback - function="Notification.Show" - parameter="ChangeConnectionPort" /> - </check_box> - <spinner - control_name="BrowserProxyPort" - enabled_control="BrowserProxyEnabled" - decimal_digits="0" - follows="left|top" - height="23" - increment="1" - initial_value="80" - label="Port number:" - label_width="75" - layout="topleft" - left_delta="160" - max_val="12000" - min_val="10" - name="web_proxy_port" - top_delta="-2" - width="140" /> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="80" - mouse_opaque="false" - name="cache_size_label_l" - top_pad="20" - width="200"> - Cache size - </text> - <slider - can_edit_text="true" - control_name="CacheSize" - decimal_digits="0" - follows="left|top" - height="15" - increment="16" - initial_value="512" - layout="topleft" - left_delta="150" - max_val="1024" - min_val="32" - name="cache_size" - top_delta="-2" - width="180" /> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left_pad="6" - mouse_opaque="false" - name="text_box5" - top_delta="1" - width="40"> - MB - </text> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="80" - name="Cache location" - top_delta="20" - width="300"> - Cache location: - </text> - <line_editor - control_name="CacheLocationTopFolder" - border_style="line" - border_thickness="1" - enabled="false" - follows="left|top" - font="SansSerif" - handle_edit_keys_directly="true" - height="23" - layout="topleft" - left="80" - max_length="4096" - name="cache_location" - top_pad="5" - width="205" /> - <button - follows="left|top" - height="23" - label="Browse" - label_selected="Browse" - layout="topleft" - left_pad="5" - name="set_cache" - top_delta="-1" - width="100"> - <button.commit_callback - function="Pref.SetCache" /> - </button> - <button - follows="left|top" - height="23" - label="Reset" - label_selected="Reset" - layout="topleft" - left_pad="3" - name="reset_cache" - top_delta="0" - width="100"> - <button.commit_callback - function="Pref.ResetCache" /> - </button> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="30" - name="Web:" - top_pad="5" - width="300"> - Web: - </text> - <radio_group - control_name="UseExternalBrowser" - draw_border="false" - follows="top|left" - height="40" - layout="topleft" - left_delta="50" - name="use_external_browser" - top_pad="4" - width="480"> - <radio_item - height="20" - label="Use built-in browser" - layout="topleft" - left="0" - name="internal" - value="0" - tool_tip="Use the built-in web browser for help, web links, etc. This browser opens as a new window inside [APP_NAME]." - top="0" - width="480" /> - <radio_item - height="20" - label="Use my browser (IE, Firefox)" - layout="topleft" - left_delta="0" - name="external" - value="1" - tool_tip="Use the default system web browser for help, web links, etc. Not recommended if running full screen." - top_delta="20" - width="480" /> - </radio_group> - - <check_box - top_delta="4" - enabled="true" - follows="left|top" - height="16" - initial_value="false" - label="Web proxy" - left_delta="0" - mouse_opaque="true" - name="web_proxy_enabled" - radio_style="false" - width="400" - top_pad="5"/> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left_delta="1" - name="Proxy location" - top_delta="20" - width="300"> - Proxy location: - </text> - <line_editor - control_name="BrowserProxyAddress" - enabled_control="BrowserProxyEnabled" - follows="left|top" - font="SansSerif" - height="23" - layout="topleft" - left_delta="0" - name="web_proxy_editor" - tool_tip="The name or IP address of the proxy you would like to use" - top_pad="4" - width="200" /> - <button - follows="left|top" - height="23" - enabled="false" - label="Browse" - label_selected="Browse" - layout="topleft" - left_pad="5" - name="set_proxy" - top_pad="-21" - width="100"> - <button.commit_callback - function="Pref.SetCache" /> - </button> - </panel> + Network: + </text> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_delta="50" + name="Maximum bandwidth" + mouse_opaque="false" + top_pad="10" + width="200"> + Maximum bandwidth + </text> + <slider + can_edit_text="true" + control_name="ThrottleBandwidthKBPS" + decimal_digits="0" + follows="left|top" + height="15" + increment="100" + initial_value="500" + layout="topleft" + left_delta="150" + max_val="10000" + min_val="100" + name="max_bandwidth" + top_delta="0" + width="180" /> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_pad="6" + mouse_opaque="false" + name="text_box2" + top_delta="1" + width="200"> + kbps + </text> + <check_box + control_name="ConnectionPortEnabled" + height="16" + label="Custom port" + layout="topleft" + left="77" + name="connection_port_enabled" + top_pad="20" + width="256"> + <check_box.commit_callback + function="Notification.Show" + parameter="ChangeConnectionPort" /> + </check_box> + <spinner + control_name="ConnectionPort" + enabled_control="ConnectionPortEnabled" + decimal_digits="0" + follows="left|top" + height="23" + increment="1" + initial_value="13000" + label="Port number:" + label_width="75" + layout="topleft" + left_delta="160" + max_val="13050" + min_val="13000" + name="connection_port" + top_delta="-2" + width="140" /> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left="80" + mouse_opaque="false" + name="cache_size_label_l" + top_pad="20" + width="200"> + Cache size + </text> + <slider + can_edit_text="true" + control_name="CacheSize" + decimal_digits="0" + follows="left|top" + height="15" + increment="16" + initial_value="512" + layout="topleft" + left_delta="150" + max_val="1024" + min_val="32" + name="cache_size" + top_delta="-2" + width="180" /> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_pad="6" + mouse_opaque="false" + name="text_box5" + top_delta="1" + width="40"> + MB + </text> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left="80" + name="Cache location" + top_delta="20" + width="300"> + Cache location: + </text> + <line_editor + control_name="CacheLocationTopFolder" + border_style="line" + border_thickness="1" + enabled="false" + follows="left|top" + font="SansSerif" + handle_edit_keys_directly="true" + height="23" + layout="topleft" + left="80" + max_length="4096" + name="cache_location" + top_pad="5" + width="205" /> + <button + follows="left|top" + height="23" + label="Browse" + label_selected="Browse" + layout="topleft" + left_pad="5" + name="set_cache" + top_delta="-1" + width="100"> + <button.commit_callback + function="Pref.SetCache" /> + </button> + <button + follows="left|top" + height="23" + label="Reset" + label_selected="Reset" + layout="topleft" + left_pad="3" + name="reset_cache" + top_delta="0" + width="100"> + <button.commit_callback + function="Pref.ResetCache" /> + </button> + + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left="30" + name="Web:" + top_pad="5" + width="300"> + Web: + </text> + <radio_group + control_name="UseExternalBrowser" + draw_border="false" + follows="top|left" + height="40" + layout="topleft" + left_delta="50" + name="use_external_browser" + top_pad="4" + width="480"> + <radio_item + height="20" + label="Use built-in browser" + layout="topleft" + left="0" + name="internal" + value="0" + tool_tip="Use the built-in web browser for help, web links, etc. This browser opens as a new window inside [APP_NAME]." + top="0" + width="480" /> + <radio_item + height="20" + label="Use my browser (IE, Firefox)" + layout="topleft" + left_delta="0" + name="external" + value="1" + tool_tip="Use the default system web browser for help, web links, etc. Not recommended if running full screen." + top_delta="20" + width="480" /> + </radio_group> + + <check_box + top_delta="4" + enabled="true" + follows="left|top" + height="16" + initial_value="false" + control_name="BrowserProxyEnabled" + label="Enable Web Proxy" + left_delta="0" + mouse_opaque="true" + name="web_proxy_enabled" + radio_style="false" + width="400" top_pad="5"/> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_delta="1" + name="Proxy location" + top_delta="20" + width="300"> + Proxy location: + </text> + <line_editor + control_name="BrowserProxyAddress" + enabled_control="BrowserProxyEnabled" + follows="left|top" + font="SansSerif" + height="23" + layout="topleft" + left_delta="0" + name="web_proxy_editor" + tool_tip="The name or IP address of the proxy you would like to use" + top_pad="4" + width="200" /> + <spinner + control_name="BrowserProxyPort" + enabled_control="BrowserProxyEnabled" + decimal_digits="0" + follows="left|top" + height="23" + increment="1" + initial_value="80" + label="Port number:" + label_width="75" + layout="topleft" + left_delta="230" + max_val="12000" + min_val="10" + name="web_proxy_port" + top_delta="0" + width="140" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml index 2b907ed251..7c584ba2c8 100644 --- a/indra/newview/skins/default/xui/en/panel_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_profile.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel follows="all" - height="535" + height="540" label="Profile" layout="topleft" left="0" @@ -66,6 +66,7 @@ layout="topleft" follows="left|top|right" height="505" + min_height="505" name="profile_scroll_panel" top="0" left="0" @@ -108,10 +109,10 @@ textbox.max_length="512" name="sl_description_edit" top_pad="-3" - width="185" + width="180" expanded_bg_visible="true" expanded_bg_color="DkGray"> - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra orci et justo sagittis aliquet.Nullamma lesuada mauris sit amet ipsum. adipiscing elit. Ae nean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. </expandable_text> </panel> <panel @@ -151,7 +152,7 @@ textbox.max_length="512" name="fl_description_edit" top_pad="-3" - width="185" + width="180" expanded_bg_visible="true" expanded_bg_color="DkGray"> Lorem ipsum dolor sit amet, consectetur adlkjpiscing elit moose moose. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet. adipiscing elit. Aenean rigviverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet sorbet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. @@ -284,10 +285,10 @@ </layout_panel> <layout_panel follows="bottom|left" - height="28" + height="30" layout="topleft" name="profile_buttons_panel" - auto_resize="false" + auto_resize="false" width="313"> <button follows="bottom|left" @@ -355,7 +356,7 @@ </layout_panel> <layout_panel follows="bottom|left" - height="28" + height="30" layout="topleft" name="profile_me_buttons_panel" visible="false" @@ -364,7 +365,7 @@ follows="bottom|right" height="23" left="20" - top="0" + top="0" label="Edit Profile" name="edit_profile_btn" tool_tip="Edit your personal information" @@ -378,6 +379,6 @@ tool_tip="Create/edit your appearance: physical data, clothes and etc." width="130" /> </layout_panel> - + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml index c51447eaf0..d46e1f9852 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_view.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml @@ -60,7 +60,7 @@ tab_min_width="80" tab_height="30" tab_position="top" - top_pad="10" + top_pad="5" width="313"> <panel class="panel_profile" diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml index 328d521636..63f08a4250 100644 --- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml +++ b/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml @@ -4,13 +4,13 @@ name="im_adhoc_chiclet" show_speaker="false" width="25"> - <chiclet_im_adhoc.chiclet_button - height="23" - image_selected="PushButton_Selected" + <chiclet_im_adhoc.chiclet_button + height="25" + image_selected="PushButton_On" image_unselected="PushButton_Off" name="chiclet_button" tab_stop="false" - width="25"/> + width="25" /> <chiclet_im_adhoc.speaker auto_update="true" draw_border="false" @@ -20,15 +20,15 @@ visible="false" width="20" /> <chiclet_im_adhoc.avatar_icon - bottom="2" + bottom="3" follows="left|top|bottom" - height="19" - left="3" + height="20" + left="2" mouse_opaque="true" name="adhoc_icon" - width="18" /> + width="21" /> <chiclet_im_adhoc.unread_notifications - font_halign="center" + halign="center" height="23" left="25" mouse_opaque="false" diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml index 60658899ee..372a89cbc7 100644 --- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml +++ b/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml @@ -4,33 +4,33 @@ name="im_group_chiclet" show_speaker="false" width="25"> - <chiclet_im_group.chiclet_button - height="23" - image_selected="PushButton_Selected" + <chiclet_im_group.chiclet_button + height="25" + image_selected="PushButton_On" image_unselected="PushButton_Off" name="chiclet_button" tab_stop="false" - width="25"/> + width="25" /> <chiclet_im_group.speaker auto_update="true" draw_border="false" - height="23" + height="25" left="25" name="speaker" visible="false" width="20" /> <chiclet_im_group.group_icon - bottom="2" + bottom="3" default_icon="Generic_Group" follows="left|top|bottom" - height="18" - left="3" + height="20" + left="2" mouse_opaque="false" name="group_icon" - width="19" /> + width="21" /> <chiclet_im_group.unread_notifications height="23" - font_halign="center" + halign="center" left="25" mouse_opaque="false" name="unread" diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml index b5b8f0d07a..99807d4717 100644 --- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml +++ b/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml @@ -4,9 +4,9 @@ name="im_p2p_chiclet" show_speaker="false" width="25"> - <chiclet_im_p2p.chiclet_button - height="23" - image_selected="PushButton_Selected" + <chiclet_im_p2p.chiclet_button + height="25" + image_selected="PushButton_On" image_unselected="PushButton_Off" name="chiclet_button" tab_stop="false" @@ -18,18 +18,18 @@ left="25" name="speaker" visible="false" - width="20"/> + width="20" /> <chiclet_im_p2p.avatar_icon - bottom="2" + bottom="3" follows="left|top|bottom" - height="18" - left="3" + height="20" + left="2" mouse_opaque="false" name="avatar_icon" - width="19" /> + width="21" /> <chiclet_im_p2p.unread_notifications height="23" - font_halign="center" + halign="center" left="25" mouse_opaque="false" name="unread" @@ -45,4 +45,4 @@ name="new_message_icon" visible="false" width="14" /> -</chiclet_im_p2p>
\ No newline at end of file +</chiclet_im_p2p> diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_offer.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_offer.xml index 1bf9bc9e71..4bc295f747 100644 --- a/indra/newview/skins/default/xui/en/widgets/chiclet_offer.xml +++ b/indra/newview/skins/default/xui/en/widgets/chiclet_offer.xml @@ -3,22 +3,22 @@ height="23" name="offer_chiclet" width="25"> - <chiclet_offer.chiclet_button - height="23" - image_selected="PushButton_Selected" + <chiclet_offer.chiclet_button + height="25" + image_selected="PushButton_On" image_unselected="PushButton_Off" name="chiclet_button" tab_stop="false" - width="25"/> + width="25" /> <chiclet_offer.icon - bottom="2" + bottom="3" default_icon="Generic_Object_Small" follows="all" - height="18" - left="3" + height="20" + left="2" mouse_opaque="false" name="chiclet_icon" - width="19" /> + width="21" /> <chiclet_offer.new_message_icon bottom="11" height="14" diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml index f3207ddeae..5f51f4afd9 100644 --- a/indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml +++ b/indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <chiclet_panel - name="chiclet_panel" + name="chiclet_panel" chiclet_padding="3" scrolling_offset="40" - scroll_button_hpad="5" + scroll_button_hpad="0" scroll_ratio="10" min_width="180" />
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_script.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_script.xml index 38d9904d13..db6a9434df 100644 --- a/indra/newview/skins/default/xui/en/widgets/chiclet_script.xml +++ b/indra/newview/skins/default/xui/en/widgets/chiclet_script.xml @@ -3,22 +3,22 @@ height="23" name="script_chiclet" width="25"> - <chiclet_script.chiclet_button - height="23" - image_selected="PushButton_Selected" + <chiclet_script.chiclet_button + height="25" + image_selected="PushButton_On" image_unselected="PushButton_Off" name="chiclet_button" tab_stop="false" width="25"/> <chiclet_script.icon - bottom="2" + bottom="3" follows="all" height="18" image_name="Generic_Object_Small" - left="3" + left="2" mouse_opaque="false" name="chiclet_icon" - width="19"/> + width="21"/> <chiclet_script.new_message_icon bottom="11" height="14" diff --git a/indra/newview/skins/default/xui/en/widgets/color_swatch.xml b/indra/newview/skins/default/xui/en/widgets/color_swatch.xml index bda88857ae..dfd301a770 100644 --- a/indra/newview/skins/default/xui/en/widgets/color_swatch.xml +++ b/indra/newview/skins/default/xui/en/widgets/color_swatch.xml @@ -3,6 +3,6 @@ border_color="ColorSwatchBorderColor" name="color_swatch"> <color_swatch.caption_text name="caption" - font="SansSerifSmall" + halign="center" follows="left|right|bottom"/> </color_swatch> diff --git a/indra/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml index 5545ab29e0..e8e38316f9 100644 --- a/indra/newview/skins/default/xui/es/floater_about.xml +++ b/indra/newview/skins/default/xui/es/floater_about.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_about" title="ACERCA DE [APP_NAME]"> +<floater name="floater_about" title="ACERCA DE [CAPITALIZED_APP_NAME]"> <tab_container name="about_tab"> <panel name="credits_panel"> <text_editor name="credits_editor"> diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml index 33299f4cd4..7d6d736c5e 100644 --- a/indra/newview/skins/default/xui/fr/floater_about.xml +++ b/indra/newview/skins/default/xui/fr/floater_about.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_about" title="À PROPOS DE [APP_NAME]"> +<floater name="floater_about" title="À PROPOS DE [CAPITALIZED_APP_NAME]"> <floater.string name="AboutHeader"> [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2] ([VIEWER_VERSION_3]) [BUILD_DATE] [BUILD_TIME] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] diff --git a/indra/newview/skins/default/xui/fr/panel_edit_profile.xml b/indra/newview/skins/default/xui/fr/panel_edit_profile.xml index b8ab805b13..a4771db91b 100644 --- a/indra/newview/skins/default/xui/fr/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/fr/panel_edit_profile.xml @@ -39,10 +39,10 @@ <line_editor name="homepage_edit" value="http://"/> <check_box label="Afficher dans les résultats de recherche" name="show_in_search_checkbox"/> <text name="title_acc_status_text" value="Mon compte :"/> - <text name="my_account_link" value="Accéder à ma Page d'accueil"/> + <text name="my_account_link" value="[[URL] Accéder à ma Page d'accueil]"/> <text name="acc_status_text" value="Résident. Aucune info de paiement enregistrée."/> <text name="title_partner_text" value="Mon partenaire :"/> - <text name="partner_edit_link" value="[Modifier [URL]]"/> + <text name="partner_edit_link" value="[[URL] Modifier]"/> <panel name="partner_data_panel"> <text name="partner_text" value="[FIRST] [LAST]"/> </panel> diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml index a5aff9d486..f80f810dba 100644 --- a/indra/newview/skins/default/xui/it/floater_about.xml +++ b/indra/newview/skins/default/xui/it/floater_about.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_about" title="INFORMAZIONI SU [APP_NAME]"> +<floater name="floater_about" title="INFORMAZIONI SU [CAPITALIZED_APP_NAME]"> <tab_container name="about_tab"> <panel name="credits_panel"> <text_editor name="credits_editor"> diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml index bab805dbd2..0fa20ab1ac 100644 --- a/indra/newview/skins/default/xui/ja/floater_about.xml +++ b/indra/newview/skins/default/xui/ja/floater_about.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_about" title="[APP_NAME] について"> +<floater name="floater_about" title="[CAPITALIZED_APP_NAME] について"> <floater.string name="AboutHeader"> [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2] ([VIEWER_VERSION_3]) [BUILD_DATE] [BUILD_TIME] ([CHANNEL]) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] diff --git a/indra/newview/skins/default/xui/ja/panel_edit_profile.xml b/indra/newview/skins/default/xui/ja/panel_edit_profile.xml index 8af0802ac2..b232a8db61 100644 --- a/indra/newview/skins/default/xui/ja/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/ja/panel_edit_profile.xml @@ -39,7 +39,7 @@ <line_editor name="homepage_edit" value="http://"/> <check_box label="検索結果に表示" name="show_in_search_checkbox"/> <text name="title_acc_status_text" value="マイアカウント:"/> - <text name="my_account_link" value="マイアカウントに移動"/> + <text name="my_account_link" value="[[URL] マイアカウントに移動]"/> <text name="acc_status_text" value="住人。 支払情報未登録。"/> <text name="title_partner_text" value="マイパートナー:"/> <text name="partner_edit_link" value="[[URL] 編集]"/> diff --git a/indra/newview/skins/default/xui/nl/floater_about.xml b/indra/newview/skins/default/xui/nl/floater_about.xml index 0c57a22be1..10c30eb361 100644 --- a/indra/newview/skins/default/xui/nl/floater_about.xml +++ b/indra/newview/skins/default/xui/nl/floater_about.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_about" title="OVER [APP_NAME]"> +<floater name="floater_about" title="OVER [CAPITALIZED_APP_NAME]"> <tab_container name="about_tab"> <panel name="credits_panel"> <text_editor name="credits_editor"> diff --git a/indra/newview/skins/default/xui/pl/floater_about.xml b/indra/newview/skins/default/xui/pl/floater_about.xml index 0f100b9d83..f59630edc7 100755 --- a/indra/newview/skins/default/xui/pl/floater_about.xml +++ b/indra/newview/skins/default/xui/pl/floater_about.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater name="floater_about" title="O [APP_NAME]"> +<floater name="floater_about" title="O [CAPITALIZED_APP_NAME]"> <tab_container name="about_tab"> <panel name="credits_panel"> <text_editor name="credits_editor"> diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml index 9c19b12893..704e2f4107 100644 --- a/indra/newview/skins/default/xui/pt/floater_about.xml +++ b/indra/newview/skins/default/xui/pt/floater_about.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_about" title="SOBRE O [APP_NAME]"> +<floater name="floater_about" title="SOBRE O [CAPITALIZED_APP_NAME]"> <tab_container name="about_tab"> <panel name="credits_panel"> <text_editor name="credits_editor"> |