From 1a8008ea150d1eb9a8f4036988ef971fb1901cb3 Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Thu, 14 Jan 2010 14:44:43 -0800 Subject: Backed out changeset f34a69c2af56 (this backs-out my backout, now that I'm happy the original merge works okay :)) --- indra/llcommon/llfasttimer.h | 163 +++++++------ indra/llplugin/llpluginclassmedia.cpp | 30 ++- indra/llplugin/llpluginclassmedia.h | 12 + indra/llui/llfloater.cpp | 46 ++-- indra/llui/llmenugl.cpp | 2 +- indra/llui/lltexteditor.cpp | 3 +- indra/media_plugins/webkit/media_plugin_webkit.cpp | 1 + indra/newview/CMakeLists.txt | 8 +- indra/newview/app_settings/settings.xml | 13 +- .../darwin/fix_application_icon_position.sh | 14 ++ indra/newview/llagent.cpp | 9 +- indra/newview/llagent.h | 1 + indra/newview/llavatarlist.cpp | 7 +- indra/newview/llavatarlistitem.cpp | 251 ++++++++++++-------- indra/newview/llavatarlistitem.h | 71 ++++-- indra/newview/llbottomtray.cpp | 17 +- indra/newview/llcallfloater.cpp | 12 +- indra/newview/llchathistory.cpp | 49 ++-- indra/newview/llfloaterabout.cpp | 2 +- indra/newview/llfloaterchat.cpp | 15 +- indra/newview/llfloatergesture.cpp | 2 +- indra/newview/llfloatergroups.cpp | 9 +- indra/newview/llfloaterland.cpp | 7 +- indra/newview/llfloaterland.h | 1 - indra/newview/llfloaterpreference.cpp | 2 +- indra/newview/llfloaterregioninfo.cpp | 5 + indra/newview/llgesturemgr.cpp | 10 + indra/newview/llgesturemgr.h | 2 + indra/newview/llgroupactions.cpp | 10 +- indra/newview/llimfloater.cpp | 86 ++++--- indra/newview/llimfloater.h | 5 +- indra/newview/llimfloatercontainer.cpp | 11 + indra/newview/llimfloatercontainer.h | 6 +- indra/newview/llimview.cpp | 19 +- indra/newview/llimview.h | 5 + indra/newview/llinspectavatar.cpp | 1 + indra/newview/llinspecttoast.cpp | 122 ++++++++++ indra/newview/llinspecttoast.h | 40 ++++ indra/newview/llinventorymodel.cpp | 8 +- indra/newview/llinventoryobserver.cpp | 35 ++- indra/newview/llmediactrl.cpp | 45 ++-- indra/newview/llmediactrl.h | 1 - indra/newview/llnamebox.cpp | 24 +- indra/newview/llnamebox.h | 5 + indra/newview/llnearbychat.cpp | 22 +- indra/newview/llnearbychatbar.cpp | 252 +++++++++++++++----- indra/newview/llnearbychatbar.h | 47 ++-- indra/newview/llnearbychathandler.cpp | 25 +- indra/newview/lloutputmonitorctrl.cpp | 65 +++++- indra/newview/lloutputmonitorctrl.h | 29 ++- indra/newview/llpanelavatar.cpp | 18 +- indra/newview/llpanelgroup.cpp | 55 ++++- indra/newview/llpanelgroup.h | 4 + indra/newview/llpanelgroupgeneral.cpp | 11 +- indra/newview/llpanelgrouproles.cpp | 61 ++--- indra/newview/llpanelgrouproles.h | 13 +- indra/newview/llpanelimcontrolpanel.cpp | 2 +- indra/newview/llpanelpeople.cpp | 8 +- indra/newview/llpanelpick.cpp | 80 ++++--- indra/newview/llpanelpick.h | 18 +- indra/newview/llpanelplaces.h | 4 + indra/newview/llpanelteleporthistory.cpp | 2 +- indra/newview/llpanelvolumepulldown.cpp | 154 +++++++++++++ indra/newview/llpanelvolumepulldown.h | 64 ++++++ indra/newview/llparticipantlist.cpp | 8 +- indra/newview/llscreenchannel.cpp | 149 +++--------- indra/newview/llscreenchannel.h | 19 +- indra/newview/llspeakers.cpp | 5 + indra/newview/llspeakers.h | 2 + indra/newview/llspeakingindicatormanager.cpp | 254 +++++++++++++++++++++ indra/newview/llspeakingindicatormanager.h | 67 ++++++ indra/newview/llstatusbar.cpp | 19 +- indra/newview/llstatusbar.h | 2 +- indra/newview/llsyswellitem.cpp | 3 +- indra/newview/llsyswellwindow.cpp | 3 +- indra/newview/llsyswellwindow.h | 3 + indra/newview/llteleporthistorystorage.cpp | 7 - indra/newview/lltoastnotifypanel.cpp | 4 +- indra/newview/llviewerdisplay.cpp | 20 +- indra/newview/llviewerfloaterreg.cpp | 5 +- indra/newview/llviewermessage.cpp | 56 ++--- indra/newview/llviewerwindow.cpp | 34 +-- indra/newview/llvoiceclient.cpp | 11 + indra/newview/llvoiceclient.h | 1 + .../default/textures/bottomtray/Unread_Chiclet.png | Bin 250 -> 328 bytes .../default/textures/bottomtray/WellButton_Lit.png | Bin 553 -> 490 bytes .../bottomtray/WellButton_Lit_Selected.png | Bin 687 -> 302 bytes indra/newview/skins/default/textures/textures.xml | 28 +-- .../skins/default/xui/de/floater_buy_currency.xml | 2 +- .../skins/default/xui/de/floater_help_browser.xml | 4 +- indra/newview/skins/default/xui/de/strings.xml | 72 +++--- .../newview/skins/default/xui/en/floater_about.xml | 2 +- .../skins/default/xui/en/floater_about_land.xml | 8 +- .../skins/default/xui/en/floater_buy_currency.xml | 4 +- .../skins/default/xui/en/floater_customize.xml | 120 +++++----- .../skins/default/xui/en/floater_god_tools.xml | 2 +- indra/newview/skins/default/xui/en/floater_im.xml | 2 +- .../skins/default/xui/en/floater_nearby_chat.xml | 4 +- .../skins/default/xui/en/floater_report_abuse.xml | 4 +- .../skins/default/xui/en/floater_select_key.xml | 8 +- .../skins/default/xui/en/floater_top_objects.xml | 20 +- indra/newview/skins/default/xui/en/floater_tos.xml | 6 +- .../default/xui/en/floater_voice_controls.xml | 143 +++++------- .../newview/skins/default/xui/en/inspect_toast.xml | 19 ++ indra/newview/skins/default/xui/en/menu_viewer.xml | 36 +-- .../newview/skins/default/xui/en/notifications.xml | 33 ++- .../default/xui/en/panel_adhoc_control_panel.xml | 17 +- .../default/xui/en/panel_avatar_list_item.xml | 7 +- .../default/xui/en/panel_block_list_sidetray.xml | 6 +- .../skins/default/xui/en/panel_bottomtray.xml | 45 ++-- .../skins/default/xui/en/panel_edit_pick.xml | 32 ++- .../skins/default/xui/en/panel_edit_profile.xml | 3 +- .../newview/skins/default/xui/en/panel_friends.xml | 2 +- .../default/xui/en/panel_group_control_panel.xml | 20 +- .../default/xui/en/panel_group_info_sidetray.xml | 18 +- .../skins/default/xui/en/panel_group_invite.xml | 14 +- .../skins/default/xui/en/panel_group_list_item.xml | 1 + .../skins/default/xui/en/panel_group_notices.xml | 1 + .../skins/default/xui/en/panel_group_roles.xml | 55 +++-- indra/newview/skins/default/xui/en/panel_login.xml | 1 + .../xui/en/panel_media_settings_general.xml | 5 +- .../skins/default/xui/en/panel_my_profile.xml | 20 +- .../skins/default/xui/en/panel_navigation_bar.xml | 4 +- .../skins/default/xui/en/panel_nearby_chat_bar.xml | 4 +- indra/newview/skins/default/xui/en/panel_notes.xml | 6 +- .../newview/skins/default/xui/en/panel_people.xml | 10 +- .../skins/default/xui/en/panel_pick_info.xml | 33 +-- .../default/xui/en/panel_preferences_advanced.xml | 1 - .../default/xui/en/panel_preferences_general.xml | 15 +- .../default/xui/en/panel_preferences_graphics1.xml | 4 +- .../default/xui/en/panel_prim_media_controls.xml | 1 + .../newview/skins/default/xui/en/panel_profile.xml | 26 ++- .../skins/default/xui/en/panel_region_covenant.xml | 10 +- .../skins/default/xui/en/panel_region_estate.xml | 12 +- .../skins/default/xui/en/panel_region_texture.xml | 4 +- .../skins/default/xui/en/panel_status_bar.xml | 36 ++- .../skins/default/xui/en/panel_volume_pulldown.xml | 55 +++++ .../skins/default/xui/en/sidepanel_task_info.xml | 36 +-- indra/newview/skins/default/xui/en/strings.xml | 16 +- .../default/xui/en/widgets/chiclet_im_adhoc.xml | 22 +- .../default/xui/en/widgets/chiclet_im_group.xml | 23 +- .../default/xui/en/widgets/chiclet_im_p2p.xml | 18 +- .../skins/default/xui/en/widgets/chiclet_offer.xml | 14 +- .../default/xui/en/widgets/chiclet_script.xml | 14 +- .../default/xui/en/widgets/gesture_combo_box.xml | 30 --- .../default/xui/en/widgets/gesture_combo_list.xml | 21 ++ .../default/xui/en/widgets/location_input.xml | 18 +- .../skins/default/xui/es/floater_buy_currency.xml | 3 + .../skins/default/xui/fr/floater_buy_currency.xml | 4 +- .../skins/default/xui/fr/floater_help_browser.xml | 4 +- indra/newview/skins/default/xui/fr/strings.xml | 74 +++--- .../skins/default/xui/it/floater_buy_currency.xml | 9 +- .../skins/default/xui/ja/floater_buy_currency.xml | 2 +- indra/newview/skins/default/xui/ja/strings.xml | 48 ++-- .../skins/default/xui/pt/floater_buy_currency.xml | 3 + install.xml | 12 +- 156 files changed, 2689 insertions(+), 1460 deletions(-) create mode 100644 indra/newview/installers/darwin/fix_application_icon_position.sh create mode 100644 indra/newview/llinspecttoast.cpp create mode 100644 indra/newview/llinspecttoast.h create mode 100644 indra/newview/llpanelvolumepulldown.cpp create mode 100644 indra/newview/llpanelvolumepulldown.h create mode 100644 indra/newview/llspeakingindicatormanager.cpp create mode 100644 indra/newview/llspeakingindicatormanager.h create mode 100644 indra/newview/skins/default/xui/en/inspect_toast.xml create mode 100644 indra/newview/skins/default/xui/en/panel_volume_pulldown.xml delete mode 100644 indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml create mode 100644 indra/newview/skins/default/xui/en/widgets/gesture_combo_list.xml diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index f5c90291b8..5058a2e772 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -39,40 +39,30 @@ #define TIME_FAST_TIMERS 0 #if LL_WINDOWS - +// because MS has different signatures for these functions in winnt.h +// need to rename them to avoid conflicts +#define _interlockedbittestandset _renamed_interlockedbittestandset +#define _interlockedbittestandreset _renamed_interlockedbittestandreset +#include +#undef _interlockedbittestandset +#undef _interlockedbittestandreset + +#define LL_INLINE __forceinline // shift off lower 8 bits for lower resolution but longer term timing // on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing inline U32 get_cpu_clock_count_32() { - U32 ret_val; - __asm - { - _emit 0x0f - _emit 0x31 - shr eax,8 - shl edx,24 - or eax, edx - mov dword ptr [ret_val], eax - } - return ret_val; + U64 time_stamp = __rdtsc(); + return (U32)(time_stamp >> 8); } // return full timer value, *not* shifted by 8 bits inline U64 get_cpu_clock_count_64() { - U64 ret_val; - __asm - { - _emit 0x0f - _emit 0x31 - mov eax,eax - mov edx,edx - mov dword ptr [ret_val+4], edx - mov dword ptr [ret_val], eax - } - return ret_val; + return __rdtsc(); } - +#else +#define LL_INLINE #endif // LL_WINDOWS #if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__)) @@ -113,10 +103,25 @@ class LLMutex; #include #include "llsd.h" - class LL_COMMON_API LLFastTimer { public: + + class NamedTimer; + + struct LL_COMMON_API FrameState + { + FrameState(NamedTimer* timerp); + + U32 mSelfTimeCounter; + U32 mCalls; + FrameState* mParent; // info for caller timer + FrameState* mLastCaller; // used to bootstrap tree construction + NamedTimer* mTimer; + U16 mActiveCount; // number of timers with this ID active on stack + bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame + }; + // stores a "named" timer instance to be reused via multiple LLFastTimer stack instances class LL_COMMON_API NamedTimer : public LLInstanceTracker @@ -149,24 +154,10 @@ public: static NamedTimer& getRootNamedTimer(); - struct FrameState - { - FrameState(NamedTimer* timerp); - - U32 mSelfTimeCounter; - U32 mCalls; - FrameState* mParent; // info for caller timer - FrameState* mLastCaller; // used to bootstrap tree construction - NamedTimer* mTimer; - U16 mActiveCount; // number of timers with this ID active on stack - bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame - }; - S32 getFrameStateIndex() const { return mFrameStateIndex; } FrameState& getFrameState() const; - private: friend class LLFastTimer; friend class NamedTimerFactory; @@ -185,7 +176,6 @@ public: static void buildHierarchy(); static void resetFrame(); static void reset(); - // // members @@ -207,58 +197,47 @@ public: std::vector mChildren; bool mCollapsed; // don't show children bool mNeedsSorting; // sort children whenever child added - }; // used to statically declare a new named timer class LL_COMMON_API DeclareTimer : public LLInstanceTracker { + friend class LLFastTimer; public: DeclareTimer(const std::string& name, bool open); DeclareTimer(const std::string& name); static void updateCachedPointers(); - // convertable to NamedTimer::FrameState for convenient usage of LLFastTimer(declared_timer) - operator NamedTimer::FrameState&() { return *mFrameState; } private: - NamedTimer& mTimer; - NamedTimer::FrameState* mFrameState; + NamedTimer& mTimer; + FrameState* mFrameState; }; - public: - static LLMutex* sLogLock; - static std::queue sLogQueue; - static BOOL sLog; - static BOOL sMetricLog; - - typedef std::vector info_list_t; - static info_list_t& getFrameStateList(); + LLFastTimer(LLFastTimer::FrameState* state); - enum RootTimerMarker { ROOT }; - LLFastTimer(RootTimerMarker); - - LLFastTimer(NamedTimer::FrameState& timer) - : mFrameState(&timer) + LL_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer) + : mFrameState(timer.mFrameState) { #if TIME_FAST_TIMERS U64 timer_start = get_cpu_clock_count_64(); #endif #if FAST_TIMER_ON - NamedTimer::FrameState* frame_state = &timer; - U32 cur_time = get_cpu_clock_count_32(); - mStartSelfTime = cur_time; - mStartTotalTime = cur_time; + LLFastTimer::FrameState* frame_state = mFrameState; + mStartTime = get_cpu_clock_count_32(); frame_state->mActiveCount++; frame_state->mCalls++; // keep current parent as long as it is active when we are frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0); - mLastTimer = sCurTimer; - sCurTimer = this; + LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData; + mLastTimerData = *cur_timer_data; + cur_timer_data->mCurTimer = this; + cur_timer_data->mFrameState = frame_state; + cur_timer_data->mChildTime = 0; #endif #if TIME_FAST_TIMERS U64 timer_end = get_cpu_clock_count_64(); @@ -266,26 +245,26 @@ public: #endif } - ~LLFastTimer() + LL_INLINE ~LLFastTimer() { #if TIME_FAST_TIMERS U64 timer_start = get_cpu_clock_count_64(); #endif #if FAST_TIMER_ON - NamedTimer::FrameState* frame_state = mFrameState; - U32 cur_time = get_cpu_clock_count_32(); - frame_state->mSelfTimeCounter += cur_time - mStartSelfTime; + LLFastTimer::FrameState* frame_state = mFrameState; + U32 total_time = get_cpu_clock_count_32() - mStartTime; + frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime; frame_state->mActiveCount--; - LLFastTimer* last_timer = mLastTimer; - sCurTimer = last_timer; // store last caller to bootstrap tree creation - frame_state->mLastCaller = last_timer->mFrameState; + // do this in the destructor in case of recursion to get topmost caller + frame_state->mLastCaller = mLastTimerData.mFrameState; // we are only tracking self time, so subtract our total time delta from parents - U32 total_time = cur_time - mStartTotalTime; - last_timer->mStartSelfTime += total_time; + mLastTimerData.mChildTime += total_time; + + LLFastTimer::sCurTimerData = mLastTimerData; #endif #if TIME_FAST_TIMERS U64 timer_end = get_cpu_clock_count_64(); @@ -294,7 +273,20 @@ public: #endif } +public: + static LLMutex* sLogLock; + static std::queue sLogQueue; + static BOOL sLog; + static BOOL sMetricLog; + static bool sPauseHistory; + static bool sResetHistory; + static U64 sTimerCycles; + static U32 sTimerCalls; + typedef std::vector info_list_t; + static info_list_t& getFrameStateList(); + + // call this once a frame to reset timers static void nextFrame(); @@ -312,23 +304,26 @@ public: static void writeLog(std::ostream& os); static const NamedTimer* getTimerByName(const std::string& name); -public: - static bool sPauseHistory; - static bool sResetHistory; - static U64 sTimerCycles; - static U32 sTimerCalls; - + struct CurTimerData + { + LLFastTimer* mCurTimer; + FrameState* mFrameState; + U32 mChildTime; + }; + static CurTimerData sCurTimerData; + private: - static LLFastTimer* sCurTimer; static S32 sCurFrameIndex; static S32 sLastFrameIndex; static U64 sLastFrameTime; static info_list_t* sTimerInfos; - U32 mStartSelfTime; // start time + time of all child timers - U32 mStartTotalTime; // start time + time of all child timers - NamedTimer::FrameState* mFrameState; - LLFastTimer* mLastTimer; + U32 mStartTime; + LLFastTimer::FrameState* mFrameState; + LLFastTimer::CurTimerData mLastTimerData; + }; +typedef class LLFastTimer LLFastTimer; + #endif // LL_LLFASTTIMER_H diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index ed8d10a88c..3d2eaed5c5 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -37,6 +37,8 @@ #include "llpluginclassmedia.h" #include "llpluginmessageclasses.h" +#include "llqtwebkit.h" + static int LOW_PRIORITY_TEXTURE_SIZE_DEFAULT = 256; static int nextPowerOf2( int value ) @@ -124,7 +126,7 @@ void LLPluginClassMedia::reset() mCanPaste = false; mMediaName.clear(); mMediaDescription.clear(); - mBackgroundColor = LLColor4::white; + mBackgroundColor = LLColor4(1.0f, 1.0f, 1.0f, 1.0f); // media_browser class mNavigateURI.clear(); @@ -134,6 +136,9 @@ void LLPluginClassMedia::reset() mHistoryForwardAvailable = false; mStatusText.clear(); mProgressPercent = 0; + mClickURL.clear(); + mClickTarget.clear(); + mClickTargetType = TARGET_NONE; // media_time class mCurrentTime = 0.0f; @@ -669,6 +674,26 @@ void LLPluginClassMedia::paste() sendMessage(message); } +LLPluginClassMedia::ETargetType getTargetTypeFromLLQtWebkit(int target_type) +{ + // convert a LinkTargetType value from llqtwebkit to an ETargetType + // so that we don't expose the llqtwebkit header in viewer code + switch (target_type) + { + case LinkTargetType::LTT_TARGET_NONE: + return LLPluginClassMedia::TARGET_NONE; + + case LinkTargetType::LTT_TARGET_BLANK: + return LLPluginClassMedia::TARGET_BLANK; + + case LinkTargetType::LTT_TARGET_EXTERNAL: + return LLPluginClassMedia::TARGET_EXTERNAL; + + default: + return LLPluginClassMedia::TARGET_OTHER; + } +} + /* virtual */ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) { @@ -921,12 +946,15 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) { mClickURL = message.getValue("uri"); mClickTarget = message.getValue("target"); + U32 target_type = message.getValueU32("target_type"); + mClickTargetType = ::getTargetTypeFromLLQtWebkit(target_type); mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF); } else if(message_name == "click_nofollow") { mClickURL = message.getValue("uri"); mClickTarget.clear(); + mClickTargetType = TARGET_NONE; mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_NOFOLLOW); } else diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index 5a1928ab1d..ebb9099576 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -214,6 +214,17 @@ public: // This is valid after MEDIA_EVENT_CLICK_LINK_HREF std::string getClickTarget() const { return mClickTarget; }; + typedef enum + { + TARGET_NONE, // empty href target string + TARGET_BLANK, // target to open link in user's preferred browser + TARGET_EXTERNAL, // target to open link in external browser + TARGET_OTHER // nonempty and unsupported target type + }ETargetType; + + // This is valid after MEDIA_EVENT_CLICK_LINK_HREF + ETargetType getClickTargetType() const { return mClickTargetType; }; + std::string getMediaName() const { return mMediaName; }; std::string getMediaDescription() const { return mMediaDescription; }; @@ -344,6 +355,7 @@ protected: std::string mLocation; std::string mClickURL; std::string mClickTarget; + ETargetType mClickTargetType; ///////////////////////////////////////// // media_time class diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 845203b420..a17e306325 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -878,9 +878,11 @@ void LLFloater::setSnappedTo(const LLView* snap_view) else { //RN: assume it's a floater as it must be a sibling to our parent floater - LLFloater* floaterp = (LLFloater*)snap_view; - - setSnapTarget(floaterp->getHandle()); + const LLFloater* floaterp = dynamic_cast(snap_view); + if (floaterp) + { + setSnapTarget(floaterp->getHandle()); + } } } @@ -1065,10 +1067,6 @@ void LLFloater::setMinimized(BOOL minimize) reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE ); } - // don't show the help button while minimized - it's - // not very useful when minimized and uses up space - mButtonsEnabled[BUTTON_HELP] = !minimize; - applyTitle (); make_ui_sound("UISndWindowClose"); @@ -1741,14 +1739,32 @@ void LLFloater::updateButtons() S32 button_count = 0; for (S32 i = 0; i < BUTTON_COUNT; i++) { - if(!mButtons[i]) continue; - mButtons[i]->setEnabled(mButtonsEnabled[i]); + if (!mButtons[i]) + { + continue; + } - if (mButtonsEnabled[i] - //*HACK: always render close button for hosted floaters - // so that users don't accidentally hit the button when closing multiple windows - // in the chatterbox - || (i == BUTTON_CLOSE && mButtonScale != 1.f)) + bool enabled = mButtonsEnabled[i]; + if (i == BUTTON_HELP) + { + // don't show the help button if the floater is minimized + // or if it is a tear-off hosted floater + if (isMinimized() || mButtonsEnabled[BUTTON_TEAR_OFF]) + { + enabled = false; + } + } + if (i == BUTTON_CLOSE && mButtonScale != 1.f) + { + //*HACK: always render close button for hosted floaters so + //that users don't accidentally hit the button when + //closing multiple windows in the chatterbox + enabled = true; + } + + mButtons[i]->setEnabled(enabled); + + if (enabled) { button_count++; @@ -1775,7 +1791,7 @@ void LLFloater::updateButtons() // the restore button should have a tab stop so that it takes action when you Ctrl-Tab to a minimized floater mButtons[i]->setTabStop(i == BUTTON_RESTORE); } - else if (mButtons[i]) + else { mButtons[i]->setVisible(FALSE); } diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index bd67949c2a..21f3f15739 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -2966,7 +2966,7 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) LLUI::getMousePositionLocal(menu->getParent(), &mouse_x, &mouse_y); LLMenuHolderGL::sContextMenuSpawnPos.set(mouse_x,mouse_y); - const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect(); + const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getRect(); const S32 HPAD = 2; LLRect rect = menu->getRect(); diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index e8fc9475a5..f2c3879a6c 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -308,7 +308,8 @@ LLTextEditor::~LLTextEditor() // Scrollbar is deleted by LLView std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); - delete mContextMenu; + // context menu is owned by menu holder, not us + //delete mContextMenu; } //////////////////////////////////////////////////////////// diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp index a0336f6156..084cdd9561 100644 --- a/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -429,6 +429,7 @@ private: LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href"); message.setValue("uri", event.getStringValue()); message.setValue("target", event.getStringValue2()); + message.setValueU32("target_type", event.getLinkType()); sendMessage(message); } diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 32761dbf27..5b4edefbc1 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -218,7 +218,6 @@ set(viewer_SOURCE_FILES llfloaterurldisplay.cpp llfloaterurlentry.cpp llfloatervoicedevicesettings.cpp - llfloatervolumepulldown.cpp llfloaterwater.cpp llfloaterwhitelistentry.cpp llfloaterwindlight.cpp @@ -256,6 +255,7 @@ set(viewer_SOURCE_FILES llinspectgroup.cpp llinspectobject.cpp llinspectremoteobject.cpp + llinspecttoast.cpp llinventorybridge.cpp llinventoryclipboard.cpp llinventoryfilter.cpp @@ -355,6 +355,7 @@ set(viewer_SOURCE_FILES llpanelshower.cpp llpanelteleporthistory.cpp llpanelvolume.cpp + llpanelvolumepulldown.cpp llparcelselection.cpp llparticipantlist.cpp llpatchvertexarray.cpp @@ -393,6 +394,7 @@ set(viewer_SOURCE_FILES llspatialpartition.cpp llspeakbutton.cpp llspeakers.cpp + llspeakingindicatormanager.cpp llsplitbutton.cpp llsprite.cpp llstartup.cpp @@ -765,6 +767,7 @@ set(viewer_HEADER_FILES llinspectgroup.h llinspectobject.h llinspectremoteobject.h + llinspecttoast.h llinventorybridge.h llinventoryclipboard.h llinventoryfilter.h @@ -860,6 +863,7 @@ set(viewer_HEADER_FILES llpanelshower.h llpanelteleporthistory.h llpanelvolume.h + llpanelvolumepulldown.h llparcelselection.h llparticipantlist.h llpatchvertexarray.h @@ -900,6 +904,7 @@ set(viewer_HEADER_FILES llspatialpartition.h llspeakbutton.h llspeakers.h + llspeakingindicatormanager.h llsplitbutton.h llsprite.h llstartup.h @@ -1770,6 +1775,7 @@ if (INSTALL) endif (INSTALL) if (LL_TESTS) +else (LL_TESTS) # To add a viewer unit test, just add the test .cpp file below # This creates a separate test project per file listed. include(LLAddBuildTest) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 4bfc6f9e4f..db759f052a 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1141,7 +1141,18 @@ Persist 1 Type - Boolean + S32 + Value + 5 + + CallFloaterMaxItems + + Comment + Max number of visible participants in voice controls window + Persist + 1 + Type + S32 Value 1 diff --git a/indra/newview/installers/darwin/fix_application_icon_position.sh b/indra/newview/installers/darwin/fix_application_icon_position.sh new file mode 100644 index 0000000000..a0b72a89f2 --- /dev/null +++ b/indra/newview/installers/darwin/fix_application_icon_position.sh @@ -0,0 +1,14 @@ +# just run this script each time after you change the installer's name to fix the icon misalignment +#!/bin/bash +cp -r ./../../../build-darwin-i386/newview/*.dmg ~/Desktop/TempBuild.dmg +hdid ~/Desktop/TempBuild.dmg +open -a finder /Volumes/Second\ Life\ Installer +osascript dmg-cleanup.applescript +cp /Volumes/Second\ Life\ Installer/.DS_Store ~/Desktop/_DS_Store +chflags nohidden ~/Desktop/_DS_Store +cp ~/Desktop/_DS_Store ./firstlook-dmg/_DS_Store +cp ~/Desktop/_DS_Store ./publicnightly-dmg/_DS_Store +cp ~/Desktop/_DS_Store ./release-dmg/_DS_Store +cp ~/Desktop/_DS_Store ./releasecandidate-dmg/_DS_Store +umount /Volumes/Second\ Life\ Installer/ +rm ~/Desktop/_DS_Store ~/Desktop/TempBuild.dmg diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 5e2e374df6..5ea253709c 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -514,6 +514,8 @@ void LLAgent::resetView(BOOL reset_camera, BOOL change_camera) } setFocusOnAvatar(TRUE, ANIMATE); + + mCameraFOVZoomFactor = 0.f; } mHUDTargetZoom = 1.f; @@ -3584,7 +3586,7 @@ F32 LLAgent::calcCameraFOVZoomFactor() { return 0.f; } - else if (mFocusObject.notNull() && !mFocusObject->isAvatar()) + else if (mFocusObject.notNull() && !mFocusObject->isAvatar() && !mFocusOnAvatar) { // don't FOV zoom on mostly transparent objects LLVector3 focus_offset = mFocusObjectOffset; @@ -5157,6 +5159,11 @@ BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOO return FALSE; } +BOOL LLAgent::canJoinGroups() const +{ + return mGroups.count() < MAX_AGENT_GROUPS; +} + LLQuaternion LLAgent::getHeadRotation() { if (mAvatarObject.isNull() || !mAvatarObject->mPelvisp || !mAvatarObject->mHeadp) diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 2e95dc72be..beede7fbe3 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -972,6 +972,7 @@ public: BOOL setGroupContribution(const LLUUID& group_id, S32 contribution); BOOL setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOOL list_in_profile); const std::string &getGroupName() const { return mGroupName; } + BOOL canJoinGroups() const; private: std::string mGroupName; LLUUID mGroupID; diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 5df73a994e..19e9e52ddf 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -82,7 +82,7 @@ void LLAvatarList::setSpeakingIndicatorsVisible(bool visible) getItems(items); for( std::vector::const_iterator it = items.begin(); it != items.end(); it++) { - static_cast(*it)->setSpeakingIndicatorVisible(mShowSpeakingIndicator); + static_cast(*it)->showSpeakingIndicator(mShowSpeakingIndicator); } } @@ -323,18 +323,15 @@ boost::signals2::connection LLAvatarList::setRefreshCompleteCallback(const commi void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_online, EAddPosition pos) { LLAvatarListItem* item = new LLAvatarListItem(); - item->showInfoBtn(true); - item->showSpeakingIndicator(true); item->setName(name); item->setAvatarId(id, mIgnoreOnlineStatus); item->setOnline(mIgnoreOnlineStatus ? true : is_online); item->showLastInteractionTime(mShowLastInteractionTime); - item->childSetVisible("info_btn", false); item->setAvatarIconVisible(mShowIcons); item->setShowInfoBtn(mShowInfoBtn); item->setShowProfileBtn(mShowProfileBtn); - item->setSpeakingIndicatorVisible(mShowSpeakingIndicator); + item->showSpeakingIndicator(mShowSpeakingIndicator); addItem(item, id, pos); } diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 6945ac6932..1043858373 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -44,10 +44,10 @@ #include "llbutton.h" bool LLAvatarListItem::sStaticInitialized = false; -S32 LLAvatarListItem::sIconWidth = 0; -S32 LLAvatarListItem::sInfoBtnWidth = 0; -S32 LLAvatarListItem::sProfileBtnWidth = 0; -S32 LLAvatarListItem::sSpeakingIndicatorWidth = 0; +S32 LLAvatarListItem::sLeftPadding = 0; +S32 LLAvatarListItem::sRightNamePadding = 0; +S32 LLAvatarListItem::sChildrenWidths[LLAvatarListItem::ALIC_COUNT]; + LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/) : LLPanel(), @@ -91,43 +91,25 @@ BOOL LLAvatarListItem::postBuild() mProfileBtn->setVisible(false); mProfileBtn->setClickedCallback(boost::bind(&LLAvatarListItem::onProfileBtnClick, this)); - // Remember avatar icon width including its padding from the name text box, - // so that we can hide and show the icon again later. if (!sStaticInitialized) { - sIconWidth = mAvatarName->getRect().mLeft - mAvatarIcon->getRect().mLeft; - sInfoBtnWidth = mInfoBtn->getRect().mRight - mSpeakingIndicator->getRect().mRight; - sProfileBtnWidth = mProfileBtn->getRect().mRight - mInfoBtn->getRect().mRight; - sSpeakingIndicatorWidth = mSpeakingIndicator->getRect().mRight - mAvatarName->getRect().mRight; + // Remember children widths including their padding from the next sibling, + // so that we can hide and show them again later. + initChildrenWidths(this); sStaticInitialized = true; } -/* - if(!p.buttons.profile) - { - delete mProfile; - mProfile = NULL; - - LLRect rect; - - rect.setLeftTopAndSize(mName->getRect().mLeft, mName->getRect().mTop, mName->getRect().getWidth() + 30, mName->getRect().getHeight()); - mName->setRect(rect); - - if(mLocator) - { - rect.setLeftTopAndSize(mLocator->getRect().mLeft + 30, mLocator->getRect().mTop, mLocator->getRect().getWidth(), mLocator->getRect().getHeight()); - mLocator->setRect(rect); - } + return TRUE; +} - if(mInfo) - { - rect.setLeftTopAndSize(mInfo->getRect().mLeft + 30, mInfo->getRect().mTop, mInfo->getRect().getWidth(), mInfo->getRect().getHeight()); - mInfo->setRect(rect); - } +S32 LLAvatarListItem::notifyParent(const LLSD& info) +{ + if (info.has("visibility_changed")) + { + updateChildren(); } -*/ - return TRUE; + return 0; } void LLAvatarListItem::onMouseEnter(S32 x, S32 y, MASK mask) @@ -137,6 +119,8 @@ void LLAvatarListItem::onMouseEnter(S32 x, S32 y, MASK mask) mProfileBtn->setVisible(mShowProfileBtn); LLPanel::onMouseEnter(x, y, mask); + + updateChildren(); } void LLAvatarListItem::onMouseLeave(S32 x, S32 y, MASK mask) @@ -146,6 +130,8 @@ void LLAvatarListItem::onMouseLeave(S32 x, S32 y, MASK mask) mProfileBtn->setVisible(false); LLPanel::onMouseLeave(x, y, mask); + + updateChildren(); } // virtual, called by LLAvatarTracker @@ -215,12 +201,8 @@ void LLAvatarListItem::showLastInteractionTime(bool show) if (show) return; - LLRect name_rect = mAvatarName->getRect(); - LLRect time_rect = mLastInteractionTime->getRect(); - mLastInteractionTime->setVisible(false); - name_rect.mRight += (time_rect.mRight - name_rect.mRight); - mAvatarName->setRect(name_rect); + updateChildren(); } void LLAvatarListItem::setLastInteractionTime(U32 secs_since) @@ -234,12 +216,6 @@ void LLAvatarListItem::setShowInfoBtn(bool show) if(mShowInfoBtn == show) return; mShowInfoBtn = show; - S32 width_delta = show ? - sInfoBtnWidth : sInfoBtnWidth; - - //Translating speaking indicator - mSpeakingIndicator->translate(width_delta, 0); - //Reshaping avatar name - mAvatarName->reshape(mAvatarName->getRect().getWidth() + width_delta, mAvatarName->getRect().getHeight()); } void LLAvatarListItem::setShowProfileBtn(bool show) @@ -248,24 +224,17 @@ void LLAvatarListItem::setShowProfileBtn(bool show) if(mShowProfileBtn == show) return; mShowProfileBtn = show; - S32 width_delta = show ? - sProfileBtnWidth : sProfileBtnWidth; - - //Translating speaking indicator - mSpeakingIndicator->translate(width_delta, 0); - //Reshaping avatar name - mAvatarName->reshape(mAvatarName->getRect().getWidth() + width_delta, mAvatarName->getRect().getHeight()); } -void LLAvatarListItem::setSpeakingIndicatorVisible(bool visible) +void LLAvatarListItem::showSpeakingIndicator(bool visible) { // Already done? Then do nothing. if (mSpeakingIndicator->getVisible() == (BOOL)visible) return; - mSpeakingIndicator->setVisible(visible); - S32 width_delta = visible ? - sSpeakingIndicatorWidth : sSpeakingIndicatorWidth; - - //Reshaping avatar name - mAvatarName->reshape(mAvatarName->getRect().getWidth() + width_delta, mAvatarName->getRect().getHeight()); +// Disabled to not contradict with SpeakingIndicatorManager functionality. EXT-3976 +// probably this method should be totally removed. +// mSpeakingIndicator->setVisible(visible); +// updateChildren(); } void LLAvatarListItem::setAvatarIconVisible(bool visible) @@ -276,36 +245,12 @@ void LLAvatarListItem::setAvatarIconVisible(bool visible) // Show/hide avatar icon. mAvatarIcon->setVisible(visible); - - // Move the avatar name horizontally by icon size + its distance from the avatar name. - LLRect name_rect = mAvatarName->getRect(); - name_rect.mLeft += visible ? sIconWidth : -sIconWidth; - mAvatarName->setRect(name_rect); + updateChildren(); } void LLAvatarListItem::onInfoBtnClick() { LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", mAvatarId)); - - /* TODO fix positioning of inspector - localPointToScreen(mXPos, mYPos, &mXPos, &mYPos); - - - LLRect rect; - - // *TODO Vadim: rewrite this. "+= -" looks weird. - S32 delta = mYPos - inspector->getRect().getHeight(); - if(delta < 0) - { - mYPos += -delta; - } - - rect.setLeftTopAndSize(mXPos, mYPos, - inspector->getRect().getWidth(), inspector->getRect().getHeight()); - inspector->setRect(rect); - inspector->setFrontmost(true); - inspector->setVisible(true); - */ } void LLAvatarListItem::onProfileBtnClick() @@ -344,21 +289,6 @@ void LLAvatarListItem::onNameCache(const std::string& first_name, const std::str setName(name); } -void LLAvatarListItem::reshapeAvatarName() -{ - S32 width_delta = 0; - width_delta += mShowProfileBtn ? sProfileBtnWidth : 0; - width_delta += mSpeakingIndicator->getVisible() ? sSpeakingIndicatorWidth : 0; - width_delta += mAvatarIcon->getVisible() ? sIconWidth : 0; - width_delta += mShowInfoBtn ? sInfoBtnWidth : 0; - width_delta += mLastInteractionTime->getVisible() ? mLastInteractionTime->getRect().getWidth() : 0; - - S32 height = mAvatarName->getRect().getHeight(); - S32 width = getRect().getWidth() - width_delta; - - mAvatarName->reshape(width, height); -} - // Convert given number of seconds to a string like "23 minutes", "15 hours" or "3 years", // taking i18n into account. The format string to use is taken from the panel XML. std::string LLAvatarListItem::formatSeconds(U32 secs) @@ -492,4 +422,133 @@ LLAvatarListItem::icon_color_map_t& LLAvatarListItem::getItemIconColorMap() return item_icon_color_map; } +// static +void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item) +{ + //profile btn width + padding + S32 profile_btn_width = avatar_item->getRect().getWidth() - avatar_item->mProfileBtn->getRect().mLeft; + + //info btn width + padding + S32 info_btn_width = avatar_item->mProfileBtn->getRect().mLeft - avatar_item->mInfoBtn->getRect().mLeft; + + //speaking indicator width + padding + S32 speaking_indicator_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mSpeakingIndicator->getRect().mLeft; + + // last interaction time textbox width + padding + S32 last_interaction_time_width = avatar_item->mSpeakingIndicator->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft; + + // icon width + padding + S32 icon_width = avatar_item->mAvatarName->getRect().mLeft - avatar_item->mAvatarIcon->getRect().mLeft; + + sLeftPadding = avatar_item->mAvatarIcon->getRect().mLeft; + sRightNamePadding = avatar_item->mLastInteractionTime->getRect().mLeft - avatar_item->mAvatarName->getRect().mRight; + + S32 index = ALIC_COUNT; + sChildrenWidths[--index] = icon_width; + sChildrenWidths[--index] = 0; // for avatar name we don't need its width, it will be calculated as "left available space" + sChildrenWidths[--index] = last_interaction_time_width; + sChildrenWidths[--index] = speaking_indicator_width; + sChildrenWidths[--index] = info_btn_width; + sChildrenWidths[--index] = profile_btn_width; +} + +void LLAvatarListItem::updateChildren() +{ + LL_DEBUGS("AvatarItemReshape") << LL_ENDL; + LL_DEBUGS("AvatarItemReshape") << "Updating for: " << getAvatarName() << LL_ENDL; + + S32 name_new_width = getRect().getWidth(); + S32 ctrl_new_left = name_new_width; + S32 name_new_left = sLeftPadding; + + // iterate through all children and set them into correct position depend on each child visibility + // assume that child indexes are in back order: the first in Enum is the last (right) in the item + // iterate & set child views starting from right to left + for (S32 i = 0; i < ALIC_COUNT; ++i) + { + // skip "name" textbox, it will be processed out of loop later + if (ALIC_NAME == i) continue; + + LLView* control = getItemChildView((EAvatarListItemChildIndex)i); + + LL_DEBUGS("AvatarItemReshape") << "Processing control: " << control->getName() << LL_ENDL; + // skip invisible views + if (!control->getVisible()) continue; + + S32 ctrl_width = sChildrenWidths[i]; // including space between current & left controls + + // decrease available for + name_new_width -= ctrl_width; + LL_DEBUGS("AvatarItemReshape") << "width: " << ctrl_width << ", name_new_width: " << name_new_width << LL_ENDL; + + LLRect control_rect = control->getRect(); + LL_DEBUGS("AvatarItemReshape") << "rect before: " << control_rect << LL_ENDL; + + if (ALIC_ICON == i) + { + // assume that this is the last iteration, + // so it is not necessary to save "ctrl_new_left" value calculated on previous iterations + ctrl_new_left = sLeftPadding; + name_new_left = ctrl_new_left + ctrl_width; + } + else + { + ctrl_new_left -= ctrl_width; + } + + LL_DEBUGS("AvatarItemReshape") << "ctrl_new_left: " << ctrl_new_left << LL_ENDL; + + control_rect.setLeftTopAndSize( + ctrl_new_left, + control_rect.mTop, + control_rect.getWidth(), + control_rect.getHeight()); + + LL_DEBUGS("AvatarItemReshape") << "rect after: " << control_rect << LL_ENDL; + control->setShape(control_rect); + } + + // set size and position of the "name" child + LLView* name_view = getItemChildView(ALIC_NAME); + LLRect name_view_rect = name_view->getRect(); + LL_DEBUGS("AvatarItemReshape") << "name rect before: " << name_view_rect << LL_ENDL; + + // apply paddings + name_new_width -= sLeftPadding; + name_new_width -= sRightNamePadding; + + name_view_rect.setLeftTopAndSize( + name_new_left, + name_view_rect.mTop, + name_new_width, + name_view_rect.getHeight()); + + name_view->setShape(name_view_rect); + + LL_DEBUGS("AvatarItemReshape") << "name rect after: " << name_view_rect << LL_ENDL; +} + +LLView* LLAvatarListItem::getItemChildView(EAvatarListItemChildIndex child_view_index) +{ + LLView* child_view = mAvatarName; + if (child_view_index < 0 || ALIC_COUNT <= child_view_index) + { + LL_WARNS("AvatarItemReshape") << "Child view index is out of range: " << child_view_index << LL_ENDL; + return child_view; + } + switch (child_view_index) + { + case ALIC_ICON: child_view = mAvatarIcon; break; + case ALIC_NAME: child_view = mAvatarName; break; + case ALIC_INTERACTION_TIME: child_view = mLastInteractionTime; break; + case ALIC_SPEAKER_INDICATOR: child_view = mSpeakingIndicator; break; + case ALIC_INFO_BUTTON: child_view = mInfoBtn; break; + case ALIC_PROFILE_BUTTON: child_view = mProfileBtn; break; + default: + LL_WARNS("AvatarItemReshape") << "Unexpected child view index is passed: " << child_view_index << LL_ENDL; + } + + return child_view; +} + // EOF diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index 96097bc9b5..f76ffb391d 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -74,6 +74,11 @@ public: virtual ~LLAvatarListItem(); virtual BOOL postBuild(); + + /** + * Processes notification from speaker indicator to update children when indicator's visibility is changed. + */ + virtual S32 notifyParent(const LLSD& info); virtual void onMouseLeave(S32 x, S32 y, MASK mask); virtual void onMouseEnter(S32 x, S32 y, MASK mask); virtual void setValue(const LLSD& value); @@ -88,7 +93,8 @@ public: //Show/hide profile/info btn, translating speaker indicator and avatar name coordinates accordingly void setShowProfileBtn(bool show); void setShowInfoBtn(bool show); - void setSpeakingIndicatorVisible(bool visible); + void showSpeakingIndicator(bool show); + void showLastInteractionTime(bool show); void setAvatarIconVisible(bool visible); const LLUUID& getAvatarId() const; @@ -97,17 +103,6 @@ public: void onInfoBtnClick(); void onProfileBtnClick(); - void showSpeakingIndicator(bool show) { mSpeakingIndicator->setVisible(show); } - void showInfoBtn(bool show_info_btn) {mInfoBtn->setVisible(show_info_btn); } - void showLastInteractionTime(bool show); - - /** - * This method was added to fix EXT-2364 (Items in group/ad-hoc IM participant list (avatar names) should be reshaped when adding/removing the "(Moderator)" label) - * But this is a *HACK. The real reason of it was in incorrect logic while hiding profile/info/speaker buttons - * *TODO: new reshape method should be provided in lieu of this one to be called when visibility if those buttons is changed - */ - void reshapeAvatarName(); - protected: /** * Contains indicator to show voice activity. @@ -124,6 +119,23 @@ private: E_UNKNOWN, } EOnlineStatus; + /** + * Enumeration of item elements in order from right to left. + * + * updateChildren() assumes that indexes are in the such order to process avatar icon easier. + * + * @see updateChildren() + */ + typedef enum e_avatar_item_child { + ALIC_PROFILE_BUTTON, + ALIC_INFO_BUTTON, + ALIC_SPEAKER_INDICATOR, + ALIC_INTERACTION_TIME, + ALIC_NAME, + ALIC_ICON, + ALIC_COUNT, + } EAvatarListItemChildIndex; + void setNameInternal(const std::string& name, const std::string& highlight); void onNameCache(const std::string& first_name, const std::string& last_name); @@ -135,6 +147,26 @@ private: typedef std::map icon_color_map_t; static icon_color_map_t& getItemIconColorMap(); + /** + * Initializes widths of all children to use them while changing visibility of any of them. + * + * @see updateChildren() + */ + static void initChildrenWidths(LLAvatarListItem* self); + + /** + * Updates position and rectangle of visible children to fit all available item's width. + */ + void updateChildren(); + + /** + * Gets child view specified by index. + * + * This method implemented via switch by all EAvatarListItemChildIndex values. + * It is used to not store children in array or vector to avoid of increasing memory usage. + */ + LLView* getItemChildView(EAvatarListItemChildIndex child_index); + LLTextBox* mAvatarName; LLTextBox* mLastInteractionTime; LLStyle::Params mAvatarNameStyle; @@ -151,10 +183,17 @@ private: bool mShowProfileBtn; static bool sStaticInitialized; // this variable is introduced to improve code readability - static S32 sIconWidth; // icon width + padding - static S32 sInfoBtnWidth; //info btn width + padding - static S32 sProfileBtnWidth; //profile btn width + padding - static S32 sSpeakingIndicatorWidth; //speaking indicator width + padding + static S32 sLeftPadding; // padding to first left visible child (icon or name) + static S32 sRightNamePadding; // right padding from name to next visible child + + /** + * Contains widths of each child specified by EAvatarListItemChildIndex + * including padding to the next right one. + * + * @see initChildrenWidths() + */ + static S32 sChildrenWidths[ALIC_COUNT]; + }; #endif //LL_LLAVATARLISTITEM_H diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 976b312509..beccefa430 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -161,6 +161,9 @@ void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& nam { chiclet->setIMSessionName(name); chiclet->setOtherParticipantId(other_participant_id); + + LLIMFloater::onIMChicletCreated(session_id); + } else { @@ -251,14 +254,24 @@ void LLBottomTray::setVisible(BOOL visible) { LLView* viewp = *child_it; std::string name = viewp->getName(); - - if ("chat_bar" == name || "movement_panel" == name || "cam_panel" == name || "snapshot_panel" == name || "gesture_panel" == name) + + // 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 || (visibility && ("movement_panel" == name || "cam_panel" == name || "snapshot_panel" == name))) continue; else { viewp->setVisible(visibility); } } + + // Apply the saved settings when we are not in mouselook mode, see EXT-3988. + if (visibility) + { + showCameraButton(gSavedSettings.getBOOL("ShowCameraButton")); + showSnapshotButton(gSavedSettings.getBOOL("ShowSnapshotButton")); + showMoveButton(gSavedSettings.getBOOL("ShowMoveButton")); + showGestureButton(gSavedSettings.getBOOL("ShowGestureButton")); + } } } diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index 1468f6d584..c0efb85b51 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -51,6 +51,7 @@ #include "lltransientfloatermgr.h" #include "llviewerwindow.h" #include "llvoicechannel.h" +#include "lllayoutstack.h" static void get_voice_participants_uuids(std::vector& speakers_uuids); @@ -314,7 +315,7 @@ void LLCallFloater::updateSession() //hide "Leave Call" button for nearby chat bool is_local_chat = mVoiceType == VC_LOCAL_CHAT; - childSetVisible("leave_call_btn", !is_local_chat); + childSetVisible("leave_call_btn_panel", !is_local_chat); refreshParticipantList(); updateAgentModeratorState(); @@ -818,8 +819,8 @@ void reshape_floater(LLCallFloater* floater, S32 delta_height) } } - floater->reshape(floater_rect.getWidth(), floater_rect.getHeight()); - floater->setRect(floater_rect); + floater->setShape(floater_rect); + floater->getChild("my_call_stack")->updateLayout(FALSE); } void LLCallFloater::reshapeToFitContent() @@ -864,9 +865,8 @@ S32 LLCallFloater::getParticipantItemHeight() S32 LLCallFloater::getMaxVisibleItems() { - S32 value = 5; // default value, in case convertToS32() fails. - LLStringUtil::convertToS32(getString("max_visible_items"), value); - return value; + static LLCachedControl max_visible_items(*LLUI::sSettingGroups["config"],"CallFloaterMaxItems"); + return max_visible_items; } //EOF diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index cda3e3a419..2fc83c7e54 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -499,7 +499,24 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_ style_params.font.name(font_name); style_params.font.size(font_size); style_params.font.style(input_append_params.font.style); - + + std::string prefix = chat.mText.substr(0, 4); + + //IRC styled /me messages. + bool irc_me = prefix == "/me " || prefix == "/me'"; + + // Delimiter after a name in header copy/past and in plain text mode + std::string delimiter = (chat.mChatType != CHAT_TYPE_SHOUT && chat.mChatType != CHAT_TYPE_WHISPER) + ? ": " + : " "; + + // Don't add any delimiter after name in irc styled messages + if (irc_me || chat.mChatStyle == CHAT_STYLE_IRC) + { + delimiter = LLStringUtil::null; + style_params.font.style = "ITALIC"; + } + if (use_plain_text_chat_history) { mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getText().size() != 0, style_params); @@ -512,11 +529,11 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_ LLStyle::Params link_params(style_params); link_params.fillFrom(LLStyleMap::instance().lookupAgent(chat.mFromID)); // Convert the name to a hotlink and add to message. - mEditor->appendText(chat.mFromName + ": ", false, link_params); + mEditor->appendText(chat.mFromName + delimiter, false, link_params); } else { - mEditor->appendText(chat.mFromName + ": ", false, style_params); + mEditor->appendText(chat.mFromName + delimiter, false, style_params); } } } @@ -562,36 +579,22 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_ std::string header_text = "[" + chat.mTimeStr + "] "; if (utf8str_trim(chat.mFromName).size() != 0 && chat.mFromName != SYSTEM_FROM) - header_text += chat.mFromName + ": "; + header_text += chat.mFromName + delimiter; mEditor->appendWidget(p, header_text, false); mLastFromName = chat.mFromName; mLastFromID = chat.mFromID; mLastMessageTime = new_message_time; } - //Handle IRC styled /me messages. - std::string prefix = chat.mText.substr(0, 4); - if (prefix == "/me " || prefix == "/me'") - { - style_params.font.style = "ITALIC"; - if (chat.mFromName.size() > 0) - mEditor->appendText(chat.mFromName, TRUE, style_params); + std::string message = irc_me ? chat.mText.substr(3) : chat.mText; + if ( message.size() > 0 && !LLStringOps::isSpace(message[message.size() - 1]) ) + { // Ensure that message ends with NewLine, to avoid losing of new lines // while copy/paste from text chat. See EXT-3263. - mEditor->appendText(chat.mText.substr(3) + NEW_LINE, FALSE, style_params); - } - else - { - std::string message(chat.mText); - if ( message.size() > 0 && !LLStringOps::isSpace(message[message.size() - 1]) ) - { - // Ensure that message ends with NewLine, to avoid losing of new lines - // while copy/paste from text chat. See EXT-3263. - message += NEW_LINE; - } - mEditor->appendText(message, FALSE, style_params); + message += NEW_LINE; } + mEditor->appendText(message, FALSE, style_params); mEditor->blockUndo(); // automatically scroll to end when receiving chat from myself diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index aa343b2f69..ef69f39ad2 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -269,7 +269,7 @@ LLSD LLFloaterAbout::getInfo() info["VIVOX_VERSION"] = gVoiceClient ? gVoiceClient->getAPIVersion() : LLTrans::getString("NotConnected"); // TODO: Implement media plugin version query - info["QT_WEBKIT_VERSION"] = "4.5.2 (version number hard-coded)"; + info["QT_WEBKIT_VERSION"] = "4.6 (version number hard-coded)"; if (gPacketsIn > 0) { diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp index b9e0f928f1..18b9f0484f 100644 --- a/indra/newview/llfloaterchat.cpp +++ b/indra/newview/llfloaterchat.cpp @@ -190,7 +190,14 @@ void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file) { if (log_to_file && (gSavedPerAccountSettings.getBOOL("LogChat"))) { - LLLogChat::saveHistory("chat", chat.mFromName, chat.mFromID, chat.mText); + if (chat.mChatType != CHAT_TYPE_WHISPER && chat.mChatType != CHAT_TYPE_SHOUT) + { + LLLogChat::saveHistory("chat", chat.mFromName, chat.mFromID, chat.mText); + } + else + { + LLLogChat::saveHistory("chat", "", chat.mFromID, chat.mFromName + " " + chat.mText); + } } LLColor4 color = get_text_color(chat); @@ -311,8 +318,10 @@ void LLFloaterChat::addChat(const LLChat& chat, BOOL from_instant_message, BOOL triggerAlerts(chat.mText); // Add the sender to the list of people with which we've recently interacted. - if(chat.mSourceType == CHAT_SOURCE_AGENT && chat.mFromID.notNull()) - LLRecentPeople::instance().add(chat.mFromID); + // this is not the best place to add _all_ messages to recent list + // comment this for now, may remove later on code cleanup + //if(chat.mSourceType == CHAT_SOURCE_AGENT && chat.mFromID.notNull()) + // LLRecentPeople::instance().add(chat.mFromID); bool add_chat = true; bool log_chat = true; diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index 5072bc8c82..6a9c602db2 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -415,7 +415,7 @@ void LLFloaterGesture::onClickPlay() LL_DEBUGS("Gesture")<<" Trying to play gesture id: "<< item_id <refresh(); mPanelMedia->refresh(); mPanelAccess->refresh(); + mPanelCovenant->refresh(); } @@ -2795,12 +2796,6 @@ LLPanelLandCovenant::~LLPanelLandCovenant() { } -BOOL LLPanelLandCovenant::postBuild() -{ - refresh(); - return TRUE; -} - // virtual void LLPanelLandCovenant::refresh() { diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index d7d02ba1a3..a4785e8f5b 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -391,7 +391,6 @@ class LLPanelLandCovenant public: LLPanelLandCovenant(LLSafeHandle& parcelp); virtual ~LLPanelLandCovenant(); - virtual BOOL postBuild(); void refresh(); static void updateCovenantText(const std::string& string); static void updateEstateName(const std::string& name); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index d0716f67b8..9af37e8174 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -602,8 +602,8 @@ void LLFloaterPreference::onBtnOK() apply(); closeFloater(false); - gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); LLUIColorTable::instance().saveUserSettings(); + gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE); // save all settings, even if equals defaults gCrashSettings.saveToFile(crash_settings_filename, FALSE); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index c4b87c1b2d..0402ba20e2 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -406,6 +406,11 @@ LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant() void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region) { + if (!region) + { + return; + } + // call refresh from region on all panels std::for_each( mInfoPanels.begin(), diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index df7aa9eabf..82293b4aa0 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -417,6 +417,16 @@ BOOL LLGestureManager::isGesturePlaying(const LLUUID& item_id) return gesture->mPlaying; } +BOOL LLGestureManager::isGesturePlaying(LLMultiGesture* gesture) +{ + if(!gesture) + { + return FALSE; + } + + return gesture->mPlaying; +} + void LLGestureManager::replaceGesture(const LLUUID& item_id, LLMultiGesture* new_gesture, const LLUUID& asset_id) { const LLUUID& base_item_id = get_linked_uuid(item_id); diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h index e80eea9ae9..c562587c6f 100644 --- a/indra/newview/llgesturemgr.h +++ b/indra/newview/llgesturemgr.h @@ -103,6 +103,8 @@ public: BOOL isGesturePlaying(const LLUUID& item_id); + BOOL isGesturePlaying(LLMultiGesture* gesture); + const item_map_t& getActiveGestures() const { return mActive; } // Force a gesture to be played, for example, if it is being // previewed. diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index 7dd8ea694e..d6e2bb0445 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -146,6 +146,12 @@ void LLGroupActions::startCall(const LLUUID& group_id) // static void LLGroupActions::join(const LLUUID& group_id) { + if (!gAgent.canJoinGroups()) + { + LLNotificationsUtil::add("JoinedTooManyGroups"); + return; + } + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id); @@ -226,7 +232,9 @@ void LLGroupActions::activate(const LLUUID& group_id) static bool isGroupUIVisible() { - LLPanel* panel = LLSideTray::getInstance()->findChild("panel_group_info_sidetray"); + static LLPanel* panel = 0; + if(!panel) + panel = LLSideTray::getInstance()->findChild("panel_group_info_sidetray"); if(!panel) return false; return panel->isInVisibleChain(); diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index b05568f353..aee34eb0af 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -361,35 +361,7 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id) { if (!gIMMgr->hasSession(session_id)) return NULL; - // we should make sure all related chiclets are in place when the session is a voice call - // chiclets come firts, then comes IM window - if (gIMMgr->isVoiceCall(session_id)) - { - LLIMModel* im_model = LLIMModel::getInstance(); - LLBottomTray* b_tray = LLBottomTray::getInstance(); - - //*TODO hide that into Bottom tray - if (!b_tray->getChicletPanel()->findChiclet(session_id)) - { - LLIMChiclet* chiclet = b_tray->createIMChiclet(session_id); - if(chiclet) - { - chiclet->setIMSessionName(im_model->getName(session_id)); - chiclet->setOtherParticipantId(im_model->getOtherParticipantID(session_id)); - } - } - - LLIMWellWindow::getInstance()->addIMRow(session_id); - } - - bool not_existed = true; - - if(isChatMultiTab()) - { - LLIMFloater* target_floater = findInstance(session_id); - not_existed = NULL == target_floater; - } - else + if(!isChatMultiTab()) { //hide all LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel"); @@ -404,19 +376,33 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id) } } - LLIMFloater* floater = LLFloaterReg::showTypedInstance("impanel", session_id); + bool exist = findInstance(session_id); + + LLIMFloater* floater = getInstance(session_id); + if (!floater) return NULL; if(isChatMultiTab()) { + LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance(); + // do not add existed floaters to avoid adding torn off instances - if (not_existed) + if (!exist) { // LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END; // TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END; + + if (floater_container) + { + floater_container->addFloater(floater, TRUE, i_pt); + } + } - LLIMFloaterContainer* floater_container = LLFloaterReg::showTypedInstance("im_container"); - floater_container->addFloater(floater, TRUE, i_pt); + if (floater_container) + { + //selecting the panel resets a chiclet's counter + floater_container->selectFloater(floater); + floater_container->setVisible(TRUE); } } else @@ -443,8 +429,8 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id) } // window is positioned, now we can show it. - floater->setVisible(true); } + floater->setVisible(TRUE); return floater; } @@ -484,16 +470,6 @@ void LLIMFloater::setDocked(bool docked, bool pop_on_undock) } } -void LLIMFloater::setTornOff(bool torn_off) -{ - // When IM Floater isn't torn off, "close" button should be hidden. - // This call will just disables it, since there is a hack in LLFloater::updateButton, - // which prevents hiding of close button in that case. - setCanClose(torn_off); - - LLTransientDockableFloater::setTornOff(torn_off); -} - void LLIMFloater::setVisible(BOOL visible) { LLNotificationsUI::LLScreenChannel* channel = dynamic_cast @@ -548,6 +524,11 @@ LLIMFloater* LLIMFloater::findInstance(const LLUUID& session_id) return LLFloaterReg::findTypedInstance("impanel", session_id); } +LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id) +{ + return LLFloaterReg::getTypedInstance("impanel", session_id); +} + void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id) { mSessionInitialized = true; @@ -1026,3 +1007,20 @@ void LLIMFloater::sRemoveTypingIndicator(const LLSD& data) floater->removeTypingIndicator(); } + +void LLIMFloater::onIMChicletCreated( const LLUUID& session_id ) +{ + + if (isChatMultiTab()) + { + LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance(); + if (!im_box) return; + + if (LLIMFloater::findInstance(session_id)) return; + + LLIMFloater* new_tab = LLIMFloater::getInstance(session_id); + + im_box->addFloater(new_tab, FALSE, LLTabContainer::END); + } + +} diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index bc7a43e852..d9db385d06 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -64,7 +64,6 @@ public: // LLFloater overrides /*virtual*/ void onClose(bool app_quitting); /*virtual*/ void setDocked(bool docked, bool pop_on_undock = true); - /*virtual*/ void setTornOff(bool torn_off); // Make IM conversion visible and update the message history static LLIMFloater* show(const LLUUID& session_id); @@ -75,6 +74,8 @@ public: static LLIMFloater* findInstance(const LLUUID& session_id); + static LLIMFloater* getInstance(const LLUUID& session_id); + void sessionInitReplyReceived(const LLUUID& im_session_id); // get new messages from LLIMModel @@ -113,6 +114,8 @@ public: //used as a callback on receiving new IM message static void sRemoveTypingIndicator(const LLSD& data); + static void onIMChicletCreated(const LLUUID& session_id); + 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 2d7333f7e4..6cc985aef4 100644 --- a/indra/newview/llimfloatercontainer.cpp +++ b/indra/newview/llimfloatercontainer.cpp @@ -34,6 +34,7 @@ #include "llviewerprecompiledheaders.h" #include "llimfloatercontainer.h" +#include "llfloaterreg.h" // // LLIMFloaterContainer @@ -93,4 +94,14 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp, } } +LLIMFloaterContainer* LLIMFloaterContainer::findInstance() +{ + return LLFloaterReg::findTypedInstance("im_container"); +} + +LLIMFloaterContainer* LLIMFloaterContainer::getInstance() +{ + return LLFloaterReg::getTypedInstance("im_container"); +} + // EOF diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h index ead7cf4730..d4a542dfc2 100644 --- a/indra/newview/llimfloatercontainer.h +++ b/indra/newview/llimfloatercontainer.h @@ -52,7 +52,11 @@ public: LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END); static LLFloater* getCurrentVoiceFloater(); - + + static LLIMFloaterContainer* findInstance(); + + static LLIMFloaterContainer* getInstance(); + protected: LLFloater* mActiveVoiceFloater; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index daabf1f717..e9661003ea 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -382,10 +382,6 @@ void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& f mSpeakers->speakerChatted(from_id); mSpeakers->setSpeakerTyping(from_id, FALSE); } - - if( mSessionType == P2P_SESSION || - mSessionType == ADHOC_SESSION) - LLRecentPeople::instance().add(from_id); } void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list& history) @@ -684,6 +680,12 @@ bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, co LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file); if (!session) return false; + //good place to add some1 to recent list + //other places may be called from message history. + if( !from_id.isNull() && + ( session->isP2PSessionType() || session->isAdHocSessionType() ) ) + LLRecentPeople::instance().add(from_id); + // notify listeners LLSD arg; arg["session_id"] = session_id; @@ -1377,7 +1379,7 @@ void LLCallDialogManager::onVoiceChannelChanged(const LLUUID &session_id) } sSession = session; - sSession->mVoiceChannel->setStateChangedCallback(LLCallDialogManager::onVoiceChannelStateChanged); + sSession->mVoiceChannel->setStateChangedCallback(boost::bind(LLCallDialogManager::onVoiceChannelStateChanged, _1, _2, _3)); if(sCurrentSessionlName != session->mName) { sPreviousSessionlName = sCurrentSessionlName; @@ -1601,7 +1603,12 @@ void LLOutgoingCallDialog::show(const LLSD& key) if (!mPayload["disconnected_channel_name"].asString().empty()) { - childSetTextArg("nearby", "[VOICE_CHANNEL_NAME]", mPayload["disconnected_channel_name"].asString()); + std::string channel_name = mPayload["disconnected_channel_name"].asString(); + if (LLIMModel::LLIMSession::AVALINE_SESSION == mPayload["session_type"].asInteger()) + { + channel_name = LLTextUtil::formatPhoneNumber(channel_name); + } + childSetTextArg("nearby", "[VOICE_CHANNEL_NAME]", channel_name); childSetTextArg("nearby_P2P", "[VOICE_CHANNEL_NAME]", mPayload["disconnected_channel_name"].asString()); } diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 20d8e28392..e72bda6c2b 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -78,6 +78,11 @@ public: bool isP2P(); bool isOtherParticipantAvaline(); + bool isP2PSessionType() const { return mSessionType == P2P_SESSION;} + bool isAdHocSessionType() const { return mSessionType == ADHOC_SESSION;} + bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;} + bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;} + LLUUID mSessionID; std::string mName; EInstantMessage mType; diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 8f4fba244d..0374a1d25b 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -418,6 +418,7 @@ void LLInspectAvatar::updateModeratorPanel() LLPointer selected_speakerp = speaker_mgr->findSpeaker(mAvatarID); if(speaker_mgr->isVoiceActive() && selected_speakerp && + selected_speakerp->isInVoiceChannel() && ((self_speakerp && self_speakerp->mIsModerator) || gAgent.isGodlike())) { getChild("enable_voice")->setVisible(selected_speakerp->mModeratorMutedVoice); diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp new file mode 100644 index 0000000000..3ca8fa2f56 --- /dev/null +++ b/indra/newview/llinspecttoast.cpp @@ -0,0 +1,122 @@ +/** + * @file llinspecttoast.cpp + * @brief Toast inspector implementation. + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" // must be first include + +#include "llinspecttoast.h" +#include "llinspect.h" +#include "llfloaterreg.h" +#include "llscreenchannel.h" +#include "llchannelmanager.h" +#include "lltransientfloatermgr.h" + +using namespace LLNotificationsUI; + +/** + * Represents inspectable toast . + */ +class LLInspectToast: public LLInspect +{ +public: + + LLInspectToast(const LLSD& notification_idl); + virtual ~LLInspectToast(); + + /*virtual*/ void onOpen(const LLSD& notification_id); +private: + void onToastDestroy(LLToast * toast); + +private: + LLPanel* mPanel; + LLScreenChannel* mScreenChannel; +}; + +LLInspectToast::LLInspectToast(const LLSD& notification_id) : + LLInspect(LLSD()), mPanel(NULL) +{ + LLScreenChannelBase* channel = LLChannelManager::getInstance()->findChannelByID( + LLUUID(gSavedSettings.getString("NotificationChannelUUID"))); + mScreenChannel = dynamic_cast(channel); + if(NULL == mScreenChannel) + { + llwarns << "Could not get requested screen channel." << llendl; + return; + } + + LLTransientFloaterMgr::getInstance()->addControlView(this); +} +LLInspectToast::~LLInspectToast() +{ + LLTransientFloaterMgr::getInstance()->removeControlView(this); +} + +void LLInspectToast::onOpen(const LLSD& notification_id) +{ + LLInspect::onOpen(notification_id); + LLToast* toast = mScreenChannel->getToastByNotificationID(notification_id); + if (toast == NULL) + { + llwarns << "Could not get requested toast from screen channel." << llendl; + return; + } + toast->setOnToastDestroyedCallback(boost::bind(&LLInspectToast::onToastDestroy, this, _1)); + + LLPanel * panel = toast->getPanel(); + panel->setVisible(TRUE); + panel->setMouseOpaque(FALSE); + if(mPanel != NULL && mPanel->getParent() == this) + { + removeChild(mPanel); + } + addChild(panel); + panel->setFocus(TRUE); + mPanel = panel; + + + LLRect panel_rect; + panel_rect = panel->getRect(); + reshape(panel_rect.getWidth(), panel_rect.getHeight()); + + LLUI::positionViewNearMouse(this); +} + +void LLInspectToast::onToastDestroy(LLToast * toast) +{ + closeFloater(false); +} + +void LLNotificationsUI::registerFloater() +{ + LLFloaterReg::add("inspect_toast", "inspect_toast.xml", + &LLFloaterReg::build); +} + diff --git a/indra/newview/llinspecttoast.h b/indra/newview/llinspecttoast.h new file mode 100644 index 0000000000..ff547154b8 --- /dev/null +++ b/indra/newview/llinspecttoast.h @@ -0,0 +1,40 @@ +/** + * @file llinspecttoast.h + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLINSPECTTOAST_H +#define LL_LLINSPECTTOAST_H + +namespace LLNotificationsUI +{ +void registerFloater(); +} + +#endif diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 711114173c..a468a9a95c 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2001,14 +2001,16 @@ void LLInventoryModel::accountForUpdate(const LLCategoryUpdate& update) const } if(!accounted) { - lldebugs << "No accounting for: '" << cat->getName() << "' " + // Error condition, this means that the category did not register that + // it got new descendents (perhaps because it is still being loaded) + // which means its descendent count will be wrong. + llwarns << "Accounting failed for '" << cat->getName() << "' version:" << version << llendl; } } else { - llwarns << "No category found for update " << update.mCategoryID - << llendl; + llwarns << "No category found for update " << update.mCategoryID << llendl; } } diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 2d9ea21b5f..2fb8aea4e9 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -311,10 +311,10 @@ bool LLInventoryFetchDescendentsObserver::isEverythingComplete() const bool LLInventoryFetchDescendentsObserver::isComplete(LLViewerInventoryCategory* cat) { - S32 version = cat->getVersion(); - S32 descendents = cat->getDescendentCount(); - if((LLViewerInventoryCategory::VERSION_UNKNOWN == version) - || (LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN == descendents)) + const S32 version = cat->getVersion(); + const S32 expected_num_descendents = cat->getDescendentCount(); + if ((version == LLViewerInventoryCategory::VERSION_UNKNOWN) || + (expected_num_descendents == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)) { return false; } @@ -325,15 +325,28 @@ bool LLInventoryFetchDescendentsObserver::isComplete(LLViewerInventoryCategory* gInventory.getDirectDescendentsOf(cat->getUUID(), cats, items); if(!cats || !items) { - // bit of a hack - pretend we're done if they are gone or - // incomplete. should never know, but it would suck if this - // kept tight looping because of a corrupt memory state. + llwarns << "Category '" << cat->getName() << "' descendents corrupted, fetch failed." << llendl; + // NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean + // that the cat just doesn't have any items or subfolders). + // Unrecoverable, so just return done so that this observer can be cleared + // from memory. return true; } - S32 known = cats->count() + items->count(); - if(descendents == known) + const S32 current_num_known_descendents = cats->count() + items->count(); + + // Got the number of descendents that we were expecting, so we're done. + if (current_num_known_descendents == expected_num_descendents) + { + return true; + } + + // Error condition, but recoverable. This happens if something was added to the + // category before it was initialized, so accountForUpdate didn't update descendent + // count and thus the category thinks it has fewer descendents than it actually has. + if (current_num_known_descendents >= expected_num_descendents) { - // hey - we're done. + llwarns << "Category '" << cat->getName() << "' expected descendentcount:" << expected_num_descendents << " descendents but got descendentcount:" << current_num_known_descendents << llendl; + cat->setDescendentCount(current_num_known_descendents); return true; } return false; @@ -352,7 +365,7 @@ void LLInventoryFetchComboObserver::changed(U32 mask) continue; } if(item->isComplete()) - { + { mCompleteItems.push_back(*it); it = mIncompleteItems.erase(it); continue; diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 6b0f9b709d..87ebce1d34 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -84,7 +84,6 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) : mHomePageUrl( "" ), mIgnoreUIScale( true ), mAlwaysRefresh( false ), - mExternalUrl( "" ), mMediaSource( 0 ), mTakeFocusOnClick( true ), mCurrentNavUrl( "" ), @@ -877,9 +876,27 @@ bool LLMediaCtrl::onClickLinkExternalTarget(const LLSD& notification, const LLSD S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if ( 0 == option ) { - // open in external browser because we don't support - // creation of our own secondary browser windows - LLWeb::loadURLExternal( notification["payload"]["external_url"].asString() ); + 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; } @@ -993,20 +1010,18 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) void LLMediaCtrl::onClickLinkHref( LLPluginClassMedia* self ) { // retrieve the event parameters - std::string target = self->getClickTarget(); std::string url = self->getClickURL(); + U32 target_type = self->getClickTargetType(); - // if there is a value for the target - if ( !target.empty() ) + // is there is a target specified for the link? + if (target_type == LLPluginClassMedia::TARGET_EXTERNAL || + target_type == LLPluginClassMedia::TARGET_BLANK) { - if ( target == "_external" ) - { - mExternalUrl = url; - LLSD payload; - payload["external_url"] = mExternalUrl; - LLNotificationsUtil::add( "WebLaunchExternalTarget", LLSD(), payload, onClickLinkExternalTarget); - return; - } + LLSD payload; + payload["url"] = url; + payload["target_type"] = LLSD::Integer(target_type); + LLNotificationsUtil::add( "WebLaunchExternalTarget", LLSD(), payload, onClickLinkExternalTarget); + return; } const std::string protocol1( "http://" ); diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 8f9e6e7179..b0aca3cfa4 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -182,7 +182,6 @@ public: bool mOpenLinksInInternalBrowser; bool mTrusted; std::string mHomePageUrl; - std::string mExternalUrl; std::string mCurrentNavUrl; bool mIgnoreUIScale; bool mAlwaysRefresh; diff --git a/indra/newview/llnamebox.cpp b/indra/newview/llnamebox.cpp index 2f4a266198..d434017804 100644 --- a/indra/newview/llnamebox.cpp +++ b/indra/newview/llnamebox.cpp @@ -52,6 +52,7 @@ LLNameBox::LLNameBox(const Params& p) : LLTextBox(p) { mNameID = LLUUID::null; + mLink = p.link; LLNameBox::sInstances.insert(this); setText(LLStringUtil::null); } @@ -76,7 +77,7 @@ void LLNameBox::setNameID(const LLUUID& name_id, BOOL is_group) gCacheName->getGroupName(name_id, name); } - setText(name); + setName(name, is_group); } void LLNameBox::refresh(const LLUUID& id, const std::string& firstname, @@ -93,7 +94,7 @@ void LLNameBox::refresh(const LLUUID& id, const std::string& firstname, { name = firstname; } - setText(name); + setName(name, is_group); } } @@ -109,3 +110,22 @@ void LLNameBox::refreshAll(const LLUUID& id, const std::string& firstname, box->refresh(id, firstname, lastname, is_group); } } + +void LLNameBox::setName(const std::string& name, BOOL is_group) +{ + if (mLink) + { + std::string url; + + if (is_group) + url = "[secondlife:///app/group/" + LLURI::escape(name) + "/about " + name + "]"; + else + url = "[secondlife:///app/agent/" + mNameID.asString() + "/about " + name + "]"; + + setText(url); + } + else + { + setText(name); + } +} diff --git a/indra/newview/llnamebox.h b/indra/newview/llnamebox.h index 3edb36883f..0109525e85 100644 --- a/indra/newview/llnamebox.h +++ b/indra/newview/llnamebox.h @@ -47,9 +47,11 @@ public: struct Params : public LLInitParam::Block { Optional is_group; + Optional link; Params() : is_group("is_group", false) + , link("link", false) {} }; @@ -67,10 +69,13 @@ protected: friend class LLUICtrlFactory; private: + void setName(const std::string& name, BOOL is_group); + static std::set sInstances; private: LLUUID mNameID; + BOOL mLink; }; diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index fc0e51b76d..a7c1e73328 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -179,27 +179,7 @@ void LLNearbyChat::addMessage(const LLChat& chat,bool archive) if (!chat.mMuted) { tmp_chat.mFromName = chat.mFromName; - - if (chat.mChatStyle == CHAT_STYLE_IRC) - { - LLColor4 txt_color = LLUIColorTable::instance().getColor("White"); - LLViewerChat::getChatColor(chat,txt_color); - LLFontGL* fontp = LLViewerChat::getChatFont(); - std::string font_name = LLFontGL::nameFromFont(fontp); - std::string font_size = LLFontGL::sizeFromFont(fontp); - LLStyle::Params append_style_params; - append_style_params.color(txt_color); - append_style_params.readonly_color(txt_color); - append_style_params.font.name(font_name); - append_style_params.font.size(font_size); - append_style_params.font.style = "ITALIC"; - - mChatHistory->appendMessage(chat, use_plain_text_chat_history, append_style_params); - } - else - { - mChatHistory->appendMessage(chat, use_plain_text_chat_history); - } + mChatHistory->appendMessage(chat, use_plain_text_chat_history); } if(archive) diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 8dbaa5ac53..6cf8bcb417 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -48,13 +48,16 @@ #include "llcommandhandler.h" #include "llviewercontrol.h" #include "llnavigationbar.h" +#include "llwindow.h" +#include "llviewerwindow.h" +#include "llrootview.h" S32 LLNearbyChatBar::sLastSpecialChatChannel = 0; // legacy callback glue void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); -static LLDefaultChildRegistry::Register r("gesture_combo_box"); +static LLDefaultChildRegistry::Register r("gesture_combo_list"); struct LLChatTypeTrigger { std::string name; @@ -66,13 +69,42 @@ static LLChatTypeTrigger sChatTypeTriggers[] = { { "/shout" , CHAT_TYPE_SHOUT} }; -LLGestureComboBox::LLGestureComboBox(const LLGestureComboBox::Params& p) - : LLComboBox(p) - , mGestureLabelTimer() +LLGestureComboList::Params::Params() +: combo_button("combo_button"), + combo_list("combo_list") +{ +} + +LLGestureComboList::LLGestureComboList(const LLGestureComboList::Params& p) +: LLUICtrl(p) , mLabel(p.label) , mViewAllItemIndex(0) { - setCommitCallback(boost::bind(&LLGestureComboBox::onCommitGesture, this)); + LLButton::Params button_params = p.combo_button; + button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM|FOLLOWS_RIGHT); + + mButton = LLUICtrlFactory::create(button_params); + mButton->reshape(getRect().getWidth(),getRect().getHeight()); + mButton->setCommitCallback(boost::bind(&LLGestureComboList::onButtonCommit, this)); + + addChild(mButton); + + LLScrollListCtrl::Params params = p.combo_list; + params.name("GestureComboList"); + params.commit_callback.function(boost::bind(&LLGestureComboList::onItemSelected, this, _2)); + params.visible(false); + params.commit_on_keyboard_movement(false); + + mList = LLUICtrlFactory::create(params); + + // *HACK: adding list as a child to NonSideTrayView to make it fully visible without + // making it top control (because it would cause problems). + gViewerWindow->getNonSideTrayView()->addChild(mList); + mList->setVisible(FALSE); + + //****************************Gesture Part********************************/ + + setCommitCallback(boost::bind(&LLGestureComboList::onCommitGesture, this)); // now register us as observer since we have a place to put the results LLGestureManager::instance().addObserver(this); @@ -80,23 +112,139 @@ LLGestureComboBox::LLGestureComboBox(const LLGestureComboBox::Params& p) // refresh list from current active gestures refreshGestures(); - // This forces using of halign from xml, since LLComboBox - // sets it to LLFontGL::LEFT, if text entry is disabled - mButton->setHAlign(p.drop_down_button.font_halign); + setFocusLostCallback(boost::bind(&LLGestureComboList::hideList, this)); } -LLGestureComboBox::~LLGestureComboBox() +BOOL LLGestureComboList::handleKey(KEY key, MASK mask, BOOL called_from_parent) { - LLGestureManager::instance().removeObserver(this); + BOOL handled = FALSE; + + if (key == KEY_ESCAPE && mask == MASK_NONE ) + { + hideList(); + handled = TRUE; + } + else + { + handled = mList->handleKey(key, mask, called_from_parent); + } + + return handled; +} + +void LLGestureComboList::showList() +{ + LLRect rect = mList->getRect(); + LLRect screen; + mButton->localRectToScreen(getRect(), &screen); + + // Calculating amount of space between the navigation bar and gestures combo + LLNavigationBar* nb = LLNavigationBar::getInstance(); + + S32 x, nb_bottom; + nb->localPointToScreen(0, 0, &x, &nb_bottom); + + S32 max_height = nb_bottom - screen.mTop; + mList->calcColumnWidths(); + rect.setOriginAndSize(screen.mLeft, screen.mTop, llmax(mList->getMaxContentWidth(),mButton->getRect().getWidth()), max_height); + + mList->setRect(rect); + mList->fitContents( llmax(mList->getMaxContentWidth(),mButton->getRect().getWidth()), max_height); + + gFocusMgr.setKeyboardFocus(this); + + // Show the list and push the button down + mButton->setToggleState(TRUE); + mList->setVisible(TRUE); +} + +void LLGestureComboList::onButtonCommit() +{ + if (!mList->getVisible()) + { + // highlight the last selected item from the original selection before potentially selecting a new item + // as visual cue to original value of combo box + LLScrollListItem* last_selected_item = mList->getLastSelectedItem(); + if (last_selected_item) + { + mList->mouseOverHighlightNthItem(mList->getItemIndex(last_selected_item)); + } + + if (mList->getItemCount() != 0) + { + showList(); + } + } + else + { + hideList(); + } +} + +void LLGestureComboList::hideList() +{ + if (mList->getVisible()) + { + mButton->setToggleState(FALSE); + mList->setVisible(FALSE); + mList->mouseOverHighlightNthItem(-1); + gFocusMgr.setKeyboardFocus(NULL); + } +} + +S32 LLGestureComboList::getCurrentIndex() const +{ + LLScrollListItem* item = mList->getFirstSelected(); + if( item ) + { + return mList->getItemIndex( item ); + } + return -1; +} + +void LLGestureComboList::onItemSelected(const LLSD& data) +{ + const std::string name = mList->getSelectedItemLabel(); + + S32 cur_id = getCurrentIndex(); + mLastSelectedIndex = cur_id; + if (cur_id != mList->getItemCount()-1 && cur_id != -1) + { + mButton->setLabel(name); + } + + // hiding the list reasserts the old value stored in the text editor/dropdown button + hideList(); + + // commit does the reverse, asserting the value in the list + onCommit(); +} + +void LLGestureComboList::sortByName(bool ascending) +{ + mList->sortOnce(0, ascending); +} + +LLSD LLGestureComboList::getValue() const +{ + LLScrollListItem* item = mList->getFirstSelected(); + if( item ) + { + return item->getValue(); + } + else + { + return LLSD(); + } } -void LLGestureComboBox::refreshGestures() +void LLGestureComboList::refreshGestures() { //store current selection so we can maintain it LLSD cur_gesture = getValue(); - selectFirstItem(); - // clear - clearRows(); + + mList->selectFirstItem(); + mList->clearRows(); mGestures.clear(); LLGestureManager::item_map_t::const_iterator it; @@ -107,7 +255,7 @@ void LLGestureComboBox::refreshGestures() LLMultiGesture* gesture = (*it).second; if (gesture) { - addSimpleElement(gesture->mName, ADD_BOTTOM, LLSD(idx)); + mList->addSimpleElement(gesture->mName, ADD_BOTTOM, LLSD(idx)); mGestures.push_back(gesture); idx++; } @@ -117,23 +265,42 @@ void LLGestureComboBox::refreshGestures() // store index followed by the last added Gesture and add View All item at bottom mViewAllItemIndex = idx; - addSimpleElement(LLTrans::getString("ViewAllGestures"), ADD_BOTTOM, LLSD(mViewAllItemIndex)); + + mList->addSimpleElement(LLTrans::getString("ViewAllGestures"), ADD_BOTTOM, LLSD(mViewAllItemIndex)); // Insert label after sorting, at top, with separator below it - addSeparator(ADD_TOP); - addSimpleElement(mLabel, ADD_TOP); + mList->addSeparator(ADD_TOP); + mList->addSimpleElement(mLabel, ADD_TOP); if (cur_gesture.isDefined()) { - selectByValue(cur_gesture); + mList->selectByValue(cur_gesture); + } else { - selectFirstItem(); + mList->selectFirstItem(); } + + LLCtrlListInterface* gestures = getListInterface(); + LLMultiGesture* gesture = NULL; + + if (gestures) + { + S32 index = gestures->getSelectedValue().asInteger(); + if(index > 0) + gesture = mGestures.at(index); + } + + if(gesture && LLGestureManager::instance().isGesturePlaying(gesture)) + { + return; + } + + mButton->setLabel(mLabel); } -void LLGestureComboBox::onCommitGesture() +void LLGestureComboList::onCommitGesture() { LLCtrlListInterface* gestures = getListInterface(); if (gestures) @@ -164,50 +331,11 @@ void LLGestureComboBox::onCommitGesture() } } } - - mGestureLabelTimer.start(); - // free focus back to chat bar - setFocus(FALSE); } -//virtual -void LLGestureComboBox::draw() +LLGestureComboList::~LLGestureComboList() { - // HACK: Leave the name of the gesture in place for a few seconds. - const F32 SHOW_GESTURE_NAME_TIME = 2.f; - if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME) - { - LLCtrlListInterface* gestures = getListInterface(); - if (gestures) gestures->selectFirstItem(); - mGestureLabelTimer.stop(); - } - - LLComboBox::draw(); -} - -//virtual -void LLGestureComboBox::showList() -{ - LLComboBox::showList(); - - // Calculating amount of space between the navigation bar and gestures combo - LLNavigationBar* nb = LLNavigationBar::getInstance(); - S32 x, nb_bottom; - nb->localPointToScreen(0, 0, &x, &nb_bottom); - - S32 list_bottom; - mList->localPointToScreen(0, 0, &x, &list_bottom); - - S32 max_height = nb_bottom - list_bottom; - - LLRect rect = mList->getRect(); - // List overlapped navigation bar, downsize it - if (rect.getHeight() > max_height) - { - rect.setOriginAndSize(rect.mLeft, rect.mBottom, rect.getWidth(), max_height); - mList->setRect(rect); - mList->reshape(rect.getWidth(), rect.getHeight()); - } + LLGestureManager::instance().removeObserver(this); } LLNearbyChatBar::LLNearbyChatBar() diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index 224118e088..d9a7403611 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -42,33 +42,52 @@ #include "llspeakers.h" -class LLGestureComboBox - : public LLComboBox - , public LLGestureManagerObserver +class LLGestureComboList + : public LLGestureManagerObserver + , public LLUICtrl { public: - struct Params : public LLInitParam::Block { }; + struct Params : public LLInitParam::Block + { + Optional combo_button; + Optional combo_list; + + Params(); + }; + protected: - LLGestureComboBox(const Params&); + friend class LLUICtrlFactory; + LLGestureComboList(const Params&); + std::vector mGestures; + std::string mLabel; + LLSD::Integer mViewAllItemIndex; + public: - ~LLGestureComboBox(); + ~LLGestureComboList(); + + LLCtrlListInterface* getListInterface() { return (LLCtrlListInterface*)mList; }; + virtual void showList(); + virtual void hideList(); + virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); + + S32 getCurrentIndex() const; + void onItemSelected(const LLSD& data); + void sortByName(bool ascending = true); void refreshGestures(); void onCommitGesture(); - virtual void draw(); + void onButtonCommit(); + virtual LLSD getValue() const; // LLGestureManagerObserver trigger virtual void changed() { refreshGestures(); } -protected: - - virtual void showList(); +private: - LLFrameTimer mGestureLabelTimer; - std::vector mGestures; - std::string mLabel; - LLSD::Integer mViewAllItemIndex; + LLButton* mButton; + LLScrollListCtrl* mList; + S32 mLastSelectedIndex; }; class LLNearbyChatBar diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index 9e13a626b4..96442fafcc 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -180,6 +180,11 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification) if(panel && panel->messageID() == fromID && panel->canAddText()) { + if (CHAT_STYLE_IRC == notification["chat_style"].asInteger()) + { + notification["message"] = notification["from"].asString() + notification["message"].asString(); + } + panel->addMessage(notification); toast->reshapeToPanel(); toast->resetTimer(); @@ -302,7 +307,6 @@ LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& i channel->setCreatePanelCallback(callback); mChannel = LLChannelManager::getInstance()->addChannel(channel); - mChannel->setOverflowFormatString("You have %d unread nearby chat messages"); } LLNearbyChatHandler::~LLNearbyChatHandler() @@ -332,25 +336,22 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg) LLChat& tmp_chat = const_cast(chat_msg); - if (tmp_chat.mChatStyle == CHAT_STYLE_IRC) - { - if(!tmp_chat.mFromName.empty()) - tmp_chat.mText = tmp_chat.mFromName + tmp_chat.mText.substr(3); - else - tmp_chat.mText = tmp_chat.mText.substr(3); - } - + LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("nearby_chat", LLSD()); { //sometimes its usefull to have no name at all... //if(tmp_chat.mFromName.empty() && tmp_chat.mFromID!= LLUUID::null) // tmp_chat.mFromName = tmp_chat.mFromID.asString(); } - - LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance("nearby_chat", LLSD()); nearby_chat->addMessage(chat_msg); if(nearby_chat->getVisible()) return;//no need in toast if chat is visible - + + // Handle irc styled messages for toast panel + if (tmp_chat.mChatStyle == CHAT_STYLE_IRC) + { + tmp_chat.mText = tmp_chat.mText.substr(3); + } + // arrange a channel on a screen if(!mChannel->getVisible()) { diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp index 63803469dd..f816dc589d 100644 --- a/indra/newview/lloutputmonitorctrl.cpp +++ b/indra/newview/lloutputmonitorctrl.cpp @@ -77,7 +77,9 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p) mImageLevel3(p.image_level_3), mAutoUpdate(p.auto_update), mSpeakerId(p.speaker_id), - mIsAgentControl(false) + mIsAgentControl(false), + mIsSwitchDirty(false), + mShouldSwitchOn(false) { //static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange); //static LLUIColor output_monitor_overdriven_color = LLUIColorTable::instance().getColor("OutputMonitorOverdrivenColor", LLColor4::red); @@ -108,6 +110,7 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p) LLOutputMonitorCtrl::~LLOutputMonitorCtrl() { LLMuteList::getInstance()->removeObserver(this); + LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this); } void LLOutputMonitorCtrl::setPower(F32 val) @@ -117,6 +120,26 @@ void LLOutputMonitorCtrl::setPower(F32 val) void LLOutputMonitorCtrl::draw() { + // see also switchIndicator() + if (mIsSwitchDirty) + { + mIsSwitchDirty = false; + if (mShouldSwitchOn) + { + // just notify parent visibility may have changed + notifyParentVisibilityChanged(); + } + else + { + // make itself invisible and notify parent about this + setVisible(FALSE); + notifyParentVisibilityChanged(); + + // no needs to render for invisible element + return; + } + } + // Copied from llmediaremotectrl.cpp // *TODO: Give the LLOutputMonitorCtrl an agent-id to monitor, then // call directly into gVoiceClient to ask if that agent-id is muted, is @@ -229,6 +252,7 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id) if (speaker_id.isNull() || speaker_id == mSpeakerId) return; mSpeakerId = speaker_id; + LLSpeakingIndicatorManager::registerSpeakingIndicator(mSpeakerId, this); //mute management if (mAutoUpdate) @@ -251,3 +275,42 @@ void LLOutputMonitorCtrl::onChange() // check only blocking on voice. EXT-3542 setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat)); } + +// virtual +void LLOutputMonitorCtrl::switchIndicator(bool switch_on) +{ + // ensure indicator is visible in case it is not in visible chain + // to be called when parent became visible next time to notify parent that visibility is changed. + setVisible(TRUE); + + // if parent is in visible chain apply switch_on state and notify it immediately + if (getParent() && getParent()->isInVisibleChain()) + { + LL_DEBUGS("SpeakingIndicator") << "Indicator is in visible chain, notifying parent: " << mSpeakerId << LL_ENDL; + setVisible((BOOL)switch_on); + notifyParentVisibilityChanged(); + } + + // otherwise remember necessary state and mark itself as dirty. + // State will be applied i next draw when parents chain became visible. + else + { + LL_DEBUGS("SpeakingIndicator") << "Indicator is not in visible chain, parent won't be notified: " << mSpeakerId << LL_ENDL; + mIsSwitchDirty = true; + mShouldSwitchOn = switch_on; + } +} + +////////////////////////////////////////////////////////////////////////// +// PRIVATE SECTION +////////////////////////////////////////////////////////////////////////// +void LLOutputMonitorCtrl::notifyParentVisibilityChanged() +{ + LL_DEBUGS("SpeakingIndicator") << "Notify parent that visibility was changed: " << mSpeakerId << " ,new_visibility: " << getVisible() << LL_ENDL; + + LLSD params = LLSD().with("visibility_changed", getVisible()); + + notifyParent(params); +} + +// EOF diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h index 85ea552a57..2bbfa251e9 100644 --- a/indra/newview/lloutputmonitorctrl.h +++ b/indra/newview/lloutputmonitorctrl.h @@ -36,6 +36,7 @@ #include "v4color.h" #include "llview.h" #include "llmutelist.h" +#include "llspeakingindicatormanager.h" class LLTextBox; class LLUICtrlFactory; @@ -45,7 +46,7 @@ class LLUICtrlFactory; // class LLOutputMonitorCtrl -: public LLView, LLMuteListObserver +: public LLView, public LLSpeakingIndicator, LLMuteListObserver { public: struct Params : public LLInitParam::Block @@ -90,7 +91,29 @@ public: //called by mute list virtual void onChange(); + /** + * Implementation of LLSpeakingIndicator interface. + * Behavior is implemented via changing visibility. + * + * If instance is in visible chain now (all parents are visible) it changes visibility + * and notify parent about this. + * + * Otherwise it marks an instance as dirty and stores necessary visibility. + * It will be applied in next draw and parent will be notified. + */ + virtual void switchIndicator(bool switch_on); + private: + + /** + * Notifies parent about changed visibility. + * + * Passes LLSD with "visibility_changed" => value. + * For now it is processed by LLAvatarListItem to update (reshape) its children. + * Implemented fo complete EXT-3976 + */ + void notifyParentVisibilityChanged(); + //static LLColor4 sColorMuted; //static LLColor4 sColorNormal; //static LLColor4 sColorOverdriven; @@ -117,6 +140,10 @@ private: /** uuid of a speaker being monitored */ LLUUID mSpeakerId; + + /** indicates if the instance is dirty and should notify parent */ + bool mIsSwitchDirty; + bool mShouldSwitchOn; }; #endif diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index fb898f7cdf..85e95ca1d6 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -52,6 +52,7 @@ #include "llfloaterreg.h" #include "llnotificationsutil.h" #include "llvoiceclient.h" +#include "llnamebox.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLDropTarget @@ -595,7 +596,10 @@ void LLPanelAvatarProfile::processGroupProperties(const LLAvatarGroups* avatar_g groups += ", "; std::string group_name = LLURI::escape(it->first); - std::string group_url="[secondlife:///app/group/" + it->second.asString() + "/about " + group_name + "]"; + std::string group_url= it->second.notNull() + ? "[secondlife:///app/group/" + it->second.asString() + "/about " + group_name + "]" + : getString("no_group_text"); + groups += group_url; } @@ -621,19 +625,15 @@ void LLPanelAvatarProfile::fillCommonData(const LLAvatarData* avatar_data) void LLPanelAvatarProfile::fillPartnerData(const LLAvatarData* avatar_data) { + LLNameBox* name_box = getChild("partner_text"); if (avatar_data->partner_id.notNull()) { - std::string first, last; - BOOL found = gCacheName->getName(avatar_data->partner_id, first, last); - if (found) - { - childSetTextArg("partner_text", "[FIRST]", first); - childSetTextArg("partner_text", "[LAST]", last); - } + name_box->setNameID(avatar_data->partner_id, FALSE); } else { - childSetTextArg("partner_text", "[FIRST]", getString("no_partner_text")); + name_box->setNameID(LLUUID::null, FALSE); + name_box->setText(getString("no_partner_text")); } } diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 94de17c17d..daec793d75 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -151,6 +151,11 @@ BOOL LLPanelGroup::postBuild() button->setVisible(true); button->setEnabled(false); + button = getChild("btn_call"); + button->setClickedCallback(onBtnGroupCallClicked, this); + + button = getChild("btn_chat"); + button->setClickedCallback(onBtnGroupChatClicked, this); button = getChild("btn_join"); button->setVisible(false); @@ -215,6 +220,8 @@ void LLPanelGroup::reposButtons() reposButton("btn_create"); reposButton("btn_refresh"); reposButton("btn_cancel"); + reposButton("btn_chat"); + reposButton("btn_call"); } void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent ) @@ -262,6 +269,18 @@ void LLPanelGroup::onBtnApply(void* user_data) self->apply(); } +void LLPanelGroup::onBtnGroupCallClicked(void* user_data) +{ + LLPanelGroup* self = static_cast(user_data); + self->callGroup(); +} + +void LLPanelGroup::onBtnGroupChatClicked(void* user_data) +{ + LLPanelGroup* self = static_cast(user_data); + self->chatGroup(); +} + void LLPanelGroup::onBtnJoin() { lldebugs << "joining group: " << mID << llendl; @@ -349,6 +368,8 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id) LLButton* button_create = findChild("btn_create"); LLButton* button_join = findChild("btn_join"); LLButton* button_cancel = findChild("btn_cancel"); + LLButton* button_call = findChild("btn_call"); + LLButton* button_chat = findChild("btn_chat"); bool is_null_group_id = group_id == LLUUID::null; @@ -362,6 +383,11 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id) if(button_cancel) button_cancel->setVisible(!is_null_group_id); + if(button_call) + button_call->setVisible(!is_null_group_id); + if(button_chat) + button_chat->setVisible(!is_null_group_id); + getChild("prepend_founded_by")->setVisible(!is_null_group_id); LLAccordionCtrl* tab_ctrl = findChild("group_accordion"); @@ -423,12 +449,15 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id) getChild("group_name")->setVisible(true); getChild("group_name_editor")->setVisible(false); + + if(button_apply) + button_apply->setVisible(is_member); } reposButtons(); } -bool LLPanelGroup::apply(LLPanelGroupTab* tab) +bool LLPanelGroup::apply(LLPanelGroupTab* tab) { if(!tab) return false; @@ -471,12 +500,17 @@ void LLPanelGroup::draw() childEnable("btn_refresh"); } - bool enable = false; - std::string mesg; - for(std::vector::iterator it = mTabs.begin();it!=mTabs.end();++it) - enable = enable || (*it)->needsApply(mesg); + LLButton* button_apply = findChild("btn_apply"); + + if(button_apply && button_apply->getVisible()) + { + bool enable = false; + std::string mesg; + for(std::vector::iterator it = mTabs.begin();it!=mTabs.end();++it) + enable = enable || (*it)->needsApply(mesg); - childSetEnabled("btn_apply", enable); + childSetEnabled("btn_apply", enable); + } } void LLPanelGroup::refreshData() @@ -491,6 +525,15 @@ void LLPanelGroup::refreshData() mRefreshTimer.setTimerExpirySec(5); } +void LLPanelGroup::callGroup() +{ + LLGroupActions::startCall(getID()); +} + +void LLPanelGroup::chatGroup() +{ + LLGroupActions::startIM(getID()); +} void LLPanelGroup::showNotice(const std::string& subject, const std::string& message, diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index f6aefdb676..7ea5e67b44 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -74,6 +74,8 @@ public: bool apply(); void refreshData(); + void callGroup(); + void chatGroup(); virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); @@ -103,6 +105,8 @@ protected: static void onBtnApply(void*); static void onBtnRefresh(void*); + static void onBtnGroupCallClicked(void*); + static void onBtnGroupChatClicked(void*); void reposButton(const std::string& name); void reposButtons(); diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 31dfdde887..21b253223f 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -580,7 +580,6 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) } } - mComboActiveTitle->resetDirty(); } // If this was just a titles update, we are done. @@ -595,8 +594,6 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) { mCtrlShowInGroupList->set(gdatap->mShowInList); mCtrlShowInGroupList->setEnabled(mAllowEdit && can_change_ident); - mCtrlShowInGroupList->resetDirty(); - } if (mComboMature) { @@ -610,19 +607,16 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) } mComboMature->setEnabled(mAllowEdit && can_change_ident); mComboMature->setVisible( !gAgent.isTeen() ); - mComboMature->resetDirty(); } if (mCtrlOpenEnrollment) { mCtrlOpenEnrollment->set(gdatap->mOpenEnrollment); mCtrlOpenEnrollment->setEnabled(mAllowEdit && can_change_member_opts); - mCtrlOpenEnrollment->resetDirty(); } if (mCtrlEnrollmentFee) { mCtrlEnrollmentFee->set(gdatap->mMembershipFee > 0); mCtrlEnrollmentFee->setEnabled(mAllowEdit && can_change_member_opts); - mCtrlEnrollmentFee->resetDirty(); } if (mSpinEnrollmentFee) @@ -632,7 +626,6 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) mSpinEnrollmentFee->setEnabled( mAllowEdit && (fee > 0) && can_change_member_opts); - mSpinEnrollmentFee->resetDirty(); } if (mCtrlReceiveNotices) { @@ -641,7 +634,6 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) { mCtrlReceiveNotices->setEnabled(mAllowEdit); } - mCtrlReceiveNotices->resetDirty(); } @@ -665,7 +657,6 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) if (mEditCharter) { mEditCharter->setText(gdatap->mCharter); - mEditCharter->resetDirty(); } if (mListVisibleMembers) @@ -693,6 +684,8 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) mListVisibleMembers->addElement(row); } } + + resetDirty(); } void LLPanelGroupGeneral::updateMembers() diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 29b647415c..0e55ff3214 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -460,17 +460,8 @@ LLPanelGroupSubTab::~LLPanelGroupSubTab() { } -BOOL LLPanelGroupSubTab::postBuild() -{ - // Hook up the search widgets. - bool recurse = true; - mSearchEditor = getChild("filter_input", recurse); - - if (!mSearchEditor) - return FALSE; - - mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::setSearchFilter, this, _2)); - +BOOL LLPanelGroupSubTab::postBuildSubTab(LLView* root) +{ // Get icons for later use. mActionIcons.clear(); @@ -488,6 +479,19 @@ BOOL LLPanelGroupSubTab::postBuild() { mActionIcons["partial"] = getString("power_partial_icon"); } + return TRUE; +} + +BOOL LLPanelGroupSubTab::postBuild() +{ + // Hook up the search widgets. + bool recurse = true; + mSearchEditor = getChild("filter_input", recurse); + + if (!mSearchEditor) + return FALSE; + + mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::setSearchFilter, this, _2)); return LLPanelGroupTab::postBuild(); } @@ -567,7 +571,6 @@ bool LLPanelGroupSubTab::matchesActionSearchFilter(std::string action) void LLPanelGroupSubTab::buildActionsList(LLScrollListCtrl* ctrl, U64 allowed_by_some, U64 allowed_by_all, - icon_map_t& icons, LLUICtrl::commit_callback_t commit_callback, BOOL show_all, BOOL filter, @@ -588,7 +591,6 @@ void LLPanelGroupSubTab::buildActionsList(LLScrollListCtrl* ctrl, allowed_by_some, allowed_by_all, (*ras_it), - icons, commit_callback, show_all, filter, @@ -600,7 +602,6 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl, U64 allowed_by_some, U64 allowed_by_all, LLRoleActionSet* action_set, - icon_map_t& icons, LLUICtrl::commit_callback_t commit_callback, BOOL show_all, BOOL filter, @@ -614,26 +615,26 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl, LLSD row; row["columns"][0]["column"] = "icon"; - icon_map_t::iterator iter = icons.find("folder"); - if (iter != icons.end()) + row["columns"][0]["type"] = "icon"; + + icon_map_t::iterator iter = mActionIcons.find("folder"); + if (iter != mActionIcons.end()) { - row["columns"][0]["type"] = "icon"; row["columns"][0]["value"] = (*iter).second; } row["columns"][1]["column"] = "action"; + row["columns"][1]["type"] = "text"; row["columns"][1]["value"] = action_set->mActionSetData->mName; row["columns"][1]["font"]["name"] = "SANSSERIF_SMALL"; - row["columns"][1]["font"]["style"] = "BOLD"; + LLScrollListItem* title_row = ctrl->addElement(row, ADD_BOTTOM, action_set->mActionSetData); - LLScrollListText* name_textp = dynamic_cast(title_row->getColumn(1)); + LLScrollListText* name_textp = dynamic_cast(title_row->getColumn(2)); //?? I have no idea fix getColumn(1) return column spacer... if (name_textp) name_textp->setFontStyle(LLFontGL::BOLD); - - bool category_matches_filter = (filter) ? matchesActionSearchFilter(action_set->mActionSetData->mName) : true; std::vector::iterator ra_it = action_set->mActions.begin(); @@ -686,8 +687,8 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl, { if (show_full_strength) { - icon_map_t::iterator iter = icons.find("full"); - if (iter != icons.end()) + icon_map_t::iterator iter = mActionIcons.find("full"); + if (iter != mActionIcons.end()) { row["columns"][column_index]["column"] = "checkbox"; row["columns"][column_index]["type"] = "icon"; @@ -697,8 +698,8 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl, } else { - icon_map_t::iterator iter = icons.find("partial"); - if (iter != icons.end()) + icon_map_t::iterator iter = mActionIcons.find("partial"); + if (iter != mActionIcons.end()) { row["columns"][column_index]["column"] = "checkbox"; row["columns"][column_index]["type"] = "icon"; @@ -792,6 +793,8 @@ LLPanelGroupMembersSubTab::~LLPanelGroupMembersSubTab() BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) { + LLPanelGroupSubTab::postBuildSubTab(root); + // Upcast parent so we can ask it for sibling controls. LLPanelGroupRoles* parent = (LLPanelGroupRoles*) root; @@ -888,7 +891,6 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() buildActionsList(mAllowedActionsList, allowed_by_some, allowed_by_all, - mActionIcons, NULL, FALSE, FALSE, @@ -1211,7 +1213,6 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id, buildActionsList(mAllowedActionsList, powers_some_have, powers_all_have, - mActionIcons, NULL, FALSE, FALSE, @@ -1684,6 +1685,8 @@ LLPanelGroupRolesSubTab::~LLPanelGroupRolesSubTab() BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root) { + LLPanelGroupSubTab::postBuildSubTab(root); + // Upcast parent so we can ask it for sibling controls. LLPanelGroupRoles* parent = (LLPanelGroupRoles*) root; @@ -1994,7 +1997,6 @@ void LLPanelGroupRolesSubTab::handleRoleSelect() buildActionsList(mAllowedActionsList, rd.mRolePowers, 0LL, - mActionIcons, boost::bind(&LLPanelGroupRolesSubTab::handleActionCheck, this, _1, false), TRUE, FALSE, @@ -2381,6 +2383,8 @@ LLPanelGroupActionsSubTab::~LLPanelGroupActionsSubTab() BOOL LLPanelGroupActionsSubTab::postBuildSubTab(LLView* root) { + LLPanelGroupSubTab::postBuildSubTab(root); + // Upcast parent so we can ask it for sibling controls. LLPanelGroupRoles* parent = (LLPanelGroupRoles*) root; @@ -2448,7 +2452,6 @@ void LLPanelGroupActionsSubTab::update(LLGroupChange gc) buildActionsList(mActionList, GP_ALL_POWERS, GP_ALL_POWERS, - mActionIcons, NULL, FALSE, TRUE, diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index bb3c9096cf..2f81900e60 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -108,7 +108,7 @@ public: virtual BOOL postBuild(); // This allows sub-tabs to collect child widgets from a higher level in the view hierarchy. - virtual BOOL postBuildSubTab(LLView* root) { return TRUE; } + virtual BOOL postBuildSubTab(LLView* root); virtual void setSearchFilter( const std::string& filter ); @@ -117,10 +117,15 @@ public: // Helper functions bool matchesActionSearchFilter(std::string action); + + + void setFooterEnabled(BOOL enable); + + virtual void setGroupID(const LLUUID& id); +protected: void buildActionsList(LLScrollListCtrl* ctrl, U64 allowed_by_some, U64 allowed_by_all, - icon_map_t& icons, LLUICtrl::commit_callback_t commit_callback, BOOL show_all, BOOL filter, @@ -129,15 +134,11 @@ public: U64 allowed_by_some, U64 allowed_by_all, LLRoleActionSet* action_set, - icon_map_t& icons, LLUICtrl::commit_callback_t commit_callback, BOOL show_all, BOOL filter, BOOL is_owner_role); - void setFooterEnabled(BOOL enable); - - virtual void setGroupID(const LLUUID& id); protected: LLPanel* mHeader; LLPanel* mFooter; diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index b547997e7a..0cfe501fab 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -302,7 +302,7 @@ void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id) { LLPanelChatControlPanel::setSessionId(session_id); - mGroupID = LLIMModel::getInstance()->getOtherParticipantID(session_id); + mGroupID = session_id; // for group and Ad-hoc chat we need to include agent into list if(!mParticipantList) diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index e14a5778ad..03cc870a59 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -35,6 +35,7 @@ // libs #include "llfloaterreg.h" #include "llmenugl.h" +#include "llnotificationsutil.h" #include "llfiltereditor.h" #include "lltabcontainer.h" #include "lluictrlfactory.h" @@ -750,7 +751,6 @@ void LLPanelPeople::updateButtons() LLPanel* groups_panel = mTabContainer->getCurrentPanel(); groups_panel->childSetEnabled("activate_btn", item_selected && !cur_group_active); // "none" or a non-active group selected - groups_panel->childSetEnabled("plus_btn", item_selected); groups_panel->childSetEnabled("minus_btn", item_selected && selected_id.notNull()); } else @@ -1138,6 +1138,12 @@ void LLPanelPeople::onAvatarPicked( void LLPanelPeople::onGroupPlusButtonClicked() { + if (!gAgent.canJoinGroups()) + { + LLNotificationsUtil::add("JoinedTooManyGroups"); + return; + } + LLMenuGL* plus_menu = (LLMenuGL*)mGroupPlusMenuHandle.get(); if (!plus_menu) return; diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp index 7a4dd3569d..e7615929c8 100644 --- a/indra/newview/llpanelpick.cpp +++ b/indra/newview/llpanelpick.cpp @@ -35,24 +35,30 @@ // profile. #include "llviewerprecompiledheaders.h" -#include "llpanel.h" + +#include "llpanelpick.h" + #include "message.h" -#include "llagent.h" -#include "llagentpicksinfo.h" + +#include "llparcel.h" + #include "llbutton.h" +#include "llfloaterreg.h" #include "lliconctrl.h" #include "lllineeditor.h" -#include "llparcel.h" -#include "llviewerparcelmgr.h" +#include "llpanel.h" +#include "llscrollcontainer.h" #include "lltexteditor.h" + +#include "llagent.h" +#include "llagentpicksinfo.h" +#include "llavatarpropertiesprocessor.h" +#include "llfloaterworldmap.h" #include "lltexturectrl.h" #include "lluiconstants.h" +#include "llviewerparcelmgr.h" #include "llviewerregion.h" #include "llworldmap.h" -#include "llfloaterworldmap.h" -#include "llfloaterreg.h" -#include "llavatarpropertiesprocessor.h" -#include "llpanelpick.h" #define XML_PANEL_EDIT_PICK "panel_edit_pick.xml" @@ -93,6 +99,10 @@ LLPanelPickInfo::LLPanelPickInfo() , mPickId(LLUUID::null) , mParcelId(LLUUID::null) , mRequestedId(LLUUID::null) + , mScrollingPanelMinHeight(0) + , mScrollingPanelWidth(0) + , mScrollingPanel(NULL) + , mScrollContainer(NULL) { } @@ -146,9 +156,35 @@ BOOL LLPanelPickInfo::postBuild() childSetAction("show_on_map_btn", boost::bind(&LLPanelPickInfo::onClickMap, this)); childSetAction("back_btn", boost::bind(&LLPanelPickInfo::onClickBack, this)); + mScrollingPanel = getChild("scroll_content_panel"); + mScrollContainer = getChild("profile_scroll"); + + mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight(); + mScrollingPanelWidth = mScrollingPanel->getRect().getWidth(); + return TRUE; } +void LLPanelPickInfo::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + LLPanel::reshape(width, height, called_from_parent); + + if (!mScrollContainer || !mScrollingPanel) + return; + + static LLUICachedControl scrollbar_size ("UIScrollbarSize", 0); + + S32 scroll_height = mScrollContainer->getRect().getHeight(); + if (mScrollingPanelMinHeight >= scroll_height) + { + mScrollingPanel->reshape(mScrollingPanelWidth, mScrollingPanelMinHeight); + } + else + { + mScrollingPanel->reshape(mScrollingPanelWidth + scrollbar_size, scroll_height); + } +} + void LLPanelPickInfo::processProperties(void* data, EAvatarProcessorType type) { if(APT_PICK_INFO != type) @@ -284,7 +320,6 @@ void LLPanelPickInfo::setPickName(const std::string& name) void LLPanelPickInfo::setPickDesc(const std::string& desc) { childSetValue(XML_DESC, desc); - updateContentPanelRect(); } void LLPanelPickInfo::setPickLocation(const std::string& location) @@ -292,31 +327,6 @@ void LLPanelPickInfo::setPickLocation(const std::string& location) childSetValue(XML_LOCATION, location); } -void LLPanelPickInfo::updateContentPanelRect() -{ - LLTextBox* desc = getChild(XML_DESC); - - S32 text_height = desc->getTextPixelHeight(); - LLRect text_rect = desc->getRect(); - - // let text-box height fit text height - text_rect.set(text_rect.mLeft, text_rect.mTop, text_rect.mRight, text_rect.mTop - text_height); - desc->setRect(text_rect); - desc->reshape(text_rect.getWidth(), text_rect.getHeight()); - // force reflow - desc->setText(desc->getText()); - - // bottom of description text-box will be bottom of content panel - desc->localRectToOtherView(desc->getLocalRect(), &text_rect, getChild("profile_scroll")); - - LLPanel* content_panel = getChild("scroll_content_panel"); - LLRect content_rect = content_panel->getRect(); - content_rect.set(content_rect.mLeft, content_rect.mTop, content_rect.mRight, text_rect.mBottom); - // Somehow setRect moves all elements down. - // Single reshape() updates rect and does not move anything. - content_panel->reshape(content_rect.getWidth(), content_rect.getHeight()); -} - void LLPanelPickInfo::onClickMap() { LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal()); diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h index 12b5a116b4..62c3b20c0d 100644 --- a/indra/newview/llpanelpick.h +++ b/indra/newview/llpanelpick.h @@ -43,6 +43,7 @@ class LLIconCtrl; class LLTextureCtrl; +class LLScrollContainer; class LLMessageSystem; class LLAvatarPropertiesObserver; @@ -69,6 +70,8 @@ public: /*virtual*/ BOOL postBuild(); + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); /** @@ -139,15 +142,6 @@ protected: virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; } virtual LLVector3d& getPosGlobal() { return mPosGlobal; } - /** - * Reshapes content panel to fit all elements. - * - * Assume that description text-box is the last element of panel. - * Reshape text-box to fit text height and then reshape content panel to fit - * text-box bottom. EXT-1326 - */ - void updateContentPanelRect(); - /** * Callback for "Map" button, opens Map */ @@ -162,7 +156,11 @@ protected: protected: - LLTextureCtrl* mSnapshotCtrl; + S32 mScrollingPanelMinHeight; + S32 mScrollingPanelWidth; + LLScrollContainer* mScrollContainer; + LLPanel* mScrollingPanel; + LLTextureCtrl* mSnapshotCtrl; LLUUID mAvatarId; LLVector3d mPosGlobal; diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 5ee8704992..b134cf0cba 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -71,6 +71,10 @@ public: void setItem(LLInventoryItem* item); + LLInventoryItem* getItem() { return mItem; } + + std::string getPlaceInfoType() { return mPlaceInfoType; } + private: void onLandmarkLoaded(LLLandmark* landmark); void onFilterEdit(const std::string& search_string, bool force_filter); diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 65a3d9d41b..0a2217fc51 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -550,7 +550,7 @@ void LLTeleportHistoryPanel::updateVerbs() LLTeleportHistoryFlatItem* itemp = dynamic_cast (mLastSelectedFlatlList->getSelectedItem()); - mTeleportBtn->setEnabled(NULL != itemp && itemp->getIndex() < (S32)mTeleportHistory->getItems().size() - 1); + mTeleportBtn->setEnabled(NULL != itemp); mShowOnMapBtn->setEnabled(NULL != itemp); } diff --git a/indra/newview/llpanelvolumepulldown.cpp b/indra/newview/llpanelvolumepulldown.cpp new file mode 100644 index 0000000000..74e37efe4e --- /dev/null +++ b/indra/newview/llpanelvolumepulldown.cpp @@ -0,0 +1,154 @@ +/** + * @file llpanelvolumepulldown.cpp + * @author Tofu Linden + * @brief A floater showing the master volume pull-down + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelvolumepulldown.h" + +// Viewer libs +#include "llviewercontrol.h" +#include "llstatusbar.h" + +// Linden libs +#include "llbutton.h" +#include "lltabcontainer.h" +#include "llfloaterreg.h" +#include "llfloaterpreference.h" +#include "llslider.h" + +/* static */ const F32 LLPanelVolumePulldown::sAutoCloseFadeStartTimeSec = 4.0f; +/* static */ const F32 LLPanelVolumePulldown::sAutoCloseTotalTimeSec = 5.0f; + +///---------------------------------------------------------------------------- +/// Class LLPanelVolumePulldown +///---------------------------------------------------------------------------- + +// Default constructor +LLPanelVolumePulldown::LLPanelVolumePulldown() +{ + mCommitCallbackRegistrar.add("Vol.setControlFalse", boost::bind(&LLPanelVolumePulldown::setControlFalse, this, _2)); + mCommitCallbackRegistrar.add("Vol.GoAudioPrefs", boost::bind(&LLPanelVolumePulldown::onAdvancedButtonClick, this, _2)); + LLUICtrlFactory::instance().buildPanel(this, "panel_volume_pulldown.xml"); +} + +BOOL LLPanelVolumePulldown::postBuild() +{ + // set the initial volume-slider's position to reflect reality + LLSlider* volslider = getChild( "mastervolume" ); + volslider->setValue(gSavedSettings.getF32("AudioLevelMaster")); + + return LLPanel::postBuild(); +} + +/*virtual*/ +void LLPanelVolumePulldown::onMouseEnter(S32 x, S32 y, MASK mask) +{ + mHoverTimer.stop(); + LLPanel::onMouseEnter(x,y,mask); +} + + +/*virtual*/ +void LLPanelVolumePulldown::onMouseLeave(S32 x, S32 y, MASK mask) +{ + mHoverTimer.start(); + LLPanel::onMouseLeave(x,y,mask); +} + +/*virtual*/ +void LLPanelVolumePulldown::handleVisibilityChange ( BOOL new_visibility ) +{ + if (new_visibility) + { + mHoverTimer.start(); // timer will be stopped when mouse hovers over panel + gFocusMgr.setTopCtrl(this); + } + else + { + mHoverTimer.stop(); + gFocusMgr.setTopCtrl(NULL); + } +} + +/*virtual*/ +void LLPanelVolumePulldown::onTopLost() +{ + setVisible(FALSE); +} + +void LLPanelVolumePulldown::onAdvancedButtonClick(const LLSD& user_data) +{ + // close the global volume minicontrol, we're bringing up the big one + setVisible(FALSE); + + // bring up the prefs floater + LLFloaterPreference* prefsfloater = dynamic_cast + (LLFloaterReg::showInstance("preferences")); + if (prefsfloater) + { + // grab the 'audio' panel from the preferences floater and + // bring it the front! + LLTabContainer* tabcontainer = prefsfloater->getChild("pref core"); + LLPanel* audiopanel = prefsfloater->getChild("audio"); + if (tabcontainer && audiopanel) + { + tabcontainer->selectTabPanel(audiopanel); + } + } +} + +void LLPanelVolumePulldown::setControlFalse(const LLSD& user_data) +{ + std::string control_name = user_data.asString(); + LLControlVariable* control = findControl(control_name); + + if (control) + control->set(LLSD(FALSE)); +} + +//virtual +void LLPanelVolumePulldown::draw() +{ + F32 alpha = mHoverTimer.getStarted() + ? clamp_rescale(mHoverTimer.getElapsedTimeF32(), sAutoCloseFadeStartTimeSec, sAutoCloseTotalTimeSec, 1.f, 0.f) + : 1.0f; + LLViewDrawContext context(alpha); + + LLPanel::draw(); + + if (alpha == 0.f) + { + setVisible(FALSE); + } +} + diff --git a/indra/newview/llpanelvolumepulldown.h b/indra/newview/llpanelvolumepulldown.h new file mode 100644 index 0000000000..9f20caa1a8 --- /dev/null +++ b/indra/newview/llpanelvolumepulldown.h @@ -0,0 +1,64 @@ +/** + * @file llpanelvolumepulldown.h + * @author Tofu Linden + * @brief A panel showing the master volume pull-down + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELVOLUMEPULLDOWN_H +#define LL_LLPANELVOLUMEPULLDOWN_H + +#include "linden_common.h" + +#include "llpanel.h" + +class LLFrameTimer; + +class LLPanelVolumePulldown : public LLPanel +{ + public: + LLPanelVolumePulldown(); + /*virtual*/ void draw(); + /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); + /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); + /*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); + /*virtual*/ void onTopLost(); + /*virtual*/ BOOL postBuild(); + + private: + void setControlFalse(const LLSD& user_data); + void onAdvancedButtonClick(const LLSD& user_data); + + LLFrameTimer mHoverTimer; + static const F32 sAutoCloseFadeStartTimeSec; + static const F32 sAutoCloseTotalTimeSec; +}; + + +#endif // LL_LLPANELVOLUMEPULLDOWN_H diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index e2da4c4475..b6f78d08f1 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -166,7 +166,6 @@ void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param) { name.erase(found, moderator_indicator_len); item->setName(name); - item->reshapeAvatarName(); } } } @@ -188,7 +187,6 @@ void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param) name += " "; name += moderator_indicator; item->setName(name); - item->reshapeAvatarName(); } } } @@ -279,6 +277,9 @@ bool LLParticipantList::onModeratorUpdateEvent(LLPointer e mModeratorList.erase(id); } } + + // apply changes immediately + onAvatarListRefreshed(mAvatarList, LLSD()); } } return true; @@ -592,8 +593,7 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD& if (speakerp.notNull()) { // not in voice participants can not be moderated - return speakerp->mStatus == LLSpeaker::STATUS_VOICE_ACTIVE - || speakerp->mStatus == LLSpeaker::STATUS_MUTED; + return speakerp->isInVoiceChannel(); } } return false; diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index da3f1543dd..027f3daffb 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -59,17 +59,14 @@ bool LLScreenChannel::mWasStartUpToastShown = false; // LLScreenChannelBase ////////////////////// LLScreenChannelBase::LLScreenChannelBase(const LLUUID& id) : - mOverflowToastPanel(NULL) - ,mToastAlignment(NA_BOTTOM) + mToastAlignment(NA_BOTTOM) ,mCanStoreToasts(true) ,mHiddenToastsNum(0) - ,mOverflowToastHidden(false) ,mHoveredToast(NULL) ,mControlHovering(false) ,mShowToasts(true) { mID = id; - mOverflowFormatString = LLTrans::getString("OverflowInfoChannelString"); mWorldViewRectConnection = gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLScreenChannelBase::updatePositionAndSize, this, _1, _2)); setMouseOpaque( false ); setVisible(FALSE); @@ -217,11 +214,6 @@ void LLScreenChannel::addToast(const LLToast::Params& p) ToastElem new_toast_elem(p); - // reset HIDDEN flags for the Overflow Toast - mOverflowToastHidden = false; - if(mOverflowToastPanel) - mOverflowToastPanel->setIsHidden(false); - new_toast_elem.toast->setOnFadeCallback(boost::bind(&LLScreenChannel::onToastFade, this, _1)); new_toast_elem.toast->setOnToastDestroyedCallback(boost::bind(&LLScreenChannel::onToastDestroyed, this, _1)); if(mControlHovering) @@ -322,8 +314,6 @@ void LLScreenChannel::loadStoredToastsToChannel() if(mStoredToastList.size() == 0) return; - - mOverflowToastHidden = false; for(it = mStoredToastList.begin(); it != mStoredToastList.end(); ++it) { @@ -344,8 +334,6 @@ void LLScreenChannel::loadStoredToastByNotificationIDToChannel(LLUUID id) if( it == mStoredToastList.end() ) return; - mOverflowToastHidden = false; - LLToast* toast = (*it).toast; if(toast->getVisible()) @@ -357,7 +345,6 @@ void LLScreenChannel::loadStoredToastByNotificationIDToChannel(LLUUID id) toast->setIsHidden(false); toast->resetTimer(); mToastList.push_back((*it)); - mStoredToastList.erase(it); redrawToasts(); } @@ -491,7 +478,7 @@ void LLScreenChannel::showToastsBottom() if(floater && floater->overlapsScreenChannel()) { LLRect world_rect = gViewerWindow->getWorldViewRectScaled(); - if(toast_rect.mTop + getOverflowToastHeight() + toast_margin > world_rect.mTop) + if(toast_rect.mTop > world_rect.mTop) { break; } @@ -527,7 +514,7 @@ void LLScreenChannel::showToastsBottom() } } - if(it != mToastList.rend() && !mOverflowToastHidden) + if(it != mToastList.rend()) { mHiddenToastsNum = 0; for(; it != mToastList.rend(); it++) @@ -536,7 +523,6 @@ void LLScreenChannel::showToastsBottom() (*it).toast->setVisible(FALSE); mHiddenToastsNum++; } - createOverflowToast(bottom, gSavedSettings.getS32("NotificationTipToastLifeTime")); } else { @@ -566,94 +552,6 @@ void LLScreenChannel::showToastsTop() { } -//-------------------------------------------------------------------------- -void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer) -{ - LLRect toast_rect; - LLToast::Params p; - p.lifetime_secs = timer; - - if(!mOverflowToastPanel) - mOverflowToastPanel = new LLToast(p); - - if(!mOverflowToastPanel) - return; - - mOverflowToastPanel->startFading(); - mOverflowToastPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::onOverflowToastHide, this)); - - LLTextBox* text_box = mOverflowToastPanel->getChild("toast_text"); - std::string text = llformat(mOverflowFormatString.c_str(),mHiddenToastsNum); - if(mHiddenToastsNum == 1) - { - text += "."; - } - else - { - text += "s."; - } - - toast_rect = mOverflowToastPanel->getRect(); - mOverflowToastPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true); - toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastGap"), getRect().getWidth(), toast_rect.getHeight()); - mOverflowToastPanel->setRect(toast_rect); - - // don't show overflow toast if there is not enough space for it. - LLDockableFloater* floater = dynamic_cast(LLDockableFloater::getInstanceHandle().get()); - if(floater && floater->overlapsScreenChannel()) - { - LLRect world_rect = gViewerWindow->getWorldViewRectScaled(); - if(toast_rect.mTop > world_rect.mTop) - { - closeOverflowToastPanel(); - return; - } - } - - text_box->setValue(text); - text_box->setVisible(TRUE); - - mOverflowToastPanel->setVisible(TRUE); -} - -//-------------------------------------------------------------------------- -void LLScreenChannel::onOverflowToastHide() -{ - mOverflowToastHidden = true; - - // remove all hidden toasts from channel and save interactive notifications - for(std::vector::iterator it = mToastList.begin(); it != mToastList.end();) - { - if(!(*it).toast->getVisible()) - { - if((*it).toast->getCanBeStored()) - { - storeToast((*it)); - } - else - { - deleteToast((*it).toast); - } - - it = mToastList.erase(it); - } - else - { - ++it; - } - } -} - -//-------------------------------------------------------------------------- -void LLScreenChannel::closeOverflowToastPanel() -{ - if(mOverflowToastPanel != NULL) - { - mOverflowToastPanel->setVisible(FALSE); - mOverflowToastPanel->stopFading(); - } -} - //-------------------------------------------------------------------------- void LLScreenChannel::createStartUpToast(S32 notif_num, F32 timer) { @@ -699,24 +597,6 @@ F32 LLScreenChannel::getHeightRatio() return ratio; } -S32 LLScreenChannel::getOverflowToastHeight() -{ - if(mOverflowToastPanel) - { - return mOverflowToastPanel->getRect().getHeight(); - } - - static S32 height = 0; - if(0 == height) - { - LLToast::Params p; - LLToast* toast = new LLToast(p); - height = toast->getRect().getHeight(); - delete toast; - } - return height; -} - //-------------------------------------------------------------------------- void LLScreenChannel::updateStartUpString(S32 num) { @@ -778,6 +658,19 @@ void LLScreenChannel::hideToastsFromScreen() (*it).toast->setVisible(FALSE); } +//-------------------------------------------------------------------------- +void LLScreenChannel::hideToast(const LLUUID& notification_id) +{ + std::vector::iterator it = find(mToastList.begin(), mToastList.end(), notification_id); + if(mToastList.end() != it) + { + ToastElem te = *it; + te.toast->setVisible(FALSE); + te.toast->stopTimer(); + mToastList.erase(it); + } +} + //-------------------------------------------------------------------------- void LLScreenChannel::removeToastsFromChannel() { @@ -896,3 +789,13 @@ void LLScreenChannel::updateShowToastsState() //-------------------------------------------------------------------------- +LLToast* LLScreenChannel::getToastByNotificationID(LLUUID id) +{ + std::vector::iterator it = find(mStoredToastList.begin(), + mStoredToastList.end(), id); + + if (it == mStoredToastList.end()) + return NULL; + + return it->toast; +} diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h index 38f27f756b..88053d87d9 100644 --- a/indra/newview/llscreenchannel.h +++ b/indra/newview/llscreenchannel.h @@ -72,8 +72,7 @@ public: virtual void setToastAlignment(EToastAlignment align) {mToastAlignment = align;} virtual void setChannelAlignment(EChannelAlignment align) {mChannelAlignment = align;} - virtual void setOverflowFormatString ( const std::string& str) { mOverflowFormatString = str; } - + // kill or modify a toast by its ID virtual void killToastByNotificationID(LLUUID id) {}; virtual void modifyToastNotificationByID(LLUUID id, LLSD data) {}; @@ -121,17 +120,13 @@ protected: LLToast* mHoveredToast; bool mCanStoreToasts; bool mDisplayToastsAlways; - bool mOverflowToastHidden; // controls whether a channel shows toasts or not bool mShowToasts; // EToastAlignment mToastAlignment; EChannelAlignment mChannelAlignment; - // attributes for the Overflow Toast S32 mHiddenToastsNum; - LLToast* mOverflowToastPanel; - std::string mOverflowFormatString; // channel's ID LLUUID mID; @@ -176,6 +171,8 @@ public: void modifyToastByNotificationID(LLUUID id, LLPanel* panel); // hide all toasts from screen, but not remove them from a channel void hideToastsFromScreen(); + // hide toast by notification id + void hideToast(const LLUUID& notification_id); // removes all toasts from a channel void removeToastsFromChannel(); // show all toasts in a channel @@ -190,8 +187,6 @@ public: void removeToastsBySessionID(LLUUID id); // remove all storable toasts from screen and store them void removeAndStoreAllStorableToasts(); - // close the Overflow Toast - void closeOverflowToastPanel(); // close the StartUp Toast void closeStartUpToast(); @@ -214,6 +209,8 @@ public: // update number of notifications in the StartUp Toast void updateStartUpString(S32 num); + LLToast* getToastByNotificationID(LLUUID id); + // Channel's signals // signal on storing of faded toasts event typedef boost::function store_tost_callback_t; @@ -257,7 +254,6 @@ private: void onToastHover(LLToast* toast, bool mouse_enter); void onToastFade(LLToast* toast); void onToastDestroyed(LLToast* toast); - void onOverflowToastHide(); void onStartUpToastHide(); // @@ -270,9 +266,6 @@ private: void showToastsCentre(); void showToastsTop(); - // create the Overflow Toast - void createOverflowToast(S32 bottom, F32 timer); - // create the StartUp Toast void createStartUpToast(S32 notif_num, F32 timer); @@ -281,8 +274,6 @@ private: */ static F32 getHeightRatio(); - S32 getOverflowToastHeight(); - // Channel's flags static bool mWasStartUpToastShown; diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 010dfd1b33..0dd9203c6d 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -88,6 +88,11 @@ void LLSpeaker::onAvatarNameLookup(const LLUUID& id, const std::string& first, c mDisplayName = first + " " + last; } +bool LLSpeaker::isInVoiceChannel() +{ + return mStatus == LLSpeaker::STATUS_VOICE_ACTIVE || mStatus == LLSpeaker::STATUS_MUTED; +} + LLSpeakerUpdateModeratorEvent::LLSpeakerUpdateModeratorEvent(LLSpeaker* source) : LLEvent(source, "Speaker add moderator event"), mSpeakerID (source->mID), diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h index 1a8c23f56a..da8dfdf548 100644 --- a/indra/newview/llspeakers.h +++ b/indra/newview/llspeakers.h @@ -67,6 +67,8 @@ public: void onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); + bool isInVoiceChannel(); + ESpeakerStatus mStatus; // current activity status in speech group F32 mLastSpokeTime; // timestamp when this speaker last spoke F32 mSpeechVolume; // current speech amplitude (timea average rms amplitude?) diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp new file mode 100644 index 0000000000..42db6bf9c3 --- /dev/null +++ b/indra/newview/llspeakingindicatormanager.cpp @@ -0,0 +1,254 @@ +/** + * @file llspeakingindicatormanager.cpp + * @author Mike Antipov + * @brief Implementation of SpeackerIndicatorManager class to process registered LLSpeackerIndicator + * depend on avatars are in the same voice channel. + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llspeakingindicatormanager.h" + + +#include "llagentdata.h" +#include "llvoicechannel.h" +#include "llvoiceclient.h" + +/** + * This class intended to control visibility of avatar speaking indicators depend on whether avatars + * are in the same voice channel. + * + * Speaking indicator should be visible for avatars in the same voice channel. See EXT-3976. + * + * It stores passed instances of LLOutputMonitorCtrl in a multimap by avatar LLUUID. + * It observes changing of voice channel and changing of participant list in voice channel. + * When voice channel or voice participant list is changed it updates visibility of an appropriate + * speaking indicator. + * + * Several indicators can be registered for the same avatar. + */ +class SpeakingIndicatorManager : public LLSingleton, LLVoiceClientParticipantObserver +{ + LOG_CLASS(SpeakingIndicatorManager); +public: + + /** + * Stores passed speaking indicator to control its visibility. + * + * Registered indicator is set visible if an appropriate avatar is in the same voice channel with Agent. + * It ignores instances of Agent's indicator. + * + * @param speaker_id LLUUID of an avatar whose speaking indicator is registered. + * @param speaking_indicator instance of the speaking indicator to be registered. + */ + void registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator); + + /** + * Removes passed speaking indicator from observing. + * + * @param speaker_id LLUUID of an avatar whose speaking indicator should be unregistered. + * @param speaking_indicator instance of the speaking indicator to be unregistered. + */ + void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator); + +private: + typedef std::set speaker_ids_t; + typedef std::multimap speaking_indicators_mmap_t; + typedef speaking_indicators_mmap_t::value_type speaking_indicator_value_t; + typedef speaking_indicators_mmap_t::const_iterator indicator_const_iterator; + typedef std::pair indicator_range_t; + + friend class LLSingleton; + SpeakingIndicatorManager(); + ~SpeakingIndicatorManager(); + + /** + * Callback to determine when voice channel is changed. + * + * It switches all registered speaking indicators off. + * To reduce overheads only switched on indicators are processed. + */ + void sOnCurrentChannelChanged(const LLUUID& session_id); + + /** + * Callback of changing voice participant list (from LLVoiceClientParticipantObserver). + * + * Switches off indicators had been switched on and switches on indicators of current participants list. + * There is only a few indicators in lists should be switched off/on. + * So, method does not calculate difference between these list it only switches off already + * switched on indicators and switches on indicators of voice channel participants + */ + void onChange(); + + /** + * Changes state of indicators specified by LLUUIDs + * + * @param speakers_uuids - avatars' LLUUIDs whose speaking indicators should be switched + * @param switch_on - if TRUE specified indicator will be switched on, off otherwise. + */ + void switchSpeakerIndicators(const speaker_ids_t& speakers_uuids, BOOL switch_on); + + /** + * Multimap with all registered speaking indicators + */ + speaking_indicators_mmap_t mSpeakingIndicators; + + /** + * LUUIDs of avatar for which we have speaking indicators switched on. + * + * Is used to switch off all previously ON indicators when voice participant list is changed. + * + * @see onChange() + */ + speaker_ids_t mSwitchedIndicatorsOn; +}; + +////////////////////////////////////////////////////////////////////////// +// PUBLIC SECTION +////////////////////////////////////////////////////////////////////////// +void SpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator) +{ + if (speaker_id == gAgentID) return; + + LL_DEBUGS("SpeakingIndicator") << "Registering indicator: " << speaker_id << LL_ENDL; + speaking_indicator_value_t value_type(speaker_id, speaking_indicator); + mSpeakingIndicators.insert(value_type); + + speaker_ids_t speakers_uuids; + BOOL is_in_same_voice = LLVoiceClient::getInstance()->findParticipantByID(speaker_id) != NULL; + + speakers_uuids.insert(speaker_id); + switchSpeakerIndicators(speakers_uuids, is_in_same_voice); +} + +void SpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator) +{ + speaking_indicators_mmap_t::iterator it; + it = mSpeakingIndicators.find(speaker_id); + for (;it != mSpeakingIndicators.end(); ++it) + { + if (it->second == speaking_indicator) + { + mSpeakingIndicators.erase(it); + break; + } + } +} + +////////////////////////////////////////////////////////////////////////// +// PRIVATE SECTION +////////////////////////////////////////////////////////////////////////// +SpeakingIndicatorManager::SpeakingIndicatorManager() +{ + LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&SpeakingIndicatorManager::sOnCurrentChannelChanged, this, _1)); + LLVoiceClient::getInstance()->addObserver(this); +} + +SpeakingIndicatorManager::~SpeakingIndicatorManager() +{ + // Don't use LLVoiceClient::getInstance() here without check + // singleton MAY have already been destroyed. + if(LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->removeObserver(this); + } +} + +void SpeakingIndicatorManager::sOnCurrentChannelChanged(const LLUUID& /*session_id*/) +{ + switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE); + mSwitchedIndicatorsOn.clear(); +} + +void SpeakingIndicatorManager::onChange() +{ + LL_DEBUGS("SpeakingIndicator") << "Voice participant list was changed, updating indicators" << LL_ENDL; + + speaker_ids_t speakers_uuids; + LLVoiceClient::getInstance()->getParticipantsUUIDSet(speakers_uuids); + + LL_DEBUGS("SpeakingIndicator") << "Switching all OFF, count: " << mSwitchedIndicatorsOn.size() << LL_ENDL; + // switch all indicators off + switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE); + mSwitchedIndicatorsOn.clear(); + + LL_DEBUGS("SpeakingIndicator") << "Switching all ON, count: " << speakers_uuids.size() << LL_ENDL; + // then switch current voice participants indicators on + switchSpeakerIndicators(speakers_uuids, TRUE); +} + +void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& speakers_uuids, BOOL switch_on) +{ + speaker_ids_t::const_iterator it_uuid = speakers_uuids.begin(); + for (; it_uuid != speakers_uuids.end(); ++it_uuid) + { + LL_DEBUGS("SpeakingIndicator") << "Looking for indicator: " << *it_uuid << LL_ENDL; + indicator_range_t it_range = mSpeakingIndicators.equal_range(*it_uuid); + indicator_const_iterator it_indicator = it_range.first; + bool was_found = false; + for (; it_indicator != it_range.second; ++it_indicator) + { + was_found = true; + LLSpeakingIndicator* indicator = (*it_indicator).second; + indicator->switchIndicator(switch_on); + } + + if (was_found) + { + LL_DEBUGS("SpeakingIndicator") << mSpeakingIndicators.count(*it_uuid) << " indicators where found" << LL_ENDL; + + if (switch_on) + { + // store switched on indicator to be able switch it off + mSwitchedIndicatorsOn.insert(*it_uuid); + } + } + else + { + LL_WARNS("SpeakingIndicator") << "indicator was not found among registered: " << *it_uuid << LL_ENDL; + } + } +} + +/************************************************************************/ +/* LLSpeakingIndicatorManager namespace implementation */ +/************************************************************************/ + +void LLSpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator) +{ + SpeakingIndicatorManager::instance().registerSpeakingIndicator(speaker_id, speaking_indicator); +} + +void LLSpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator) +{ + SpeakingIndicatorManager::instance().unregisterSpeakingIndicator(speaker_id, speaking_indicator); +} + +// EOF + diff --git a/indra/newview/llspeakingindicatormanager.h b/indra/newview/llspeakingindicatormanager.h new file mode 100644 index 0000000000..ce0158f7d8 --- /dev/null +++ b/indra/newview/llspeakingindicatormanager.h @@ -0,0 +1,67 @@ +/** + * @file llspeakingindicatormanager.h + * @author Mike Antipov + * @brief Interfeace of LLSpeackerIndicator class to be processed depend on avatars are in the same voice channel. + * Also register/unregister methods for this class are declared + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLSPEAKINGINDICATORMANAGER_H +#define LL_LLSPEAKINGINDICATORMANAGER_H + +class LLSpeakingIndicator +{ +public: + virtual void switchIndicator(bool switch_on) = 0; +}; + +// See EXT-3976. +namespace LLSpeakingIndicatorManager +{ + /** + * Stores passed speaking indicator to control its visibility. + * + * Registered indicator is set visible if an appropriate avatar is in the same voice channel with Agent. + * It ignores instances of Agent's indicator. + * + * @param speaker_id LLUUID of an avatar whose speaker indicator is registered. + * @param speaking_indicator instance of the speaker indicator to be registered. + */ + void registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator); + + /** + * Removes passed speaking indicator from observing. + * + * @param speaker_id LLUUID of an avatar whose speaker indicator should be unregistered. + * @param speaking_indicator instance of the speaker indicator to be unregistered. + */ + void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator); +} + +#endif // LL_LLSPEAKINGINDICATORMANAGER_H diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 5ce3bbb9f6..b3b2b9ee5d 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -42,7 +42,7 @@ #include "llfloaterbuycurrency.h" #include "llfloaterchat.h" #include "llfloaterlagmeter.h" -#include "llfloatervolumepulldown.h" +#include "llpanelvolumepulldown.h" #include "llfloaterregioninfo.h" #include "llfloaterscriptdebug.h" #include "llhudicon.h" @@ -204,6 +204,21 @@ LLStatusBar::LLStatusBar(const LLRect& rect) addChild(mSGPacketLoss); childSetActionTextbox("stat_btn", onClickStatGraph); + + mPanelVolumePulldown = new LLPanelVolumePulldown(); + addChild(mPanelVolumePulldown); + + LLRect volume_pulldown_rect = mPanelVolumePulldown->getRect(); + LLButton* volbtn = getChild( "volume_btn" ); + volume_pulldown_rect.setLeftTopAndSize(volbtn->getRect().mLeft - + (volume_pulldown_rect.getWidth() - volbtn->getRect().getWidth())/2, + volbtn->calcScreenRect().mBottom, + volume_pulldown_rect.getWidth(), + volume_pulldown_rect.getHeight()); + + mPanelVolumePulldown->setShape(volume_pulldown_rect); + mPanelVolumePulldown->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT); + mPanelVolumePulldown->setVisible(FALSE); } LLStatusBar::~LLStatusBar() @@ -501,7 +516,7 @@ static void onClickScriptDebug(void*) void LLStatusBar::onMouseEnterVolume(LLUICtrl* ctrl) { // show the master volume pull-down - LLFloaterReg::showInstance("volume_pulldown"); + gStatusBar->mPanelVolumePulldown->setVisible(TRUE); } static void onClickVolume(void* data) diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h index f77cc1acb8..0e98da0fe4 100644 --- a/indra/newview/llstatusbar.h +++ b/indra/newview/llstatusbar.h @@ -112,7 +112,7 @@ private: S32 mSquareMetersCommitted; LLFrameTimer* mBalanceTimer; LLFrameTimer* mHealthTimer; - + LLPanelVolumePulldown* mPanelVolumePulldown; static std::vector sDays; static std::vector sMonths; static const U32 MAX_DATE_STRING_LENGTH; diff --git a/indra/newview/llsyswellitem.cpp b/indra/newview/llsyswellitem.cpp index eef8435006..0cfcfdc634 100644 --- a/indra/newview/llsyswellitem.cpp +++ b/indra/newview/llsyswellitem.cpp @@ -77,10 +77,11 @@ void LLSysWellItem::onClickCloseBtn() //--------------------------------------------------------------------------------- BOOL LLSysWellItem::handleMouseDown(S32 x, S32 y, MASK mask) { + BOOL res = LLPanel::handleMouseDown(x, y, mask); if(!mCloseBtn->getRect().pointInRect(x, y)) mOnItemClick(this); - return LLPanel::handleMouseDown(x, y, mask); + return res; } //--------------------------------------------------------------------------------- diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 44cf82540a..ba15053381 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -700,8 +700,7 @@ void LLNotificationWellWindow::connectListUpdaterToSignal(std::string notificati void LLNotificationWellWindow::onItemClick(LLSysWellItem* item) { LLUUID id = item->getID(); - if(mChannel) - mChannel->loadStoredToastByNotificationIDToChannel(id); + LLFloaterReg::showInstance("inspect_toast", id); } void LLNotificationWellWindow::onItemClose(LLSysWellItem* item) diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index ded3abcbf4..0c81d1f369 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -162,6 +162,9 @@ private: void onItemClick(LLSysWellItem* item); void onItemClose(LLSysWellItem* item); + // ID of a toast loaded by user (by clicking notification well item) + LLUUID mLoadedToastId; + }; /** diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp index d3bbda1c72..c635f91423 100644 --- a/indra/newview/llteleporthistorystorage.cpp +++ b/indra/newview/llteleporthistorystorage.cpp @@ -246,13 +246,6 @@ void LLTeleportHistoryStorage::goToItem(S32 idx) dump(); return; } - - if (idx == (S32)mItems.size() - 1) - { - llwarns << "Will not teleport to the same location." << llendl; - dump(); - return; - } // Attempt to teleport to the requested item. gAgent.teleportViaLocation(mItems[idx].mGlobalPos); diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index 766cf83a01..d0c125eb77 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -179,7 +179,9 @@ void LLToastNotifyPanel::adjustPanelForScriptNotice(const LLNotificationFormPtr //adjust layout LLRect button_rect = mControlPanel->getRect(); reshape(getRect().getWidth(), mInfoPanel->getRect().getHeight() + button_panel_height); + button_rect.set(0, button_rect.mBottom + button_panel_height, button_rect.getWidth(), button_rect.mBottom); mControlPanel->reshape(button_rect.getWidth(), button_panel_height); + mControlPanel->setRect(button_rect); } // static @@ -217,7 +219,7 @@ LLButton* LLToastNotifyPanel::addButton(const std::string& name, const std::stri S32 ignore_pad = 0; S32 button_index = mNumButtons; S32 index = button_index; - S32 x = (HPAD * 4) + 32; + S32 x = HPAD * 2; // *2 - to make a nice offset if (mIsScriptDialog) { diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 66451f47a3..b16134cc28 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1005,7 +1005,7 @@ void render_hud_attachments() LLRect get_whole_screen_region() { - LLRect whole_screen = gViewerWindow->getWindowRectScaled(); + LLRect whole_screen = gViewerWindow->getWorldViewRectScaled(); // apply camera zoom transform (for high res screenshots) F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor(); @@ -1013,13 +1013,13 @@ LLRect get_whole_screen_region() if (zoom_factor > 1.f) { S32 num_horizontal_tiles = llceil(zoom_factor); - S32 tile_width = llround((F32)gViewerWindow->getWindowWidthScaled() / zoom_factor); - S32 tile_height = llround((F32)gViewerWindow->getWindowHeightScaled() / zoom_factor); + S32 tile_width = llround((F32)gViewerWindow->getWorldViewWidthScaled() / zoom_factor); + S32 tile_height = llround((F32)gViewerWindow->getWorldViewHeightScaled() / zoom_factor); int tile_y = sub_region / num_horizontal_tiles; int tile_x = sub_region - (tile_y * num_horizontal_tiles); glh::matrix4f mat; - whole_screen.setLeftTopAndSize(tile_x * tile_width, gViewerWindow->getWindowHeightScaled() - (tile_y * tile_height), tile_width, tile_height); + whole_screen.setLeftTopAndSize(tile_x * tile_width, gViewerWindow->getWorldViewHeightScaled() - (tile_y * tile_height), tile_width, tile_height); } return whole_screen; } @@ -1039,12 +1039,12 @@ bool get_hud_matrices(const LLRect& screen_region, glh::matrix4f &proj, glh::mat F32 aspect_ratio = LLViewerCamera::getInstance()->getAspect(); glh::matrix4f mat; - F32 scale_x = (F32)gViewerWindow->getWindowWidthScaled() / (F32)screen_region.getWidth(); - F32 scale_y = (F32)gViewerWindow->getWindowHeightScaled() / (F32)screen_region.getHeight(); + F32 scale_x = (F32)gViewerWindow->getWorldViewWidthScaled() / (F32)screen_region.getWidth(); + F32 scale_y = (F32)gViewerWindow->getWorldViewHeightScaled() / (F32)screen_region.getHeight(); mat.set_scale(glh::vec3f(scale_x, scale_y, 1.f)); mat.set_translate( - glh::vec3f(clamp_rescale((F32)screen_region.getCenterX(), 0.f, (F32)gViewerWindow->getWindowWidthScaled(), 0.5f * scale_x * aspect_ratio, -0.5f * scale_x * aspect_ratio), - clamp_rescale((F32)screen_region.getCenterY(), 0.f, (F32)gViewerWindow->getWindowHeightScaled(), 0.5f * scale_y, -0.5f * scale_y), + glh::vec3f(clamp_rescale((F32)screen_region.getCenterX(), 0.f, (F32)gViewerWindow->getWorldViewWidthScaled(), 0.5f * scale_x * aspect_ratio, -0.5f * scale_x * aspect_ratio), + clamp_rescale((F32)screen_region.getCenterY(), 0.f, (F32)gViewerWindow->getWorldViewHeightScaled(), 0.5f * scale_y, -0.5f * scale_y), 0.f)); proj *= mat; @@ -1294,8 +1294,8 @@ void render_ui_2d() if (gAgent.getAvatarObject() && gAgent.mHUDCurZoom < 0.98f) { glPushMatrix(); - S32 half_width = (gViewerWindow->getWindowWidthScaled() / 2); - S32 half_height = (gViewerWindow->getWindowHeightScaled() / 2); + S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2); + S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2); glScalef(LLUI::sGLScaleFactor.mV[0], LLUI::sGLScaleFactor.mV[1], 1.f); glTranslatef((F32)half_width, (F32)half_height, 0.f); F32 zoom = gAgent.mHUDCurZoom; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 801c2d0fd2..0edd4ac025 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -107,7 +107,6 @@ #include "llfloateruipreview.h" #include "llfloaterurldisplay.h" #include "llfloatervoicedevicesettings.h" -#include "llfloatervolumepulldown.h" #include "llfloaterwater.h" #include "llfloaterwhitelistentry.h" #include "llfloaterwindlight.h" @@ -118,6 +117,7 @@ #include "llinspectgroup.h" #include "llinspectobject.h" #include "llinspectremoteobject.h" +#include "llinspecttoast.h" #include "llmediaremotectrl.h" #include "llmoveview.h" #include "llnearbychat.h" @@ -189,6 +189,7 @@ void LLViewerFloaterReg::registerFloaters() LLInspectGroupUtil::registerFloater(); LLInspectObjectUtil::registerFloater(); LLInspectRemoteObjectUtil::registerFloater(); + LLNotificationsUI::registerFloater(); LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); @@ -260,7 +261,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("upload_image", "floater_image_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); LLFloaterReg::add("upload_model", "floater_model_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); - LLFloaterReg::add("volume_pulldown", "floater_volume_pulldown.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("whitelist_entry", "floater_whitelist_entry.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 42c45589c0..43c7574830 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -904,7 +904,19 @@ void open_inventory_offer(const std::vector& items, const std::string& f LLPanelPlaces *places_panel = dynamic_cast(LLSideTray::getInstance()->showPanel("panel_places", LLSD())); if (places_panel) { - places_panel->setItem(item); + // we are creating a landmark + if("create_landmark" == places_panel->getPlaceInfoType() && !places_panel->getItem()) + { + places_panel->setItem(item); + } + // we are opening a group notice attachment + else + { + LLSD args; + args["type"] = "landmark"; + args["id"] = item_id; + LLSideTray::getInstance()->showPanel("panel_places", args); + } } } } @@ -1098,28 +1110,6 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4,this)); } - // *NOTE dzaporozhan - // Restored from viewer-1-23 to fix EXT-3520 - // Saves Group Notice Attachments to inventory. - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ImprovedInstantMessage); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_MessageBlock); - msg->addBOOLFast(_PREHASH_FromGroup, FALSE); - msg->addUUIDFast(_PREHASH_ToAgentID, mFromID); - msg->addU8Fast(_PREHASH_Offline, IM_ONLINE); - msg->addUUIDFast(_PREHASH_ID, mTransactionID); - msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary - std::string name; - LLAgentUI::buildFullname(name); - msg->addStringFast(_PREHASH_FromAgentName, name); - msg->addStringFast(_PREHASH_Message, ""); - msg->addU32Fast(_PREHASH_ParentEstateID, 0); - msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null); - msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); - std::string from_string; // Used in the pop-up. std::string chatHistory_string; // Used in chat history. @@ -1155,8 +1145,10 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& } } break; - case IM_TASK_INVENTORY_OFFERED: case IM_GROUP_NOTICE: + send_auto_receive_response(); + break; + case IM_TASK_INVENTORY_OFFERED: case IM_GROUP_NOTICE_REQUESTED: // This is an offer from a task or group. // We don't use a new instance of an opener @@ -1171,10 +1163,6 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& // end switch (mIM) case IOR_ACCEPT: - msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1)); - msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData), sizeof(mFolderID.mData)); - msg->sendReliable(mHost); - //don't spam them if they are getting flooded if (check_offer_throttle(mFromName, true)) { @@ -1197,7 +1185,10 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& { chat.mMuted = TRUE; } - LLFloaterChat::addChatHistory(chat); + + // *NOTE dzaporozhan + // Disabled logging to old chat floater to fix crash in group notices - EXT-4149 + // LLFloaterChat::addChatHistory(chat); LLInventoryFetchComboObserver::folder_ref_t folders; LLInventoryFetchComboObserver::item_ref_t items; @@ -1768,10 +1759,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } else if (from_id.isNull()) { - // Messages from "Second Life" ID don't go to IM history - // messages which should be routed to IM window come from a user ID with name=SYSTEM_NAME - chat.mText = name + ": " + message; - LLFloaterChat::addChat(chat, FALSE, FALSE); + LLSD args; + args["MESSAGE"] = message; + LLNotificationsUtil::add("SystemMessage", args); } else if (to_id.isNull()) { diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 9285ab94dc..33bfee798a 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -604,7 +604,6 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK { const char* buttonname = ""; const char* buttonstatestr = ""; - BOOL handled = FALSE; S32 x = pos.mX; S32 y = pos.mY; x = llround((F32)x / mDisplayScale.mV[VX]); @@ -699,7 +698,10 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK } else { - handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleMouseUp(local_x, local_y, mask); + if (top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleMouseUp(local_x, local_y, mask)) + { + return TRUE; + } } } @@ -717,34 +719,12 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK llinfos << buttonname << " Mouse " << buttonstatestr << " not handled by view" << llendl; } - if (down) + // Do not allow tool manager to handle mouseclicks if we have disconnected + if(!gDisconnected && LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) ) { - if (gDisconnected) - { - return FALSE; - } - - if(LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) ) - { - return TRUE; - } + return TRUE; } - else - { - if( !handled ) - { - handled = mRootView->handleAnyMouseClick(x, y, mask, clicktype, down); - } - if( !handled ) - { - LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); - if (tool) - { - handled = tool->handleAnyMouseClick(x, y, mask, clicktype, down); - } - } - } // If we got this far on a down-click, it wasn't handled. // Up-clicks, though, are always handled as far as the OS is concerned. diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 423c46e14c..42b8a1c2b6 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -5004,6 +5004,17 @@ LLVoiceClient::participantMap *LLVoiceClient::getParticipantList(void) return result; } +void LLVoiceClient::getParticipantsUUIDSet(std::set& participant_uuids) +{ + if (NULL == mAudioSession) return; + + participantUUIDMap::const_iterator it = mAudioSession->mParticipantsByUUID.begin(), + it_end = mAudioSession->mParticipantsByUUID.end(); + for (; it != it_end; ++it) + { + participant_uuids.insert((*(*it).first)); + } +} LLVoiceClient::participantState *LLVoiceClient::sessionState::findParticipant(const std::string &uri) { diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 724179847d..6231c6ba29 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -354,6 +354,7 @@ static void updatePosition(void); participantState *findParticipantByID(const LLUUID& id); participantMap *getParticipantList(void); + void getParticipantsUUIDSet(std::set& participant_uuids); typedef std::map sessionMap; typedef std::set sessionSet; diff --git a/indra/newview/skins/default/textures/bottomtray/Unread_Chiclet.png b/indra/newview/skins/default/textures/bottomtray/Unread_Chiclet.png index 447e0af0be..6343ddf035 100644 Binary files a/indra/newview/skins/default/textures/bottomtray/Unread_Chiclet.png and b/indra/newview/skins/default/textures/bottomtray/Unread_Chiclet.png differ diff --git a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png index dd9133bcc4..661d1c5611 100644 Binary files a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png and b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png differ diff --git a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png index 0080e71f41..f927fd3989 100644 Binary files a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png and b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index db60b90a93..cfa7479fa9 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -224,7 +224,7 @@ with the same filename but different name scale.left="4" scale.top="28" scale.right="60" scale.bottom="4" /> - + @@ -650,6 +650,12 @@ with the same filename but different name + + + + + + @@ -678,8 +684,6 @@ with the same filename but different name - - @@ -698,7 +702,6 @@ with the same filename but different name - @@ -719,27 +722,10 @@ with the same filename but different name - - - - - - - - - - - - - - - - - diff --git a/indra/newview/skins/default/xui/de/floater_buy_currency.xml b/indra/newview/skins/default/xui/de/floater_buy_currency.xml index 3c336cc40b..c320e796c2 100644 --- a/indra/newview/skins/default/xui/de/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/de/floater_buy_currency.xml @@ -46,7 +46,7 @@ [AMT] L$ - [http://www.secondlife.com/ payment method] | [http://www.secondlife.com/ currency] | [http://www.secondlife.com exchange rate] + [http://www.secondlife.com/my/account/payment_method_management.php?lang=de-DE payment method] | [http://www.secondlife.com/my/account/currency.php?lang=de-DE currency] | [http://www.secondlife.com/my/account/exchange_rates.php?lang=de-DE exchange rate] Geben Sie den Betrag erneut ein, um die aktuellste Umtauschrate anzuzeigen. diff --git a/indra/newview/skins/default/xui/de/floater_help_browser.xml b/indra/newview/skins/default/xui/de/floater_help_browser.xml index 53bddcced1..2344d6f412 100644 --- a/indra/newview/skins/default/xui/de/floater_help_browser.xml +++ b/indra/newview/skins/default/xui/de/floater_help_browser.xml @@ -1,10 +1,10 @@ - http://www.secondlife.com + http://de.secondlife.com - http://support.secondlife.com + http://de.secondlife.com/support diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 809ac33e15..e93a38f187 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -166,7 +166,7 @@ Anklicken, um Befehl secondlife:// auszuführen - + Teleportieren nach @@ -821,46 +821,46 @@ Sie haben keine Kopie dieser Textur in Ihrem Inventar. - - - - - - + + + + + + Inhalte werden geladen... Keine Inhalte - + Ja Nein - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + Mein Inventar @@ -1239,13 +1239,13 @@ keine - + (unbekannt) - - - + + + Kontostand @@ -1324,8 +1324,8 @@ Zuletzt geändert: - - + + In Gruppenbesitz @@ -1616,7 +1616,7 @@ Falls der Fehler dann weiterhin auftritt, müssen Sie [APP_NAME] von Ihrem Syste Unbehebbarer Fehler - [APP_NAME] erfordert einen Prozessor mit AltiVec (G4 oder später). + [APP_NAME] erfordert einen Prozessor mit AltiVec (G4 oder später). [APP_NAME] läuft bereits. diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index 82ed1a7d7f..9806f45bc4 100644 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -112,7 +112,7 @@ Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number word_wrap="true"> Second Life is brought to you by Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les and many others. -Thank you to the following residents for helping to ensure that this is the best version yet: (in progress) +Thank you to the following Residents for helping to ensure that this is the best version yet: (in progress) 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 33fdd923ad..900f4c5956 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1036,7 +1036,7 @@ Leyla Linden name="Autoreturn" top="164" width="294"> - Autoreturn other residents' objects (minutes, 0 for off): + Autoreturn other Residents' objects (minutes, 0 for off): - Allow other residents to: + Allow other Residents to: L$ @@ -123,7 +123,7 @@ label="L$" left_pad="3" name="currency_amt" - width="60"> + width="85"> 1234 - Put on a new shape by dragging one from your inventory -to your avatar. Alternately, you create a new one from -scratch and wear it. + Put on a new shape by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it. You do not have permission to modify this wearable. @@ -300,7 +300,7 @@ scratch and wear it. left="10" name="Create New" top="104" - width="140" /> + width="160" /> + diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml index d26e855e2f..2dfcdf4a4c 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml @@ -153,28 +153,19 @@ layout="topleft" left="5" name="CreatorNameLabel" - top_pad="10" + top_pad="12" width="78"> Creator: - Erica Linden @@ -186,28 +177,19 @@ layout="topleft" left="5" name="Owner:" - top_pad="10" + top_pad="15" width="78"> Owner: - Erica Linden @@ -219,7 +201,7 @@ layout="topleft" left="5" name="Group_label" - top_pad="10" + top_pad="15" width="78"> Group: diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index bd868ef61e..fbdac7164d 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -67,7 +67,7 @@ Click to view this web page Click to view this location's information - Click to view this resident's profile + Click to view this Resident's profile Click to view this group's description Click to view this event's description Click to view this classified @@ -1609,11 +1609,11 @@ Sends an HTTP request to the specified url with the body of the request and para llResetLandBanList() -Removes all residents from the land ban list +Removes all Residents from the land ban list llResetLandPassList() -Removes all residents from the land access/pass list +Removes all Residents from the land access/pass list integer llGetObjectPrimCount(key object_id) @@ -1621,7 +1621,7 @@ Returns the total number of prims for an object in the region list llGetParcelPrimOwners(vector pos) -Returns a list of all residents who own objects on the parcel at pos and with individual prim counts. +Returns a list of all Residents who own objects on the parcel at pos and with individual prim counts. Requires owner-like permissions for the parcel. @@ -1808,7 +1808,7 @@ Clears (deletes) the media and all params from the given face. No matching items found in inventory. - Drag and drop a landmark here to add to your favorites. + Drag a landmark here to add it to your favorites. You do not have a copy of this texture in your inventory @@ -2040,7 +2040,7 @@ this texture in your inventory all estates that you manage for [OWNER] - Allowed residents: ([ALLOWEDAGENTS], max [MAXACCESS]) + Allowed Residents: ([ALLOWEDAGENTS], max [MAXACCESS]) Allowed groups: ([ALLOWEDGROUPS], max [MAXACCESS]) @@ -2111,7 +2111,7 @@ this texture in your inventory (by name) - (resident) + (Resident) (object) (group) @@ -2938,7 +2938,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. Click the [BUTTON NAME] button to accept/connect to this voice chat. - You have blocked this resident. Sending a message will automatically unblock them. + You have blocked this Resident. Sending a message will automatically unblock them.