diff options
70 files changed, 1058 insertions, 423 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt index 4b36c44a5f..cf10ecccfb 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -600,6 +600,7 @@ Tharax Ferraris Thickbrick Sleaford VWR-7109 VWR-9287 + VWR-13483 VWR-13947 Thraxis Epsilon SVC-371 diff --git a/indra/develop.py b/indra/develop.py index 05ad12f20e..eaecdd0ab6 100755 --- a/indra/develop.py +++ b/indra/develop.py @@ -573,7 +573,7 @@ class WindowsSetup(PlatformSetup): if self.gens[self.generator]['ver'] in [ r'8.0', r'9.0' ]: config = '\"%s|Win32\"' % config - return "buildconsole %s.sln /build %s" % (self.project_name, config) + return "buildconsole %(prj)s.sln /build /cfg=%(cfg)s" % {'prj': self.project_name, 'cfg': config} # devenv.com is CLI friendly, devenv.exe... not so much. return ('"%sdevenv.com" %s.sln /build %s' % diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 7ad5f9608f..37a28ac721 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -135,7 +135,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons S32 scaled_max_pixels = max_pixels == S32_MAX ? S32_MAX : llceil((F32)max_pixels * sScaleX); - // determine which style flags need to be added programmatically by striping off the + // determine which style flags need to be added programmatically by stripping off the // style bits that are drawn by the underlying Freetype font U8 style_to_add = (style | mFontDescriptor.getStyle()) & ~mFontFreetype->getStyle(); diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp index 63faf44f9d..6a5b475134 100644 --- a/indra/llui/lldockablefloater.cpp +++ b/indra/llui/lldockablefloater.cpp @@ -54,6 +54,7 @@ void LLDockableFloater::init(LLDockableFloater* thiz) LLDockableFloater::LLDockableFloater(LLDockControl* dockControl, const LLSD& key, const Params& params) : LLFloater(key, params), mDockControl(dockControl), mUniqueDocking(true) + , mOverlapsScreenChannel(false) { init(this); } diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h index 2c339f4a3f..2c0a484cc8 100644 --- a/indra/llui/lldockablefloater.h +++ b/indra/llui/lldockablefloater.h @@ -85,6 +85,14 @@ public: LLDockControl* getDockControl(); + /** + * Returns true if screen channel should consider floater's size when drawing toasts. + * + * By default returns false. + */ + virtual bool overlapsScreenChannel() { return mOverlapsScreenChannel && getVisible() && isDocked(); } + virtual void setOverlapsScreenChannel(bool overlaps) { mOverlapsScreenChannel = overlaps; } + private: /** * Provides unique of dockable floater. @@ -105,6 +113,8 @@ private: * non exclusively. */ bool mUniqueDocking; + + bool mOverlapsScreenChannel; }; #endif /* LL_DOCKABLEFLOATER_H */ diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 202ed04fbc..60ef01074b 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -3610,6 +3610,11 @@ public: LLContextMenuBranch(const Params&); + virtual ~LLContextMenuBranch() + { + delete mBranch; + } + // called to rebuild the draw label virtual void buildDrawLabel( void ); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index e54032ac5e..7447a984ac 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -842,7 +842,7 @@ BOOL LLTextBase::handleMouseUp(S32 x, S32 y, MASK mask) { // Did we just click on a link? if (cur_segment->getStyle() - && cur_segment->getStyle()->isLink()) + && cur_segment->getStyle()->isLink()) { // *TODO: send URL here? mURLClickSignal(this, LLSD() ); @@ -1477,7 +1477,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) } } -void LLTextBase::setText(const LLStringExplicit &utf8str ,const LLStyle::Params& input_params) +void LLTextBase::setText(const LLStringExplicit &utf8str, const LLStyle::Params& input_params) { // clear out the existing text and segments getViewModel()->setDisplay(LLWStringUtil::null); @@ -2320,14 +2320,14 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele S32 end = llmin( selection_start, seg_end ); S32 length = end - start; font->render(text, start, - rect.mLeft, rect.mTop, - color, - LLFontGL::LEFT, LLFontGL::TOP, - 0, - mStyle->getShadowType(), - length, rect.getWidth(), - &right_x, - mEditor.getUseEllipses()); + rect.mLeft, rect.mTop, + color, + LLFontGL::LEFT, LLFontGL::TOP, + LLFontGL::NORMAL, + mStyle->getShadowType(), + length, rect.getWidth(), + &right_x, + mEditor.getUseEllipses()); } rect.mLeft = (S32)ceil(right_x); @@ -2339,14 +2339,14 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele S32 length = end - start; font->render(text, start, - rect.mLeft, rect.mTop, - LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ), - LLFontGL::LEFT, LLFontGL::TOP, - 0, - LLFontGL::NO_SHADOW, - length, rect.getWidth(), - &right_x, - mEditor.getUseEllipses()); + rect.mLeft, rect.mTop, + LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ), + LLFontGL::LEFT, LLFontGL::TOP, + LLFontGL::NORMAL, + LLFontGL::NO_SHADOW, + length, rect.getWidth(), + &right_x, + mEditor.getUseEllipses()); } rect.mLeft = (S32)ceil(right_x); if( selection_end < seg_end ) @@ -2356,14 +2356,14 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele S32 end = seg_end; S32 length = end - start; font->render(text, start, - rect.mLeft, rect.mTop, - color, - LLFontGL::LEFT, LLFontGL::TOP, - 0, - mStyle->getShadowType(), - length, rect.getWidth(), - &right_x, - mEditor.getUseEllipses()); + rect.mLeft, rect.mTop, + color, + LLFontGL::LEFT, LLFontGL::TOP, + LLFontGL::NORMAL, + mStyle->getShadowType(), + length, rect.getWidth(), + &right_x, + mEditor.getUseEllipses()); } return right_x; } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index c91578b637..038b9eaa62 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -184,6 +184,7 @@ public: bool scrolledToEnd(); const LLFontGL* getDefaultFont() const { return mDefaultFont; } + LLStyle::Params getDefaultStyle(); public: // Fired when a URL link is clicked @@ -256,7 +257,6 @@ protected: LLTextBase(const Params &p); virtual ~LLTextBase(); void initFromParams(const Params& p); - LLStyle::Params getDefaultStyle(); virtual void onValueChange(S32 start, S32 end); // draw methods diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp index 109e20f179..484948bd9f 100644 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp +++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp @@ -108,7 +108,7 @@ gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf) slvideo = GST_SLVIDEO(bsink); - DEBUGMSG("\n\ntransferring a frame of %dx%d <- %p (%d)\n\n", + DEBUGMSG("transferring a frame of %dx%d <- %p (%d)", slvideo->width, slvideo->height, GST_BUFFER_DATA(buf), slvideo->format); @@ -336,7 +336,7 @@ gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, #define MAXDEPTHHACK 4 GST_OBJECT_LOCK(slvideo); - if (slvideo->resize_forced) + if (slvideo->resize_forced_always) // app is giving us a fixed size to work with { gint slwantwidth, slwantheight; slwantwidth = slvideo->resize_try_width; @@ -385,6 +385,8 @@ gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, } } + GST_OBJECT_UNLOCK(slvideo); + if (!made_bufferdata_ptr) // need to fallback to malloc at original size { GST_BUFFER_SIZE(newbuf) = width * height * MAXDEPTHHACK; @@ -393,8 +395,6 @@ gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), caps); } - GST_OBJECT_UNLOCK(slvideo); - *buf = GST_BUFFER_CAST(newbuf); return GST_FLOW_OK; @@ -458,7 +458,7 @@ gst_slvideo_init (GstSLVideo * filter, filter->retained_frame_format = SLV_PF_UNKNOWN; GstCaps *caps = llgst_caps_from_string (SLV_ALLCAPS); llgst_caps_replace (&filter->caps, caps); - filter->resize_forced = false; + filter->resize_forced_always = false; filter->resize_try_width = -1; filter->resize_try_height = -1; GST_OBJECT_UNLOCK(filter); @@ -499,7 +499,7 @@ gst_slvideo_get_property (GObject * object, guint prop_id, static gboolean plugin_init (GstPlugin * plugin) { - DEBUGMSG("\n\n\nPLUGIN INIT\n\n\n"); + DEBUGMSG("PLUGIN INIT"); GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, (gchar*)"private-slvideo-plugin", 0, (gchar*)"Second Life Video Sink"); @@ -527,7 +527,7 @@ void gst_slvideo_init_class (void) "http://www.secondlife.com/"); #undef PACKAGE ll_gst_plugin_register_static (&gst_plugin_desc); - DEBUGMSG("\n\n\nCLASS INIT\n\n\n"); + DEBUGMSG("CLASS INIT"); } #endif // LL_GSTREAMER010_ENABLED diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h index 208523e8d0..8f1cf84978 100644 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h +++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h @@ -90,7 +90,7 @@ struct _GstSLVideo int retained_frame_width, retained_frame_height; SLVPixelFormat retained_frame_format; // sticky resize info - bool resize_forced; + bool resize_forced_always; int resize_try_width; int resize_try_height; }; diff --git a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp index 8e850ed7ff..26173314a7 100644 --- a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp +++ b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp @@ -105,7 +105,7 @@ private: void mouseUp( int x, int y ); void mouseMove( int x, int y ); - bool sizeChanged(); + void sizeChanged(); static bool mDoneInit; @@ -477,9 +477,8 @@ MediaPluginGStreamer010::update(int milliseconds) mCurrentWidth <= mWidth && !mTextureSegmentName.empty()) { - // we're gonna totally consume this frame - reset 'ready' flag - mVideoSink->retained_frame_ready = FALSE; + mVideoSink->retained_frame_ready = FALSE; int destination_rowbytes = mWidth * mDepth; for (int row=0; row<mCurrentHeight; ++row) { @@ -840,7 +839,7 @@ MediaPluginGStreamer010::startup() } -bool +void MediaPluginGStreamer010::sizeChanged() { // the shared writing space has possibly changed size/location/whatever @@ -855,8 +854,9 @@ MediaPluginGStreamer010::sizeChanged() mNaturalWidth, mNaturalHeight); } + // if the size has changed then the shm has changed and the app needs telling if (mCurrentWidth != mPreviousWidth || - mCurrentHeight != mPreviousHeight) // if the size has changed then the shm has changed and the app needs telling + mCurrentHeight != mPreviousHeight) { mPreviousWidth = mCurrentWidth; mPreviousHeight = mCurrentHeight; @@ -865,11 +865,9 @@ MediaPluginGStreamer010::sizeChanged() message.setValue("name", mTextureSegmentName); message.setValueS32("width", mNaturalWidth); message.setValueS32("height", mNaturalHeight); - DEBUGMSG("<--- Sending size change request to application with name: '%s' - size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight); + DEBUGMSG("<--- Sending size change request to application with name: '%s' - natural size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight); sendMessage(message); } - - return true; } @@ -1000,7 +998,6 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string) INFOMSG("MediaPluginGStreamer010::receiveMessage: shared memory added, name: %s, size: %d, address: %p", name.c_str(), int(info.mSize), info.mAddress); mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); - } else if(message_name == "shm_remove") { @@ -1079,7 +1076,7 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string) INFOMSG("**** = REAL RESIZE REQUEST FROM APP"); GST_OBJECT_LOCK(mVideoSink); - mVideoSink->resize_forced = true; + mVideoSink->resize_forced_always = true; mVideoSink->resize_try_width = texture_width; mVideoSink->resize_try_height = texture_height; GST_OBJECT_UNLOCK(mVideoSink); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 7d8e9268e5..a26aae3590 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -258,7 +258,6 @@ set(viewer_SOURCE_FILES llinventorymodel.cpp llinventoryobserver.cpp llinventorypanel.cpp - llinventorysubtreepanel.cpp lljoystickbutton.cpp lllandmarkactions.cpp lllandmarklist.cpp @@ -354,6 +353,7 @@ set(viewer_SOURCE_FILES llparticipantlist.cpp llpatchvertexarray.cpp llplacesinventorybridge.cpp + llplacesinventorypanel.cpp llpolymesh.cpp llpolymorph.cpp llpreview.cpp @@ -766,7 +766,6 @@ set(viewer_HEADER_FILES llinventorymodel.h llinventoryobserver.h llinventorypanel.h - llinventorysubtreepanel.h lljoystickbutton.h lllandmarkactions.h lllandmarklist.h @@ -858,6 +857,7 @@ set(viewer_HEADER_FILES llparticipantlist.h llpatchvertexarray.h llplacesinventorybridge.h + llplacesinventorypanel.h llpolymesh.h llpolymorph.h llpreview.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 455c3587ff..ba78d80ad1 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3585,7 +3585,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>http://int.searchwww-phx0.damballah.lindenlab.com/viewer/[CATEGORY]?q=[QUERY]&p=[AUTH_TOKEN]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]</string> + <string>http://int.searchwww-phx0.damballah.lindenlab.com/viewer/[CATEGORY]?q=[QUERY]&p=[AUTH_TOKEN]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]</string> </map> <key>HighResSnapshot</key> <map> @@ -10378,6 +10378,17 @@ <key>Value</key> <string>Default</string> </map> + <key>VoiceParticipantLeftRemoveDelay</key> + <map> + <key>Comment</key> + <string>Timeout to remove participants who has left Voice chat from the list in Voice Controls Panel</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>10</integer> + </map> <key>VoicePort</key> <map> <key>Comment</key> diff --git a/indra/newview/linux_tools/register_secondlifeprotocol.sh b/indra/newview/linux_tools/register_secondlifeprotocol.sh index c7b4d55461..16e73cb854 100755 --- a/indra/newview/linux_tools/register_secondlifeprotocol.sh +++ b/indra/newview/linux_tools/register_secondlifeprotocol.sh @@ -22,13 +22,12 @@ else fi # Register handler for KDE-aware apps -if [ -z "$KDEHOME" ]; then - KDEHOME=~/.kde -fi -LLKDEPROTDIR=${KDEHOME}/share/services -if [ -d "$LLKDEPROTDIR" ]; then - LLKDEPROTFILE=${LLKDEPROTDIR}/secondlife.protocol - cat > ${LLKDEPROTFILE} <<EOF || echo Warning: Did not register secondlife:// handler with KDE: Could not write ${LLKDEPROTFILE} +for LLKDECONFIG in kde-config kde4-config; do + if [ `which $LLKDECONFIG` ]; then + LLKDEPROTODIR=`$LLKDECONFIG --path services | cut -d ':' -f 1` + if [ -d "$LLKDEPROTODIR" ]; then + LLKDEPROTOFILE=${LLKDEPROTODIR}/secondlife.protocol + cat > ${LLKDEPROTOFILE} <<EOF || echo Warning: Did not register secondlife:// handler with KDE: Could not write ${LLKDEPROTOFILE} [Protocol] exec=${HANDLER} '%u' protocol=secondlife @@ -41,6 +40,9 @@ writing=false makedir=false deleting=false EOF -else - echo Warning: Did not register secondlife:// handler with KDE: Directory $LLKDEPROTDIR does not exist. -fi + else + echo Warning: Did not register secondlife:// handler with KDE: Directory $LLKDEPROTODIR does not exist. + fi + fi +done + diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index c8544bc3fb..8bc11b0c1c 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -158,7 +158,6 @@ void LLAvatarListItem::changed(U32 mask) void LLAvatarListItem::setOnline(bool online) { // *FIX: setName() overrides font style set by setOnline(). Not an issue ATM. - // *TODO: Make the colors configurable via XUI. if (mOnlineStatus != E_UNKNOWN && (bool) mOnlineStatus == online) return; @@ -166,11 +165,7 @@ void LLAvatarListItem::setOnline(bool online) mOnlineStatus = (EOnlineStatus) online; // Change avatar name font style depending on the new online status. - mAvatarNameStyle.color = online ? LLColor4::white : LLColor4::grey; - setNameInternal(mAvatarName->getText(), mHighlihtSubstring); - - // Make the icon fade if the avatar goes offline. - mAvatarIcon->setColor(online ? LLColor4::white : LLColor4::smoke); + setStyle(online ? IS_ONLINE : IS_OFFLINE); } void LLAvatarListItem::setName(const std::string& name) @@ -183,28 +178,21 @@ void LLAvatarListItem::setHighlight(const std::string& highlight) setNameInternal(mAvatarName->getText(), mHighlihtSubstring = highlight); } -void LLAvatarListItem::setStyle(const LLStyle::Params& new_style) +void LLAvatarListItem::setStyle(EItemStyle item_style) { -// LLTextUtil::textboxSetHighlightedVal(mAvatarName, mAvatarNameStyle = new_style); - - // Active group should be bold. - LLFontDescriptor new_desc(mAvatarName->getDefaultFont()->getFontDesc()); + item_style_map_t& item_styles_params_map = getItemStylesParams(); - new_desc.setStyle(new_style.font()->getFontDesc().getStyle()); - // *NOTE dzaporozhan - // On Windows LLFontGL::NORMAL will not remove LLFontGL::BOLD if font - // is predefined as bold (SansSerifSmallBold, for example) -// new_desc.setStyle(active ? LLFontGL::BOLD : LLFontGL::NORMAL); - LLFontGL* new_font = LLFontGL::getFont(new_desc); - -// - mAvatarNameStyle.font = new_font; + mAvatarNameStyle = item_styles_params_map[item_style]; // *NOTE: You cannot set the style on a text box anymore, you must // rebuild the text. This will cause problems if the text contains // hyperlinks, as their styles will be wrong. - mAvatarName->setText(mAvatarName->getText(), mAvatarNameStyle/* = new_style*/); + setNameInternal(mAvatarName->getText(), mHighlihtSubstring); + + icon_color_map_t& item_icon_color_map = getItemIconColorMap(); + mAvatarIcon->setColor(item_icon_color_map[item_style]); } + void LLAvatarListItem::setAvatarId(const LLUUID& id, bool ignore_status_changes) { if (mAvatarId.notNull()) @@ -418,3 +406,90 @@ std::string LLAvatarListItem::formatSeconds(U32 secs) args["[COUNT]"] = llformat("%u", count); return getString(fmt, args); } + +// static +LLAvatarListItem::item_style_map_t& LLAvatarListItem::getItemStylesParams() +{ + static item_style_map_t item_styles_params_map; + if (!item_styles_params_map.empty()) return item_styles_params_map; + + LLPanel::Params params = LLUICtrlFactory::getDefaultParams<LLPanel>(); + LLPanel* params_panel = LLUICtrlFactory::create<LLPanel>(params); + + BOOL sucsess = LLUICtrlFactory::instance().buildPanel(params_panel, "panel_avatar_list_item_params.xml"); + + if (sucsess) + { + + item_styles_params_map.insert( + std::make_pair(IS_DEFAULT, + params_panel->getChild<LLTextBox>("default_style")->getDefaultStyle())); + + item_styles_params_map.insert( + std::make_pair(IS_VOICE_INVITED, + params_panel->getChild<LLTextBox>("voice_call_invited_style")->getDefaultStyle())); + + item_styles_params_map.insert( + std::make_pair(IS_VOICE_JOINED, + params_panel->getChild<LLTextBox>("voice_call_joined_style")->getDefaultStyle())); + + item_styles_params_map.insert( + std::make_pair(IS_VOICE_LEFT, + params_panel->getChild<LLTextBox>("voice_call_left_style")->getDefaultStyle())); + + item_styles_params_map.insert( + std::make_pair(IS_ONLINE, + params_panel->getChild<LLTextBox>("online_style")->getDefaultStyle())); + + item_styles_params_map.insert( + std::make_pair(IS_OFFLINE, + params_panel->getChild<LLTextBox>("offline_style")->getDefaultStyle())); + } + else + { + item_styles_params_map.insert(std::make_pair(IS_DEFAULT, LLStyle::Params())); + item_styles_params_map.insert(std::make_pair(IS_VOICE_INVITED, LLStyle::Params())); + item_styles_params_map.insert(std::make_pair(IS_VOICE_JOINED, LLStyle::Params())); + item_styles_params_map.insert(std::make_pair(IS_VOICE_LEFT, LLStyle::Params())); + item_styles_params_map.insert(std::make_pair(IS_ONLINE, LLStyle::Params())); + item_styles_params_map.insert(std::make_pair(IS_OFFLINE, LLStyle::Params())); + } + if (params_panel) params_panel->die(); + + return item_styles_params_map; +} + +// static +LLAvatarListItem::icon_color_map_t& LLAvatarListItem::getItemIconColorMap() +{ + static icon_color_map_t item_icon_color_map; + if (!item_icon_color_map.empty()) return item_icon_color_map; + + item_icon_color_map.insert( + std::make_pair(IS_DEFAULT, + LLUIColorTable::instance().getColor("AvatarListItemIconDefaultColor", LLColor4::white))); + + item_icon_color_map.insert( + std::make_pair(IS_VOICE_INVITED, + LLUIColorTable::instance().getColor("AvatarListItemIconVoiceInvitedColor", LLColor4::white))); + + item_icon_color_map.insert( + std::make_pair(IS_VOICE_JOINED, + LLUIColorTable::instance().getColor("AvatarListItemIconVoiceJoinedColor", LLColor4::white))); + + item_icon_color_map.insert( + std::make_pair(IS_VOICE_LEFT, + LLUIColorTable::instance().getColor("AvatarListItemIconVoiceLeftColor", LLColor4::white))); + + item_icon_color_map.insert( + std::make_pair(IS_ONLINE, + LLUIColorTable::instance().getColor("AvatarListItemIconOnlineColor", LLColor4::white))); + + item_icon_color_map.insert( + std::make_pair(IS_OFFLINE, + LLUIColorTable::instance().getColor("AvatarListItemIconOfflineColor", LLColor4::white))); + + return item_icon_color_map; +} + +// EOF diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index 0e058f75db..8e359f16b3 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -46,6 +46,15 @@ class LLAvatarIconCtrl; class LLAvatarListItem : public LLPanel, public LLFriendObserver { public: + typedef enum e_item_style_type { + IS_DEFAULT, + IS_VOICE_INVITED, + IS_VOICE_JOINED, + IS_VOICE_LEFT, + IS_ONLINE, + IS_OFFLINE, + } EItemStyle; + class ContextMenu { public: @@ -73,7 +82,7 @@ public: void setOnline(bool online); void setName(const std::string& name); void setHighlight(const std::string& highlight); - void setStyle(const LLStyle::Params& new_style); + void setStyle(EItemStyle item_style); void setAvatarId(const LLUUID& id, bool ignore_status_changes = false); void setLastInteractionTime(U32 secs_since); //Show/hide profile/info btn, translating speaker indicator and avatar name coordinates accordingly @@ -118,6 +127,12 @@ private: std::string formatSeconds(U32 secs); + typedef std::map<EItemStyle, LLStyle::Params> item_style_map_t; + static item_style_map_t& getItemStylesParams(); + + typedef std::map<EItemStyle, LLColor4> icon_color_map_t; + static icon_color_map_t& getItemIconColorMap(); + LLAvatarIconCtrl* mAvatarIcon; LLTextBox* mAvatarName; LLTextBox* mLastInteractionTime; diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index 02d13b4807..581890c4fd 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -96,12 +96,6 @@ BOOL LLCallFloater::LLAvatarListItemRemoveTimer::tick() return TRUE; } - -LLCallFloater::Params::Params() -: voice_left_remove_delay("voice_left_remove_delay", 10) -{ -} - LLCallFloater::LLCallFloater(const LLSD& key) : LLDockableFloater(NULL, false, key) , mSpeakerManager(NULL) @@ -113,8 +107,11 @@ LLCallFloater::LLCallFloater(const LLSD& key) , mSpeakingIndicator(NULL) , mIsModeratorMutedVoice(false) , mInitParticipantsVoiceState(false) -, mVoiceLeftRemoveDelay(10) // TODO: mantipov: make xml driven +, mVoiceLeftRemoveDelay(10) { + static LLUICachedControl<S32> voice_left_remove_delay ("VoiceParticipantLeftRemoveDelay", 10); + mVoiceLeftRemoveDelay = voice_left_remove_delay; + mFactoryMap["non_avatar_caller"] = LLCallbackMap(create_non_avatar_caller, NULL); LLVoiceClient::getInstance()->addObserver(this); LLTransientFloaterMgr::getInstance()->addControlView(this); @@ -300,15 +297,6 @@ void LLCallFloater::updateSession() if (show_me) { setVisible(true); - // Workaround(EM): Set current call dialog to front most because - // connect/leaving popups should appear on top of VCP. - // See bug EXT-3628. - LLOutgoingCallDialog* instance = - LLFloaterReg::findTypedInstance<LLOutgoingCallDialog>("outgoing_call", LLOutgoingCallDialog::OCD_KEY); - if(instance && instance->getVisible()) - { - instance->setFrontmost(); - } } } } @@ -632,38 +620,25 @@ void LLCallFloater::setState(LLAvatarListItem* item, ESpeakerState state) setState(item->getAvatarId(), state); - LLStyle::Params speaker_style; - LLFontDescriptor new_desc(speaker_style.font()->getFontDesc()); - switch (state) { case STATE_INVITED: - new_desc.setStyle(LLFontGL::NORMAL); + item->setStyle(LLAvatarListItem::IS_VOICE_INVITED); break; case STATE_JOINED: removeVoiceRemoveTimer(item->getAvatarId()); - new_desc.setStyle(LLFontGL::NORMAL); + item->setStyle(LLAvatarListItem::IS_VOICE_JOINED); break; case STATE_LEFT: { setVoiceRemoveTimer(item->getAvatarId()); - new_desc.setStyle(LLFontGL::ITALIC); + item->setStyle(LLAvatarListItem::IS_VOICE_LEFT); } break; default: llwarns << "Unrecognized avatar panel state (" << state << ")" << llendl; break; } - - LLFontGL* new_font = LLFontGL::getFont(new_desc); - speaker_style.font = new_font; - item->setStyle(speaker_style); - -// if () - { - // found speaker is in voice, mark him as online - item->setOnline(STATE_JOINED == state); - } } void LLCallFloater::setVoiceRemoveTimer(const LLUUID& voice_speaker_id) diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h index 0e942d7f95..3df9e333c5 100644 --- a/indra/newview/llcallfloater.h +++ b/indra/newview/llcallfloater.h @@ -57,12 +57,6 @@ class LLSpeakerMgr; class LLCallFloater : public LLDockableFloater, LLVoiceClientParticipantObserver { public: - struct Params : public LLInitParam::Block<Params, LLDockableFloater::Params> - { - Optional<S32> voice_left_remove_delay; - - Params(); - }; LOG_CLASS(LLCallFloater); diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index e6f56d89f7..2719f10a3d 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -173,6 +173,9 @@ LLSysWellChiclet::~LLSysWellChiclet() void LLSysWellChiclet::setCounter(S32 counter) { + // do nothing if the same counter is coming. EXT-3678. + if (counter == mCounter) return; + // note same code in LLChicletNotificationCounterCtrl::setCounter(S32 counter) std::string s_count; if(counter != 0) @@ -1128,14 +1131,6 @@ LLChicletPanel::Params::Params() , scrolling_offset("scrolling_offset") , min_width("min_width") { - chiclet_padding = 3; - scrolling_offset = 40; - - if (!min_width.isProvided()) - { - // min_width = 4 chiclets + 3 paddings - min_width = 180 + 3*chiclet_padding; - } }; LLChicletPanel::LLChicletPanel(const Params&p) @@ -1148,6 +1143,9 @@ LLChicletPanel::LLChicletPanel(const Params&p) , mMinWidth(p.min_width) , mShowControls(true) { + // min_width = 4 chiclets + 3 paddings + mMinWidth += 3 * mChicletPadding; + LLPanel::Params panel_params; panel_params.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT); mScrollArea = LLUICtrlFactory::create<LLPanel>(panel_params,this); diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 9cca1b07db..474d2ca21f 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -1822,6 +1822,13 @@ BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, BOOL handled = LLView::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + // When there are no visible children drag and drop is handled + // by the folder which is the hierarchy root. + if (!handled && !hasVisibleChildren()) + { + handled = mFolders.front()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg); + } + if (handled) { lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderView" << llendl; diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 0ce8d4b7cd..259f629bdd 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -109,6 +109,7 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id) default: break; } } + setOverlapsScreenChannel(true); } void LLIMFloater::onFocusLost() diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index e2e3524f74..388e0c8d8d 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -248,7 +248,8 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES switch(mSessionType) { case AVALINE_SESSION: - // *TODO: test avaline calls (EXT-2211) + // no text notifications + break; case P2P_SESSION: gCacheName->getFullName(mOtherParticipantID, other_avatar_name); @@ -283,28 +284,14 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES break; } } - - // Update speakers list when connected - if (LLVoiceChannel::STATE_CONNECTED == new_state) - { - mSpeakers->update(true); - } - break; case GROUP_SESSION: case ADHOC_SESSION: - // *TODO: determine call starter's name "other_avatar_name" (EXT-2211) - // decide how to show notifications for a group/adhoc chat already opened - // for now there is no notification from voice channel for this case if(direction == LLVoiceChannel::INCOMING_CALL) { switch(new_state) { - case LLVoiceChannel::STATE_CALL_STARTED : - message = other_avatar_name + " " + started_call; - LLIMModel::getInstance()->addMessageSilently(mSessionID, SYSTEM_FROM, LLUUID::null, message); - break; case LLVoiceChannel::STATE_CONNECTED : message = you + " " + joined_call; LLIMModel::getInstance()->addMessageSilently(mSessionID, SYSTEM_FROM, LLUUID::null, message); @@ -324,13 +311,11 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES break; } } - - // Update speakers list when connected - if (LLVoiceChannel::STATE_CONNECTED == new_state) - { - mSpeakers->update(true); - } - break; + } + // Update speakers list when connected + if (LLVoiceChannel::STATE_CONNECTED == new_state) + { + mSpeakers->update(true); } } @@ -1497,13 +1482,17 @@ LLCallDialog(payload) } } -void LLOutgoingCallDialog::draw() +void LLCallDialog::draw() { if (lifetimeHasExpired()) { onLifetimeExpired(); } - LLDockableFloater::draw(); + + if (getDockControl() != NULL) + { + LLDockableFloater::draw(); + } } bool LLOutgoingCallDialog::lifetimeHasExpired() @@ -1648,14 +1637,6 @@ LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) : LLCallDialog(payload) { } -void LLIncomingCallDialog::draw() -{ - if (lifetimeHasExpired()) - { - onLifetimeExpired(); - } - LLDockableFloater::draw(); -} bool LLIncomingCallDialog::lifetimeHasExpired() { @@ -1878,6 +1859,14 @@ void LLIncomingCallDialog::processCallResponse(S32 response) new LLViewerChatterBoxInvitationAcceptResponder( session_id, inv_type)); + + // send notification message to the corresponding chat + if (mPayload["notify_box_type"].asString() == "VoiceInviteGroup" || mPayload["notify_box_type"].asString() == "VoiceInviteAdHoc") + { + std::string started_call = LLTrans::getString("started_call"); + std::string message = mPayload["caller_name"].asString() + " " + started_call; + LLIMModel::getInstance()->addMessageSilently(session_id, SYSTEM_FROM, LLUUID::null, message); + } } } if (voice) @@ -2545,6 +2534,11 @@ void LLIMMgr::processAgentListUpdates(const LLUUID& session_id, const LLSD& body if (speaker_mgr) { speaker_mgr->updateSpeakers(body); + + // also the same call is added into LLVoiceClient::participantUpdatedEvent because + // sometimes it is called AFTER LLViewerChatterBoxSessionAgentListUpdates::post() + // when moderation state changed too late. See EXT-3544. + speaker_mgr->update(true); } else { diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index d0ac819161..cec9d1642f 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -488,6 +488,9 @@ public: virtual BOOL postBuild(); + // check timer state + /*virtual*/ void draw(); + protected: // lifetime timer for a notification LLTimer mLifetimeTimer; @@ -509,9 +512,6 @@ public: /*virtual*/ BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); - // check timer state - /*virtual*/ void draw(); - static void onAccept(void* user_data); static void onReject(void* user_data); static void onStartIM(void* user_data); @@ -533,9 +533,6 @@ public: static void onCancel(void* user_data); static const LLUUID OCD_KEY; - // check timer state - /*virtual*/ void draw(); - private: // hide all text boxes void hideAllText(); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 3fc2cbecbe..d70221b22a 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -4555,18 +4555,8 @@ void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* mod } else if (isRemoveAction(action)) { - if (get_is_item_worn(mUUID)) - { - LLViewerInventoryItem* item = getItem(); - if (item) - { - LLWearableList::instance().getAsset(item->getAssetUUID(), - item->getName(), - item->getType(), - LLWearableBridge::onRemoveFromAvatarArrived, - new OnRemoveStruct(mUUID)); - } - } + removeFromAvatar(); + return; } else LLItemBridge::performAction(folder, model, action); } @@ -4949,6 +4939,66 @@ void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable, delete on_remove_struct; } +/* static */ +void LLWearableBridge::removeAllClothesFromAvatar() +{ + // Remove COF links. + for (S32 itype = WT_SHAPE; itype < WT_COUNT; ++itype) + { + if (itype == WT_SHAPE || itype == WT_SKIN || itype == WT_HAIR || itype == WT_EYES) + continue; + + // MULTI-WEARABLES: fixed to index 0 + LLViewerInventoryItem *item = dynamic_cast<LLViewerInventoryItem*>( + gAgentWearables.getWearableInventoryItem((EWearableType)itype, 0)); + if (!item) + continue; + const LLUUID &item_id = gInventory.getLinkedItemID(item->getUUID()); + const LLWearable *wearable = gAgentWearables.getWearableFromItemID(item_id); + if (!wearable) + continue; + + // Find and remove this item from the COF. + LLInventoryModel::item_array_t items = gInventory.collectLinkedItems( + item_id, LLAppearanceManager::instance().getCOF()); + llassert(items.size() == 1); // Should always have one and only one item linked to this in the COF. + for (LLInventoryModel::item_array_t::const_iterator iter = items.begin(); + iter != items.end(); + ++iter) + { + const LLViewerInventoryItem *linked_item = (*iter); + const LLUUID &item_id = linked_item->getUUID(); + gInventory.purgeObject(item_id); + } + } + gInventory.notifyObservers(); + + // Remove wearables from gAgentWearables + LLAgentWearables::userRemoveAllClothes(); +} + +/* static */ +void LLWearableBridge::removeItemFromAvatar(LLViewerInventoryItem *item) +{ + if (item) + { + LLWearableList::instance().getAsset(item->getAssetUUID(), + item->getName(), + item->getType(), + LLWearableBridge::onRemoveFromAvatarArrived, + new OnRemoveStruct(item->getUUID())); + } +} + +void LLWearableBridge::removeFromAvatar() +{ + if (get_is_item_worn(mUUID)) + { + LLViewerInventoryItem* item = getItem(); + removeItemFromAvatar(item); + } +} + LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_type, const LLUUID& uuid,LLInventoryModel* model) { diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 4d83e9b684..cc1fa45b26 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -572,7 +572,10 @@ public: static BOOL canRemoveFromAvatar( void* userdata ); static void onRemoveFromAvatar( void* userdata ); - static void onRemoveFromAvatarArrived( LLWearable* wearable, void* userdata ); + static void onRemoveFromAvatarArrived( LLWearable* wearable, void* userdata ); + static void removeItemFromAvatar(LLViewerInventoryItem *item); + static void removeAllClothesFromAvatar(); + void removeFromAvatar(); protected: LLWearableBridge(LLInventoryPanel* inventory, const LLUUID& uuid, LLAssetType::EType asset_type, LLInventoryType::EType inv_type, EWearableType wearable_type) : diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 082b7a9468..164e72e621 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -628,9 +628,15 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EAcceptance* accept, std::string& tooltip_msg) { - BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + // If folder view is empty the (x, y) point won't be in its rect + // so the handler must be called explicitly. + if (!mFolders->hasVisibleChildren()) + { + handled = mFolders->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + } + if (handled) { mFolders->setDragAndDropThisFrame(); diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 818e7e0db1..0ab3b07aea 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -684,7 +684,6 @@ void LLPanelStandStopFlying::onStopFlyingButtonClick() gAgent.setFlying(FALSE); setFocus(FALSE); // EXT-482 - setVisible(FALSE); } /** diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 1a0183a8ba..2ad82d3e8e 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -198,7 +198,7 @@ void LLNearbyChat::addMessage(const LLChat& chat,bool archive) } else { - mChatHistory->appendMessage(chat,use_plain_text_chat_history); + mChatHistory->appendMessage(chat, use_plain_text_chat_history); } } diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index 169560f688..9e13a626b4 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -335,7 +335,7 @@ void LLNearbyChatHandler::processChat(const LLChat& 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); + tmp_chat.mText = tmp_chat.mFromName + tmp_chat.mText.substr(3); else tmp_chat.mText = tmp_chat.mText.substr(3); } diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index 515c86bae8..33ef4c81cd 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -298,6 +298,11 @@ public: * Writes notification message to nearby chat. */ static void logToNearbyChat(const LLNotificationPtr& notification, EChatSourceType type); + + /** + * Spawns IM session. + */ + static void spawnIMSession(const std::string& name, const LLUUID& from_id); }; } diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 5b54092c5c..59351fcf47 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -47,11 +47,15 @@ const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"), "ObjectGiveItem"), OBJECT_GIVE_ITEM_UNKNOWN_USER( "ObjectGiveItemUnknownUser"), PAYMENT_RECIVED("PaymentRecived"), ADD_FRIEND_WITH_MESSAGE("AddFriendWithMessage"), - USER_GIVE_ITEM("UserGiveItem"), OFFER_FRIENDSHIP("OfferFriendship"), + USER_GIVE_ITEM("UserGiveItem"), + INVENTORY_ACCEPTED("InventoryAccepted"), + INVENTORY_DECLINED("InventoryDeclined"), + OFFER_FRIENDSHIP("OfferFriendship"), FRIENDSHIP_ACCEPTED("FriendshipAccepted"), FRIENDSHIP_OFFERED("FriendshipOffered"), FRIEND_ONLINE("FriendOnline"), FRIEND_OFFLINE("FriendOffline"), - SERVER_OBJECT_MESSAGE("ServerObjectMessage"); + SERVER_OBJECT_MESSAGE("ServerObjectMessage"), + TELEPORT_OFFERED("TeleportOffered"); // static bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification) @@ -60,7 +64,9 @@ bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification) || REVOKED_MODIFY_RIGHTS == notification->getName() || PAYMENT_RECIVED == notification->getName() || FRIENDSHIP_OFFERED == notification->getName() - || SERVER_OBJECT_MESSAGE == notification->getName(); + || SERVER_OBJECT_MESSAGE == notification->getName() + || INVENTORY_ACCEPTED == notification->getName() + || INVENTORY_DECLINED == notification->getName(); } // static @@ -68,7 +74,9 @@ bool LLHandlerUtil::canLogToNearbyChat(const LLNotificationPtr& notification) { return notification->getType() == "notifytip" && FRIEND_ONLINE != notification->getName() - && FRIEND_OFFLINE != notification->getName(); + && FRIEND_OFFLINE != notification->getName() + && INVENTORY_ACCEPTED != notification->getName() + && INVENTORY_DECLINED != notification->getName(); } // static @@ -76,7 +84,11 @@ bool LLHandlerUtil::canSpawnIMSession(const LLNotificationPtr& notification) { return ADD_FRIEND_WITH_MESSAGE == notification->getName() || OFFER_FRIENDSHIP == notification->getName() - || FRIENDSHIP_ACCEPTED == notification->getName(); + || FRIENDSHIP_ACCEPTED == notification->getName() + || USER_GIVE_ITEM == notification->getName() + || INVENTORY_ACCEPTED == notification->getName() + || INVENTORY_DECLINED == notification->getName() + || TELEPORT_OFFERED == notification->getName(); } // static @@ -169,3 +181,16 @@ void LLHandlerUtil::logToNearbyChat(const LLNotificationPtr& notification, EChat } } +// static +void LLHandlerUtil::spawnIMSession(const std::string& name, const LLUUID& from_id) +{ + LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id); + + LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession( + session_id); + if (session == NULL) + { + LLIMMgr::instance().addSession(name, IM_NOTHING_SPECIAL, from_id); + } +} + diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp index 4d64c5c0e4..5861a802e9 100644 --- a/indra/newview/llnotificationofferhandler.cpp +++ b/indra/newview/llnotificationofferhandler.cpp @@ -111,16 +111,7 @@ bool LLOfferHandler::processNotification(const LLSD& notify) LLUUID from_id = notification->getPayload()["from_id"]; - LLUUID session_id = LLIMMgr::computeSessionID( - IM_NOTHING_SPECIAL, from_id); - - LLIMModel::LLIMSession* session = - LLIMModel::instance().findIMSession(session_id); - if (session == NULL) - { - LLIMMgr::instance().addSession(name, IM_NOTHING_SPECIAL, - from_id); - } + LLHandlerUtil::spawnIMSession(name, from_id); } if (notification->getPayload().has("SUPPRES_TOST") diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp index 9afaddae82..83a2215ac6 100644 --- a/indra/newview/llnotificationtiphandler.cpp +++ b/indra/newview/llnotificationtiphandler.cpp @@ -101,6 +101,19 @@ bool LLTipHandler::processNotification(const LLSD& notify) } } + const std::string name = notification->getSubstitutions()["NAME"]; + LLUUID from_id = notification->getPayload()["from_id"]; + if (LLHandlerUtil::canLogToIM(notification)) + { + LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, name, name, + notification->getMessage(), from_id, from_id); + } + + if (LLHandlerUtil::canSpawnIMSession(notification)) + { + LLHandlerUtil::spawnIMSession(name, from_id); + } + LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification); LLToast::Params p; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index e9131a342e..913152e259 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -179,6 +179,10 @@ void LLPanelAvatarNotes::onOpen(const LLSD& key) void LLPanelAvatarNotes::fillRightsData() { + childSetValue("status_check", FALSE); + childSetValue("map_check", FALSE); + childSetValue("objects_check", FALSE); + const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); // If true - we are viewing friend's profile, enable check boxes and set values. if(relation) diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index e16bac2098..d75744ead9 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -49,9 +49,9 @@ #include "llfloaterworldmap.h" #include "llfolderviewitem.h" #include "llinventorypanel.h" -#include "llinventorysubtreepanel.h" #include "lllandmarkactions.h" #include "llplacesinventorybridge.h" +#include "llplacesinventorypanel.h" #include "llsidetray.h" #include "llviewermenu.h" #include "llviewerregion.h" @@ -66,15 +66,13 @@ static const std::string TRASH_BUTTON_NAME = "trash_btn"; // helper functions -static void filter_list(LLInventorySubTreePanel* inventory_list, const std::string& string); -static void save_folder_state_if_no_filter(LLInventorySubTreePanel* inventory_list); +static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::string& string); +static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list); /** - * Bridge to support knowing when the inventory has changed to update folder (open/close) state - * for landmarks panels. - * - * Due to Inventory data are loaded in background we need to save folder state each time - * next level is loaded. See EXT-3094. + * Bridge to support knowing when the inventory has changed to update Landmarks tab + * ShowFolderState filter setting to show all folders when the filter string is empty and + * empty folder message when Landmarks inventory category has no children. */ class LLLandmarksPanelObserver : public LLInventoryObserver { @@ -89,7 +87,7 @@ private: void LLLandmarksPanelObserver::changed(U32 mask) { - mLP->saveFolderStateIfNoFilter(); + mLP->updateShowFolderState(); } LLLandmarksPanel::LLLandmarksPanel() @@ -134,22 +132,12 @@ BOOL LLLandmarksPanel::postBuild() getChild<LLAccordionCtrlTab>("tab_favorites")->setDisplayChildren(true); getChild<LLAccordionCtrlTab>("tab_landmarks")->setDisplayChildren(true); - gIdleCallbacks.addFunction(LLLandmarksPanel::doIdle, this); return TRUE; } // virtual void LLLandmarksPanel::onSearchEdit(const std::string& string) { - // show all folders in Landmarks Accordion for empty filter - if (mLandmarksInventoryPanel->getFilter()) - { - mLandmarksInventoryPanel->setShowFolderState(string.empty() ? - LLInventoryFilter::SHOW_ALL_FOLDERS : - LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS - ); - } - // give FolderView a chance to be refreshed. So, made all accordions visible for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) { @@ -162,7 +150,7 @@ void LLLandmarksPanel::onSearchEdit(const std::string& string) tab->changeOpenClose(false); } - LLInventorySubTreePanel* inventory_list = dynamic_cast<LLInventorySubTreePanel*>(tab->getAccordionView()); + LLPlacesInventoryPanel* inventory_list = dynamic_cast<LLPlacesInventoryPanel*>(tab->getAccordionView()); if (NULL == inventory_list) continue; if (inventory_list->getFilter()) @@ -173,6 +161,10 @@ void LLLandmarksPanel::onSearchEdit(const std::string& string) if (sFilterSubString != string) sFilterSubString = string; + + // show all folders in Landmarks Accordion for empty filter + // only if Landmarks inventory folder is not empty + updateShowFolderState(); } // virtual @@ -226,7 +218,7 @@ void LLLandmarksPanel::updateVerbs() updateListCommands(); } -void LLLandmarksPanel::onSelectionChange(LLInventorySubTreePanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action) +void LLLandmarksPanel::onSelectionChange(LLPlacesInventoryPanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action) { if (user_action && (items.size() > 0)) { @@ -254,12 +246,21 @@ void LLLandmarksPanel::onSelectorButtonClicked() } } -void LLLandmarksPanel::saveFolderStateIfNoFilter() +void LLLandmarksPanel::updateShowFolderState() { - save_folder_state_if_no_filter(mFavoritesInventoryPanel); - save_folder_state_if_no_filter(mLandmarksInventoryPanel); - save_folder_state_if_no_filter(mMyInventoryPanel); - save_folder_state_if_no_filter(mLibraryInventoryPanel); + if (!mLandmarksInventoryPanel->getFilter()) + return; + + bool show_all_folders = mLandmarksInventoryPanel->getRootFolder()->getFilterSubString().empty(); + if (show_all_folders) + { + show_all_folders = category_has_descendents(mLandmarksInventoryPanel); + } + + mLandmarksInventoryPanel->setShowFolderState(show_all_folders ? + LLInventoryFilter::SHOW_ALL_FOLDERS : + LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS + ); } ////////////////////////////////////////////////////////////////////////// @@ -361,7 +362,7 @@ void LLLandmarksPanel::setErrorStatus(U32 status, const std::string& reason) void LLLandmarksPanel::initFavoritesInventoryPanel() { - mFavoritesInventoryPanel = getChild<LLInventorySubTreePanel>("favorites_list"); + mFavoritesInventoryPanel = getChild<LLPlacesInventoryPanel>("favorites_list"); initLandmarksPanel(mFavoritesInventoryPanel); mFavoritesInventoryPanel->getFilter()->setEmptyLookupMessage("FavoritesNoMatchingItems"); @@ -371,7 +372,7 @@ void LLLandmarksPanel::initFavoritesInventoryPanel() void LLLandmarksPanel::initLandmarksInventoryPanel() { - mLandmarksInventoryPanel = getChild<LLInventorySubTreePanel>("landmarks_list"); + mLandmarksInventoryPanel = getChild<LLPlacesInventoryPanel>("landmarks_list"); initLandmarksPanel(mLandmarksInventoryPanel); @@ -390,7 +391,7 @@ void LLLandmarksPanel::initLandmarksInventoryPanel() void LLLandmarksPanel::initMyInventoryPanel() { - mMyInventoryPanel= getChild<LLInventorySubTreePanel>("my_inventory_list"); + mMyInventoryPanel= getChild<LLPlacesInventoryPanel>("my_inventory_list"); initLandmarksPanel(mMyInventoryPanel); @@ -399,14 +400,14 @@ void LLLandmarksPanel::initMyInventoryPanel() void LLLandmarksPanel::initLibraryInventoryPanel() { - mLibraryInventoryPanel = getChild<LLInventorySubTreePanel>("library_list"); + mLibraryInventoryPanel = getChild<LLPlacesInventoryPanel>("library_list"); initLandmarksPanel(mLibraryInventoryPanel); initAccordion("tab_library", mLibraryInventoryPanel); } -void LLLandmarksPanel::initLandmarksPanel(LLInventorySubTreePanel* inventory_list) +void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list) { // In case of a dummy widget further we have no Folder View widget and no Filter, // so further initialization leads to crash. @@ -430,7 +431,7 @@ void LLLandmarksPanel::initLandmarksPanel(LLInventorySubTreePanel* inventory_lis inventory_list->saveFolderState(); } -void LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLInventorySubTreePanel* inventory_list) +void LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list) { LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>(accordion_tab_name); @@ -440,7 +441,7 @@ void LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLIn accordion_tab->setDisplayChildren(false); } -void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLInventorySubTreePanel* inventory_list) +void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list) { bool expanded = param.asBoolean(); @@ -466,7 +467,7 @@ void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLInvento } } -void LLLandmarksPanel::deselectOtherThan(const LLInventorySubTreePanel* inventory_list) +void LLLandmarksPanel::deselectOtherThan(const LLPlacesInventoryPanel* inventory_list) { if (inventory_list != mFavoritesInventoryPanel) { @@ -660,7 +661,12 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata) } else if ("collapse_all" == command_name) { - root_folder->closeAllFolders(); + root_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN); + + // The top level folder is invisible, it must be open to + // display its sub-folders. + root_folder->openTopLevelFolders(); + root_folder->arrangeAll(); } else if ( "sort_by_date" == command_name) { @@ -778,46 +784,6 @@ void LLLandmarksPanel::onCustomAction(const LLSD& userdata) } } -void LLLandmarksPanel::updateFilteredAccordions() -{ - LLInventoryPanel* inventory_list = NULL; - LLAccordionCtrlTab* accordion_tab = NULL; - bool needs_arrange = false; - - for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) - { - accordion_tab = *iter; - - accordion_tab->setVisible(TRUE); - - inventory_list = dynamic_cast<LLInventorySubTreePanel*> (accordion_tab->getAccordionView()); - if (NULL == inventory_list) continue; - - // This doesn't seem to work correctly. Disabling for now. -Seraph - // Enabled to show/hide accordions with/without landmarks. See EXT-2346. (Seth PE) - LLFolderView* fv = inventory_list->getRootFolder(); - - // arrange folder view contents to draw its descendants if it has any - fv->arrangeFromRoot(); - - bool has_descendants = fv->hasFilteredDescendants(); - if (!has_descendants) - needs_arrange = true; - - accordion_tab->setVisible(has_descendants); - - //accordion_tab->setVisible(TRUE); - } - - // we have to arrange accordion tabs for cases when filter string is less restrictive but - // all items are still filtered. - if (needs_arrange) - { - static LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion"); - accordion->arrange(); - } -} - /* Processes such actions: cut/rename/delete/paste actions @@ -926,13 +892,6 @@ bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType carg return true; } -// static -void LLLandmarksPanel::doIdle(void* landmarks_panel) -{ - LLLandmarksPanel* panel = (LLLandmarksPanel* ) landmarks_panel; - panel->updateFilteredAccordions(); -} - void LLLandmarksPanel::doShowOnMap(LLLandmark* landmark) { LLVector3d landmark_global_pos; @@ -1028,10 +987,10 @@ void LLLandmarksPanel::doCreatePick(LLLandmark* landmark) ////////////////////////////////////////////////////////////////////////// // HELPER FUNCTIONS ////////////////////////////////////////////////////////////////////////// -static void filter_list(LLInventorySubTreePanel* inventory_list, const std::string& string) +static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::string& string) { // When search is cleared, restore the old folder state. - if (string == "") + if (!inventory_list->getRootFolder()->getFilterSubString().empty() && string == "") { inventory_list->setFilterSubString(LLStringUtil::null); // Re-open folders that were open before @@ -1056,15 +1015,16 @@ static void filter_list(LLInventorySubTreePanel* inventory_list, const std::stri // Set new filter string inventory_list->setFilterSubString(string); - } -static void save_folder_state_if_no_filter(LLInventorySubTreePanel* inventory_list) +static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list) { - // save current folder open state if no filter currently applied - if (inventory_list->getRootFolder() && inventory_list->getRootFolder()->getFilterSubString().empty()) + LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getStartFolderID()); + if (category) { - // inventory_list->saveFolderState(); // *TODO: commented out to fix build + return category->getDescendentCount() > 0; } + + return false; } // EOF diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index b0e537f647..569739237d 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -46,7 +46,7 @@ class LLAccordionCtrlTab; class LLFolderViewItem; class LLMenuGL; class LLInventoryPanel; -class LLInventorySubTreePanel; +class LLPlacesInventoryPanel; class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver { @@ -60,17 +60,18 @@ public: /*virtual*/ void onTeleport(); /*virtual*/ void updateVerbs(); - void onSelectionChange(LLInventorySubTreePanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action); + void onSelectionChange(LLPlacesInventoryPanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action); void onSelectorButtonClicked(); - void setCurrentSelectedList(LLInventorySubTreePanel* inventory_list) + void setCurrentSelectedList(LLPlacesInventoryPanel* inventory_list) { mCurrentSelectedList = inventory_list; } /** - * Saves folder state for all Inventory Panels if there are no applied filter. + * Update filter ShowFolderState setting to show empty folder message + * if Landmarks inventory folder is empty. */ - void saveFolderStateIfNoFilter(); + void updateShowFolderState(); protected: /** @@ -92,10 +93,10 @@ private: void initLandmarksInventoryPanel(); void initMyInventoryPanel(); void initLibraryInventoryPanel(); - void initLandmarksPanel(LLInventorySubTreePanel* inventory_list); - void initAccordion(const std::string& accordion_tab_name, LLInventorySubTreePanel* inventory_list); - void onAccordionExpandedCollapsed(const LLSD& param, LLInventorySubTreePanel* inventory_list); - void deselectOtherThan(const LLInventorySubTreePanel* inventory_list); + void initLandmarksPanel(LLPlacesInventoryPanel* inventory_list); + void initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list); + void onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list); + void deselectOtherThan(const LLPlacesInventoryPanel* inventory_list); // List Commands Handlers void initListCommandsHandlers(); @@ -112,13 +113,6 @@ private: void onCustomAction(const LLSD& command_name); /** - * Updates accordions according to filtered items in lists. - * - * It hides accordion for empty lists - */ - void updateFilteredAccordions(); - - /** * Determines if selected item can be modified via context/gear menu. * * It validates Places Landmarks rules first. And then LLFolderView permissions. @@ -133,11 +127,6 @@ private: bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept); /** - * Static callback for gIdleCallbacks to perform actions out of drawing - */ - static void doIdle(void* landmarks_panel); - - /** * Landmark actions callbacks. Fire when a landmark is loaded from the list. */ void doShowOnMap(LLLandmark* landmark); @@ -148,14 +137,14 @@ private: void doCreatePick(LLLandmark* landmark); private: - LLInventorySubTreePanel* mFavoritesInventoryPanel; - LLInventorySubTreePanel* mLandmarksInventoryPanel; - LLInventorySubTreePanel* mMyInventoryPanel; - LLInventorySubTreePanel* mLibraryInventoryPanel; + LLPlacesInventoryPanel* mFavoritesInventoryPanel; + LLPlacesInventoryPanel* mLandmarksInventoryPanel; + LLPlacesInventoryPanel* mMyInventoryPanel; + LLPlacesInventoryPanel* mLibraryInventoryPanel; LLMenuGL* mGearLandmarkMenu; LLMenuGL* mGearFolderMenu; LLMenuGL* mMenuAdd; - LLInventorySubTreePanel* mCurrentSelectedList; + LLPlacesInventoryPanel* mCurrentSelectedList; LLInventoryObserver* mInventoryObserver; LLPanel* mListCommands; diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 374af5c059..5cc4d4aec6 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -965,6 +965,13 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string) mFilterSubString = search_upper; + //store accordion tabs state before any manipulation with accordion tabs + if(!mFilterSubString.empty()) + { + notifyChildren(LLSD().with("action","store_state")); + } + + // Apply new filter. mNearbyList->setNameFilter(mFilterSubString); mOnlineFriendList->setNameFilter(mFilterSubString); @@ -976,6 +983,12 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string) setAccordionCollapsedByUser("tab_all", false); showFriendsAccordionsIfNeeded(); + + //restore accordion tabs state _after_ all manipulations... + if(mFilterSubString.empty()) + { + notifyChildren(LLSD().with("action","restore_state")); + } } void LLPanelPeople::onTabSelected(const LLSD& param) diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp index 839452d061..7a4dd3569d 100644 --- a/indra/newview/llpanelpick.cpp +++ b/indra/newview/llpanelpick.cpp @@ -284,6 +284,7 @@ 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) @@ -291,6 +292,31 @@ void LLPanelPickInfo::setPickLocation(const std::string& location) childSetValue(XML_LOCATION, location); } +void LLPanelPickInfo::updateContentPanelRect() +{ + LLTextBox* desc = getChild<LLTextBox>(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<LLView>("profile_scroll")); + + LLPanel* content_panel = getChild<LLPanel>("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 95add387d0..12b5a116b4 100644 --- a/indra/newview/llpanelpick.h +++ b/indra/newview/llpanelpick.h @@ -140,6 +140,15 @@ protected: 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 */ void onClickMap(); diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 03b616d280..77c2fb7c8c 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -472,11 +472,8 @@ void LLTeleportHistoryPanel::draw() // virtual void LLTeleportHistoryPanel::onSearchEdit(const std::string& string) { - if (sFilterSubString != string) - { - sFilterSubString = string; - showTeleportHistory(); - } + sFilterSubString = string; + showTeleportHistory(); } // virtual @@ -662,6 +659,9 @@ void LLTeleportHistoryPanel::refresh() // Expand all accordion tabs when filtering if(!sFilterSubString.empty()) { + //store accordion tab state when filter is not empty + tab->notifyChildren(LLSD().with("action","store_state")); + tab->setDisplayChildren(true); } // Restore each tab's expand state when not filtering @@ -669,6 +669,9 @@ void LLTeleportHistoryPanel::refresh() { bool collapsed = isAccordionCollapsedByUser(tab); tab->setDisplayChildren(!collapsed); + + //restore accordion state after all those accodrion tabmanipulations + tab->notifyChildren(LLSD().with("action","restore_state")); } curr_flat_view = getFlatListViewFromTab(tab); diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index ecce25dd18..479c29f656 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -215,6 +215,8 @@ void LLParticipantList::updateRecentSpeakersOrder() { if (E_SORT_BY_RECENT_SPEAKERS == getSortOrder()) { + // Need to update speakers to sort list correctly + mSpeakerMgr->update(true); // Resort avatar list sort(); } @@ -575,33 +577,45 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD& { return mUUIDs.front() != gAgentID; } - else - if (item == "can_allow_text_chat" || "can_moderate_voice" == item) + else if (item == "can_allow_text_chat") + { + return isGroupModerator(); + } + else if ("can_moderate_voice" == item) + { + if (isGroupModerator()) { - return isGroupModerator(); + LLPointer<LLSpeaker> speakerp = mParent.mSpeakerMgr->findSpeaker(mUUIDs.front()); + if (speakerp.notNull()) + { + // not in voice participants can not be moderated + return speakerp->mStatus != LLSpeaker::STATUS_TEXT_ONLY; + } } + return false; + } else if (item == std::string("can_add")) - { - // We can add friends if: - // - there are selected people - // - and there are no friends among selection yet. + { + // We can add friends if: + // - there are selected people + // - and there are no friends among selection yet. - bool result = (mUUIDs.size() > 0); + bool result = (mUUIDs.size() > 0); - std::vector<LLUUID>::const_iterator - id = mUUIDs.begin(), - uuids_end = mUUIDs.end(); + std::vector<LLUUID>::const_iterator + id = mUUIDs.begin(), + uuids_end = mUUIDs.end(); - for (;id != uuids_end; ++id) + for (;id != uuids_end; ++id) + { + if ( LLAvatarActions::isFriend(*id) ) { - if ( LLAvatarActions::isFriend(*id) ) - { - result = false; - break; - } + result = false; + break; } - return result; } + return result; + } else if (item == "can_call") { return LLVoiceClient::voiceEnabled(); diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp new file mode 100644 index 0000000000..4de953a59d --- /dev/null +++ b/indra/newview/llplacesinventorypanel.cpp @@ -0,0 +1,191 @@ +/** + * @file llplacesinventorypanel.cpp + * @brief LLPlacesInventoryPanel class definition + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 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 "llscrollcontainer.h" + +#include "llplacesinventorypanel.h" + +#include "llfoldervieweventlistener.h" +#include "llinventorybridge.h" +#include "llinventoryfunctions.h" +#include "llpanellandmarks.h" +#include "llplacesinventorybridge.h" + +static LLDefaultChildRegistry::Register<LLPlacesInventoryPanel> r("places_inventory_panel"); + +static const LLPlacesInventoryBridgeBuilder PLACES_INVENTORY_BUILDER; + +LLPlacesInventoryPanel::LLPlacesInventoryPanel(const Params& p) : + LLInventoryPanel(p), + mSavedFolderState(NULL) + +{ + mInvFVBridgeBuilder = &PLACES_INVENTORY_BUILDER; + mSavedFolderState = new LLSaveFolderState(); + mSavedFolderState->setApply(FALSE); +} + + +LLPlacesInventoryPanel::~LLPlacesInventoryPanel() +{ + delete mSavedFolderState; +} + +BOOL LLPlacesInventoryPanel::postBuild() +{ + LLInventoryPanel::postBuild(); + + // clear Contents(); + { + mFolders->destroyView(); + mFolders->getParent()->removeChild(mFolders); + mFolders->die(); + + if( mScroller ) + { + removeChild( mScroller ); + mScroller->die(); + mScroller = NULL; + } + mFolders = NULL; + } + + + mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves + + // create root folder + { + LLRect folder_rect(0, + 0, + getRect().getWidth(), + 0); + LLPlacesFolderView::Params p; + p.name = getName(); + p.rect = folder_rect; + p.parent_panel = this; + mFolders = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p); + mFolders->setAllowMultiSelect(mAllowMultiSelect); + } + + mCommitCallbackRegistrar.popScope(); + + mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar); + + // scroller + { + LLRect scroller_view_rect = getRect(); + scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); + LLScrollContainer::Params p; + p.name("Inventory Scroller"); + p.rect(scroller_view_rect); + p.follows.flags(FOLLOWS_ALL); + p.reserve_scroll_corner(true); + p.tab_stop(true); + mScroller = LLUICtrlFactory::create<LLScrollContainer>(p); + } + addChild(mScroller); + mScroller->addChild(mFolders); + + mFolders->setScrollContainer(mScroller); + + + // cut subitems + mFolders->setUseEllipses(true); + + return TRUE; +} + +// save current folder open state +void LLPlacesInventoryPanel::saveFolderState() +{ + mSavedFolderState->setApply(FALSE); + getRootFolder()->applyFunctorRecursively(*mSavedFolderState); +} + +// re-open folders which state was saved +void LLPlacesInventoryPanel::restoreFolderState() +{ + mSavedFolderState->setApply(TRUE); + getRootFolder()->applyFunctorRecursively(*mSavedFolderState); + LLOpenFoldersWithSelection opener; + getRootFolder()->applyFunctorRecursively(opener); + getRootFolder()->scrollToShowSelection(); +} + +/************************************************************************/ +/* PROTECTED METHODS */ +/************************************************************************/ + + + +/************************************************************************/ +/* LLPlacesFolderView implementation */ +/************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// PUBLIC METHODS +////////////////////////////////////////////////////////////////////////// + +BOOL LLPlacesFolderView::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + // let children to change selection first + childrenHandleRightMouseDown(x, y, mask); + mParentLandmarksPanel->setCurrentSelectedList((LLPlacesInventoryPanel*)getParentPanel()); + + // then determine its type and set necessary menu handle + if (getCurSelectedItem()) + { + LLInventoryType::EType inventory_type = getCurSelectedItem()->getListener()->getInventoryType(); + inventory_type_menu_handle_t::iterator it_handle = mMenuHandlesByInventoryType.find(inventory_type); + + if (it_handle != mMenuHandlesByInventoryType.end()) + { + mPopupMenuHandle = (*it_handle).second; + } + else + { + llwarns << "Requested menu handle for non-setup inventory type: " << inventory_type << llendl; + } + + } + + return LLFolderView::handleRightMouseDown(x, y, mask); +} + +void LLPlacesFolderView::setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle) +{ + mMenuHandlesByInventoryType[asset_type] = menu_handle; +} + +// EOF diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h new file mode 100644 index 0000000000..7b34045d32 --- /dev/null +++ b/indra/newview/llplacesinventorypanel.h @@ -0,0 +1,96 @@ +/** + * @file llplacesinventorypanel.h + * @brief LLPlacesInventoryPanel class declaration + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 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_LLINVENTORYSUBTREEPANEL_H +#define LL_LLINVENTORYSUBTREEPANEL_H + +#include "llfloaterinventory.h" +#include "llinventorypanel.h" +#include "llfolderview.h" + +class LLLandmarksPanel; + +class LLPlacesInventoryPanel : public LLInventoryPanel +{ +public: + struct Params + : public LLInitParam::Block<Params, LLInventoryPanel::Params> + { + Params() + {} + }; + + LLPlacesInventoryPanel(const Params& p); + ~LLPlacesInventoryPanel(); + + /*virtual*/ BOOL postBuild(); + + void saveFolderState(); + void restoreFolderState(); + +private: + LLSaveFolderState* mSavedFolderState; +}; + + +class LLPlacesFolderView : public LLFolderView +{ +public: + LLPlacesFolderView(const LLFolderView::Params& p) : LLFolderView(p) {}; + /** + * Handles right mouse down + * + * Contains workaround for EXT-2786: sets current selected list for landmark + * panel using @c mParentLandmarksPanel which is set in @c LLLandmarksPanel::initLandmarksPanel + */ + /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); + + void setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle); + + void setParentLandmarksPanel(LLLandmarksPanel* panel) + { + mParentLandmarksPanel = panel; + } + + S32 getSelectedCount() { return (S32)mSelectedItems.size(); } + +private: + /** + * holds pointer to landmark panel. This pointer is used in @c LLPlacesFolderView::handleRightMouseDown + */ + LLLandmarksPanel* mParentLandmarksPanel; + typedef std::map<LLInventoryType::EType, LLHandle<LLView> > inventory_type_menu_handle_t; + inventory_type_menu_handle_t mMenuHandlesByInventoryType; + +}; + +#endif //LL_LLINVENTORYSUBTREEPANEL_H diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index c18fe8ad7e..8c3f3dc5fb 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -462,6 +462,8 @@ void LLScreenChannel::showToastsBottom() S32 toast_margin = 0; std::vector<ToastElem>::reverse_iterator it; + LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get()); + for(it = mToastList.rbegin(); it != mToastList.rend(); ++it) { if(it != mToastList.rbegin()) @@ -474,6 +476,16 @@ void LLScreenChannel::showToastsBottom() toast_rect.setOriginAndSize(getRect().mLeft, bottom + toast_margin, toast_rect.getWidth() ,toast_rect.getHeight()); (*it).toast->setRect(toast_rect); + // don't show toasts if there is not enough space + if(floater && floater->overlapsScreenChannel()) + { + LLRect world_rect = gViewerWindow->getWorldViewRectScaled(); + if(toast_rect.mTop + getOverflowToastHeight() + toast_margin > world_rect.mTop) + { + break; + } + } + bool stop_showing_toasts = (*it).toast->getRect().mTop > getRect().mTop; if(!stop_showing_toasts) @@ -575,6 +587,18 @@ void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer) 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*>(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); @@ -664,6 +688,24 @@ 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) { @@ -822,25 +864,22 @@ void LLScreenChannel::updateShowToastsState() return; } - // for Message Well floater showed in a docked state - adjust channel's height - if(dynamic_cast<LLSysWellWindow*>(floater) || dynamic_cast<LLIMFloater*>(floater) - || dynamic_cast<LLScriptFloater*>(floater)) + S32 channel_bottom = gViewerWindow->getWorldViewRectScaled().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");; + LLRect this_rect = getRect(); + + // adjust channel's height + if(floater->overlapsScreenChannel()) { - S32 channel_bottom = gViewerWindow->getWorldViewRectScaled().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");; - LLRect this_rect = getRect(); - if(floater->getVisible() && floater->isDocked()) + channel_bottom += floater->getRect().getHeight(); + if(floater->getDockControl()) { - channel_bottom += floater->getRect().getHeight(); - if(floater->getDockControl()) - { - channel_bottom += floater->getDockControl()->getTongueHeight(); - } + channel_bottom += floater->getDockControl()->getTongueHeight(); } + } - if(channel_bottom != this_rect.mBottom) - { - setRect(LLRect(this_rect.mLeft, this_rect.mTop, this_rect.mRight, channel_bottom)); - } + if(channel_bottom != this_rect.mBottom) + { + setRect(LLRect(this_rect.mLeft, this_rect.mTop, this_rect.mRight, channel_bottom)); } } diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h index 321fb244a1..38f27f756b 100644 --- a/indra/newview/llscreenchannel.h +++ b/indra/newview/llscreenchannel.h @@ -281,6 +281,8 @@ private: */ static F32 getHeightRatio(); + S32 getOverflowToastHeight(); + // Channel's flags static bool mWasStartUpToastShown; diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp index 1962d871a6..cf62d47362 100644 --- a/indra/newview/llscriptfloater.cpp +++ b/indra/newview/llscriptfloater.cpp @@ -67,6 +67,7 @@ LLScriptFloater::LLScriptFloater(const LLSD& key) , mScriptForm(NULL) { setMouseDownCallback(boost::bind(&LLScriptFloater::onMouseDown, this)); + setOverlapsScreenChannel(true); } bool LLScriptFloater::toggle(const LLUUID& object_id) diff --git a/indra/newview/llspeakbutton.cpp b/indra/newview/llspeakbutton.cpp index 90214a1bd7..8f2c877c7a 100644 --- a/indra/newview/llspeakbutton.cpp +++ b/indra/newview/llspeakbutton.cpp @@ -123,7 +123,7 @@ LLSpeakButton::LLSpeakButton(const Params& p) mOutputMonitor->setIsAgentControl(true); //*TODO find a better place to do that - LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLCallFloater::sOnCurrentChannelChanged, _1)); + LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLCallFloater::sOnCurrentChannelChanged, _1), true); } LLSpeakButton::~LLSpeakButton() diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 9e72464237..23c4f00ab7 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -160,6 +160,7 @@ LLStatusBar::LLStatusBar(const LLRect& rect) mBtnVolume = getChild<LLButton>( "volume_btn" ); mBtnVolume->setClickedCallback( onClickVolume, this ); mBtnVolume->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterVolume, this)); + mBtnVolume->setIsChrome(TRUE); gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&LLStatusBar::onVolumeChanged, this, _2)); diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 3cddf6d902..bcaefc3690 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -63,6 +63,7 @@ LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLDockableFloater(NULL, key) { mTypedItemsCount[IT_NOTIFICATION] = 0; mTypedItemsCount[IT_INSTANT_MESSAGE] = 0; + setOverlapsScreenChannel(true); } //--------------------------------------------------------------------------------- diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 3f489544b4..a75f631769 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -842,10 +842,10 @@ bool LLTextureFetchWorker::doWork(S32 param) mLoaded = FALSE; mGetStatus = 0; mGetReason.clear(); - lldebugs << "HTTP GET: " << mID << " Offset: " << offset - << " Bytes: " << mRequestedSize - << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << max_bandwidth - << llendl; + LL_DEBUGS("Texture") << "HTTP GET: " << mID << " Offset: " << offset + << " Bytes: " << mRequestedSize + << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << max_bandwidth + << LL_ENDL; setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); mState = WAIT_HTTP_REQ; @@ -1257,7 +1257,7 @@ void LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, gTextureList.sTextureBits += data_size * 8; // Approximate - does not include header bits - //llinfos << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << llendl; + LL_DEBUGS("Texture") << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << LL_ENDL; if (data_size > 0) { // *TODO: set the formatted image data here directly to avoid the copy @@ -1450,8 +1450,9 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con if (!url.empty() && (!exten.empty() && LLImageBase::getCodecFromExtension(exten) != IMG_CODEC_J2C)) { // Only do partial requests for J2C at the moment - //llinfos << "Merov : LLTextureFetch::createRequest(), blocking fetch on " << url << llendl; + //llinfos << "Merov : LLTextureFetch::createRequest(), blocking fetch on " << url << llendl; desired_size = MAX_IMAGE_DATA_SIZE; + desired_discard = 0; } else if (desired_discard == 0) { diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp index b7add03e0e..d62017cc2f 100644 --- a/indra/newview/lltoastimpanel.cpp +++ b/indra/newview/lltoastimpanel.cpp @@ -35,13 +35,14 @@ #include "llnotifications.h" #include "llinstantmessage.h" +#include "llviewerchat.h" const S32 LLToastIMPanel::DEFAULT_MESSAGE_MAX_LINE_COUNT = 6; //-------------------------------------------------------------------------- LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notification), - mAvatar(NULL), mUserName(NULL), - mTime(NULL), mMessage(NULL) + mAvatar(NULL), mUserName(NULL), + mTime(NULL), mMessage(NULL) { LLUICtrlFactory::getInstance()->buildPanel(this, "panel_instant_message.xml"); @@ -52,8 +53,11 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif mMessage = getChild<LLTextBox>("message"); LLStyle::Params style_params; - style_params.font.name(LLFontGL::nameFromFont(style_params.font)); - style_params.font.size(LLFontGL::sizeFromFont(style_params.font)); + LLFontGL* fontp = LLViewerChat::getChatFont(); + std::string font_name = LLFontGL::nameFromFont(fontp); + std::string font_size = LLFontGL::sizeFromFont(fontp); + style_params.font.name(font_name); + style_params.font.size(font_size); style_params.font.style = "UNDERLINE"; //Handle IRC styled /me messages. @@ -63,13 +67,16 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif mMessage->clear(); style_params.font.style ="ITALIC"; - mMessage->appendText(p.from + " ", FALSE, style_params); + mMessage->appendText(p.from, FALSE, style_params); style_params.font.style = "ITALIC"; mMessage->appendText(p.message.substr(3), FALSE, style_params); } else + { mMessage->setValue(p.message); + } + mUserName->setValue(p.from); mTime->setValue(p.time); mSessionID = p.session_id; diff --git a/indra/newview/llviewermedia_streamingaudio.cpp b/indra/newview/llviewermedia_streamingaudio.cpp index 90cfb85821..e9293ac5a4 100644 --- a/indra/newview/llviewermedia_streamingaudio.cpp +++ b/indra/newview/llviewermedia_streamingaudio.cpp @@ -1,7 +1,7 @@ /** * @file llviewermedia_streamingaudio.h * @author Tofu Linden, Sam Kolb - * @brief LLStreamingAudio_MediaPlugins implementation - an implementation of the streaming audio interface which is implemented as a client of the media plugins API. + * @brief LLStreamingAudio_MediaPlugins implementation - an implementation of the streaming audio interface which is implemented as a client of the media plugin API. * * $LicenseInfo:firstyear=2009&license=viewergpl$ * @@ -33,6 +33,7 @@ #include "llviewerprecompiledheaders.h" #include "linden_common.h" #include "llpluginclassmedia.h" +#include "llpluginclassmediaowner.h" #include "llviewermedia.h" #include "llviewermedia_streamingaudio.h" @@ -61,18 +62,18 @@ void LLStreamingAudio_MediaPlugins::start(const std::string& url) if (!mMediaPlugin) // lazy-init the underlying media plugin { mMediaPlugin = initializeMedia("audio/mpeg"); // assumes that whatever media implementation supports mp3 also supports vorbis. - llinfos << "mMediaPlugin is now " << mMediaPlugin << llendl; + llinfos << "steaming audio mMediaPlugin is now " << mMediaPlugin << llendl; } if(!mMediaPlugin) return; - + if (!url.empty()) { llinfos << "Starting internet stream: " << url << llendl; mURL = url; mMediaPlugin->loadURI ( url ); mMediaPlugin->start(); - llinfos << "Playing....." << llendl; + llinfos << "Playing stream..." << llendl; } else { llinfos << "setting stream to NULL"<< llendl; mURL.clear(); @@ -82,6 +83,7 @@ void LLStreamingAudio_MediaPlugins::start(const std::string& url) void LLStreamingAudio_MediaPlugins::stop() { + llinfos << "Stopping internet stream." << llendl; if(mMediaPlugin) { mMediaPlugin->stop(); @@ -97,10 +99,12 @@ void LLStreamingAudio_MediaPlugins::pause(int pause) if(pause) { + llinfos << "Pausing internet stream." << llendl; mMediaPlugin->pause(); } else { + llinfos << "Unpausing internet stream." << llendl; mMediaPlugin->start(); } } @@ -114,20 +118,21 @@ void LLStreamingAudio_MediaPlugins::update() int LLStreamingAudio_MediaPlugins::isPlaying() { if (!mMediaPlugin) - return 0; + return 0; // stopped - // *TODO: can probably do better than this - if (mMediaPlugin->isPluginRunning()) - { - return 1; // Active and playing - } + LLPluginClassMediaOwner::EMediaStatus status = + mMediaPlugin->getStatus(); - if (mMediaPlugin->isPluginExited()) + switch (status) { + case LLPluginClassMediaOwner::MEDIA_LOADING: // but not MEDIA_LOADED + case LLPluginClassMediaOwner::MEDIA_PLAYING: + return 1; // Active and playing + case LLPluginClassMediaOwner::MEDIA_PAUSED: + return 2; // paused + default: return 0; // stopped } - - return 2; // paused } void LLStreamingAudio_MediaPlugins::setGain(F32 vol) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 23bcca9603..2a9c738c97 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -6479,21 +6479,27 @@ void menu_toggle_attached_particles(void* user_data) LLPipeline::sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); } -class LLAdvancedHandleAttchedLightParticles: public view_listener_t +class LLAdvancedHandleAttachedLightParticles: public view_listener_t { bool handleEvent(const LLSD& userdata) { std::string control_name = userdata.asString(); + + // toggle the control + gSavedSettings.setBOOL(control_name, + !gSavedSettings.getBOOL(control_name)); + + // update internal flags if (control_name == "RenderAttachedLights") -{ + { menu_toggle_attached_lights(NULL); -} + } else if (control_name == "RenderAttachedParticles") -{ + { menu_toggle_attached_particles(NULL); -} + } return true; -} + } }; class LLSomethingSelected : public view_listener_t @@ -7423,12 +7429,17 @@ class LLEditTakeOff : public view_listener_t { std::string clothing = userdata.asString(); if (clothing == "all") - LLAgentWearables::userRemoveAllClothes(); + LLWearableBridge::removeAllClothesFromAvatar(); else { EWearableType type = LLWearableDictionary::typeNameToType(clothing); if (type >= WT_SHAPE && type < WT_COUNT) - LLAgentWearables::userRemoveWearable(type); + { + // MULTI-WEARABLES + LLViewerInventoryItem *item = dynamic_cast<LLViewerInventoryItem*>(gAgentWearables.getWearableInventoryItem(type,0)); + LLWearableBridge::removeItemFromAvatar(item); + } + } return true; } @@ -7758,7 +7769,7 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedVectorizePerfTest(), "Advanced.VectorizePerfTest"); view_listener_t::addMenu(new LLAdvancedToggleFrameTest(), "Advanced.ToggleFrameTest"); view_listener_t::addMenu(new LLAdvancedCheckFrameTest(), "Advanced.CheckFrameTest"); - view_listener_t::addMenu(new LLAdvancedHandleAttchedLightParticles(), "Advanced.HandleAttchedLightParticles"); + view_listener_t::addMenu(new LLAdvancedHandleAttachedLightParticles(), "Advanced.HandleAttachedLightParticles"); #ifdef TOGGLE_HACKED_GODLIKE_VIEWER diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 737f7a224d..72e3c27bc9 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2526,14 +2526,9 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) std::string prefix = mesg.substr(0, 4); if (prefix == "/me " || prefix == "/me'") { -// chat.mText = from_name; -// chat.mText += mesg.substr(3); ircstyle = TRUE; } -// else -// { - chat.mText = mesg; -// } + chat.mText = mesg; // Look for the start of typing so we can put "..." in the bubbles. if (CHAT_TYPE_START == chat.mChatType) diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index 69d2458217..993853b9a6 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -446,6 +446,17 @@ void LLVoiceChannel::resume() } } +boost::signals2::connection LLVoiceChannel::setCurrentVoiceChannelChangedCallback(channel_changed_callback_t cb, bool at_front) +{ + if (at_front) + { + return sCurrentVoiceChannelChangedSignal.connect(cb, boost::signals2::at_front); + } + else + { + return sCurrentVoiceChannelChangedSignal.connect(cb); + } +} // // LLVoiceChannelGroup diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h index 77801142cb..cb86671305 100644 --- a/indra/newview/llvoicechannel.h +++ b/indra/newview/llvoicechannel.h @@ -64,7 +64,7 @@ public: typedef boost::function<void(const LLUUID& session_id)> channel_changed_callback_t; typedef boost::signals2::signal<void(const LLUUID& session_id)> channel_changed_signal_t; static channel_changed_signal_t sCurrentVoiceChannelChangedSignal; - static boost::signals2::connection setCurrentVoiceChannelChangedCallback(channel_changed_callback_t cb) { return sCurrentVoiceChannelChangedSignal.connect(cb); } + static boost::signals2::connection setCurrentVoiceChannelChangedCallback(channel_changed_callback_t cb, bool at_front = false); LLVoiceChannel(const LLUUID& session_id, const std::string& session_name); diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index cfa1f05ec0..c2d26a1971 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -4443,6 +4443,33 @@ void LLVoiceClient::participantUpdatedEvent( participant->mPower = 0.0f; } participant->mVolume = volume; + + + // *HACH: mantipov: added while working on EXT-3544 + /* + Sometimes LLVoiceClient::participantUpdatedEvent callback is called BEFORE + LLViewerChatterBoxSessionAgentListUpdates::post() sometimes AFTER. + + participantUpdatedEvent updates voice participant state in particular participantState::mIsModeratorMuted + Originally we wanted to update session Speaker Manager to fire LLSpeakerVoiceModerationEvent to fix the EXT-3544 bug. + Calling of the LLSpeakerMgr::update() method was added into LLIMMgr::processAgentListUpdates. + + But in case participantUpdatedEvent() is called after LLViewerChatterBoxSessionAgentListUpdates::post() + voice participant mIsModeratorMuted is changed after speakers are updated in Speaker Manager + and event is not fired. + + So, we have to call LLSpeakerMgr::update() here. In any case it is better than call it + in LLCallFloater::draw() + */ + LLVoiceChannel* voice_cnl = LLVoiceChannel::getCurrentVoiceChannel(); + if (voice_cnl) + { + LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(voice_cnl->getSessionID()); + if (speaker_manager) + { + speaker_manager->update(true); + } + } } else { diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index f8bb7336db..7866f735c5 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -38,10 +38,12 @@ // Library includes #include "llwindow.h" // spawnWebBrowser() +#include "llagent.h" #include "llappviewer.h" #include "llfloatermediabrowser.h" #include "llfloaterreg.h" #include "lllogininstance.h" +#include "llparcel.h" #include "llsd.h" #include "lltoastalertpanel.h" #include "llui.h" @@ -49,6 +51,8 @@ #include "llversioninfo.h" #include "llviewercontrol.h" #include "llviewernetwork.h" +#include "llviewerparcelmgr.h" +#include "llviewerregion.h" #include "llviewerwindow.h" class URLLoader : public LLToastAlertPanel::URLLoader @@ -144,7 +148,27 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url, substitution["LANGUAGE"] = LLUI::getLanguage(); substitution["GRID"] = LLViewerLogin::getInstance()->getGridLabel(); substitution["OS"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple(); + substitution["SESSION_ID"] = gAgent.getSessionID(); + // find the region ID + LLUUID region_id; + LLViewerRegion *region = gAgent.getRegion(); + if (region) + { + region_id = region->getRegionID(); + } + substitution["REGION_ID"] = region_id; + + // find the parcel ID + LLUUID parcel_id; + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (parcel) + { + parcel_id = parcel->getID(); + } + substitution["PARCEL_ID"] = parcel_id; + + // expand all of the substitution strings and escape the url std::string expanded_url = url; LLStringUtil::format(expanded_url, substitution); diff --git a/indra/newview/llworldmipmap.cpp b/indra/newview/llworldmipmap.cpp index 9897f40c4e..1cdccd2baa 100644 --- a/indra/newview/llworldmipmap.cpp +++ b/indra/newview/llworldmipmap.cpp @@ -186,9 +186,8 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::getObjectsTile(U32 grid_x, U32 LLPointer<LLViewerFetchedTexture> LLWorldMipmap::loadObjectsTile(U32 grid_x, U32 grid_y, S32 level) { // Get the grid coordinates -// std::string imageurl = llformat("http://map.secondlife.com.s3.amazonaws.com/%d/%05d/%05d/map-%d-%d-%d-objects.jpg", std::string imageurl = llformat("http://map.secondlife.com.s3.amazonaws.com/map-%d-%d-%d-objects.jpg", - level, grid_x, grid_y, level, grid_x, grid_y); + level, grid_x, grid_y); // DO NOT COMMIT!! DEBUG ONLY!!! // Use a local jpeg for every tile to test map speed without S3 access diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 706245a479..cb511c2f0b 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -102,6 +102,24 @@ name="AvatarNameColor" reference="White" /> <color + name="AvatarListItemIconDefaultColor" + reference="White" /> + <color + name="AvatarListItemIconOnlineColor" + reference="White" /> + <color + name="AvatarListItemIconOfflineColor" + value="0.5 0.5 0.5 0.5" /> + <color + name="AvatarListItemIconVoiceInvitedColor" + reference="AvatarListItemIconOfflineColor" /> + <color + name="AvatarListItemIconVoiceJoinedColor" + reference="AvatarListItemIconOnlineColor" /> + <color + name="AvatarListItemIconVoiceLeftColor" + reference="AvatarListItemIconOfflineColor" /> + <color name="BackgroundChatColor" reference="DkGray_66" /> <color diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml index 58ba346e50..920f0c909a 100644 --- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml +++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml @@ -16,6 +16,7 @@ can_dock="true" bevel_style="in" height="300" + min_width="150" layout="topleft" name="nearby_chat" help_topic="nearby_chat" diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml index ec54522d3e..a36a1b591b 100644 --- a/indra/newview/skins/default/xui/en/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml @@ -9,6 +9,7 @@ name="Snapshot" help_topic="snapshot" save_rect="true" + save_visibility="true" title="SNAPSHOT PREVIEW" width="215"> <floater.string diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml index 169a0ea676..8904d4f49c 100644 --- a/indra/newview/skins/default/xui/en/floater_world_map.xml +++ b/indra/newview/skins/default/xui/en/floater_world_map.xml @@ -480,7 +480,10 @@ name="location" select_on_focus="true" tool_tip="Type the name of a region" - width="152" /> + width="152"> + <search_editor.commit_callback + function="WMap.Location" /> + </search_editor> <button follows="top|right" height="23" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 8f1799688b..0640ae21de 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2481,30 +2481,30 @@ name="Debug Pipeline"> <menu_item_check.on_check function="CheckControl" - parameter="RenderDebugGL" /> + parameter="RenderDebugPipeline" /> <menu_item_check.on_click function="ToggleControl" - parameter="RenderDebugGL" /> + parameter="RenderDebugPipeline" /> </menu_item_check> <menu_item_check label="Fast Alpha" name="Fast Alpha"> <menu_item_check.on_check function="CheckControl" - parameter="RenderDebugGL" /> + parameter="RenderFastAlpha" /> <menu_item_check.on_click function="ToggleControl" - parameter="RenderDebugGL" /> + parameter="RenderFastAlpha" /> </menu_item_check> <menu_item_check label="Animation Textures" name="Animation Textures"> <menu_item_check.on_check function="CheckControl" - parameter="RenderDebugGL" /> + parameter="AnimateTextures" /> <menu_item_check.on_click function="ToggleControl" - parameter="RenderDebugGL" /> + parameter="AnimateTextures" /> </menu_item_check> <menu_item_check label="Disable Textures" @@ -2555,7 +2555,7 @@ function="CheckControl" parameter="RenderAttachedLights" /> <menu_item_check.on_click - function="Advanced.HandleAttchedLightParticles" + function="Advanced.HandleAttachedLightParticles" parameter="RenderAttachedLights" /> </menu_item_check> <menu_item_check @@ -2565,7 +2565,7 @@ function="CheckControl" parameter="RenderAttachedParticles" /> <menu_item_check.on_click - function="Advanced.HandleAttchedLightParticles" + function="Advanced.HandleAttachedLightParticles" parameter="RenderAttachedParticles" /> </menu_item_check> <menu_item_check diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index d4b712e048..e4ec98c35c 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -4498,14 +4498,14 @@ You don't have permission to copy this. <notification icon="notifytip.tga" name="InventoryAccepted" - type="offer"> + type="notifytip"> [NAME] received your inventory offer. </notification> <notification icon="notifytip.tga" name="InventoryDeclined" - type="offer"> + type="notifytip"> [NAME] declined your inventory offer. </notification> diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index 5ae808581d..343632b924 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -227,16 +227,20 @@ <button follows="left|right" height="23" + image_selected="PushButton_Selected_Press" + image_pressed="PushButton_Press" + image_pressed_selected="PushButton_Selected_Press" left="0" label="" layout="topleft" name="snapshots" width="36" top="4" + is_toggle="true" image_overlay="Snapshot_Off" tool_tip="Take snapshot"> - <button.commit_callback - function="Floater.Toggle" + <button.init_callback + function="Button.SetFloaterToggle" parameter="snapshot" /> </button> </layout_panel> @@ -248,7 +252,7 @@ top="0" name="chiclet_list_panel" width="189" - min_width="180" + min_width="100" user_resize="false" auto_resize="true"> <!--*NOTE: min_width of the chiclet_panel (chiclet_list) must be the same @@ -259,7 +263,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly. height="23" layout="topleft" left="1" - min_width="180" + min_width="100" name="chiclet_list" top="6" chiclet_padding="4" diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml index 1f211c0fed..c899dcb750 100644 --- a/indra/newview/skins/default/xui/en/panel_landmarks.xml +++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml @@ -23,7 +23,7 @@ layout="topleft" name="tab_favorites" title="Favorites bar"> - <inventory_subtree_panel + <places_inventory_panel allow_multi_select="true" border="true" bottom="0" @@ -39,7 +39,7 @@ layout="topleft" name="tab_landmarks" title="Landmarks"> - <inventory_subtree_panel + <places_inventory_panel allow_multi_select="true" border="true" bottom="0" @@ -55,7 +55,7 @@ layout="topleft" name="tab_inventory" title="My Inventory"> - <inventory_subtree_panel + <places_inventory_panel allow_multi_select="true" border="true" bottom="0" @@ -71,7 +71,7 @@ layout="topleft" name="tab_library" title="Library"> - <inventory_subtree_panel + <places_inventory_panel allow_multi_select="true" border="true" bottom="0" diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml index 57b090e5b4..3578c4326d 100644 --- a/indra/newview/skins/default/xui/en/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml @@ -80,16 +80,6 @@ name="volume_btn" tool_tip="Global Volume Control" width="16" /> - <panel - class="panel_volume_pulldown" - follows="all" - height="533" - layout="topleft" - left="0" - name="volume_pulldown" - top="5" - visible="false" - width="313" /> <text enabled="true" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index f004c95aca..447901f984 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2990,6 +2990,13 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="mute"> Error while moderating. </string> + <!--Some times string name is getting from the body of server response. + For ex.: from gIMMgr::showSessionStartError in the LLViewerChatterBoxSessionStartReply::post. + In case of the EXT-3459 issue 'removed' is passed into the gIMMgr::showSessionStartError as a string name. + So, let add string with name="removed" with the same value as "removed_from_group" --> + <string name="removed"> + You have been removed from the group. + </string> <string name="removed_from_group"> You have been removed from the group. </string> diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml new file mode 100644 index 0000000000..d8cf1b9815 --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<chiclet_panel + name="chiclet_panel" + chiclet_padding="3" + scrolling_offset="40" + min_width="180" + />
\ No newline at end of file |