diff options
Diffstat (limited to 'indra')
140 files changed, 1175 insertions, 240 deletions
diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake index 3652508b6a..7ce57a5572 100644 --- a/indra/cmake/Boost.cmake +++ b/indra/cmake/Boost.cmake @@ -38,9 +38,9 @@ else (STANDALONE) debug libboost_signals-vc80-mt-gd-${BOOST_VERSION}) endif (MSVC71) elseif (DARWIN) - set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt) - set(BOOST_REGEX_LIBRARY boost_regex-mt) - set(BOOST_SIGNALS_LIBRARY boost_signals-mt) + set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-xgcc40-mt) + set(BOOST_REGEX_LIBRARY boost_regex-xgcc40-mt) + set(BOOST_SIGNALS_LIBRARY boost_signals-xgcc40-mt) elseif (LINUX) set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-gcc41-mt) set(BOOST_REGEX_LIBRARY boost_regex-gcc41-mt) diff --git a/indra/cmake/PulseAudio.cmake b/indra/cmake/PulseAudio.cmake new file mode 100644 index 0000000000..f8087a8083 --- /dev/null +++ b/indra/cmake/PulseAudio.cmake @@ -0,0 +1,28 @@ +# -*- cmake -*- +include(Prebuilt) + +if (STANDALONE) + include(FindPkgConfig) + + pkg_check_modules(PULSEAUDIO REQUIRED libpulse-mainloop-glib) + +elseif (LINUX) + use_prebuilt_binary(pulseaudio) + set(PULSEAUDIO_FOUND ON FORCE BOOL) + set(PULSEAUDIO_INCLUDE_DIRS + ${LIBS_PREBUILT_DIR}/include + ) + # We don't need to explicitly link against pulseaudio itself, because + # the viewer probes for the system's copy at runtime. + set(PULSEAUDIO_LIBRARIES + # none needed! + ) +endif (STANDALONE) + +if (PULSEAUDIO_FOUND) + set(PULSEAUDIO ON CACHE BOOL "Build with PulseAudio support, if available.") +endif (PULSEAUDIO_FOUND) + +if (PULSEAUDIO) + add_definitions(-DLL_PULSEAUDIO_ENABLED=1) +endif (PULSEAUDIO) diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index ae218c28c4..aa69dfe0cc 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -103,13 +103,13 @@ void LLAccordionCtrl::draw() LLLocalClipRect clip(local_rect); LLPanel::draw(); - /*
- S32 width = getRect().getWidth();
- S32 height = getRect().getHeight();
-
- gl_rect_2d(0, 0 , width - 1 ,height - 1,LLColor4::green,true);
- gl_line_2d(0, 0 , width - 1 ,height - 1,LLColor4::black);
- */
+ /* + S32 width = getRect().getWidth(); + S32 height = getRect().getHeight(); + + gl_rect_2d(0, 0 , width - 1 ,height - 1,LLColor4::green,true); + gl_line_2d(0, 0 , width - 1 ,height - 1,LLColor4::black); + */ } diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index ac4811210b..77caaaa425 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -71,8 +71,9 @@ static LLDefaultChildRegistry::Register<LLScrollListCtrl> r("scroll_list"); // local structures & classes. struct SortScrollListItem { - SortScrollListItem(const std::vector<std::pair<S32, BOOL> >& sort_orders) + SortScrollListItem(const std::vector<std::pair<S32, BOOL> >& sort_orders,const LLScrollListCtrl::sort_signal_t* sort_signal) : mSortOrders(sort_orders) + , mSortSignal(sort_signal) {} bool operator()(const LLScrollListItem* i1, const LLScrollListItem* i2) @@ -85,12 +86,20 @@ struct SortScrollListItem S32 col_idx = it->first; BOOL sort_ascending = it->second; + S32 order = sort_ascending ? 1 : -1; // ascending or descending sort for this column? + const LLScrollListCell *cell1 = i1->getColumn(col_idx); const LLScrollListCell *cell2 = i2->getColumn(col_idx); - S32 order = sort_ascending ? 1 : -1; // ascending or descending sort for this column? if (cell1 && cell2) { - sort_result = order * LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString()); + if(mSortSignal) + { + sort_result = order * (*mSortSignal)(col_idx,i1, i2); + } + else + { + sort_result = order * LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString()); + } if (sort_result != 0) { break; // we have a sort order! @@ -100,8 +109,10 @@ struct SortScrollListItem return sort_result < 0; } + typedef std::vector<std::pair<S32, BOOL> > sort_order_t; + const LLScrollListCtrl::sort_signal_t* mSortSignal; const sort_order_t& mSortOrders; }; @@ -169,6 +180,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mOnSortChangedCallback( NULL ), mHighlightedItem(-1), mBorder(NULL), + mSortCallback(NULL), mPopupMenu(NULL), mNumDynamicWidthColumns(0), mTotalStaticColumnWidth(0), @@ -309,6 +321,8 @@ bool LLScrollListCtrl::preProcessChildNode(LLXMLNodePtr child) LLScrollListCtrl::~LLScrollListCtrl() { + delete mSortCallback; + std::for_each(mItemList.begin(), mItemList.end(), DeletePointer()); if( gEditMenuHandler == this ) @@ -540,7 +554,7 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r std::stable_sort( mItemList.begin(), mItemList.end(), - SortScrollListItem(single_sort_column)); + SortScrollListItem(single_sort_column,mSortCallback)); // ADD_SORTED just sorts by first column... // this might not match user sort criteria, so flag list as being in unsorted state @@ -2395,7 +2409,7 @@ void LLScrollListCtrl::updateSort() const std::stable_sort( mItemList.begin(), mItemList.end(), - SortScrollListItem(mSortColumns)); + SortScrollListItem(mSortColumns,mSortCallback)); mSorted = true; } @@ -2411,7 +2425,7 @@ void LLScrollListCtrl::sortOnce(S32 column, BOOL ascending) std::stable_sort( mItemList.begin(), mItemList.end(), - SortScrollListItem(sort_column)); + SortScrollListItem(sort_column,mSortCallback)); } void LLScrollListCtrl::dirtyColumns() diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index d2d2379328..50999993b5 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -73,6 +73,30 @@ public: // *TODO: Add callbacks to Params typedef boost::function<void (void)> callback_t; + + template<typename T> struct maximum
+ {
+ typedef T result_type;
+
+ template<typename InputIterator>
+ T operator()(InputIterator first, InputIterator last) const
+ {
+ // If there are no slots to call, just return the
+ // default-constructed value
+ if(first == last ) return T();
+ T max_value = *first++;
+ while (first != last) {
+ if (max_value < *first)
+ max_value = *first;
+ ++first;
+ }
+
+ return max_value;
+ }
+ };
+ + + typedef boost::signals2::signal<S32 (S32,const LLScrollListItem*,const LLScrollListItem*),maximum<S32> > sort_signal_t; struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> { @@ -362,6 +386,13 @@ public: void setNeedsSort(bool val = true) { mSorted = !val; } void dirtyColumns(); // some operation has potentially affected column layout or ordering + boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb ) + { + if (!mSortCallback) mSortCallback = new sort_signal_t(); + return mSortCallback->connect(cb); + } + + protected: // "Full" interface: use this when you're creating a list that has one or more of the following: // * contains icons @@ -474,6 +505,8 @@ private: typedef std::pair<S32, BOOL> sort_column_t; std::vector<sort_column_t> mSortColumns; + + sort_signal_t* mSortCallback; }; // end class LLScrollListCtrl #endif // LL_SCROLLLISTCTRL_H diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 07e4cc22e0..284e3e5e26 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -172,6 +172,10 @@ public: } } + LLIconCtrl* getIconCtrl() const + { + return mIcon; + } private: LLIconCtrl* mIcon; @@ -951,7 +955,7 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel) LLRect tab_panel_rect; if (!getTabsHidden() && mIsVertical) { - tab_panel_rect = LLRect(mMinTabWidth + (LLPANEL_BORDER_WIDTH * 2) + tabcntrv_pad, + tab_panel_rect = LLRect(mMinTabWidth + mRightTabBtnOffset + (LLPANEL_BORDER_WIDTH * 2) + tabcntrv_pad, getRect().getHeight() - LLPANEL_BORDER_WIDTH, getRect().getWidth() - LLPANEL_BORDER_WIDTH, LLPANEL_BORDER_WIDTH); @@ -1629,6 +1633,7 @@ void LLTabContainer::setTabImage(LLPanel* child, LLIconCtrl* icon) if(button) { button->setIcon(icon); + reshapeTuple(tuple); } } } @@ -1639,12 +1644,22 @@ void LLTabContainer::reshapeTuple(LLTabTuple* tuple) if (!mIsVertical) { + S32 image_overlay_width = 0; + + if(mCustomIconCtrlUsed) + { + LLCustomButtonIconCtrl* button = dynamic_cast<LLCustomButtonIconCtrl*>(tuple->mButton); + LLIconCtrl* icon_ctrl = button->getIconCtrl(); + image_overlay_width = icon_ctrl ? icon_ctrl->getRect().getWidth() : 0; + } + else + { + image_overlay_width = tuple->mButton->getImageOverlay().notNull() ? + tuple->mButton->getImageOverlay()->getImage()->getWidth(0) : 0; + } // remove current width from total tab strip width mTotalTabWidth -= tuple->mButton->getRect().getWidth(); - S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ? - tuple->mButton->getImageOverlay()->getImage()->getWidth(0) : 0; - tuple->mPadding = image_overlay_width; tuple->mButton->reshape(llclamp(mFont->getWidth(tuple->mButton->getLabelSelected()) + tab_padding + tuple->mPadding, mMinTabWidth, mMaxTabWidth), diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/webkit/CMakeLists.txt index 4512c22b5d..9f66a77c64 100644 --- a/indra/media_plugins/webkit/CMakeLists.txt +++ b/indra/media_plugins/webkit/CMakeLists.txt @@ -14,10 +14,12 @@ include(Linking) include(PluginAPI) include(MediaPluginBase) include(FindOpenGL) +include(PulseAudio) include(WebKitLibPlugin) include_directories( + ${PULSEAUDIO_INCLUDE_DIRS} ${LLPLUGIN_INCLUDE_DIRS} ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} ${LLCOMMON_INCLUDE_DIRS} @@ -34,25 +36,27 @@ set(media_plugin_webkit_SOURCE_FILES media_plugin_webkit.cpp ) -add_library(media_plugin_webkit - SHARED - ${media_plugin_webkit_SOURCE_FILES} -) - set(media_plugin_webkit_LINK_LIBRARIES ${LLPLUGIN_LIBRARIES} ${MEDIA_PLUGIN_BASE_LIBRARIES} ${LLCOMMON_LIBRARIES} ${WEBKIT_PLUGIN_LIBRARIES} ${PLUGIN_API_WINDOWS_LIBRARIES} + ${PULSEAUDIO_LIBRARIES} ) if (LINUX) + list(APPEND media_plugin_webkit_SOURCE_FILES linux_volume_catcher.cpp) list(APPEND media_plugin_webkit_LINK_LIBRARIES ${UI_LIBRARIES} # for glib/GTK ) endif (LINUX) +add_library(media_plugin_webkit + SHARED + ${media_plugin_webkit_SOURCE_FILES} +) + target_link_libraries(media_plugin_webkit ${media_plugin_webkit_LINK_LIBRARIES}) add_dependencies(media_plugin_webkit diff --git a/indra/media_plugins/webkit/linux_volume_catcher.cpp b/indra/media_plugins/webkit/linux_volume_catcher.cpp new file mode 100644 index 0000000000..2ba28bd4bf --- /dev/null +++ b/indra/media_plugins/webkit/linux_volume_catcher.cpp @@ -0,0 +1,483 @@ +/** + * @file linux_volume_catcher.cpp + * @brief A Linux-specific, PulseAudio-specific hack to detect and volume-adjust new audio sources + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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$ + * @endcond + */ + +/* + The high-level design is as follows: + 1) Connect to the PulseAudio daemon + 2) Watch for the creation of new audio players connecting to the daemon (this includes ALSA clients running on the PulseAudio emulation layer, such as Flash plugins) + 3) Examine any new audio player's PID to see if it belongs to our own process + 4) If so, tell PA to adjust the volume of that audio player ('sink input' in PA parlance) + 5) Keep a list of all living audio players that we care about, adjust the volumes of all of them when we get a new setVolume() call + */ + +#include "linden_common.h" + +#include "linux_volume_catcher.h" + + +#if LL_PULSEAUDIO_ENABLED + +extern "C" { +#include <glib.h> + +#include <pulse/introspect.h> +#include <pulse/context.h> +#include <pulse/subscribe.h> +#include <pulse/glib-mainloop.h> // There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken. + +#include "apr_pools.h" +#include "apr_dso.h" +} + +//////////////////////////////////////////////////// + +#define DEBUGMSG(...) do {} while(0) +#define INFOMSG(...) do {} while(0) +#define WARNMSG(...) do {} while(0) + +#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) RTN (*ll##PASYM)(__VA_ARGS__) = NULL +#include "linux_volume_catcher_pa_syms.inc" +#include "linux_volume_catcher_paglib_syms.inc" +#undef LL_PA_SYM + +static bool sSymsGrabbed = false; +static apr_pool_t *sSymPADSOMemoryPool = NULL; +static apr_dso_handle_t *sSymPADSOHandleG = NULL; + +bool grab_pa_syms(std::string pulse_dso_name) +{ + if (sSymsGrabbed) + { + // already have grabbed good syms + return true; + } + + bool sym_error = false; + bool rtn = false; + apr_status_t rv; + apr_dso_handle_t *sSymPADSOHandle = NULL; + +#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0) + + //attempt to load the shared library + apr_pool_create(&sSymPADSOMemoryPool, NULL); + + if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle, + pulse_dso_name.c_str(), + sSymPADSOMemoryPool) )) + { + INFOMSG("Found DSO: %s", pulse_dso_name.c_str()); + +#include "linux_volume_catcher_pa_syms.inc" +#include "linux_volume_catcher_paglib_syms.inc" + + if ( sSymPADSOHandle ) + { + sSymPADSOHandleG = sSymPADSOHandle; + sSymPADSOHandle = NULL; + } + + rtn = !sym_error; + } + else + { + INFOMSG("Couldn't load DSO: %s", pulse_dso_name.c_str()); + rtn = false; // failure + } + + if (sym_error) + { + WARNMSG("Failed to find necessary symbols in PulseAudio libraries."); + } +#undef LL_PA_SYM + + sSymsGrabbed = rtn; + return rtn; +} + + +void ungrab_pa_syms() +{ + // should be safe to call regardless of whether we've + // actually grabbed syms. + + if ( sSymPADSOHandleG ) + { + apr_dso_unload(sSymPADSOHandleG); + sSymPADSOHandleG = NULL; + } + + if ( sSymPADSOMemoryPool ) + { + apr_pool_destroy(sSymPADSOMemoryPool); + sSymPADSOMemoryPool = NULL; + } + + // NULL-out all of the symbols we'd grabbed +#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0) +#include "linux_volume_catcher_pa_syms.inc" +#include "linux_volume_catcher_paglib_syms.inc" +#undef LL_PA_SYM + + sSymsGrabbed = false; +} +//////////////////////////////////////////////////// + +// PulseAudio requires a chain of callbacks with C linkage +extern "C" { + void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *i, int eol, void *userdata); + void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata); + void callback_context_state(pa_context *context, void *userdata); +} + + +class LinuxVolumeCatcherImpl +{ +public: + LinuxVolumeCatcherImpl(); + ~LinuxVolumeCatcherImpl(); + + void setVolume(F32 volume); + void pump(void); + + // for internal use - can't be private because used from our C callbacks + + bool loadsyms(std::string pulse_dso_name); + void init(); + void cleanup(); + + void update_all_volumes(F32 volume); + void update_index_volume(U32 index, F32 volume); + void connected_okay(); + + std::set<U32> mSinkInputIndices; + std::map<U32,U32> mSinkInputNumChannels; + F32 mDesiredVolume; + pa_glib_mainloop *mMainloop; + pa_context *mPAContext; + bool mConnected; + bool mGotSyms; +}; + +LinuxVolumeCatcherImpl::LinuxVolumeCatcherImpl() + : mDesiredVolume(0.0f), + mMainloop(NULL), + mPAContext(NULL), + mConnected(false), + mGotSyms(false) +{ + init(); +} + +LinuxVolumeCatcherImpl::~LinuxVolumeCatcherImpl() +{ + cleanup(); +} + +bool LinuxVolumeCatcherImpl::loadsyms(std::string pulse_dso_name) +{ + return grab_pa_syms(pulse_dso_name); +} + +void LinuxVolumeCatcherImpl::init() +{ + // try to be as defensive as possible because PA's interface is a + // bit fragile and (for our purposes) we'd rather simply not function + // than crash + + // we cheat and rely upon libpulse-mainloop-glib.so.0 to pull-in + // libpulse.so.0 - this isn't a great assumption, and the two DSOs should + // probably be loaded separately. Our Linux DSO framework needs refactoring, + // we do this sort of thing a lot with practically identical logic... + mGotSyms = loadsyms("libpulse-mainloop-glib.so.0"); + if (!mGotSyms) return; + + mMainloop = llpa_glib_mainloop_new(g_main_context_default()); + if (mMainloop) + { + pa_mainloop_api *api = llpa_glib_mainloop_get_api(mMainloop); + if (api) + { + pa_proplist *proplist = llpa_proplist_new(); + if (proplist) + { + llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "multimedia-player"); + llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "com.secondlife.viewer.mediaplugvoladjust"); + llpa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "SL Plugin Volume Adjuster"); + llpa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, "1"); + + // plain old pa_context_new() is broken! + mPAContext = llpa_context_new_with_proplist(api, NULL, proplist); + llpa_proplist_free(proplist); + } + } + } + + // Now we've set up a PA context and mainloop, try connecting the + // PA context to a PA daemon. + if (mPAContext) + { + llpa_context_set_state_callback(mPAContext, callback_context_state, this); + pa_context_flags_t cflags = (pa_context_flags)0; // maybe add PA_CONTEXT_NOAUTOSPAWN? + if (llpa_context_connect(mPAContext, NULL, cflags, NULL) >= 0) + { + // Okay! We haven't definitely connected, but we + // haven't definitely failed yet. + } + else + { + // Failed to connect to PA manager... we'll leave + // things like that. Perhaps we should try again later. + } + } +} + +void LinuxVolumeCatcherImpl::cleanup() +{ + mConnected = false; + + if (mGotSyms && mPAContext) + { + llpa_context_disconnect(mPAContext); + llpa_context_unref(mPAContext); + } + mPAContext = NULL; + + if (mGotSyms && mMainloop) + { + llpa_glib_mainloop_free(mMainloop); + } + mMainloop = NULL; +} + +void LinuxVolumeCatcherImpl::setVolume(F32 volume) +{ + mDesiredVolume = volume; + + if (!mGotSyms) return; + + if (mConnected && mPAContext) + { + update_all_volumes(mDesiredVolume); + } + + pump(); +} + +void LinuxVolumeCatcherImpl::pump() +{ + gboolean may_block = FALSE; + g_main_context_iteration(g_main_context_default(), may_block); +} + +void LinuxVolumeCatcherImpl::connected_okay() +{ + pa_operation *op; + + // fetch global list of existing sinkinputs + if ((op = llpa_context_get_sink_input_info_list(mPAContext, + callback_discovered_sinkinput, + this))) + { + llpa_operation_unref(op); + } + + // subscribe to future global sinkinput changes + llpa_context_set_subscribe_callback(mPAContext, + callback_subscription_alert, + this); + if ((op = llpa_context_subscribe(mPAContext, (pa_subscription_mask_t) + (PA_SUBSCRIPTION_MASK_SINK_INPUT), + NULL, NULL))) + { + llpa_operation_unref(op); + } +} + +void LinuxVolumeCatcherImpl::update_all_volumes(F32 volume) +{ + for (std::set<U32>::iterator it = mSinkInputIndices.begin(); + it != mSinkInputIndices.end(); ++it) + { + update_index_volume(*it, volume); + } +} + +void LinuxVolumeCatcherImpl::update_index_volume(U32 index, F32 volume) +{ + static pa_cvolume cvol; + llpa_cvolume_set(&cvol, mSinkInputNumChannels[index], + llpa_sw_volume_from_linear(volume)); + + pa_context *c = mPAContext; + uint32_t idx = index; + const pa_cvolume *cvolumep = &cvol; + pa_context_success_cb_t cb = NULL; // okay as null + void *userdata = NULL; // okay as null + + pa_operation *op; + if ((op = llpa_context_set_sink_input_volume(c, idx, cvolumep, cb, userdata))) + { + llpa_operation_unref(op); + } +} + + +void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *sii, int eol, void *userdata) +{ + LinuxVolumeCatcherImpl *impl = dynamic_cast<LinuxVolumeCatcherImpl*>((LinuxVolumeCatcherImpl*)userdata); + llassert(impl); + + if (0 == eol) + { + pa_proplist *proplist = sii->proplist; + pid_t sinkpid = atoll(llpa_proplist_gets(proplist, PA_PROP_APPLICATION_PROCESS_ID)); + + if (sinkpid == getpid()) // does the discovered sinkinput belong to this process? + { + bool is_new = (impl->mSinkInputIndices.find(sii->index) == + impl->mSinkInputIndices.end()); + + impl->mSinkInputIndices.insert(sii->index); + impl->mSinkInputNumChannels[sii->index] = sii->channel_map.channels; + + if (is_new) + { + // new! + impl->update_index_volume(sii->index, impl->mDesiredVolume); + } + else + { + // seen it already, do nothing. + } + } + } +} + +void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata) +{ + LinuxVolumeCatcherImpl *impl = dynamic_cast<LinuxVolumeCatcherImpl*>((LinuxVolumeCatcherImpl*)userdata); + llassert(impl); + + switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { + case PA_SUBSCRIPTION_EVENT_SINK_INPUT: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == + PA_SUBSCRIPTION_EVENT_REMOVE) + { + // forget this sinkinput, if we were caring about it + impl->mSinkInputIndices.erase(index); + impl->mSinkInputNumChannels.erase(index); + } + else + { + // ask for more info about this new sinkinput + pa_operation *op; + if ((op = llpa_context_get_sink_input_info(impl->mPAContext, index, callback_discovered_sinkinput, impl))) + { + llpa_operation_unref(op); + } + } + break; + + default:; + } +} + +void callback_context_state(pa_context *context, void *userdata) +{ + LinuxVolumeCatcherImpl *impl = dynamic_cast<LinuxVolumeCatcherImpl*>((LinuxVolumeCatcherImpl*)userdata); + llassert(impl); + + switch (llpa_context_get_state(context)) + { + case PA_CONTEXT_READY: + impl->mConnected = true; + impl->connected_okay(); + break; + case PA_CONTEXT_TERMINATED: + impl->mConnected = false; + break; + case PA_CONTEXT_FAILED: + impl->mConnected = false; + break; + default:; + } +} + +///////////////////////////////////////////////////// + +LinuxVolumeCatcher::LinuxVolumeCatcher() +{ + pimpl = new LinuxVolumeCatcherImpl(); +} + +LinuxVolumeCatcher::~LinuxVolumeCatcher() +{ + delete pimpl; + pimpl = NULL; +} + +void LinuxVolumeCatcher::setVolume(F32 volume) +{ + llassert(pimpl); + pimpl->setVolume(volume); +} + +void LinuxVolumeCatcher::pump() +{ + llassert(pimpl); + pimpl->pump(); +} + +#else // !LL_PULSEAUDIO_ENABLED + +// stub. + +LinuxVolumeCatcher::LinuxVolumeCatcher() +{ + pimpl = NULL; +} + +LinuxVolumeCatcher::~LinuxVolumeCatcher() +{ +} + +void LinuxVolumeCatcher::setVolume(F32 volume) +{ +} + +void LinuxVolumeCatcher::pump() +{ +} + +#endif // LL_PULSEAUDIO_ENABLED diff --git a/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc b/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc new file mode 100644 index 0000000000..d806b48428 --- /dev/null +++ b/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc @@ -0,0 +1,21 @@ +// required symbols to grab +LL_PA_SYM(true, pa_context_connect, int, pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api); +LL_PA_SYM(true, pa_context_disconnect, void, pa_context *c); +LL_PA_SYM(true, pa_context_get_sink_input_info, pa_operation*, pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata); +LL_PA_SYM(true, pa_context_get_sink_input_info_list, pa_operation*, pa_context *c, pa_sink_input_info_cb_t cb, void *userdata); +LL_PA_SYM(true, pa_context_get_state, pa_context_state_t, pa_context *c); +LL_PA_SYM(true, pa_context_new_with_proplist, pa_context*, pa_mainloop_api *mainloop, const char *name, pa_proplist *proplist); +LL_PA_SYM(true, pa_context_set_sink_input_volume, pa_operation*, pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); +LL_PA_SYM(true, pa_context_set_state_callback, void, pa_context *c, pa_context_notify_cb_t cb, void *userdata); +LL_PA_SYM(true, pa_context_set_subscribe_callback, void, pa_context *c, pa_context_subscribe_cb_t cb, void *userdata); +LL_PA_SYM(true, pa_context_subscribe, pa_operation*, pa_context *c, pa_subscription_mask_t m, pa_context_success_cb_t cb, void *userdata); +LL_PA_SYM(true, pa_context_unref, void, pa_context *c); +LL_PA_SYM(true, pa_cvolume_set, pa_cvolume*, pa_cvolume *a, unsigned channels, pa_volume_t v); +LL_PA_SYM(true, pa_operation_unref, void, pa_operation *o); +LL_PA_SYM(true, pa_proplist_free, void, pa_proplist* p); +LL_PA_SYM(true, pa_proplist_gets, const char*, pa_proplist *p, const char *key); +LL_PA_SYM(true, pa_proplist_new, pa_proplist*, void); +LL_PA_SYM(true, pa_proplist_sets, int, pa_proplist *p, const char *key, const char *value); +LL_PA_SYM(true, pa_sw_volume_from_linear, pa_volume_t, double v); + +// optional symbols to grab diff --git a/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc b/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc new file mode 100644 index 0000000000..abf628c96c --- /dev/null +++ b/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc @@ -0,0 +1,6 @@ +// required symbols to grab +LL_PA_SYM(true, pa_glib_mainloop_free, void, pa_glib_mainloop* g); +LL_PA_SYM(true, pa_glib_mainloop_get_api, pa_mainloop_api*, pa_glib_mainloop* g); +LL_PA_SYM(true, pa_glib_mainloop_new, pa_glib_mainloop *, GMainContext *c); + +// optional symbols to grab diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp index 688d3bcd3d..c7aba04492 100644 --- a/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -43,11 +43,15 @@ #include "llpluginmessageclasses.h" #include "media_plugin_base.h" +#if LL_LINUX +# include "linux_volume_catcher.h" +#endif // LL_LINUX + #if LL_WINDOWS -#include <direct.h> +# include <direct.h> #else -#include <unistd.h> -#include <stdlib.h> +# include <unistd.h> +# include <stdlib.h> #endif #if LL_WINDOWS @@ -102,6 +106,10 @@ private: F32 mBackgroundG; F32 mBackgroundB; +#if LL_LINUX + LinuxVolumeCatcher mLinuxVolumeCatcher; +#endif // LL_LINUX + void setInitState(int state) { // std::cerr << "changing init state to " << state << std::endl; @@ -114,6 +122,10 @@ private: { LLQtWebKit::getInstance()->pump( milliseconds ); +#if LL_LINUX + mLinuxVolumeCatcher.pump(); +#endif // LL_LINUX + checkEditState(); if(mInitState == INIT_STATE_NAVIGATE_COMPLETE) @@ -281,6 +293,7 @@ private: return false; }; + void setVolume(F32 vol); //////////////////////////////////////////////////////////////////////////////// // virtual @@ -732,6 +745,14 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) // std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; } } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) + { + if(message_name == "set_volume") + { + F32 volume = message_in.getValueReal("volume"); + setVolume(volume); + } + } else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) { if(message_name == "size_change") @@ -998,6 +1019,13 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) } } +void MediaPluginWebKit::setVolume(F32 volume) +{ +#if LL_LINUX + mLinuxVolumeCatcher.setVolume(volume); +#endif // LL_LINUX +} + int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) { MediaPluginWebKit *self = new MediaPluginWebKit(host_send_func, host_user_data); diff --git a/indra/newview/linux_tools/client-readme.txt b/indra/newview/linux_tools/client-readme.txt index 92d321d8c0..e01b9e4bc6 100644 --- a/indra/newview/linux_tools/client-readme.txt +++ b/indra/newview/linux_tools/client-readme.txt @@ -15,7 +15,7 @@ Life itself - please see <http://www.secondlife.com/whatis/>. 5.3. Blank window after minimizing it 5.4. Audio 5.5. 'Alt' key for camera controls doesn't work - 5.6. In-world streaming movie/music playback + 5.6. In-world streaming movie, music and Flash playback 6. Advanced Troubleshooting 6.1. Audio 6.2. OpenGL @@ -169,12 +169,15 @@ SOLUTION:- Some window managers eat the Alt key for their own purposes; you example, the 'Windows' key!) which will allow the Alt key to function properly with mouse actions in Second Life and other applications. -PROBLEM 6:- In-world movie and/or music playback doesn't work for me. +PROBLEM 6:- In-world movie, music, or Flash playback doesn't work for me. SOLUTION:- You need to have a working installation of GStreamer 0.10; this is usually an optional package for most versions of Linux. If you have installed GStreamer 0.10 and you can play some music/movies but not others then you need to install a wider selection of GStreamer plugins, either - from your vendor or an appropriate third party. + from your vendor (i.e. the 'Ugly' plugins) or an appropriate third party. + For Flash playback, you need to have Flash 10 installed for your normal + web browser (for example, Firefox). PulseAudio is required for Flash + volume control / muting to fully function inside Second Life. 6. ADVANCED TROUBLESHOOTING diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index f4bc35002b..08cd101b01 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -286,6 +286,7 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i } if (mTodo & CALL_RECOVERDONE) { + LLAppearanceManager::instance().addCOFItemLink(inv_item,false); gAgentWearables.recoverMissingWearableDone(); } /* @@ -1038,7 +1039,7 @@ void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void* { return; } - + if (wearable) { llassert(type == wearable->getType()); @@ -1057,6 +1058,7 @@ void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void* // Somehow the asset doesn't exist in the database. gAgentWearables.recoverMissingWearable(type,index); } + gInventory.notifyObservers(); @@ -1576,7 +1578,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it const LLDynamicArray< LLWearable* >& wearables, BOOL remove) { - lldebugs << "setWearableOutfit() start" << llendl; + llinfos << "setWearableOutfit() start" << llendl; BOOL wearables_to_remove[WT_COUNT]; wearables_to_remove[WT_SHAPE] = FALSE; @@ -2485,7 +2487,7 @@ class LLFetchAndLinkObserver: public LLInventoryFetchObserver public: LLFetchAndLinkObserver(LLInventoryFetchObserver::item_ref_t& ids): m_ids(ids), - LLInventoryFetchObserver(true) + LLInventoryFetchObserver(true) // retry for missing items { } ~LLFetchAndLinkObserver() @@ -2494,7 +2496,9 @@ public: virtual void done() { gInventory.removeObserver(this); + // Link to all fetched items in COF. + LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy; for (LLInventoryFetchObserver::item_ref_t::iterator it = m_ids.begin(); it != m_ids.end(); ++it) @@ -2506,8 +2510,13 @@ public: llwarns << "fetch failed!" << llendl; continue; } - link_inventory_item(gAgent.getID(), item->getLinkedUUID(), LLAppearanceManager::instance().getCOF(), item->getName(), - LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL)); + + link_inventory_item(gAgent.getID(), + item->getLinkedUUID(), + LLAppearanceManager::instance().getCOF(), + item->getName(), + LLAssetType::AT_LINK, + link_waiter); } } private: @@ -2530,11 +2539,13 @@ void LLInitialWearablesFetch::processWearablesMessage() #ifdef USE_CURRENT_OUTFIT_FOLDER ids.push_back(wearable_data->mItemID); #endif - // Fetch the wearables - LLWearableList::instance().getAsset(wearable_data->mAssetID, - LLStringUtil::null, - LLWearableDictionary::getAssetType(wearable_data->mType), - LLAgentWearables::onInitialWearableAssetArrived, (void*)(wearable_data)); +#if 0 +// // Fetch the wearables +// LLWearableList::instance().getAsset(wearable_data->mAssetID, +// LLStringUtil::null, +// LLWearableDictionary::getAssetType(wearable_data->mType), +// LLAgentWearables::onInitialWearableAssetArrived, (void*)(wearable_data)); +#endif } else { diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index eb4a47664b..c9da08701d 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -301,50 +301,52 @@ void LLOutfitFetch::done() delete this; } -class LLUpdateAppearanceOnDestroy: public LLInventoryCallback +LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(): + mFireCount(0) { -public: - LLUpdateAppearanceOnDestroy(): - mFireCount(0) - { - } +} - virtual ~LLUpdateAppearanceOnDestroy() +LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy() +{ + llinfos << "done update appearance on destroy" << llendl; + + if (!LLApp::isExiting()) { - llinfos << "done update appearance on destroy" << llendl; - - if (!LLApp::isExiting()) - { - LLAppearanceManager::instance().updateAppearanceFromCOF(); - } + LLAppearanceManager::instance().updateAppearanceFromCOF(); } +} - /* virtual */ void fire(const LLUUID& inv_item) - { - llinfos << "callback fired" << llendl; - mFireCount++; - } -private: - U32 mFireCount; -}; +void LLUpdateAppearanceOnDestroy::fire(const LLUUID& inv_item) +{ + llinfos << "callback fired" << llendl; + mFireCount++; +} struct LLFoundData { - LLFoundData() : mAssetType(LLAssetType::AT_NONE), mWearable(NULL) {} + LLFoundData() : + mAssetType(LLAssetType::AT_NONE), + mWearableType(WT_INVALID), + mWearable(NULL) {} + LLFoundData(const LLUUID& item_id, - const LLUUID& asset_id, - const std::string& name, - LLAssetType::EType asset_type) : + const LLUUID& asset_id, + const std::string& name, + const LLAssetType::EType& asset_type, + const EWearableType& wearable_type + ) : mItemID(item_id), mAssetID(asset_id), mName(name), mAssetType(asset_type), + mWearableType(wearable_type), mWearable( NULL ) {} LLUUID mItemID; LLUUID mAssetID; std::string mName; LLAssetType::EType mAssetType; + EWearableType mWearableType; LLWearable* mWearable; }; @@ -355,14 +357,26 @@ public: LLWearableHoldingPattern(); ~LLWearableHoldingPattern(); - bool pollCompletion(); + bool pollFetchCompletion(); + void onFetchCompletion(); bool isFetchCompleted(); bool isTimedOut(); + + void checkMissingWearables(); + bool pollMissingWearables(); + bool isMissingCompleted(); + void recoverMissingWearable(EWearableType type); + void clearCOFLinksForMissingWearables(); + + void onAllComplete(); typedef std::list<LLFoundData> found_list_t; found_list_t mFoundList; LLInventoryModel::item_array_t mObjItems; LLInventoryModel::item_array_t mGestItems; + typedef std::set<S32> type_set_t; + type_set_t mTypesToRecover; + type_set_t mTypesToLink; S32 mResolved; LLTimer mWaitTime; bool mFired; @@ -389,13 +403,99 @@ bool LLWearableHoldingPattern::isTimedOut() return mWaitTime.getElapsedTimeF32() > max_wait_time; } -bool LLWearableHoldingPattern::pollCompletion() +void LLWearableHoldingPattern::checkMissingWearables() +{ + std::vector<S32> found_by_type(WT_COUNT,0); + std::vector<S32> requested_by_type(WT_COUNT,0); + for (found_list_t::iterator it = mFoundList.begin(); it != mFoundList.end(); ++it) + { + LLFoundData &data = *it; + if (data.mWearableType < WT_COUNT) + requested_by_type[data.mWearableType]++; + if (data.mWearable) + found_by_type[data.mWearableType]++; + } + + for (S32 type = 0; type < WT_COUNT; ++type) + { + llinfos << "type " << type << " requested " << requested_by_type[type] << " found " << found_by_type[type] << llendl; + if (found_by_type[type] > 0) + continue; + if ( + // Need to recover if at least one wearable of that type + // was requested but none was found (prevent missing + // pants) + (requested_by_type[type] > 0) || + // or if type is a body part and no wearables were found. + ((type == WT_SHAPE) || (type == WT_SKIN) || (type == WT_HAIR) || (type == WT_EYES))) + { + mTypesToRecover.insert(type); + mTypesToLink.insert(type); + recoverMissingWearable((EWearableType)type); + llwarns << "need to replace " << type << llendl; + } + } + + if (!pollMissingWearables()) + { + mWaitTime.reset(); + doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollMissingWearables,this)); + } +} + +void LLWearableHoldingPattern::onAllComplete() +{ + // Activate all gestures in this folder + if (mGestItems.count() > 0) + { + llinfos << "Activating " << mGestItems.count() << " gestures" << llendl; + + LLGestureManager::instance().activateGestures(mGestItems); + + // Update the inventory item labels to reflect the fact + // they are active. + LLViewerInventoryCategory* catp = + gInventory.getCategory(LLAppearanceManager::instance().getCOF()); + + if (catp) + { + gInventory.updateCategory(catp); + gInventory.notifyObservers(); + } + } + + // Update wearables. + llinfos << "Updating agent wearables with " << mResolved << " wearable items " << llendl; + LLAppearanceManager::instance().updateAgentWearables(this, false); + + // Update attachments to match those requested. + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if( avatar ) + { + llinfos << "Updating " << mObjItems.count() << " attachments" << llendl; + LLAgentWearables::userUpdateAttachments(mObjItems); + } + + if (isFetchCompleted() && isMissingCompleted()) + { + // Only safe to delete if all wearable callbacks and all missing wearables completed. + delete this; + } +} + +void LLWearableHoldingPattern::onFetchCompletion() +{ + checkMissingWearables(); +} + +// Runs as an idle callback until all wearables are fetched (or we time out). +bool LLWearableHoldingPattern::pollFetchCompletion() { bool completed = isFetchCompleted(); bool timed_out = isTimedOut(); bool done = completed || timed_out; - llinfos << "polling, done status: " << completed << " timed out? " << timed_out << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl; + llinfos << "polling, done status: " << completed << " timed out " << timed_out << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl; if (done) { @@ -406,46 +506,184 @@ bool LLWearableHoldingPattern::pollCompletion() llwarns << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl; } - // Activate all gestures in this folder - if (mGestItems.count() > 0) - { - llinfos << "Activating " << mGestItems.count() << " gestures" << llendl; - - LLGestureManager::instance().activateGestures(mGestItems); - - // Update the inventory item labels to reflect the fact - // they are active. - LLViewerInventoryCategory* catp = - gInventory.getCategory(LLAppearanceManager::instance().getCOF()); + onFetchCompletion(); + } + return done; +} - if (catp) - { - gInventory.updateCategory(catp); - gInventory.notifyObservers(); - } - } +class RecoveredItemLinkCB: public LLInventoryCallback +{ +public: + RecoveredItemLinkCB(EWearableType type, LLWearable *wearable, LLWearableHoldingPattern* holder): + mHolder(holder), + mWearable(wearable), + mType(type) + { + } + void fire(const LLUUID& item_id) + { + llinfos << "Recovered item link for type " << mType << llendl; + mHolder->mTypesToLink.erase(mType); + // Add wearable to FoundData for actual wearing + LLViewerInventoryItem *item = gInventory.getItem(item_id); + LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL; - // Update wearables. - llinfos << "Updating agent wearables with " << mResolved << " wearable items " << llendl; - LLAppearanceManager::instance().updateAgentWearables(this, false); - - // Update attachments to match those requested. - LLVOAvatar* avatar = gAgent.getAvatarObject(); - if( avatar ) + gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID()); + + if (item && linked_item) { - llinfos << "Updating " << mObjItems.count() << " attachments" << llendl; - LLAgentWearables::userUpdateAttachments(mObjItems); + LLFoundData found(linked_item->getUUID(), + linked_item->getAssetUUID(), + linked_item->getName(), + linked_item->getType(), + linked_item->isWearableType() ? linked_item->getWearableType() : WT_INVALID + ); + found.mWearable = mWearable; + mHolder->mFoundList.push_front(found); } + else + { + llwarns << "inventory item or link not found for recovered wearable" << llendl; + } + } +private: + LLWearableHoldingPattern* mHolder; + LLWearable *mWearable; + EWearableType mType; +}; - if (completed) +class RecoveredItemCB: public LLInventoryCallback +{ +public: + RecoveredItemCB(EWearableType type, LLWearable *wearable, LLWearableHoldingPattern* holder): + mHolder(holder), + mWearable(wearable), + mType(type) + { + } + void fire(const LLUUID& item_id) + { + llinfos << "Recovered item for type " << mType << llendl; + LLViewerInventoryItem *itemp = gInventory.getItem(item_id); + LLPointer<LLInventoryCallback> cb = new RecoveredItemLinkCB(mType,mWearable,mHolder); + mHolder->mTypesToRecover.erase(mType); + link_inventory_item( gAgent.getID(), + item_id, + LLAppearanceManager::instance().getCOF(), + itemp->getName(), + LLAssetType::AT_LINK, + cb); + } +private: + LLWearableHoldingPattern* mHolder; + LLWearable *mWearable; + EWearableType mType; +}; + +void LLWearableHoldingPattern::recoverMissingWearable(EWearableType type) +{ + // Try to recover by replacing missing wearable with a new one. + LLNotificationsUtil::add("ReplacedMissingWearable"); + lldebugs << "Wearable " << LLWearableDictionary::getTypeLabel(type) + << " could not be downloaded. Replaced inventory item with default wearable." << llendl; + LLWearable* wearable = LLWearableList::instance().createNewWearable(type); + + // Add a new one in the lost and found folder. + const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); + LLPointer<LLInventoryCallback> cb = new RecoveredItemCB(type,wearable,this); + + create_inventory_item(gAgent.getID(), + gAgent.getSessionID(), + lost_and_found_id, + wearable->getTransactionID(), + wearable->getName(), + wearable->getDescription(), + wearable->getAssetType(), + LLInventoryType::IT_WEARABLE, + wearable->getType(), + wearable->getPermissions().getMaskNextOwner(), + cb); +} + +bool LLWearableHoldingPattern::isMissingCompleted() +{ + return mTypesToLink.size()==0 && mTypesToRecover.size()==0; +} + +void LLWearableHoldingPattern::clearCOFLinksForMissingWearables() +{ + for (found_list_t::iterator it = mFoundList.begin(); it != mFoundList.end(); ++it) + { + LLFoundData &data = *it; + if ((data.mWearableType < WT_COUNT) && (!data.mWearable)) { - // Only safe to delete if all wearable callbacks completed. - delete this; + // Wearable link that was never resolved; remove links to it from COF + llinfos << "removing link for unresolved item " << data.mItemID.asString() << llendl; + LLAppearanceManager::instance().removeCOFItemLinks(data.mItemID,false); } } +} + +bool LLWearableHoldingPattern::pollMissingWearables() +{ + bool timed_out = isTimedOut(); + bool missing_completed = isMissingCompleted(); + bool done = timed_out || missing_completed; + + llinfos << "polling missing wearables, waiting for items " << mTypesToRecover.size() + << " links " << mTypesToLink.size() + << " wearables, timed out " << timed_out + << " elapsed " << mWaitTime.getElapsedTimeF32() + << " done " << done << llendl; + + if (done) + { + clearCOFLinksForMissingWearables(); + onAllComplete(); + } return done; } +static void onWearableAssetFetch(LLWearable* wearable, void* data) +{ + LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data; + holder->mResolved += 1; // just counting callbacks, not successes. + llinfos << "onWearableAssetFetch, resolved count " << holder->mResolved << " of requested " << holder->mFoundList.size() << llendl; + if (wearable) + { + llinfos << "wearable found, type " << wearable->getType() << " asset " << wearable->getAssetID() << llendl; + } + else + { + llwarns << "no wearable found" << llendl; + } + + if (holder->mFired) + { + llwarns << "called after holder fired" << llendl; + return; + } + + if (!wearable) + { + return; + } + + for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin(); + iter != holder->mFoundList.end(); ++iter) + { + LLFoundData& data = *iter; + if(wearable->getAssetID() == data.mAssetID) + { + data.mWearable = wearable; + // Failing this means inventory or asset server are corrupted in a way we don't handle. + llassert((data.mWearableType < WT_COUNT) && (wearable->getType() == data.mWearableType)); + break; + } + } +} + + static void removeDuplicateItems(LLInventoryModel::item_array_t& items) { LLInventoryModel::item_array_t new_items; @@ -473,30 +711,6 @@ static void removeDuplicateItems(LLInventoryModel::item_array_t& items) items = new_items; } -static void onWearableAssetFetch(LLWearable* wearable, void* data) -{ - LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data; - if (holder->mFired) - { - llwarns << "called after holder fired" << llendl; - } - - if(wearable) - { - for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin(); - iter != holder->mFoundList.end(); ++iter) - { - LLFoundData& data = *iter; - if(wearable->getAssetID() == data.mAssetID) - { - data.mWearable = wearable; - break; - } - } - } - holder->mResolved += 1; -} - const LLUUID LLAppearanceManager::getCOF() const { return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); @@ -718,7 +932,8 @@ void LLAppearanceManager::linkAll(const LLUUID& category, void LLAppearanceManager::updateCOF(const LLUUID& category, bool append) { - llinfos << "starting" << llendl; + LLViewerInventoryCategory *pcat = gInventory.getCategory(category); + llinfos << "starting, cat " << (pcat ? pcat->getName() : "[UNKNOWN]") << llendl; const LLUUID cof = getCOF(); @@ -893,6 +1108,9 @@ void LLAppearanceManager::updateAppearanceFromCOF() // wearables can be resolved immediately, then the // callback will be called (and this object deleted) // before the final getNextData(). + + // BAP future cleanup - no point having found_container when + // mFoundList already has all the info. LLDynamicArray<LLFoundData> found_container; for(S32 i = 0; i < wear_items.count(); ++i) { @@ -903,7 +1121,21 @@ void LLAppearanceManager::updateAppearanceFromCOF() LLFoundData found(linked_item->getUUID(), linked_item->getAssetUUID(), linked_item->getName(), - linked_item->getType()); + linked_item->getType(), + linked_item->isWearableType() ? linked_item->getWearableType() : WT_INVALID + ); + +#if 0 + // Fault injection: uncomment this block to test asset + // fetch failures (should be replaced by new defaults in + // lost&found). + if (found.mWearableType == WT_SHAPE || found.mWearableType == WT_JACKET) + { + found.mAssetID.generate(); // Replace with new UUID, guaranteed not to exist in DB + + } +#endif + holder->mFoundList.push_front(found); found_container.put(found); } @@ -923,7 +1155,9 @@ void LLAppearanceManager::updateAppearanceFromCOF() for(S32 i = 0; i < found_container.count(); ++i) { LLFoundData& found = found_container.get(i); - + + llinfos << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << llendl; + // Fetch the wearables about to be worn. LLWearableList::instance().getAsset(found.mAssetID, found.mName, @@ -933,9 +1167,9 @@ void LLAppearanceManager::updateAppearanceFromCOF() } - if (!holder->pollCompletion()) + if (!holder->pollFetchCompletion()) { - doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollCompletion,holder)); + doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollFetchCompletion,holder)); } } diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 28b51ee0f6..e7e2f33520 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -151,6 +151,18 @@ public: BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const; }; +class LLUpdateAppearanceOnDestroy: public LLInventoryCallback +{ +public: + LLUpdateAppearanceOnDestroy(); + virtual ~LLUpdateAppearanceOnDestroy(); + /* virtual */ void fire(const LLUUID& inv_item); + +private: + U32 mFireCount; +}; + + #define SUPPORT_ENSEMBLES 0 LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name); diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 6e7321f739..ea5462a3e3 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -838,7 +838,8 @@ static void formatDateString(std::string &date_string) std::string day = result[2]; // ISO 8601 date format - date_string = llformat("%02s/%02s/%04s", month.c_str(), day.c_str(), year.c_str()); + //date_string = llformat("%02s/%02s/%04s", month.c_str(), day.c_str(), year.c_str()); + date_string = llformat("%04s/%02s/%04s", year.c_str(), month.c_str(), day.c_str()); } } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 5b59f52fa5..d0513c35ce 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1925,7 +1925,7 @@ bool LLFindCOFValidItems::operator()(LLInventoryCategory* cat, // - links to attachments // - links to gestures // - links to ensemble folders - LLViewerInventoryItem *linked_item = ((LLViewerInventoryItem*)item)->getLinkedItem(); // BAP - safe? + LLViewerInventoryItem *linked_item = ((LLViewerInventoryItem*)item)->getLinkedItem(); if (linked_item) { LLAssetType::EType type = linked_item->getType(); @@ -1936,7 +1936,7 @@ bool LLFindCOFValidItems::operator()(LLInventoryCategory* cat, } else { - LLViewerInventoryCategory *linked_category = ((LLViewerInventoryItem*)item)->getLinkedCategory(); // BAP - safe? + LLViewerInventoryCategory *linked_category = ((LLViewerInventoryItem*)item)->getLinkedCategory(); // BAP remove AT_NONE support after ensembles are fully working? return (linked_category && ((linked_category->getPreferredType() == LLFolderType::FT_NONE) || @@ -2962,8 +2962,6 @@ void LLFolderBridge::modifyOutfit(BOOL append) LLViewerInventoryCategory* cat = getCategory(); if(!cat) return; - // BAP - was: - // wear_inventory_category_on_avatar( cat, append ); LLAppearanceManager::instance().wearInventoryCategory( cat, FALSE, append ); } diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index a9ead36a70..f8f9ea7379 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -788,15 +788,19 @@ void LLLocationInputCtrl::refreshParcelIcons() // Our "cursor" moving right to left S32 x = mAddLandmarkBtn->getRect().mLeft; - if (gSavedSettings.getBOOL("NavBarShowParcelProperties")) - { - LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstance(); + LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstance(); + + LLViewerRegion* agent_region = gAgent.getRegion(); + LLParcel* agent_parcel = vpm->getAgentParcel(); + if (!agent_region || !agent_parcel) + return; + + mForSaleBtn->setVisible(vpm->canAgentBuyParcel(agent_parcel, false)); - LLViewerRegion* agent_region = gAgent.getRegion(); - LLParcel* agent_parcel = vpm->getAgentParcel(); - if (!agent_region || !agent_parcel) - return; + x = layout_widget(mForSaleBtn, x); + if (gSavedSettings.getBOOL("NavBarShowParcelProperties")) + { LLParcel* current_parcel; LLViewerRegion* selection_region = vpm->getSelectionRegion(); LLParcel* selected_parcel = vpm->getParcelSelection()->getParcel(); @@ -816,7 +820,6 @@ void LLLocationInputCtrl::refreshParcelIcons() current_parcel = agent_parcel; } - bool allow_buy = vpm->canAgentBuyParcel(current_parcel, false); bool allow_voice = vpm->allowAgentVoice(agent_region, current_parcel); bool allow_fly = vpm->allowAgentFly(agent_region, current_parcel); bool allow_push = vpm->allowAgentPush(agent_region, current_parcel); @@ -825,7 +828,6 @@ void LLLocationInputCtrl::refreshParcelIcons() bool allow_damage = vpm->allowAgentDamage(agent_region, current_parcel); // Most icons are "block this ability" - mForSaleBtn->setVisible(allow_buy); mParcelIcon[VOICE_ICON]->setVisible( !allow_voice ); mParcelIcon[FLY_ICON]->setVisible( !allow_fly ); mParcelIcon[PUSH_ICON]->setVisible( !allow_push ); @@ -833,11 +835,10 @@ void LLLocationInputCtrl::refreshParcelIcons() mParcelIcon[SCRIPTS_ICON]->setVisible( !allow_scripts ); mParcelIcon[DAMAGE_ICON]->setVisible( allow_damage ); mDamageText->setVisible(allow_damage); - - x = layout_widget(mForSaleBtn, x); + // Padding goes to left of both landmark star and for sale btn x -= mAddLandmarkHPad; - + // Slide the parcel icons rect from right to left, adjusting rectangles for (S32 i = 0; i < ICON_COUNT; ++i) { @@ -849,7 +850,6 @@ void LLLocationInputCtrl::refreshParcelIcons() } else { - mForSaleBtn->setVisible(false); for (S32 i = 0; i < ICON_COUNT; ++i) { mParcelIcon[i]->setVisible(false); diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 16b13d9218..be8b2363ad 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -46,7 +46,17 @@ #include <boost/regex.hpp> #include <boost/regex/v4/match_results.hpp> +#if LL_MSVC +// disable warning about boost::lexical_cast unreachable code +// when it fails to parse the string +#pragma warning (disable:4702) +#endif + #include <boost/date_time/gregorian/gregorian.hpp> +#if LL_MSVC +#pragma warning(pop) // Restore all warnings to the previous state +#endif + #include <boost/date_time/posix_time/posix_time.hpp> #include <boost/date_time/local_time_adjustor.hpp> diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index 3c390c0281..a211adc79d 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -34,6 +34,7 @@ #include "llnearbychathandler.h" +#include "llbottomtray.h" #include "llchatitemscontainerctrl.h" #include "llnearbychat.h" #include "llrecentpeople.h" @@ -319,9 +320,9 @@ LLNearbyChatHandler::~LLNearbyChatHandler() void LLNearbyChatHandler::initChannel() { LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD()); + LLView* chat_box = LLBottomTray::getInstance()->getChildView("chat_box"); S32 channel_right_bound = nearby_chat->getRect().mRight; - S32 channel_width = nearby_chat->getRect().mRight; - mChannel->init(channel_right_bound - channel_width, channel_right_bound); + mChannel->init(chat_box->getRect().mLeft, channel_right_bound); } diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index b61d3ef371..57b478ffef 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -47,7 +47,6 @@ #include "lltooldraganddrop.h" #include "llscrollcontainer.h" #include "llavatariconctrl.h" -#include "llweb.h" #include "llfloaterreg.h" #include "llnotificationsutil.h" #include "llvoiceclient.h" @@ -486,7 +485,6 @@ LLPanelAvatarProfile::LLPanelAvatarProfile() BOOL LLPanelAvatarProfile::postBuild() { - childSetActionTextbox("homepage_edit", boost::bind(&LLPanelAvatarProfile::onHomepageTextboxClicked, this)); childSetCommitCallback("add_friend",(boost::bind(&LLPanelAvatarProfile::onAddFriendButtonClick,this)),NULL); childSetCommitCallback("im",(boost::bind(&LLPanelAvatarProfile::onIMButtonClick,this)),NULL); childSetCommitCallback("call",(boost::bind(&LLPanelAvatarProfile::onCallButtonClick,this)),NULL); @@ -732,20 +730,6 @@ void LLPanelAvatarProfile::csr() LLAvatarActions::csr(getAvatarId(), name); } -void LLPanelAvatarProfile::onUrlTextboxClicked(const std::string& url) -{ - LLWeb::loadURL(url); -} - -void LLPanelAvatarProfile::onHomepageTextboxClicked() -{ - std::string url = childGetValue("homepage_edit").asString(); - if(!url.empty()) - { - onUrlTextboxClicked(url); - } -} - void LLPanelAvatarProfile::onAddFriendButtonClick() { LLAvatarActions::requestFriendshipDialog(getAvatarId()); diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index babbe534b4..2bd23b6e9c 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -207,8 +207,6 @@ protected: bool enableGod(); - void onUrlTextboxClicked(const std::string& url); - void onHomepageTextboxClicked(); void onAddFriendButtonClick(); void onIMButtonClick(); void onCallButtonClick(); diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 555e277ce5..517204b232 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -111,6 +111,8 @@ BOOL LLPanelGroupGeneral::postBuild() { mListVisibleMembers->setDoubleClickCallback(openProfile, this); mListVisibleMembers->setContextMenu(LLScrollListCtrl::MENU_AVATAR); + + mListVisibleMembers->setSortCallback(boost::bind(&LLPanelGroupGeneral::sortMembersList,this,_1,_2,_3)); } // Options @@ -944,4 +946,18 @@ void LLPanelGroupGeneral::setGroupID(const LLUUID& id) activate(); } +S32 LLPanelGroupGeneral::sortMembersList(S32 col_idx,const LLScrollListItem* i1,const LLScrollListItem* i2) +{ + const LLScrollListCell *cell1 = i1->getColumn(col_idx); + const LLScrollListCell *cell2 = i2->getColumn(col_idx); + + if(col_idx == 2) + { + if(LLStringUtil::compareDict(cell1->getValue().asString(),"Online") == 0 ) + return 1; + if(LLStringUtil::compareDict(cell2->getValue().asString(),"Online") == 0 ) + return -1; + } + return LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString()); +} diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h index 7e90e43cf9..6245018871 100644 --- a/indra/newview/llpanelgroupgeneral.h +++ b/indra/newview/llpanelgroupgeneral.h @@ -83,6 +83,8 @@ private: static void onReceiveNotices(LLUICtrl* ctrl, void* data); static void openProfile(void* data); + S32 sortMembersList(S32,const LLScrollListItem*,const LLScrollListItem*); + static bool joinDlgCB(const LLSD& notification, const LLSD& response); void updateMembers(); diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index 8ad5389566..b73d7db770 100644 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -535,7 +535,9 @@ void LLPanelNearByMedia::refreshParcelItems() const LLSD &choice_llsd = mShowCtrl->getSelectedValue(); MediaClass choice = (MediaClass)choice_llsd.asInteger(); // Only show "special parcel items" if "All" or "Within" filter - bool should_include = choice == MEDIA_CLASS_ALL || choice == MEDIA_CLASS_WITHIN_PARCEL; + // (and if media is "enabled") + bool should_include = gSavedSettings.getBOOL("AudioStreamingMedia") && + (choice == MEDIA_CLASS_ALL || choice == MEDIA_CLASS_WITHIN_PARCEL); // First Parcel Media: add or remove it as necessary if (should_include && LLViewerMedia::hasParcelMedia()) @@ -579,8 +581,8 @@ void LLPanelNearByMedia::refreshParcelItems() "parcel media"); } - // Next Parcel Audio: add or remove it as necessary - if (should_include && LLViewerMedia::hasParcelAudio()) + // Next Parcel Audio: add or remove it as necessary (don't show if disabled in prefs) + if (should_include && LLViewerMedia::hasParcelAudio() && gSavedSettings.getBOOL("AudioStreamingMusic")) { // Yes, there is parcel audio. if (NULL == mParcelAudioItem) @@ -692,14 +694,16 @@ void LLPanelNearByMedia::refreshList() } } } - mDisableAllCtrl->setEnabled(LLViewerMedia::isAnyMediaShowing() || - LLViewerMedia::isParcelMediaPlaying() || - LLViewerMedia::isParcelAudioPlaying()); - mEnableAllCtrl->setEnabled(disabled_count > 0 || - // parcel media (if we have it, and it isn't playing, enable "start") - (LLViewerMedia::hasParcelMedia() && ! LLViewerMedia::isParcelMediaPlaying()) || - // parcel audio (if we have it, and it isn't playing, enable "start") - (LLViewerMedia::hasParcelAudio() && ! LLViewerMedia::isParcelAudioPlaying())); + mDisableAllCtrl->setEnabled(gSavedSettings.getBOOL("AudioStreamingMedia") && + (LLViewerMedia::isAnyMediaShowing() || + LLViewerMedia::isParcelMediaPlaying() || + LLViewerMedia::isParcelAudioPlaying())); + mEnableAllCtrl->setEnabled(gSavedSettings.getBOOL("AudioStreamingMedia") && + (disabled_count > 0 || + // parcel media (if we have it, and it isn't playing, enable "start") + (LLViewerMedia::hasParcelMedia() && ! LLViewerMedia::isParcelMediaPlaying()) || + // parcel audio (if we have it, and it isn't playing, enable "start") + (LLViewerMedia::hasParcelAudio() && ! LLViewerMedia::isParcelAudioPlaying()))); // Iterate over the rows in the control, updating ones whose impl exists, and deleting ones whose impl has gone away. std::vector<LLScrollListItem*> items = mMediaList->getAllData(); @@ -953,15 +957,29 @@ void LLPanelNearByMedia::onMoreLess() void LLPanelNearByMedia::updateControls() { + if (! gSavedSettings.getBOOL("AudioStreamingMedia")) + { + // Just show disabled controls + showDisabledControls(); + return; + } + LLUUID selected_media_id = mMediaList->getValue().asUUID(); if (selected_media_id == PARCEL_AUDIO_LIST_ITEM_UUID) { - showTimeBasedControls(LLViewerMedia::isParcelAudioPlaying(), + if (!LLViewerMedia::hasParcelAudio() || !gSavedSettings.getBOOL("AudioStreamingMusic")) + { + // Shouldn't happen, but do this anyway + showDisabledControls(); + } + else { + showTimeBasedControls(LLViewerMedia::isParcelAudioPlaying(), false, // include_zoom false, // is_zoomed gSavedSettings.getBOOL("MuteMusic"), gSavedSettings.getF32("AudioLevelMusic") ); + } } else if (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) { @@ -1075,15 +1093,18 @@ void LLPanelNearByMedia::onClickSelectedMediaPlay() { LLViewerMediaImpl *impl = (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) ? ((LLViewerMediaImpl*)LLViewerParcelMedia::getParcelMedia()) : LLViewerMedia::getMediaImplFromTextureID(selected_media_id); - if (NULL != impl && impl->isMediaTimeBased() && impl->isMediaPaused()) - { - // Aha! It's really time-based media that's paused, so unpause - impl->play(); - return; - } - else if (impl->isParcelMedia()) + if (NULL != impl) { - LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); + if (impl->isMediaTimeBased() && impl->isMediaPaused()) + { + // Aha! It's really time-based media that's paused, so unpause + impl->play(); + return; + } + else if (impl->isParcelMedia()) + { + LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); + } } } } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 83f773fadc..025dd6029a 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -121,7 +121,6 @@ #include "lllogininstance.h" // Host the login module. #include "llpanellogin.h" #include "llmutelist.h" -#include "llpanelavatar.h" #include "llavatarpropertiesprocessor.h" #include "llfloaterevent.h" #include "llpanelclassified.h" diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index e83c882866..732c23982b 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -358,8 +358,10 @@ void LLStatusBar::refresh() bool mute_audio = LLAppViewer::instance()->getMasterSystemAudioMute(); mBtnVolume->setToggleState(mute_audio); - // Don't show media toggle if there's no media, parcel media, and no parcel audio - mMediaToggle->setVisible(LLViewerMedia::hasInWorldMedia() || LLViewerMedia::hasParcelMedia() || LLViewerMedia::hasParcelAudio()); + // Disable media toggle if there's no media, parcel media, and no parcel audio + // (or if media is disabled) + mMediaToggle->setEnabled(gSavedSettings.getBOOL("AudioStreamingMedia") && + (LLViewerMedia::hasInWorldMedia() || LLViewerMedia::hasParcelMedia() || LLViewerMedia::hasParcelAudio())); // Note the "sense" of the toggle is opposite whether media is playing or not mMediaToggle->setValue(! (LLViewerMedia::isAnyMediaShowing() || LLViewerMedia::isParcelMediaPlaying() || @@ -547,13 +549,13 @@ void LLStatusBar::onMouseEnterNearbyMedia() LLButton* nearby_media_btn = getChild<LLButton>( "media_toggle_btn" ); LLRect nearby_media_btn_rect = nearby_media_btn->calcScreenRect(); nearby_media_rect.setLeftTopAndSize(nearby_media_btn_rect.mLeft - - (nearby_media_rect.getWidth() - nearby_media_btn_rect.getWidth())/2, - nearby_media_btn_rect.mBottom, - nearby_media_rect.getWidth(), - nearby_media_rect.getHeight()); + (nearby_media_rect.getWidth() - nearby_media_btn_rect.getWidth())/2, + nearby_media_btn_rect.mBottom, + nearby_media_rect.getWidth(), + nearby_media_rect.getHeight()); // force onscreen nearby_media_rect.translate(popup_holder->getRect().getWidth() - nearby_media_rect.mRight, 0); - + // show the master volume pull-down mPanelNearByMedia->setShape(nearby_media_rect); mPanelNearByMedia->setVisible(TRUE); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 395467dffb..0948afee8b 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -944,7 +944,10 @@ void LLViewerMedia::setAllMediaEnabled(bool val) LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); } - if (!LLViewerMedia::isParcelAudioPlaying() && gAudiop && LLViewerMedia::hasParcelAudio()) + if (gSavedSettings.getBOOL("AudioStreamingMusic") && + !LLViewerMedia::isParcelAudioPlaying() && + gAudiop && + LLViewerMedia::hasParcelAudio()) { gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL()); } @@ -972,7 +975,6 @@ bool LLViewerMedia::isParcelAudioPlaying() bool LLViewerMedia::hasInWorldMedia() { - if (! gSavedSettings.getBOOL("AudioStreamingMedia")) return false; if (sInWorldMediaDisabled) return false; impl_list::iterator iter = sViewerMediaImplList.begin(); impl_list::iterator end = sViewerMediaImplList.end(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 02bde51fb6..15c72fdef1 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -4422,35 +4422,22 @@ bool visible_take_object() return !is_selection_buy_not_take() && enable_take(); } +bool tools_visible_buy_object() +{ + return is_selection_buy_not_take(); +} + +bool tools_visible_take_object() +{ + return !is_selection_buy_not_take(); +} + class LLToolsEnableBuyOrTake : public view_listener_t { bool handleEvent(const LLSD& userdata) { bool is_buy = is_selection_buy_not_take(); bool new_value = is_buy ? enable_buy_object() : enable_take(); - - // Update label - std::string label; - std::string buy_text; - std::string take_text; - std::string param = userdata.asString(); - std::string::size_type offset = param.find(","); - if (offset != param.npos) - { - buy_text = param.substr(0, offset); - take_text = param.substr(offset+1); - } - if (is_buy) - { - label = buy_text; - } - else - { - label = take_text; - } - gMenuHolder->childSetText("Pie Object Take", label); - gMenuHolder->childSetText("Menu Object Take", label); - return new_value; } }; @@ -7802,12 +7789,11 @@ void initialize_menus() view_listener_t::addMenu(new LLToolsEnableUnlink(), "Tools.EnableUnlink"); view_listener_t::addMenu(new LLToolsEnableBuyOrTake(), "Tools.EnableBuyOrTake"); enable.add("Tools.EnableTakeCopy", boost::bind(&enable_object_take_copy)); + enable.add("Tools.VisibleBuyObject", boost::bind(&tools_visible_buy_object)); + enable.add("Tools.VisibleTakeObject", boost::bind(&tools_visible_take_object)); view_listener_t::addMenu(new LLToolsEnableSaveToInventory(), "Tools.EnableSaveToInventory"); view_listener_t::addMenu(new LLToolsEnableSaveToObjectInventory(), "Tools.EnableSaveToObjectInventory"); - /*view_listener_t::addMenu(new LLToolsVisibleBuyObject(), "Tools.VisibleBuyObject"); - view_listener_t::addMenu(new LLToolsVisibleTakeObject(), "Tools.VisibleTakeObject");*/ - // Help menu // most items use the ShowFloater method diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml index 7aa8e23e76..d7a7daf30c 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences.xml @@ -46,6 +46,7 @@ tab_group="1" tab_position="left" tab_width="115" + tab_padding_right="5" top="21" width="620"> <panel diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml index d66818e91a..9436b2cd73 100644 --- a/indra/newview/skins/default/xui/en/menu_object.xml +++ b/indra/newview/skins/default/xui/en/menu_object.xml @@ -124,16 +124,28 @@ </menu_item_call> </context_menu> <menu_item_separator layout="topleft" /> - <menu_item_call - enabled="false" + <menu_item_call + label="Buy" + layout="topleft" + name="Pie Object Bye"> + <menu_item_call.on_click + function="Tools.BuyOrTake"/> + <menu_item_call.on_visible + function="Tools.VisibleBuyObject"/> + <menu_item_call.on_enable + function="Tools.EnableBuyOrTake"/> + </menu_item_call> + <menu_item_call label="Take" + layout="topleft" name="Pie Object Take"> - <menu_item_call.on_click - function="Tools.BuyOrTake" /> - <menu_item_call.on_enable - function="Tools.EnableBuyOrTake" - parameter="Buy,Take" /> - </menu_item_call> + <menu_item_call.on_click + function="Tools.BuyOrTake"/> + <menu_item_call.on_visible + function="Tools.VisibleTakeObject"/> + <menu_item_call.on_enable + function="Tools.EnableBuyOrTake"/> + </menu_item_call> <menu_item_call enabled="false" label="Take Copy" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 4c4867b862..158e764eae 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -719,16 +719,26 @@ name="Object" tear_off="true"> <menu_item_call - label="Buy" - layout="topleft" - name="Menu Object Take" - visible="true"> - <menu_item_call.on_click - function="Tools.BuyOrTake" /> - <menu_item_call.on_enable - function="Tools.EnableBuyOrTake" - name="EnableBuyOrTake" - parameter="Buy,Take" /> + label="Buy" + layout="topleft" + name="Menu Object Buy"> + <menu_item_call.on_click + function="Tools.BuyOrTake"/> + <menu_item_call.on_visible + function="Tools.VisibleBuyObject"/> + <menu_item_call.on_enable + function="Tools.EnableBuyOrTake"/> + </menu_item_call> + <menu_item_call + label="Take" + layout="topleft" + name="Menu Object Take"> + <menu_item_call.on_click + function="Tools.BuyOrTake"/> + <menu_item_call.on_visible + function="Tools.VisibleTakeObject"/> + <menu_item_call.on_enable + function="Tools.EnableBuyOrTake"/> </menu_item_call> <menu_item_call label="Take Copy" diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml index 96c61b69f5..4167401338 100644 --- a/indra/newview/skins/default/xui/en/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml @@ -102,7 +102,7 @@ left_pad="15" top="2" name="media_toggle_btn" - tool_tip="Click to toggle media" + tool_tip="Start/Stop All Media (Music, Video, Web pages)" width="16" > </button> <button diff --git a/indra/newview/skins/default/xui/pl/floater_about.xml b/indra/newview/skins/default/xui/pl/floater_about.xml index 29a5aca90d..29a5aca90d 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_about.xml +++ b/indra/newview/skins/default/xui/pl/floater_about.xml diff --git a/indra/newview/skins/default/xui/pl/floater_about_land.xml b/indra/newview/skins/default/xui/pl/floater_about_land.xml index d456ea26b4..d456ea26b4 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_about_land.xml +++ b/indra/newview/skins/default/xui/pl/floater_about_land.xml diff --git a/indra/newview/skins/default/xui/pl/floater_animation_preview.xml b/indra/newview/skins/default/xui/pl/floater_animation_preview.xml index 0524b8ade3..0524b8ade3 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_animation_preview.xml +++ b/indra/newview/skins/default/xui/pl/floater_animation_preview.xml diff --git a/indra/newview/skins/default/xui/pl/floater_auction.xml b/indra/newview/skins/default/xui/pl/floater_auction.xml index 37e35ed1e9..37e35ed1e9 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_auction.xml +++ b/indra/newview/skins/default/xui/pl/floater_auction.xml diff --git a/indra/newview/skins/default/xui/pl/floater_avatar_picker.xml b/indra/newview/skins/default/xui/pl/floater_avatar_picker.xml index 8c09f7294c..8c09f7294c 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_avatar_picker.xml +++ b/indra/newview/skins/default/xui/pl/floater_avatar_picker.xml diff --git a/indra/newview/skins/default/xui/pl/floater_avatar_textures.xml b/indra/newview/skins/default/xui/pl/floater_avatar_textures.xml index dce2330807..dce2330807 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/pl/floater_avatar_textures.xml diff --git a/indra/newview/skins/default/xui/pl/floater_build_options.xml b/indra/newview/skins/default/xui/pl/floater_build_options.xml index f538be218c..f538be218c 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_build_options.xml +++ b/indra/newview/skins/default/xui/pl/floater_build_options.xml diff --git a/indra/newview/skins/default/xui/pl/floater_bumps.xml b/indra/newview/skins/default/xui/pl/floater_bumps.xml index 10f9d73284..10f9d73284 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_bumps.xml +++ b/indra/newview/skins/default/xui/pl/floater_bumps.xml diff --git a/indra/newview/skins/default/xui/pl/floater_buy_contents.xml b/indra/newview/skins/default/xui/pl/floater_buy_contents.xml index ebe1c9dfd8..ebe1c9dfd8 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_buy_contents.xml +++ b/indra/newview/skins/default/xui/pl/floater_buy_contents.xml diff --git a/indra/newview/skins/default/xui/pl/floater_buy_currency.xml b/indra/newview/skins/default/xui/pl/floater_buy_currency.xml index 5e59482883..5e59482883 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/pl/floater_buy_currency.xml diff --git a/indra/newview/skins/default/xui/pl/floater_buy_land.xml b/indra/newview/skins/default/xui/pl/floater_buy_land.xml index 648888828b..648888828b 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_buy_land.xml +++ b/indra/newview/skins/default/xui/pl/floater_buy_land.xml diff --git a/indra/newview/skins/default/xui/pl/floater_buy_object.xml b/indra/newview/skins/default/xui/pl/floater_buy_object.xml index bad7982228..bad7982228 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_buy_object.xml +++ b/indra/newview/skins/default/xui/pl/floater_buy_object.xml diff --git a/indra/newview/skins/default/xui/pl/floater_camera.xml b/indra/newview/skins/default/xui/pl/floater_camera.xml index 5957018144..5957018144 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_camera.xml +++ b/indra/newview/skins/default/xui/pl/floater_camera.xml diff --git a/indra/newview/skins/default/xui/pl/floater_choose_group.xml b/indra/newview/skins/default/xui/pl/floater_choose_group.xml index 72b6617094..72b6617094 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_choose_group.xml +++ b/indra/newview/skins/default/xui/pl/floater_choose_group.xml diff --git a/indra/newview/skins/default/xui/pl/floater_color_picker.xml b/indra/newview/skins/default/xui/pl/floater_color_picker.xml index 904a2cc270..904a2cc270 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_color_picker.xml +++ b/indra/newview/skins/default/xui/pl/floater_color_picker.xml diff --git a/indra/newview/skins/default/xui/pl/floater_critical.xml b/indra/newview/skins/default/xui/pl/floater_critical.xml index 8221a4e1bd..8221a4e1bd 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_critical.xml +++ b/indra/newview/skins/default/xui/pl/floater_critical.xml diff --git a/indra/newview/skins/default/xui/pl/floater_customize.xml b/indra/newview/skins/default/xui/pl/floater_customize.xml index 0c01d15faf..0c01d15faf 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_customize.xml +++ b/indra/newview/skins/default/xui/pl/floater_customize.xml diff --git a/indra/newview/skins/default/xui/pl/floater_day_cycle_options.xml b/indra/newview/skins/default/xui/pl/floater_day_cycle_options.xml index 6671bb853e..6671bb853e 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_day_cycle_options.xml +++ b/indra/newview/skins/default/xui/pl/floater_day_cycle_options.xml diff --git a/indra/newview/skins/default/xui/pl/floater_device_settings.xml b/indra/newview/skins/default/xui/pl/floater_device_settings.xml index e79478731d..e79478731d 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_device_settings.xml +++ b/indra/newview/skins/default/xui/pl/floater_device_settings.xml diff --git a/indra/newview/skins/default/xui/pl/floater_env_settings.xml b/indra/newview/skins/default/xui/pl/floater_env_settings.xml index e197d94b27..e197d94b27 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_env_settings.xml +++ b/indra/newview/skins/default/xui/pl/floater_env_settings.xml diff --git a/indra/newview/skins/default/xui/pl/floater_gesture.xml b/indra/newview/skins/default/xui/pl/floater_gesture.xml index 4685eb6afe..4685eb6afe 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_gesture.xml +++ b/indra/newview/skins/default/xui/pl/floater_gesture.xml diff --git a/indra/newview/skins/default/xui/pl/floater_god_tools.xml b/indra/newview/skins/default/xui/pl/floater_god_tools.xml index a3ccffac03..a3ccffac03 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_god_tools.xml +++ b/indra/newview/skins/default/xui/pl/floater_god_tools.xml diff --git a/indra/newview/skins/default/xui/pl/floater_hardware_settings.xml b/indra/newview/skins/default/xui/pl/floater_hardware_settings.xml index 39695a67b6..39695a67b6 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_hardware_settings.xml +++ b/indra/newview/skins/default/xui/pl/floater_hardware_settings.xml diff --git a/indra/newview/skins/default/xui/pl/floater_hud.xml b/indra/newview/skins/default/xui/pl/floater_hud.xml index ff2d702132..ff2d702132 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_hud.xml +++ b/indra/newview/skins/default/xui/pl/floater_hud.xml diff --git a/indra/newview/skins/default/xui/pl/floater_im.xml b/indra/newview/skins/default/xui/pl/floater_im.xml index 67c9d13496..67c9d13496 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_im.xml +++ b/indra/newview/skins/default/xui/pl/floater_im.xml diff --git a/indra/newview/skins/default/xui/pl/floater_image_preview.xml b/indra/newview/skins/default/xui/pl/floater_image_preview.xml index 27f898a66b..27f898a66b 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_image_preview.xml +++ b/indra/newview/skins/default/xui/pl/floater_image_preview.xml diff --git a/indra/newview/skins/default/xui/pl/floater_inspect.xml b/indra/newview/skins/default/xui/pl/floater_inspect.xml index c98e0541d8..c98e0541d8 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_inspect.xml +++ b/indra/newview/skins/default/xui/pl/floater_inspect.xml diff --git a/indra/newview/skins/default/xui/pl/floater_inventory.xml b/indra/newview/skins/default/xui/pl/floater_inventory.xml index 157be76c4d..157be76c4d 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_inventory.xml +++ b/indra/newview/skins/default/xui/pl/floater_inventory.xml diff --git a/indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml index 665172dd49..665172dd49 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml +++ b/indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml diff --git a/indra/newview/skins/default/xui/pl/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/pl/floater_inventory_view_finder.xml index 9204262304..9204262304 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_inventory_view_finder.xml +++ b/indra/newview/skins/default/xui/pl/floater_inventory_view_finder.xml diff --git a/indra/newview/skins/default/xui/pl/floater_joystick.xml b/indra/newview/skins/default/xui/pl/floater_joystick.xml index 22ac458b85..22ac458b85 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_joystick.xml +++ b/indra/newview/skins/default/xui/pl/floater_joystick.xml diff --git a/indra/newview/skins/default/xui/pl/floater_lagmeter.xml b/indra/newview/skins/default/xui/pl/floater_lagmeter.xml index 69d563bdba..69d563bdba 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_lagmeter.xml +++ b/indra/newview/skins/default/xui/pl/floater_lagmeter.xml diff --git a/indra/newview/skins/default/xui/pl/floater_land_holdings.xml b/indra/newview/skins/default/xui/pl/floater_land_holdings.xml index 13e6a8b16d..13e6a8b16d 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_land_holdings.xml +++ b/indra/newview/skins/default/xui/pl/floater_land_holdings.xml diff --git a/indra/newview/skins/default/xui/pl/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/pl/floater_live_lsleditor.xml index 8120ff8c77..8120ff8c77 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_live_lsleditor.xml +++ b/indra/newview/skins/default/xui/pl/floater_live_lsleditor.xml diff --git a/indra/newview/skins/default/xui/pl/floater_lsl_guide.xml b/indra/newview/skins/default/xui/pl/floater_lsl_guide.xml index 5601aa4464..5601aa4464 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_lsl_guide.xml +++ b/indra/newview/skins/default/xui/pl/floater_lsl_guide.xml diff --git a/indra/newview/skins/default/xui/pl/floater_media_browser.xml b/indra/newview/skins/default/xui/pl/floater_media_browser.xml index 74210c75e5..74210c75e5 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_media_browser.xml +++ b/indra/newview/skins/default/xui/pl/floater_media_browser.xml diff --git a/indra/newview/skins/default/xui/pl/floater_mem_leaking.xml b/indra/newview/skins/default/xui/pl/floater_mem_leaking.xml index 88a878af72..88a878af72 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_mem_leaking.xml +++ b/indra/newview/skins/default/xui/pl/floater_mem_leaking.xml diff --git a/indra/newview/skins/default/xui/pl/floater_moveview.xml b/indra/newview/skins/default/xui/pl/floater_moveview.xml index e28cfd589d..e28cfd589d 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_moveview.xml +++ b/indra/newview/skins/default/xui/pl/floater_moveview.xml diff --git a/indra/newview/skins/default/xui/pl/floater_mute_object.xml b/indra/newview/skins/default/xui/pl/floater_mute_object.xml index 8055617371..8055617371 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_mute_object.xml +++ b/indra/newview/skins/default/xui/pl/floater_mute_object.xml diff --git a/indra/newview/skins/default/xui/pl/floater_my_friends.xml b/indra/newview/skins/default/xui/pl/floater_my_friends.xml index 0bcf6ba4d5..0bcf6ba4d5 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_my_friends.xml +++ b/indra/newview/skins/default/xui/pl/floater_my_friends.xml diff --git a/indra/newview/skins/default/xui/pl/floater_openobject.xml b/indra/newview/skins/default/xui/pl/floater_openobject.xml index fbbed0f11d..fbbed0f11d 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_openobject.xml +++ b/indra/newview/skins/default/xui/pl/floater_openobject.xml diff --git a/indra/newview/skins/default/xui/pl/floater_pay.xml b/indra/newview/skins/default/xui/pl/floater_pay.xml index dfb1b6616c..dfb1b6616c 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_pay.xml +++ b/indra/newview/skins/default/xui/pl/floater_pay.xml diff --git a/indra/newview/skins/default/xui/pl/floater_pay_object.xml b/indra/newview/skins/default/xui/pl/floater_pay_object.xml index 376f517aaa..376f517aaa 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_pay_object.xml +++ b/indra/newview/skins/default/xui/pl/floater_pay_object.xml diff --git a/indra/newview/skins/default/xui/pl/floater_post_process.xml b/indra/newview/skins/default/xui/pl/floater_post_process.xml index 6bd91f97b1..6bd91f97b1 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_post_process.xml +++ b/indra/newview/skins/default/xui/pl/floater_post_process.xml diff --git a/indra/newview/skins/default/xui/pl/floater_postcard.xml b/indra/newview/skins/default/xui/pl/floater_postcard.xml index 8f4018924d..8f4018924d 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_postcard.xml +++ b/indra/newview/skins/default/xui/pl/floater_postcard.xml diff --git a/indra/newview/skins/default/xui/pl/floater_preferences.xml b/indra/newview/skins/default/xui/pl/floater_preferences.xml index 2be663283f..2be663283f 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_preferences.xml +++ b/indra/newview/skins/default/xui/pl/floater_preferences.xml diff --git a/indra/newview/skins/default/xui/pl/floater_preview_animation.xml b/indra/newview/skins/default/xui/pl/floater_preview_animation.xml index 7139c470a4..7139c470a4 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/pl/floater_preview_animation.xml diff --git a/indra/newview/skins/default/xui/pl/floater_preview_classified.xml b/indra/newview/skins/default/xui/pl/floater_preview_classified.xml index eae9ba2690..eae9ba2690 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_preview_classified.xml +++ b/indra/newview/skins/default/xui/pl/floater_preview_classified.xml diff --git a/indra/newview/skins/default/xui/pl/floater_preview_event.xml b/indra/newview/skins/default/xui/pl/floater_preview_event.xml index 9fc0ff4da6..9fc0ff4da6 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_preview_event.xml +++ b/indra/newview/skins/default/xui/pl/floater_preview_event.xml diff --git a/indra/newview/skins/default/xui/pl/floater_preview_gesture.xml b/indra/newview/skins/default/xui/pl/floater_preview_gesture.xml index 1c7a3f6631..1c7a3f6631 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_preview_gesture.xml +++ b/indra/newview/skins/default/xui/pl/floater_preview_gesture.xml diff --git a/indra/newview/skins/default/xui/pl/floater_preview_notecard.xml b/indra/newview/skins/default/xui/pl/floater_preview_notecard.xml index b9f80490ab..b9f80490ab 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_preview_notecard.xml +++ b/indra/newview/skins/default/xui/pl/floater_preview_notecard.xml diff --git a/indra/newview/skins/default/xui/pl/floater_preview_sound.xml b/indra/newview/skins/default/xui/pl/floater_preview_sound.xml index 656b9bec38..656b9bec38 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_preview_sound.xml +++ b/indra/newview/skins/default/xui/pl/floater_preview_sound.xml diff --git a/indra/newview/skins/default/xui/pl/floater_preview_texture.xml b/indra/newview/skins/default/xui/pl/floater_preview_texture.xml index 8bcd800411..8bcd800411 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/pl/floater_preview_texture.xml diff --git a/indra/newview/skins/default/xui/pl/floater_region_info.xml b/indra/newview/skins/default/xui/pl/floater_region_info.xml index ca3c1391db..ca3c1391db 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_region_info.xml +++ b/indra/newview/skins/default/xui/pl/floater_region_info.xml diff --git a/indra/newview/skins/default/xui/pl/floater_report_abuse.xml b/indra/newview/skins/default/xui/pl/floater_report_abuse.xml index 18ce1b230f..18ce1b230f 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_report_abuse.xml +++ b/indra/newview/skins/default/xui/pl/floater_report_abuse.xml diff --git a/indra/newview/skins/default/xui/pl/floater_script_debug.xml b/indra/newview/skins/default/xui/pl/floater_script_debug.xml index 714a600262..714a600262 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_script_debug.xml +++ b/indra/newview/skins/default/xui/pl/floater_script_debug.xml diff --git a/indra/newview/skins/default/xui/pl/floater_script_preview.xml b/indra/newview/skins/default/xui/pl/floater_script_preview.xml index e3e72e15a3..e3e72e15a3 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_script_preview.xml +++ b/indra/newview/skins/default/xui/pl/floater_script_preview.xml diff --git a/indra/newview/skins/default/xui/pl/floater_script_queue.xml b/indra/newview/skins/default/xui/pl/floater_script_queue.xml index 7655f5fcac..7655f5fcac 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_script_queue.xml +++ b/indra/newview/skins/default/xui/pl/floater_script_queue.xml diff --git a/indra/newview/skins/default/xui/pl/floater_script_search.xml b/indra/newview/skins/default/xui/pl/floater_script_search.xml index 255ab4264c..255ab4264c 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_script_search.xml +++ b/indra/newview/skins/default/xui/pl/floater_script_search.xml diff --git a/indra/newview/skins/default/xui/pl/floater_select_key.xml b/indra/newview/skins/default/xui/pl/floater_select_key.xml index 194a6da1bd..194a6da1bd 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_select_key.xml +++ b/indra/newview/skins/default/xui/pl/floater_select_key.xml diff --git a/indra/newview/skins/default/xui/pl/floater_sell_land.xml b/indra/newview/skins/default/xui/pl/floater_sell_land.xml index a306ec2c34..a306ec2c34 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/pl/floater_sell_land.xml diff --git a/indra/newview/skins/default/xui/pl/floater_settings_debug.xml b/indra/newview/skins/default/xui/pl/floater_settings_debug.xml index f87e2edecc..f87e2edecc 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_settings_debug.xml +++ b/indra/newview/skins/default/xui/pl/floater_settings_debug.xml diff --git a/indra/newview/skins/default/xui/pl/floater_snapshot.xml b/indra/newview/skins/default/xui/pl/floater_snapshot.xml index c807087170..c807087170 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/pl/floater_snapshot.xml diff --git a/indra/newview/skins/default/xui/pl/floater_sound_preview.xml b/indra/newview/skins/default/xui/pl/floater_sound_preview.xml index 0826508fd6..0826508fd6 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_sound_preview.xml +++ b/indra/newview/skins/default/xui/pl/floater_sound_preview.xml diff --git a/indra/newview/skins/default/xui/pl/floater_telehub.xml b/indra/newview/skins/default/xui/pl/floater_telehub.xml index 9f564452a9..9f564452a9 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_telehub.xml +++ b/indra/newview/skins/default/xui/pl/floater_telehub.xml diff --git a/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml index 48366e2b64..48366e2b64 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml diff --git a/indra/newview/skins/default/xui/pl/floater_tools.xml b/indra/newview/skins/default/xui/pl/floater_tools.xml index e898c283c5..e898c283c5 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_tools.xml +++ b/indra/newview/skins/default/xui/pl/floater_tools.xml diff --git a/indra/newview/skins/default/xui/pl/floater_top_objects.xml b/indra/newview/skins/default/xui/pl/floater_top_objects.xml index e7299b0abb..e7299b0abb 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/pl/floater_top_objects.xml diff --git a/indra/newview/skins/default/xui/pl/floater_tos.xml b/indra/newview/skins/default/xui/pl/floater_tos.xml index b9a146df22..b9a146df22 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_tos.xml +++ b/indra/newview/skins/default/xui/pl/floater_tos.xml diff --git a/indra/newview/skins/default/xui/pl/floater_url_entry.xml b/indra/newview/skins/default/xui/pl/floater_url_entry.xml index fc170d8d1b..fc170d8d1b 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_url_entry.xml +++ b/indra/newview/skins/default/xui/pl/floater_url_entry.xml diff --git a/indra/newview/skins/default/xui/pl/floater_water.xml b/indra/newview/skins/default/xui/pl/floater_water.xml index 7333633c1d..7333633c1d 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_water.xml +++ b/indra/newview/skins/default/xui/pl/floater_water.xml diff --git a/indra/newview/skins/default/xui/pl/floater_wearable_save_as.xml b/indra/newview/skins/default/xui/pl/floater_wearable_save_as.xml index 2d4582392c..2d4582392c 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_wearable_save_as.xml +++ b/indra/newview/skins/default/xui/pl/floater_wearable_save_as.xml diff --git a/indra/newview/skins/default/xui/pl/floater_windlight_options.xml b/indra/newview/skins/default/xui/pl/floater_windlight_options.xml index 86ef9300da..86ef9300da 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_windlight_options.xml +++ b/indra/newview/skins/default/xui/pl/floater_windlight_options.xml diff --git a/indra/newview/skins/default/xui/pl/floater_world_map.xml b/indra/newview/skins/default/xui/pl/floater_world_map.xml index 36e3b0651b..36e3b0651b 100644..100755 --- a/indra/newview/skins/default/xui/pl/floater_world_map.xml +++ b/indra/newview/skins/default/xui/pl/floater_world_map.xml diff --git a/indra/newview/skins/default/xui/pl/menu_inventory.xml b/indra/newview/skins/default/xui/pl/menu_inventory.xml index 75c84c275d..75c84c275d 100644..100755 --- a/indra/newview/skins/default/xui/pl/menu_inventory.xml +++ b/indra/newview/skins/default/xui/pl/menu_inventory.xml diff --git a/indra/newview/skins/default/xui/pl/menu_login.xml b/indra/newview/skins/default/xui/pl/menu_login.xml index 5084b59397..5084b59397 100644..100755 --- a/indra/newview/skins/default/xui/pl/menu_login.xml +++ b/indra/newview/skins/default/xui/pl/menu_login.xml diff --git a/indra/newview/skins/default/xui/pl/menu_slurl.xml b/indra/newview/skins/default/xui/pl/menu_slurl.xml index 719959df6a..719959df6a 100644..100755 --- a/indra/newview/skins/default/xui/pl/menu_slurl.xml +++ b/indra/newview/skins/default/xui/pl/menu_slurl.xml diff --git a/indra/newview/skins/default/xui/pl/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml index 2a5842e553..2a5842e553 100644..100755 --- a/indra/newview/skins/default/xui/pl/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pl/menu_viewer.xml diff --git a/indra/newview/skins/default/xui/pl/mime_types.xml b/indra/newview/skins/default/xui/pl/mime_types.xml index c90d5761e6..c90d5761e6 100644..100755 --- a/indra/newview/skins/default/xui/pl/mime_types.xml +++ b/indra/newview/skins/default/xui/pl/mime_types.xml diff --git a/indra/newview/skins/default/xui/pl/panel_audio_device.xml b/indra/newview/skins/default/xui/pl/panel_audio_device.xml index fc3b3776f0..fc3b3776f0 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_audio_device.xml +++ b/indra/newview/skins/default/xui/pl/panel_audio_device.xml diff --git a/indra/newview/skins/default/xui/pl/panel_friends.xml b/indra/newview/skins/default/xui/pl/panel_friends.xml index b6df36f199..b6df36f199 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_friends.xml +++ b/indra/newview/skins/default/xui/pl/panel_friends.xml diff --git a/indra/newview/skins/default/xui/pl/panel_group_general.xml b/indra/newview/skins/default/xui/pl/panel_group_general.xml index d09ff72226..d09ff72226 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_group_general.xml +++ b/indra/newview/skins/default/xui/pl/panel_group_general.xml diff --git a/indra/newview/skins/default/xui/pl/panel_group_invite.xml b/indra/newview/skins/default/xui/pl/panel_group_invite.xml index 12d48279ad..12d48279ad 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/pl/panel_group_invite.xml diff --git a/indra/newview/skins/default/xui/pl/panel_group_land_money.xml b/indra/newview/skins/default/xui/pl/panel_group_land_money.xml index dbfa8e3122..dbfa8e3122 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/pl/panel_group_land_money.xml diff --git a/indra/newview/skins/default/xui/pl/panel_group_notices.xml b/indra/newview/skins/default/xui/pl/panel_group_notices.xml index 1c19571ec0..1c19571ec0 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/pl/panel_group_notices.xml diff --git a/indra/newview/skins/default/xui/pl/panel_group_roles.xml b/indra/newview/skins/default/xui/pl/panel_group_roles.xml index dd46b4aeaa..dd46b4aeaa 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/pl/panel_group_roles.xml diff --git a/indra/newview/skins/default/xui/pl/panel_groups.xml b/indra/newview/skins/default/xui/pl/panel_groups.xml index 9df90fc797..9df90fc797 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_groups.xml +++ b/indra/newview/skins/default/xui/pl/panel_groups.xml diff --git a/indra/newview/skins/default/xui/pl/panel_login.xml b/indra/newview/skins/default/xui/pl/panel_login.xml index cec7e34da5..cec7e34da5 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_login.xml +++ b/indra/newview/skins/default/xui/pl/panel_login.xml diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/pl/panel_preferences_alerts.xml index 7195c30f20..7195c30f20 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/pl/panel_preferences_alerts.xml diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml b/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml index 5599c21686..5599c21686 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_general.xml b/indra/newview/skins/default/xui/pl/panel_preferences_general.xml index 97b4975f29..97b4975f29 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/pl/panel_preferences_general.xml diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml index ddd4c736d6..ddd4c736d6 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/pl/panel_preferences_privacy.xml index e3cdaae840..e3cdaae840 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/pl/panel_preferences_privacy.xml diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_setup.xml b/indra/newview/skins/default/xui/pl/panel_preferences_setup.xml index 1e2289b496..1e2289b496 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/pl/panel_preferences_setup.xml diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_sound.xml b/indra/newview/skins/default/xui/pl/panel_preferences_sound.xml index f9b5d221a5..f9b5d221a5 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/pl/panel_preferences_sound.xml diff --git a/indra/newview/skins/default/xui/pl/panel_region_covenant.xml b/indra/newview/skins/default/xui/pl/panel_region_covenant.xml index f20387dd25..f20387dd25 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_region_covenant.xml +++ b/indra/newview/skins/default/xui/pl/panel_region_covenant.xml diff --git a/indra/newview/skins/default/xui/pl/panel_region_debug.xml b/indra/newview/skins/default/xui/pl/panel_region_debug.xml index fe7b554a13..fe7b554a13 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/pl/panel_region_debug.xml diff --git a/indra/newview/skins/default/xui/pl/panel_region_estate.xml b/indra/newview/skins/default/xui/pl/panel_region_estate.xml index 4275f3f647..4275f3f647 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/pl/panel_region_estate.xml diff --git a/indra/newview/skins/default/xui/pl/panel_region_general.xml b/indra/newview/skins/default/xui/pl/panel_region_general.xml index 20296dac71..20296dac71 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_region_general.xml +++ b/indra/newview/skins/default/xui/pl/panel_region_general.xml diff --git a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml index b206616e34..b206616e34 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml diff --git a/indra/newview/skins/default/xui/pl/panel_region_texture.xml b/indra/newview/skins/default/xui/pl/panel_region_texture.xml index d24579fc75..d24579fc75 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_region_texture.xml +++ b/indra/newview/skins/default/xui/pl/panel_region_texture.xml diff --git a/indra/newview/skins/default/xui/pl/panel_scrolling_param.xml b/indra/newview/skins/default/xui/pl/panel_scrolling_param.xml index 70a6e39412..70a6e39412 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_scrolling_param.xml +++ b/indra/newview/skins/default/xui/pl/panel_scrolling_param.xml diff --git a/indra/newview/skins/default/xui/pl/panel_status_bar.xml b/indra/newview/skins/default/xui/pl/panel_status_bar.xml index 9226e67dff..9226e67dff 100644..100755 --- a/indra/newview/skins/default/xui/pl/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/pl/panel_status_bar.xml diff --git a/indra/newview/skins/default/xui/pl/role_actions.xml b/indra/newview/skins/default/xui/pl/role_actions.xml index 5711eacf2f..5711eacf2f 100644..100755 --- a/indra/newview/skins/default/xui/pl/role_actions.xml +++ b/indra/newview/skins/default/xui/pl/role_actions.xml diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml index e8dcfac02d..e8dcfac02d 100644..100755 --- a/indra/newview/skins/default/xui/pl/strings.xml +++ b/indra/newview/skins/default/xui/pl/strings.xml diff --git a/indra/newview/skins/default/xui/pl/teleport_strings.xml b/indra/newview/skins/default/xui/pl/teleport_strings.xml index 906978effe..906978effe 100644..100755 --- a/indra/newview/skins/default/xui/pl/teleport_strings.xml +++ b/indra/newview/skins/default/xui/pl/teleport_strings.xml diff --git a/indra/newview/skins/default/xui/pl/xui_version.xml b/indra/newview/skins/default/xui/pl/xui_version.xml index 0e777751d3..0e777751d3 100644..100755 --- a/indra/newview/skins/default/xui/pl/xui_version.xml +++ b/indra/newview/skins/default/xui/pl/xui_version.xml |