diff options
author | James Cook <james@lindenlab.com> | 2010-01-15 12:02:56 -0800 |
---|---|---|
committer | James Cook <james@lindenlab.com> | 2010-01-15 12:02:56 -0800 |
commit | 4acf56d2a79a4f3bb555977aeaef21e15e26f684 (patch) | |
tree | ac0d8ff2225916323d9b942246edd458e04fd738 /indra | |
parent | 3f83c05f7c71887825c907b0e148d81cd7de5324 (diff) | |
parent | c9cf84913d306103da51dc83e5932ff3fb308d32 (diff) |
Merge in viewer-2-0 changes
Diffstat (limited to 'indra')
102 files changed, 1409 insertions, 776 deletions
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 5058a2e772..85c78198dc 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -77,7 +77,7 @@ inline U32 get_cpu_clock_count_64() { U64 x; __asm__ volatile (".byte 0x0f, 0x31": "=A"(x)); - return x >> 8; + return x; } #endif diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index ed8d10a88c..3d2eaed5c5 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -37,6 +37,8 @@ #include "llpluginclassmedia.h" #include "llpluginmessageclasses.h" +#include "llqtwebkit.h" + static int LOW_PRIORITY_TEXTURE_SIZE_DEFAULT = 256; static int nextPowerOf2( int value ) @@ -124,7 +126,7 @@ void LLPluginClassMedia::reset() mCanPaste = false; mMediaName.clear(); mMediaDescription.clear(); - mBackgroundColor = LLColor4::white; + mBackgroundColor = LLColor4(1.0f, 1.0f, 1.0f, 1.0f); // media_browser class mNavigateURI.clear(); @@ -134,6 +136,9 @@ void LLPluginClassMedia::reset() mHistoryForwardAvailable = false; mStatusText.clear(); mProgressPercent = 0; + mClickURL.clear(); + mClickTarget.clear(); + mClickTargetType = TARGET_NONE; // media_time class mCurrentTime = 0.0f; @@ -669,6 +674,26 @@ void LLPluginClassMedia::paste() sendMessage(message); } +LLPluginClassMedia::ETargetType getTargetTypeFromLLQtWebkit(int target_type) +{ + // convert a LinkTargetType value from llqtwebkit to an ETargetType + // so that we don't expose the llqtwebkit header in viewer code + switch (target_type) + { + case LinkTargetType::LTT_TARGET_NONE: + return LLPluginClassMedia::TARGET_NONE; + + case LinkTargetType::LTT_TARGET_BLANK: + return LLPluginClassMedia::TARGET_BLANK; + + case LinkTargetType::LTT_TARGET_EXTERNAL: + return LLPluginClassMedia::TARGET_EXTERNAL; + + default: + return LLPluginClassMedia::TARGET_OTHER; + } +} + /* virtual */ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) { @@ -921,12 +946,15 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) { mClickURL = message.getValue("uri"); mClickTarget = message.getValue("target"); + U32 target_type = message.getValueU32("target_type"); + mClickTargetType = ::getTargetTypeFromLLQtWebkit(target_type); mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF); } else if(message_name == "click_nofollow") { mClickURL = message.getValue("uri"); mClickTarget.clear(); + mClickTargetType = TARGET_NONE; mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_NOFOLLOW); } else diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index 5a1928ab1d..ebb9099576 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -214,6 +214,17 @@ public: // This is valid after MEDIA_EVENT_CLICK_LINK_HREF std::string getClickTarget() const { return mClickTarget; }; + typedef enum + { + TARGET_NONE, // empty href target string + TARGET_BLANK, // target to open link in user's preferred browser + TARGET_EXTERNAL, // target to open link in external browser + TARGET_OTHER // nonempty and unsupported target type + }ETargetType; + + // This is valid after MEDIA_EVENT_CLICK_LINK_HREF + ETargetType getClickTargetType() const { return mClickTargetType; }; + std::string getMediaName() const { return mMediaName; }; std::string getMediaDescription() const { return mMediaDescription; }; @@ -344,6 +355,7 @@ protected: std::string mLocation; std::string mClickURL; std::string mClickTarget; + ETargetType mClickTargetType; ///////////////////////////////////////// // media_time class diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index a35d279500..980cd2abd7 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -233,6 +233,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) mAutoFocus(TRUE), // automatically take focus when opened mCanDock(false), mDocked(false), + mTornOff(false), mHasBeenDraggedWhileMinimized(FALSE), mPreviousMinimizedBottom(0), mPreviousMinimizedLeft(0) @@ -1067,10 +1068,6 @@ void LLFloater::setMinimized(BOOL minimize) reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE ); } - // don't show the help button while minimized - it's - // not very useful when minimized and uses up space - mButtonsEnabled[BUTTON_HELP] = !minimize; - applyTitle (); make_ui_sound("UISndWindowClose"); @@ -1460,6 +1457,7 @@ void LLFloater::onClickTearOff(LLFloater* self) } self->setTornOff(false); } + self->updateButtons(); } // static @@ -1743,14 +1741,32 @@ void LLFloater::updateButtons() S32 button_count = 0; for (S32 i = 0; i < BUTTON_COUNT; i++) { - if(!mButtons[i]) continue; - mButtons[i]->setEnabled(mButtonsEnabled[i]); + if (!mButtons[i]) + { + continue; + } - if (mButtonsEnabled[i] - //*HACK: always render close button for hosted floaters - // so that users don't accidentally hit the button when closing multiple windows - // in the chatterbox - || (i == BUTTON_CLOSE && mButtonScale != 1.f)) + bool enabled = mButtonsEnabled[i]; + if (i == BUTTON_HELP) + { + // don't show the help button if the floater is minimized + // or if it is a docked tear-off floater + if (isMinimized() || (mButtonsEnabled[BUTTON_TEAR_OFF] && ! mTornOff)) + { + enabled = false; + } + } + if (i == BUTTON_CLOSE && mButtonScale != 1.f) + { + //*HACK: always render close button for hosted floaters so + //that users don't accidentally hit the button when + //closing multiple windows in the chatterbox + enabled = true; + } + + mButtons[i]->setEnabled(enabled); + + if (enabled) { button_count++; @@ -1777,7 +1793,7 @@ void LLFloater::updateButtons() // the restore button should have a tab stop so that it takes action when you Ctrl-Tab to a minimized floater mButtons[i]->setTabStop(i == BUTTON_RESTORE); } - else if (mButtons[i]) + else { mButtons[i]->setVisible(FALSE); } diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index daf558de24..f70495c0f0 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -256,7 +256,7 @@ public: bool isDocked() const { return mDocked; } virtual void setDocked(bool docked, bool pop_on_undock = true); - virtual void setTornOff(bool torn_off) {} + virtual void setTornOff(bool torn_off) { mTornOff = torn_off; } // Return a closeable floater, if any, given the current focus. static LLFloater* getClosableFloaterFromFocus(); @@ -387,6 +387,7 @@ private: bool mCanDock; bool mDocked; + bool mTornOff; static LLMultiFloater* sHostp; static BOOL sQuitting; diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index f016c0af89..3ade46d367 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -868,14 +868,6 @@ bool LLUICtrl::findHelpTopic(std::string& help_topic_out) if (panel) { - // does the panel have an active tab with a help topic? - LLPanel *tab = panel->childGetVisibleTabWithHelp(); - if (tab) - { - help_topic_out = tab->getHelpTopic(); - return true; // success (tab) - } - // does the panel have a sub-panel with a help topic? LLPanel *subpanel = panel->childGetVisiblePanelWithHelp(); if (subpanel) @@ -884,6 +876,14 @@ bool LLUICtrl::findHelpTopic(std::string& help_topic_out) return true; // success (subpanel) } + // does the panel have an active tab with a help topic? + LLPanel *tab = panel->childGetVisibleTabWithHelp(); + if (tab) + { + help_topic_out = tab->getHelpTopic(); + return true; // success (tab) + } + // otherwise, does the panel have a help topic itself? if (!panel->getHelpTopic().empty()) { diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 1b6dd1b264..4927e57a52 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -204,7 +204,7 @@ LLUrlEntryHTTPNoProtocol::LLUrlEntryHTTPNoProtocol() mPattern = boost::regex("(" "\\bwww\\.\\S+\\.\\S+" // i.e. www.FOO.BAR "|" // or - "\\b[^ \\t\\n\\r\\f\\v:/]+\\.(?:com|net|edu|org)[^[:space:][:alnum:]]*\\>" // i.e. FOO.net + "(?<!@)\\b[^[:space:]:@/]+\\.(?:com|net|edu|org)([/:]\\S*)?\\b" // i.e. FOO.net ")", boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_http.xml"; diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 38cf7124ce..80be8fcbf7 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -571,6 +571,26 @@ namespace tut "MIT web site is at web.mit.edu and also www.mit.edu", "web.mit.edu"); + testRegex("don't match e-mail addresses", r, + "test@lindenlab.com", + ""); + + testRegex(".com URL with path", r, + "see secondlife.com/status for grid status", + "secondlife.com/status"); + + testRegex(".com URL with port", r, + "secondlife.com:80", + "secondlife.com:80"); + + testRegex(".com URL with port and path", r, + "see secondlife.com:80/status", + "secondlife.com:80/status"); + + testRegex("www.*.com URL with port and path", r, + "see www.secondlife.com:80/status", + "www.secondlife.com:80/status"); + testRegex("invalid .com URL [1]", r, "..com", ""); diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp index a0336f6156..084cdd9561 100644 --- a/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -429,6 +429,7 @@ private: LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href"); message.setValue("uri", event.getStringValue()); message.setValue("target", event.getStringValue2()); + message.setValueU32("target_type", event.getLinkType()); sendMessage(message); } diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 0e1d5ca80b..8d1eeb7ee3 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -386,6 +386,7 @@ set(viewer_SOURCE_FILES llspatialpartition.cpp llspeakbutton.cpp llspeakers.cpp + llspeakingindicatormanager.cpp llsplitbutton.cpp llsprite.cpp llstartup.cpp @@ -891,6 +892,7 @@ set(viewer_HEADER_FILES llspatialpartition.h llspeakbutton.h llspeakers.h + llspeakingindicatormanager.h llsplitbutton.h llsprite.h llstartup.h @@ -1766,9 +1768,10 @@ if (LL_TESTS) llagentaccess.cpp lldateutil.cpp llmediadataclient.cpp - llviewerhelputil.cpp lllogininstance.cpp ) +# DISABLED TEST: llviewerhelputil.cpp /* hard to mock LLAgent dependency */ + ################################################## # DISABLING PRECOMPILED HEADERS USAGE FOR TESTS ################################################## diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 184606d495..9c4c8387a8 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3607,7 +3607,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>http://viewer-help.secondlife.com/[LANGUAGE]/[CHANNEL]/[VERSION]/[TOPIC]</string> + <string>http://viewer-help.secondlife.com/[LANGUAGE]/[CHANNEL]/[VERSION]/[TOPIC]/[DEBUG_MODE]</string> </map> <key>HomeSidePanelURL</key> <map> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 08eb134bc8..297bcfd1df 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -514,6 +514,8 @@ void LLAgent::resetView(BOOL reset_camera, BOOL change_camera) } setFocusOnAvatar(TRUE, ANIMATE); + + mCameraFOVZoomFactor = 0.f; } mHUDTargetZoom = 1.f; @@ -3584,7 +3586,7 @@ F32 LLAgent::calcCameraFOVZoomFactor() { return 0.f; } - else if (mFocusObject.notNull() && !mFocusObject->isAvatar()) + else if (mFocusObject.notNull() && !mFocusObject->isAvatar() && !mFocusOnAvatar) { // don't FOV zoom on mostly transparent objects LLVector3 focus_offset = mFocusObjectOffset; diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index c3deb602ee..40c9bb6afa 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -172,24 +172,6 @@ void LLAvatarActions::offerTeleport(const std::vector<LLUUID>& ids) return; handle_lure(ids); - - // Record the offer. - for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); it++) - { - LLUUID target_id = *it; - std::string target_name; - - gCacheName->getFullName(target_id, target_name); - - LLSD args; - args["TO_NAME"] = target_name; - - LLSD payload; - payload["from_id"] = target_id; - payload["SESSION_NAME"] = target_name; - payload["SUPPRESS_TOAST"] = true; - LLNotificationsUtil::add("TeleportOfferSent", args, payload); - } } // static diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 19e9e52ddf..6784e6693b 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -320,6 +320,11 @@ boost::signals2::connection LLAvatarList::setRefreshCompleteCallback(const commi return mRefreshCompleteSignal.connect(cb); } +boost::signals2::connection LLAvatarList::setItemDoubleClickCallback(const mouse_signal_t::slot_type& cb) +{ + return mItemDoubleClickSignal.connect(cb); +} + void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_online, EAddPosition pos) { LLAvatarListItem* item = new LLAvatarListItem(); @@ -333,6 +338,8 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is item->setShowProfileBtn(mShowProfileBtn); item->showSpeakingIndicator(mShowSpeakingIndicator); + item->setDoubleClickCallback(boost::bind(&LLAvatarList::onItemDoucleClicked, this, _1, _2, _3, _4)); + addItem(item, id, pos); } @@ -400,6 +407,11 @@ void LLAvatarList::updateLastInteractionTimes() } } +void LLAvatarList::onItemDoucleClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask) +{ + mItemDoubleClickSignal(ctrl, x, y, mask); +} + bool LLAvatarItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const { const LLAvatarListItem* avatar_item1 = dynamic_cast<const LLAvatarListItem*>(item1); diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index 0d2ce884ae..a58a562378 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -92,6 +92,8 @@ public: boost::signals2::connection setRefreshCompleteCallback(const commit_signal_t::slot_type& cb); + boost::signals2::connection setItemDoubleClickCallback(const mouse_signal_t::slot_type& cb); + protected: void refresh(); @@ -101,6 +103,7 @@ protected: std::vector<LLUUID>& vadded, std::vector<LLUUID>& vremoved); void updateLastInteractionTimes(); + void onItemDoucleClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask); private: @@ -120,6 +123,7 @@ private: LLAvatarListItem::ContextMenu* mContextMenu; commit_signal_t mRefreshCompleteSignal; + mouse_signal_t mItemDoubleClickSignal; }; /** Abstract comparator for avatar items */ diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index a2e17db3d8..66ab32f3e8 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -91,40 +91,25 @@ BOOL LLAvatarListItem::postBuild() mProfileBtn->setVisible(false); mProfileBtn->setClickedCallback(boost::bind(&LLAvatarListItem::onProfileBtnClick, this)); - // Remember avatar icon width including its padding from the name text box, - // so that we can hide and show the icon again later. if (!sStaticInitialized) { + // Remember children widths including their padding from the next sibling, + // so that we can hide and show them again later. initChildrenWidths(this); sStaticInitialized = true; } -/* - if(!p.buttons.profile) - { - delete mProfile; - mProfile = NULL; - - LLRect rect; - - rect.setLeftTopAndSize(mName->getRect().mLeft, mName->getRect().mTop, mName->getRect().getWidth() + 30, mName->getRect().getHeight()); - mName->setRect(rect); - - if(mLocator) - { - rect.setLeftTopAndSize(mLocator->getRect().mLeft + 30, mLocator->getRect().mTop, mLocator->getRect().getWidth(), mLocator->getRect().getHeight()); - mLocator->setRect(rect); - } + return TRUE; +} - if(mInfo) - { - rect.setLeftTopAndSize(mInfo->getRect().mLeft + 30, mInfo->getRect().mTop, mInfo->getRect().getWidth(), mInfo->getRect().getHeight()); - mInfo->setRect(rect); - } +S32 LLAvatarListItem::notifyParent(const LLSD& info) +{ + if (info.has("visibility_changed")) + { + updateChildren(); } -*/ - return TRUE; + return 0; } void LLAvatarListItem::onMouseEnter(S32 x, S32 y, MASK mask) @@ -246,8 +231,10 @@ void LLAvatarListItem::showSpeakingIndicator(bool visible) // Already done? Then do nothing. if (mSpeakingIndicator->getVisible() == (BOOL)visible) return; - mSpeakingIndicator->setVisible(visible); - updateChildren(); +// Disabled to not contradict with SpeakingIndicatorManager functionality. EXT-3976 +// probably this method should be totally removed. +// mSpeakingIndicator->setVisible(visible); +// updateChildren(); } void LLAvatarListItem::setAvatarIconVisible(bool visible) @@ -264,26 +251,6 @@ void LLAvatarListItem::setAvatarIconVisible(bool visible) void LLAvatarListItem::onInfoBtnClick() { LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", mAvatarId)); - - /* TODO fix positioning of inspector - localPointToScreen(mXPos, mYPos, &mXPos, &mYPos); - - - LLRect rect; - - // *TODO Vadim: rewrite this. "+= -" looks weird. - S32 delta = mYPos - inspector->getRect().getHeight(); - if(delta < 0) - { - mYPos += -delta; - } - - rect.setLeftTopAndSize(mXPos, mYPos, - inspector->getRect().getWidth(), inspector->getRect().getHeight()); - inspector->setRect(rect); - inspector->setFrontmost(true); - inspector->setVisible(true); - */ } void LLAvatarListItem::onProfileBtnClick() @@ -291,6 +258,21 @@ void LLAvatarListItem::onProfileBtnClick() LLAvatarActions::showProfile(mAvatarId); } +BOOL LLAvatarListItem::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + if(mInfoBtn->getRect().pointInRect(x, y)) + { + onInfoBtnClick(); + return TRUE; + } + if(mProfileBtn->getRect().pointInRect(x, y)) + { + onProfileBtnClick(); + return TRUE; + } + return LLPanel::handleDoubleClick(x, y, mask); +} + void LLAvatarListItem::setValue( const LLSD& value ) { if (!value.isMap()) return;; diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index 868ee546d4..479a4833cb 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -74,6 +74,11 @@ public: virtual ~LLAvatarListItem(); virtual BOOL postBuild(); + + /** + * Processes notification from speaker indicator to update children when indicator's visibility is changed. + */ + virtual S32 notifyParent(const LLSD& info); virtual void onMouseLeave(S32 x, S32 y, MASK mask); virtual void onMouseEnter(S32 x, S32 y, MASK mask); virtual void setValue(const LLSD& value); @@ -98,6 +103,8 @@ public: void onInfoBtnClick(); void onProfileBtnClick(); + /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + protected: /** * Contains indicator to show voice activity. diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index c0efb85b51..6317a6a392 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -724,13 +724,28 @@ void LLCallFloater::removeVoiceRemoveTimer(const LLUUID& voice_speaker_id) bool LLCallFloater::validateSpeaker(const LLUUID& speaker_id) { - if (mVoiceType != VC_LOCAL_CHAT) - return true; + bool is_valid = true; + switch (mVoiceType) + { + case VC_LOCAL_CHAT: + { + // A nearby chat speaker is considered valid it it's known to LLVoiceClient (i.e. has enabled voice). + std::vector<LLUUID> speakers; + get_voice_participants_uuids(speakers); + is_valid = std::find(speakers.begin(), speakers.end(), speaker_id) != speakers.end(); + } + break; + case VC_GROUP_CHAT: + // if participant had left this call before do not allow add her again. See EXT-4216. + // but if she Join she will be added into the list from the LLCallFloater::onChange() + is_valid = STATE_LEFT != getState(speaker_id); + break; + default: + // do nothing. required for Linux build + break; + } - // A nearby chat speaker is considered valid it it's known to LLVoiceClient (i.e. has enabled voice). - std::vector<LLUUID> speakers; - get_voice_participants_uuids(speakers); - return std::find(speakers.begin(), speakers.end(), speaker_id) != speakers.end(); + return is_valid; } void LLCallFloater::connectToChannel(LLVoiceChannel* channel) diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 9a1572364f..2fc83c7e54 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -499,24 +499,29 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_ style_params.font.name(font_name); style_params.font.size(font_size); style_params.font.style(input_append_params.font.style); - - //whether to show colon after a name in header copy/past and in plain text mode - bool show_colon = chat.mChatType != CHAT_TYPE_SHOUT && chat.mChatType != CHAT_TYPE_WHISPER; + + std::string prefix = chat.mText.substr(0, 4); //IRC styled /me messages. - bool irc_me = false; + bool irc_me = prefix == "/me " || prefix == "/me'"; - std::string prefix = chat.mText.substr(0, 4); - if (prefix == "/me " || prefix == "/me'") + // Delimiter after a name in header copy/past and in plain text mode + std::string delimiter = (chat.mChatType != CHAT_TYPE_SHOUT && chat.mChatType != CHAT_TYPE_WHISPER) + ? ": " + : " "; + + // Don't add any delimiter after name in irc styled messages + if (irc_me || chat.mChatStyle == CHAT_STYLE_IRC) { - irc_me = true; + delimiter = LLStringUtil::null; + style_params.font.style = "ITALIC"; } if (use_plain_text_chat_history) { mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getText().size() != 0, style_params); - if (utf8str_trim(chat.mFromName).size() != 0 && !irc_me) + if (utf8str_trim(chat.mFromName).size() != 0) { // Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text. if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() ) @@ -524,11 +529,11 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_ LLStyle::Params link_params(style_params); link_params.fillFrom(LLStyleMap::instance().lookupAgent(chat.mFromID)); // Convert the name to a hotlink and add to message. - mEditor->appendText(chat.mFromName + (show_colon ? ": " : " "), false, link_params); + mEditor->appendText(chat.mFromName + delimiter, false, link_params); } else { - mEditor->appendText(chat.mFromName + (show_colon ? ": " : " "), false, style_params); + mEditor->appendText(chat.mFromName + delimiter, false, style_params); } } } @@ -574,35 +579,22 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_ std::string header_text = "[" + chat.mTimeStr + "] "; if (utf8str_trim(chat.mFromName).size() != 0 && chat.mFromName != SYSTEM_FROM) - header_text += chat.mFromName + (show_colon ? ": " : " "); + header_text += chat.mFromName + delimiter; mEditor->appendWidget(p, header_text, false); mLastFromName = chat.mFromName; mLastFromID = chat.mFromID; mLastMessageTime = new_message_time; } - - if (irc_me) - { - style_params.font.style = "ITALIC"; - if (chat.mFromName.size() > 0) - mEditor->appendText(chat.mFromName, FALSE, style_params); + std::string message = irc_me ? chat.mText.substr(3) : chat.mText; + if ( message.size() > 0 && !LLStringOps::isSpace(message[message.size() - 1]) ) + { // Ensure that message ends with NewLine, to avoid losing of new lines // while copy/paste from text chat. See EXT-3263. - mEditor->appendText(chat.mText.substr(3) + NEW_LINE, FALSE, style_params); - } - else - { - std::string message(chat.mText); - if ( message.size() > 0 && !LLStringOps::isSpace(message[message.size() - 1]) ) - { - // Ensure that message ends with NewLine, to avoid losing of new lines - // while copy/paste from text chat. See EXT-3263. - message += NEW_LINE; - } - mEditor->appendText(message, FALSE, style_params); + message += NEW_LINE; } + mEditor->appendText(message, FALSE, style_params); mEditor->blockUndo(); // automatically scroll to end when receiving chat from myself diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index dc2e22f899..5cbe6f9670 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -540,6 +540,11 @@ void LLIMChiclet::toggleSpeakerControl() void LLIMChiclet::setCounter(S32 counter) { + if (mCounterCtrl->getCounter() == counter) + { + return; + } + mCounterCtrl->setCounter(counter); setShowCounter(counter); setShowNewMessagesIcon(counter); diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 4103ccf175..fd6a92c47a 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -508,14 +508,14 @@ void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y) if (dest) { - updateItemsOrder(mItems, mDragItemId, dest->getLandmarkId()); + LLInventoryModel::updateItemsOrder(mItems, mDragItemId, dest->getLandmarkId()); } else { mItems.push_back(gInventory.getItem(mDragItemId)); } - saveItemsOrder(mItems); + gInventory.saveItemsOrder(mItems); LLToggleableMenu* menu = (LLToggleableMenu*) mPopupMenuHandle.get(); @@ -1193,25 +1193,6 @@ BOOL LLFavoritesBarCtrl::needToSaveItemsOrder(const LLInventoryModel::item_array return result; } -void LLFavoritesBarCtrl::saveItemsOrder(LLInventoryModel::item_array_t& items) -{ - int sortField = 0; - - // current order is saved by setting incremental values (1, 2, 3, ...) for the sort field - for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) - { - LLViewerInventoryItem* item = *i; - - item->setSortField(++sortField); - item->setComplete(TRUE); - item->updateServer(FALSE); - - gInventory.updateItem(item); - } - - gInventory.notifyObservers(); -} - LLInventoryModel::item_array_t::iterator LLFavoritesBarCtrl::findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id) { LLInventoryModel::item_array_t::iterator result = items.end(); @@ -1228,15 +1209,6 @@ LLInventoryModel::item_array_t::iterator LLFavoritesBarCtrl::findItemByUUID(LLIn return result; } -void LLFavoritesBarCtrl::updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& srcItemId, const LLUUID& destItemId) -{ - LLViewerInventoryItem* srcItem = gInventory.getItem(srcItemId); - LLViewerInventoryItem* destItem = gInventory.getItem(destItemId); - - items.erase(findItemByUUID(items, srcItem->getUUID())); - items.insert(findItemByUUID(items, destItem->getUUID()), srcItem); -} - void LLFavoritesBarCtrl::insertBeforeItem(LLInventoryModel::item_array_t& items, const LLUUID& beforeItemId, LLViewerInventoryItem* insertedItem) { LLViewerInventoryItem* beforeItem = gInventory.getItem(beforeItemId); diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 9ac734baff..40dd551eef 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -126,16 +126,7 @@ private: // checks if the current order of the favorites items must be saved BOOL needToSaveItemsOrder(const LLInventoryModel::item_array_t& items); - // saves current order of the favorites items - void saveItemsOrder(LLInventoryModel::item_array_t& items); - - /* - * changes favorites items order by insertion of the item identified by srcItemId - * BEFORE the item identified by destItemId. both items must exist in items array. - */ - void updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& srcItemId, const LLUUID& destItemId); - - /* + /** * inserts an item identified by insertedItemId BEFORE an item identified by beforeItemId. * this function assumes that an item identified by insertedItemId doesn't exist in items array. */ diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index aa343b2f69..ef69f39ad2 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -269,7 +269,7 @@ LLSD LLFloaterAbout::getInfo() info["VIVOX_VERSION"] = gVoiceClient ? gVoiceClient->getAPIVersion() : LLTrans::getString("NotConnected"); // TODO: Implement media plugin version query - info["QT_WEBKIT_VERSION"] = "4.5.2 (version number hard-coded)"; + info["QT_WEBKIT_VERSION"] = "4.6 (version number hard-coded)"; if (gPacketsIn > 0) { diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index 5072bc8c82..de65c6f876 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -110,7 +110,7 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key) mCommitCallbackRegistrar.add("Gesture.Action.ToogleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this)); mCommitCallbackRegistrar.add("Gesture.Action.ShowPreview", boost::bind(&LLFloaterGesture::onClickEdit, this)); - mCommitCallbackRegistrar.add("Gesture.Action.CopyPast", boost::bind(&LLFloaterGesture::onCopyPastAction, this, _2)); + mCommitCallbackRegistrar.add("Gesture.Action.CopyPaste", boost::bind(&LLFloaterGesture::onCopyPasteAction, this, _2)); mCommitCallbackRegistrar.add("Gesture.Action.SaveToCOF", boost::bind(&LLFloaterGesture::addToCurrentOutFit, this)); mEnableCallbackRegistrar.add("Gesture.EnableAction", boost::bind(&LLFloaterGesture::isActionEnabled, this, _2)); @@ -245,6 +245,7 @@ void LLFloaterGesture::refreshAll() void LLFloaterGesture::buildGestureList() { + S32 scroll_pos = mGestureList->getScrollPos(); std::vector<LLUUID> selected_items; getSelectedIds(selected_items); LL_DEBUGS("Gesture")<< "Rebuilding gesture list "<< LL_ENDL; @@ -274,13 +275,14 @@ void LLFloaterGesture::buildGestureList() } } } + // attempt to preserve scroll position through re-builds - // since we do re-build any time anything dirties + // since we do re-build whenever something gets dirty for(std::vector<LLUUID>::iterator it = selected_items.begin(); it != selected_items.end(); it++) { mGestureList->selectByID(*it); } - mGestureList->scrollToShowSelected(); + mGestureList->setScrollPos(scroll_pos); } void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gesture,LLCtrlListInterface * list ) @@ -415,7 +417,7 @@ void LLFloaterGesture::onClickPlay() LL_DEBUGS("Gesture")<<" Trying to play gesture id: "<< item_id <<LL_ENDL; if(!LLGestureManager::instance().isGestureActive(item_id)) { - // we need to inform server about gesture activating to be consistent with LLPreviewGesture and LLGestureComboBox. + // we need to inform server about gesture activating to be consistent with LLPreviewGesture and LLGestureComboList. BOOL inform_server = TRUE; BOOL deactivate_similar = FALSE; LLGestureManager::instance().setGestureLoadedCallback(item_id, boost::bind(&LLFloaterGesture::playGesture, this, item_id)); @@ -475,7 +477,7 @@ void LLFloaterGesture::onActivateBtnClick() } } -void LLFloaterGesture::onCopyPastAction(const LLSD& command) +void LLFloaterGesture::onCopyPasteAction(const LLSD& command) { std::string command_name = command.asString(); // since we select this comman inventory item had already arrived . diff --git a/indra/newview/llfloatergesture.h b/indra/newview/llfloatergesture.h index 14e132900d..629d77b949 100644 --- a/indra/newview/llfloatergesture.h +++ b/indra/newview/llfloatergesture.h @@ -99,7 +99,7 @@ private: void onClickPlay(); void onClickNew(); void onCommitList(); - void onCopyPastAction(const LLSD& command); + void onCopyPasteAction(const LLSD& command); void onDeleteSelected(); LLUUID mSelectedID; diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index df7aa9eabf..82293b4aa0 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -417,6 +417,16 @@ BOOL LLGestureManager::isGesturePlaying(const LLUUID& item_id) return gesture->mPlaying; } +BOOL LLGestureManager::isGesturePlaying(LLMultiGesture* gesture) +{ + if(!gesture) + { + return FALSE; + } + + return gesture->mPlaying; +} + void LLGestureManager::replaceGesture(const LLUUID& item_id, LLMultiGesture* new_gesture, const LLUUID& asset_id) { const LLUUID& base_item_id = get_linked_uuid(item_id); diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h index e80eea9ae9..c562587c6f 100644 --- a/indra/newview/llgesturemgr.h +++ b/indra/newview/llgesturemgr.h @@ -103,6 +103,8 @@ public: BOOL isGesturePlaying(const LLUUID& item_id); + BOOL isGesturePlaying(LLMultiGesture* gesture); + const item_map_t& getActiveGestures() const { return mActive; } // Force a gesture to be played, for example, if it is being // previewed. diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp index 0139d76f93..3ca8fa2f56 100644 --- a/indra/newview/llinspecttoast.cpp +++ b/indra/newview/llinspecttoast.cpp @@ -1,6 +1,6 @@ /** - * @file lltoast.h - * @brief This class implements a placeholder for any notification panel. + * @file llinspecttoast.cpp + * @brief Toast inspector implementation. * * $LicenseInfo:firstyear=2003&license=viewergpl$ * @@ -37,6 +37,7 @@ #include "llfloaterreg.h" #include "llscreenchannel.h" #include "llchannelmanager.h" +#include "lltransientfloatermgr.h" using namespace LLNotificationsUI; @@ -70,10 +71,12 @@ LLInspectToast::LLInspectToast(const LLSD& notification_id) : llwarns << "Could not get requested screen channel." << llendl; return; } + + LLTransientFloaterMgr::getInstance()->addControlView(this); } LLInspectToast::~LLInspectToast() { - + LLTransientFloaterMgr::getInstance()->removeControlView(this); } void LLInspectToast::onOpen(const LLSD& notification_id) diff --git a/indra/newview/llinspecttoast.h b/indra/newview/llinspecttoast.h index c4403d6196..ff547154b8 100644 --- a/indra/newview/llinspecttoast.h +++ b/indra/newview/llinspecttoast.h @@ -1,6 +1,5 @@ /** - * @file lltoast.h - * @brief This class implements a placeholder for any notification panel. + * @file llinspecttoast.h * * $LicenseInfo:firstyear=2003&license=viewergpl$ * diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 20d7f5214b..e9176da715 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2448,7 +2448,7 @@ void LLFolderBridge::folderOptionsMenu() const LLInventoryCategory* category = model->getCategory(mUUID); LLFolderType::EType type = category->getPreferredType(); - const bool is_default_folder = category && LLFolderType::lookupIsProtectedType(type); + const bool is_system_folder = category && LLFolderType::lookupIsProtectedType(type); // BAP change once we're no longer treating regular categories as ensembles. const bool is_ensemble = category && (type == LLFolderType::FT_NONE || LLFolderType::lookupIsEnsembleType(type)); @@ -2462,8 +2462,8 @@ void LLFolderBridge::folderOptionsMenu() mItems.push_back("Delete"); } - // Only enable calling-card related options for non-default folders. - if (!is_sidepanel && !is_default_folder) + // Only enable calling-card related options for non-system folders. + if (!is_sidepanel && !is_system_folder) { LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD); if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard)) @@ -2497,10 +2497,14 @@ void LLFolderBridge::folderOptionsMenu() mItems.push_back(std::string("Folder Wearables Separator")); } - // Only enable add/replace outfit for non-default folders. - if (!is_default_folder) + // Only enable add/replace outfit for non-system folders. + if (!is_system_folder) { - mItems.push_back(std::string("Add To Outfit")); + // Adding an outfit onto another (versus replacing) doesn't make sense. + if (type != LLFolderType::FT_OUTFIT) + { + mItems.push_back(std::string("Add To Outfit")); + } mItems.push_back(std::string("Replace Outfit")); } if (is_ensemble) @@ -2927,50 +2931,6 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response return false; } -/* -Next functions intended to reorder items in the inventory folder and save order on server -Is now used for Favorites folder. - -*TODO: refactoring is needed with Favorites Bar functionality. Probably should be moved in LLInventoryModel -*/ -void saveItemsOrder(LLInventoryModel::item_array_t& items) -{ - int sortField = 0; - - // current order is saved by setting incremental values (1, 2, 3, ...) for the sort field - for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) - { - LLViewerInventoryItem* item = *i; - - item->setSortField(++sortField); - item->setComplete(TRUE); - item->updateServer(FALSE); - - gInventory.updateItem(item); - - // Tell the parent folder to refresh its sort order. - gInventory.addChangedMask(LLInventoryObserver::SORT, item->getParentUUID()); - } - - gInventory.notifyObservers(); -} - -LLInventoryModel::item_array_t::iterator findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id) -{ - LLInventoryModel::item_array_t::iterator result = items.end(); - - for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) - { - if ((*i)->getUUID() == id) - { - result = i; - break; - } - } - - return result; -} - // See also LLInventorySort where landmarks in the Favorites folder are sorted. class LLViewerInventoryItemSort { @@ -2992,15 +2952,6 @@ void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items) std::sort(items.begin(), items.end(), sort_functor); } -void updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& srcItemId, const LLUUID& destItemId) -{ - LLViewerInventoryItem* srcItem = gInventory.getItem(srcItemId); - LLViewerInventoryItem* destItem = gInventory.getItem(destItemId); - - items.erase(findItemByUUID(items, srcItem->getUUID())); - items.insert(findItemByUUID(items, destItem->getUUID()), srcItem); -} - BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop) { @@ -3099,9 +3050,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, rearrange_item_order_by_sort_field(items); // update order - updateItemsOrder(items, srcItemId, destItemId); + LLInventoryModel::updateItemsOrder(items, srcItemId, destItemId); - saveItemsOrder(items); + gInventory.saveItemsOrder(items); } } else if (favorites_id == mUUID) // if target is the favorites folder we use copy diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 711114173c..ef18386e57 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1994,21 +1994,23 @@ void LLInventoryModel::accountForUpdate(const LLCategoryUpdate& update) const descendents_actual += update.mDescendentDelta; cat->setDescendentCount(descendents_actual); cat->setVersion(++version); - llinfos << "accounted: '" << cat->getName() << "' " - << version << " with " << descendents_actual - << " descendents." << llendl; + lldebugs << "accounted: '" << cat->getName() << "' " + << version << " with " << descendents_actual + << " descendents." << llendl; } } if(!accounted) { - lldebugs << "No accounting for: '" << cat->getName() << "' " + // Error condition, this means that the category did not register that + // it got new descendents (perhaps because it is still being loaded) + // which means its descendent count will be wrong. + llwarns << "Accounting failed for '" << cat->getName() << "' version:" << version << llendl; } } else { - llwarns << "No category found for update " << update.mCategoryID - << llendl; + llwarns << "No category found for update " << update.mCategoryID << llendl; } } @@ -3620,6 +3622,57 @@ BOOL LLInventoryModel::getIsFirstTimeInViewer2() return sFirstTimeInViewer2; } +static LLInventoryModel::item_array_t::iterator find_item_iter_by_uuid(LLInventoryModel::item_array_t& items, const LLUUID& id) +{ + LLInventoryModel::item_array_t::iterator result = items.end(); + + for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i) + { + if ((*i)->getUUID() == id) + { + result = i; + break; + } + } + + return result; +} + +// static +void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& src_item_id, const LLUUID& dest_item_id) +{ + LLInventoryModel::item_array_t::iterator it_src = find_item_iter_by_uuid(items, src_item_id); + LLInventoryModel::item_array_t::iterator it_dest = find_item_iter_by_uuid(items, dest_item_id); + + if (it_src == items.end() || it_dest == items.end()) return; + + LLViewerInventoryItem* src_item = *it_src; + items.erase(it_src); + items.insert(it_dest, src_item); +} + +void LLInventoryModel::saveItemsOrder(const LLInventoryModel::item_array_t& items) +{ + int sortField = 0; + + // current order is saved by setting incremental values (1, 2, 3, ...) for the sort field + for (item_array_t::const_iterator i = items.begin(); i != items.end(); ++i) + { + LLViewerInventoryItem* item = *i; + + item->setSortField(++sortField); + item->setComplete(TRUE); + item->updateServer(FALSE); + + updateItem(item); + + // Tell the parent folder to refresh its sort order. + addChangedMask(LLInventoryObserver::SORT, item->getParentUUID()); + } + + notifyObservers(); +} + //---------------------------------------------------------------------------- // *NOTE: DEBUG functionality diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 39377b4ae2..e8698c0759 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -384,6 +384,30 @@ public: void setLibraryOwnerID(const LLUUID& id); void setLibraryRootFolderID(const LLUUID& id); + + /** + * Changes items order by insertion of the item identified by src_item_id + * BEFORE the item identified by dest_item_id. Both items must exist in items array. + * + * Sorting is stored after method is finished. Only src_item_id is moved before dest_item_id. + * + * @param[in, out] items - vector with items to be updated. It should be sorted in a right way + * before calling this method. + * @param src_item_id - LLUUID of inventory item to be moved in new position + * @param dest_item_id - LLUUID of inventory item before which source item should be placed. + */ + static void updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& src_item_id, const LLUUID& dest_item_id); + + /** + * Saves current order of the passed items using inventory item sort field. + * + * It reset items' sort fields and saves them on server. + * Is used to save order for Favorites folder. + * + * @param[in] items vector of items in order to be saved. + */ + void saveItemsOrder(const LLInventoryModel::item_array_t& items); + protected: // Internal methods which add inventory and make sure that all of diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 2d9ea21b5f..2fb8aea4e9 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -311,10 +311,10 @@ bool LLInventoryFetchDescendentsObserver::isEverythingComplete() const bool LLInventoryFetchDescendentsObserver::isComplete(LLViewerInventoryCategory* cat) { - S32 version = cat->getVersion(); - S32 descendents = cat->getDescendentCount(); - if((LLViewerInventoryCategory::VERSION_UNKNOWN == version) - || (LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN == descendents)) + const S32 version = cat->getVersion(); + const S32 expected_num_descendents = cat->getDescendentCount(); + if ((version == LLViewerInventoryCategory::VERSION_UNKNOWN) || + (expected_num_descendents == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)) { return false; } @@ -325,15 +325,28 @@ bool LLInventoryFetchDescendentsObserver::isComplete(LLViewerInventoryCategory* gInventory.getDirectDescendentsOf(cat->getUUID(), cats, items); if(!cats || !items) { - // bit of a hack - pretend we're done if they are gone or - // incomplete. should never know, but it would suck if this - // kept tight looping because of a corrupt memory state. + llwarns << "Category '" << cat->getName() << "' descendents corrupted, fetch failed." << llendl; + // NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean + // that the cat just doesn't have any items or subfolders). + // Unrecoverable, so just return done so that this observer can be cleared + // from memory. return true; } - S32 known = cats->count() + items->count(); - if(descendents == known) + const S32 current_num_known_descendents = cats->count() + items->count(); + + // Got the number of descendents that we were expecting, so we're done. + if (current_num_known_descendents == expected_num_descendents) + { + return true; + } + + // Error condition, but recoverable. This happens if something was added to the + // category before it was initialized, so accountForUpdate didn't update descendent + // count and thus the category thinks it has fewer descendents than it actually has. + if (current_num_known_descendents >= expected_num_descendents) { - // hey - we're done. + llwarns << "Category '" << cat->getName() << "' expected descendentcount:" << expected_num_descendents << " descendents but got descendentcount:" << current_num_known_descendents << llendl; + cat->setDescendentCount(current_num_known_descendents); return true; } return false; @@ -352,7 +365,7 @@ void LLInventoryFetchComboObserver::changed(U32 mask) continue; } if(item->isComplete()) - { + { mCompleteItems.push_back(*it); it = mIncompleteItems.erase(it); continue; diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 6b0f9b709d..87ebce1d34 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -84,7 +84,6 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) : mHomePageUrl( "" ), mIgnoreUIScale( true ), mAlwaysRefresh( false ), - mExternalUrl( "" ), mMediaSource( 0 ), mTakeFocusOnClick( true ), mCurrentNavUrl( "" ), @@ -877,9 +876,27 @@ bool LLMediaCtrl::onClickLinkExternalTarget(const LLSD& notification, const LLSD S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if ( 0 == option ) { - // open in external browser because we don't support - // creation of our own secondary browser windows - LLWeb::loadURLExternal( notification["payload"]["external_url"].asString() ); + LLSD payload = notification["payload"]; + std::string url = payload["url"].asString(); + S32 target_type = payload["target_type"].asInteger(); + + switch (target_type) + { + case LLPluginClassMedia::TARGET_EXTERNAL: + // load target in an external browser + LLWeb::loadURLExternal(url); + break; + + case LLPluginClassMedia::TARGET_BLANK: + // load target in the user's preferred browser + LLWeb::loadURL(url); + break; + + default: + // unsupported link target - shouldn't happen + LL_WARNS("LinkTarget") << "Unsupported link target type" << LL_ENDL; + break; + } } return false; } @@ -993,20 +1010,18 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) void LLMediaCtrl::onClickLinkHref( LLPluginClassMedia* self ) { // retrieve the event parameters - std::string target = self->getClickTarget(); std::string url = self->getClickURL(); + U32 target_type = self->getClickTargetType(); - // if there is a value for the target - if ( !target.empty() ) + // is there is a target specified for the link? + if (target_type == LLPluginClassMedia::TARGET_EXTERNAL || + target_type == LLPluginClassMedia::TARGET_BLANK) { - if ( target == "_external" ) - { - mExternalUrl = url; - LLSD payload; - payload["external_url"] = mExternalUrl; - LLNotificationsUtil::add( "WebLaunchExternalTarget", LLSD(), payload, onClickLinkExternalTarget); - return; - } + LLSD payload; + payload["url"] = url; + payload["target_type"] = LLSD::Integer(target_type); + LLNotificationsUtil::add( "WebLaunchExternalTarget", LLSD(), payload, onClickLinkExternalTarget); + return; } const std::string protocol1( "http://" ); diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 8f9e6e7179..b0aca3cfa4 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -182,7 +182,6 @@ public: bool mOpenLinksInInternalBrowser; bool mTrusted; std::string mHomePageUrl; - std::string mExternalUrl; std::string mCurrentNavUrl; bool mIgnoreUIScale; bool mAlwaysRefresh; diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index fc0e51b76d..a7c1e73328 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -179,27 +179,7 @@ void LLNearbyChat::addMessage(const LLChat& chat,bool archive) if (!chat.mMuted) { tmp_chat.mFromName = chat.mFromName; - - if (chat.mChatStyle == CHAT_STYLE_IRC) - { - LLColor4 txt_color = LLUIColorTable::instance().getColor("White"); - LLViewerChat::getChatColor(chat,txt_color); - LLFontGL* fontp = LLViewerChat::getChatFont(); - std::string font_name = LLFontGL::nameFromFont(fontp); - std::string font_size = LLFontGL::sizeFromFont(fontp); - LLStyle::Params append_style_params; - append_style_params.color(txt_color); - append_style_params.readonly_color(txt_color); - append_style_params.font.name(font_name); - append_style_params.font.size(font_size); - append_style_params.font.style = "ITALIC"; - - mChatHistory->appendMessage(chat, use_plain_text_chat_history, append_style_params); - } - else - { - mChatHistory->appendMessage(chat, use_plain_text_chat_history); - } + mChatHistory->appendMessage(chat, use_plain_text_chat_history); } if(archive) diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 75c2fb07d1..6cf8bcb417 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -48,13 +48,16 @@ #include "llcommandhandler.h" #include "llviewercontrol.h" #include "llnavigationbar.h" +#include "llwindow.h" +#include "llviewerwindow.h" +#include "llrootview.h" S32 LLNearbyChatBar::sLastSpecialChatChannel = 0; // legacy callback glue void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); -static LLDefaultChildRegistry::Register<LLGestureComboBox> r("gesture_combo_box"); +static LLDefaultChildRegistry::Register<LLGestureComboList> r("gesture_combo_list"); struct LLChatTypeTrigger { std::string name; @@ -66,13 +69,42 @@ static LLChatTypeTrigger sChatTypeTriggers[] = { { "/shout" , CHAT_TYPE_SHOUT} }; -LLGestureComboBox::LLGestureComboBox(const LLGestureComboBox::Params& p) - : LLComboBox(p) - , mGestureLabelTimer() +LLGestureComboList::Params::Params() +: combo_button("combo_button"), + combo_list("combo_list") +{ +} + +LLGestureComboList::LLGestureComboList(const LLGestureComboList::Params& p) +: LLUICtrl(p) , mLabel(p.label) , mViewAllItemIndex(0) { - setCommitCallback(boost::bind(&LLGestureComboBox::onCommitGesture, this)); + LLButton::Params button_params = p.combo_button; + button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM|FOLLOWS_RIGHT); + + mButton = LLUICtrlFactory::create<LLButton>(button_params); + mButton->reshape(getRect().getWidth(),getRect().getHeight()); + mButton->setCommitCallback(boost::bind(&LLGestureComboList::onButtonCommit, this)); + + addChild(mButton); + + LLScrollListCtrl::Params params = p.combo_list; + params.name("GestureComboList"); + params.commit_callback.function(boost::bind(&LLGestureComboList::onItemSelected, this, _2)); + params.visible(false); + params.commit_on_keyboard_movement(false); + + mList = LLUICtrlFactory::create<LLScrollListCtrl>(params); + + // *HACK: adding list as a child to NonSideTrayView to make it fully visible without + // making it top control (because it would cause problems). + gViewerWindow->getNonSideTrayView()->addChild(mList); + mList->setVisible(FALSE); + + //****************************Gesture Part********************************/ + + setCommitCallback(boost::bind(&LLGestureComboList::onCommitGesture, this)); // now register us as observer since we have a place to put the results LLGestureManager::instance().addObserver(this); @@ -80,26 +112,139 @@ LLGestureComboBox::LLGestureComboBox(const LLGestureComboBox::Params& p) // refresh list from current active gestures refreshGestures(); - // This forces using of halign from xml, since LLComboBox - // sets it to LLFontGL::LEFT, if text entry is disabled - mButton->setHAlign(p.drop_down_button.font_halign); + setFocusLostCallback(boost::bind(&LLGestureComboList::hideList, this)); +} + +BOOL LLGestureComboList::handleKey(KEY key, MASK mask, BOOL called_from_parent) +{ + BOOL handled = FALSE; + + if (key == KEY_ESCAPE && mask == MASK_NONE ) + { + hideList(); + handled = TRUE; + } + else + { + handled = mList->handleKey(key, mask, called_from_parent); + } - // Pressing Gesture button by SPACE/ENTER key should open gestures list - mButton->setCommitCallback(boost::bind(&LLComboBox::onButtonMouseDown, this)); + return handled; } -LLGestureComboBox::~LLGestureComboBox() +void LLGestureComboList::showList() { - LLGestureManager::instance().removeObserver(this); + LLRect rect = mList->getRect(); + LLRect screen; + mButton->localRectToScreen(getRect(), &screen); + + // Calculating amount of space between the navigation bar and gestures combo + LLNavigationBar* nb = LLNavigationBar::getInstance(); + + S32 x, nb_bottom; + nb->localPointToScreen(0, 0, &x, &nb_bottom); + + S32 max_height = nb_bottom - screen.mTop; + mList->calcColumnWidths(); + rect.setOriginAndSize(screen.mLeft, screen.mTop, llmax(mList->getMaxContentWidth(),mButton->getRect().getWidth()), max_height); + + mList->setRect(rect); + mList->fitContents( llmax(mList->getMaxContentWidth(),mButton->getRect().getWidth()), max_height); + + gFocusMgr.setKeyboardFocus(this); + + // Show the list and push the button down + mButton->setToggleState(TRUE); + mList->setVisible(TRUE); +} + +void LLGestureComboList::onButtonCommit() +{ + if (!mList->getVisible()) + { + // highlight the last selected item from the original selection before potentially selecting a new item + // as visual cue to original value of combo box + LLScrollListItem* last_selected_item = mList->getLastSelectedItem(); + if (last_selected_item) + { + mList->mouseOverHighlightNthItem(mList->getItemIndex(last_selected_item)); + } + + if (mList->getItemCount() != 0) + { + showList(); + } + } + else + { + hideList(); + } +} + +void LLGestureComboList::hideList() +{ + if (mList->getVisible()) + { + mButton->setToggleState(FALSE); + mList->setVisible(FALSE); + mList->mouseOverHighlightNthItem(-1); + gFocusMgr.setKeyboardFocus(NULL); + } +} + +S32 LLGestureComboList::getCurrentIndex() const +{ + LLScrollListItem* item = mList->getFirstSelected(); + if( item ) + { + return mList->getItemIndex( item ); + } + return -1; } -void LLGestureComboBox::refreshGestures() +void LLGestureComboList::onItemSelected(const LLSD& data) +{ + const std::string name = mList->getSelectedItemLabel(); + + S32 cur_id = getCurrentIndex(); + mLastSelectedIndex = cur_id; + if (cur_id != mList->getItemCount()-1 && cur_id != -1) + { + mButton->setLabel(name); + } + + // hiding the list reasserts the old value stored in the text editor/dropdown button + hideList(); + + // commit does the reverse, asserting the value in the list + onCommit(); +} + +void LLGestureComboList::sortByName(bool ascending) +{ + mList->sortOnce(0, ascending); +} + +LLSD LLGestureComboList::getValue() const +{ + LLScrollListItem* item = mList->getFirstSelected(); + if( item ) + { + return item->getValue(); + } + else + { + return LLSD(); + } +} + +void LLGestureComboList::refreshGestures() { //store current selection so we can maintain it LLSD cur_gesture = getValue(); - selectFirstItem(); - // clear - clearRows(); + + mList->selectFirstItem(); + mList->clearRows(); mGestures.clear(); LLGestureManager::item_map_t::const_iterator it; @@ -110,7 +255,7 @@ void LLGestureComboBox::refreshGestures() LLMultiGesture* gesture = (*it).second; if (gesture) { - addSimpleElement(gesture->mName, ADD_BOTTOM, LLSD(idx)); + mList->addSimpleElement(gesture->mName, ADD_BOTTOM, LLSD(idx)); mGestures.push_back(gesture); idx++; } @@ -120,23 +265,42 @@ void LLGestureComboBox::refreshGestures() // store index followed by the last added Gesture and add View All item at bottom mViewAllItemIndex = idx; - addSimpleElement(LLTrans::getString("ViewAllGestures"), ADD_BOTTOM, LLSD(mViewAllItemIndex)); + + mList->addSimpleElement(LLTrans::getString("ViewAllGestures"), ADD_BOTTOM, LLSD(mViewAllItemIndex)); // Insert label after sorting, at top, with separator below it - addSeparator(ADD_TOP); - addSimpleElement(mLabel, ADD_TOP); + mList->addSeparator(ADD_TOP); + mList->addSimpleElement(mLabel, ADD_TOP); if (cur_gesture.isDefined()) { - selectByValue(cur_gesture); + mList->selectByValue(cur_gesture); + } else { - selectFirstItem(); + mList->selectFirstItem(); + } + + LLCtrlListInterface* gestures = getListInterface(); + LLMultiGesture* gesture = NULL; + + if (gestures) + { + S32 index = gestures->getSelectedValue().asInteger(); + if(index > 0) + gesture = mGestures.at(index); } + + if(gesture && LLGestureManager::instance().isGesturePlaying(gesture)) + { + return; + } + + mButton->setLabel(mLabel); } -void LLGestureComboBox::onCommitGesture() +void LLGestureComboList::onCommitGesture() { LLCtrlListInterface* gestures = getListInterface(); if (gestures) @@ -167,50 +331,11 @@ void LLGestureComboBox::onCommitGesture() } } } - - mGestureLabelTimer.start(); - // free focus back to chat bar - setFocus(FALSE); } -//virtual -void LLGestureComboBox::draw() +LLGestureComboList::~LLGestureComboList() { - // HACK: Leave the name of the gesture in place for a few seconds. - const F32 SHOW_GESTURE_NAME_TIME = 2.f; - if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME) - { - LLCtrlListInterface* gestures = getListInterface(); - if (gestures) gestures->selectFirstItem(); - mGestureLabelTimer.stop(); - } - - LLComboBox::draw(); -} - -//virtual -void LLGestureComboBox::showList() -{ - LLComboBox::showList(); - - // Calculating amount of space between the navigation bar and gestures combo - LLNavigationBar* nb = LLNavigationBar::getInstance(); - S32 x, nb_bottom; - nb->localPointToScreen(0, 0, &x, &nb_bottom); - - S32 list_bottom; - mList->localPointToScreen(0, 0, &x, &list_bottom); - - S32 max_height = nb_bottom - list_bottom; - - LLRect rect = mList->getRect(); - // List overlapped navigation bar, downsize it - if (rect.getHeight() > max_height) - { - rect.setOriginAndSize(rect.mLeft, rect.mBottom, rect.getWidth(), max_height); - mList->setRect(rect); - mList->reshape(rect.getWidth(), rect.getHeight()); - } + LLGestureManager::instance().removeObserver(this); } LLNearbyChatBar::LLNearbyChatBar() diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index 224118e088..d9a7403611 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -42,33 +42,52 @@ #include "llspeakers.h" -class LLGestureComboBox - : public LLComboBox - , public LLGestureManagerObserver +class LLGestureComboList + : public LLGestureManagerObserver + , public LLUICtrl { public: - struct Params : public LLInitParam::Block<Params, LLComboBox::Params> { }; + struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> + { + Optional<LLButton::Params> combo_button; + Optional<LLScrollListCtrl::Params> combo_list; + + Params(); + }; + protected: - LLGestureComboBox(const Params&); + friend class LLUICtrlFactory; + LLGestureComboList(const Params&); + std::vector<LLMultiGesture*> mGestures; + std::string mLabel; + LLSD::Integer mViewAllItemIndex; + public: - ~LLGestureComboBox(); + ~LLGestureComboList(); + + LLCtrlListInterface* getListInterface() { return (LLCtrlListInterface*)mList; }; + virtual void showList(); + virtual void hideList(); + virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); + + S32 getCurrentIndex() const; + void onItemSelected(const LLSD& data); + void sortByName(bool ascending = true); void refreshGestures(); void onCommitGesture(); - virtual void draw(); + void onButtonCommit(); + virtual LLSD getValue() const; // LLGestureManagerObserver trigger virtual void changed() { refreshGestures(); } -protected: - - virtual void showList(); +private: - LLFrameTimer mGestureLabelTimer; - std::vector<LLMultiGesture*> mGestures; - std::string mLabel; - LLSD::Integer mViewAllItemIndex; + LLButton* mButton; + LLScrollListCtrl* mList; + S32 mLastSelectedIndex; }; class LLNearbyChatBar diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index 9e13a626b4..96442fafcc 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -180,6 +180,11 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification) if(panel && panel->messageID() == fromID && panel->canAddText()) { + if (CHAT_STYLE_IRC == notification["chat_style"].asInteger()) + { + notification["message"] = notification["from"].asString() + notification["message"].asString(); + } + panel->addMessage(notification); toast->reshapeToPanel(); toast->resetTimer(); @@ -302,7 +307,6 @@ LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& i channel->setCreatePanelCallback(callback); mChannel = LLChannelManager::getInstance()->addChannel(channel); - mChannel->setOverflowFormatString("You have %d unread nearby chat messages"); } LLNearbyChatHandler::~LLNearbyChatHandler() @@ -332,25 +336,22 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg) LLChat& tmp_chat = const_cast<LLChat&>(chat_msg); - if (tmp_chat.mChatStyle == CHAT_STYLE_IRC) - { - if(!tmp_chat.mFromName.empty()) - tmp_chat.mText = tmp_chat.mFromName + tmp_chat.mText.substr(3); - else - tmp_chat.mText = tmp_chat.mText.substr(3); - } - + LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD()); { //sometimes its usefull to have no name at all... //if(tmp_chat.mFromName.empty() && tmp_chat.mFromID!= LLUUID::null) // tmp_chat.mFromName = tmp_chat.mFromID.asString(); } - - LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD()); nearby_chat->addMessage(chat_msg); if(nearby_chat->getVisible()) return;//no need in toast if chat is visible - + + // Handle irc styled messages for toast panel + if (tmp_chat.mChatStyle == CHAT_STYLE_IRC) + { + tmp_chat.mText = tmp_chat.mText.substr(3); + } + // arrange a channel on a screen if(!mChannel->getVisible()) { diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp index 63803469dd..f816dc589d 100644 --- a/indra/newview/lloutputmonitorctrl.cpp +++ b/indra/newview/lloutputmonitorctrl.cpp @@ -77,7 +77,9 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p) mImageLevel3(p.image_level_3), mAutoUpdate(p.auto_update), mSpeakerId(p.speaker_id), - mIsAgentControl(false) + mIsAgentControl(false), + mIsSwitchDirty(false), + mShouldSwitchOn(false) { //static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange); //static LLUIColor output_monitor_overdriven_color = LLUIColorTable::instance().getColor("OutputMonitorOverdrivenColor", LLColor4::red); @@ -108,6 +110,7 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p) LLOutputMonitorCtrl::~LLOutputMonitorCtrl() { LLMuteList::getInstance()->removeObserver(this); + LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this); } void LLOutputMonitorCtrl::setPower(F32 val) @@ -117,6 +120,26 @@ void LLOutputMonitorCtrl::setPower(F32 val) void LLOutputMonitorCtrl::draw() { + // see also switchIndicator() + if (mIsSwitchDirty) + { + mIsSwitchDirty = false; + if (mShouldSwitchOn) + { + // just notify parent visibility may have changed + notifyParentVisibilityChanged(); + } + else + { + // make itself invisible and notify parent about this + setVisible(FALSE); + notifyParentVisibilityChanged(); + + // no needs to render for invisible element + return; + } + } + // Copied from llmediaremotectrl.cpp // *TODO: Give the LLOutputMonitorCtrl an agent-id to monitor, then // call directly into gVoiceClient to ask if that agent-id is muted, is @@ -229,6 +252,7 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id) if (speaker_id.isNull() || speaker_id == mSpeakerId) return; mSpeakerId = speaker_id; + LLSpeakingIndicatorManager::registerSpeakingIndicator(mSpeakerId, this); //mute management if (mAutoUpdate) @@ -251,3 +275,42 @@ void LLOutputMonitorCtrl::onChange() // check only blocking on voice. EXT-3542 setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat)); } + +// virtual +void LLOutputMonitorCtrl::switchIndicator(bool switch_on) +{ + // ensure indicator is visible in case it is not in visible chain + // to be called when parent became visible next time to notify parent that visibility is changed. + setVisible(TRUE); + + // if parent is in visible chain apply switch_on state and notify it immediately + if (getParent() && getParent()->isInVisibleChain()) + { + LL_DEBUGS("SpeakingIndicator") << "Indicator is in visible chain, notifying parent: " << mSpeakerId << LL_ENDL; + setVisible((BOOL)switch_on); + notifyParentVisibilityChanged(); + } + + // otherwise remember necessary state and mark itself as dirty. + // State will be applied i next draw when parents chain became visible. + else + { + LL_DEBUGS("SpeakingIndicator") << "Indicator is not in visible chain, parent won't be notified: " << mSpeakerId << LL_ENDL; + mIsSwitchDirty = true; + mShouldSwitchOn = switch_on; + } +} + +////////////////////////////////////////////////////////////////////////// +// PRIVATE SECTION +////////////////////////////////////////////////////////////////////////// +void LLOutputMonitorCtrl::notifyParentVisibilityChanged() +{ + LL_DEBUGS("SpeakingIndicator") << "Notify parent that visibility was changed: " << mSpeakerId << " ,new_visibility: " << getVisible() << LL_ENDL; + + LLSD params = LLSD().with("visibility_changed", getVisible()); + + notifyParent(params); +} + +// EOF diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h index 85ea552a57..2bbfa251e9 100644 --- a/indra/newview/lloutputmonitorctrl.h +++ b/indra/newview/lloutputmonitorctrl.h @@ -36,6 +36,7 @@ #include "v4color.h" #include "llview.h" #include "llmutelist.h" +#include "llspeakingindicatormanager.h" class LLTextBox; class LLUICtrlFactory; @@ -45,7 +46,7 @@ class LLUICtrlFactory; // class LLOutputMonitorCtrl -: public LLView, LLMuteListObserver +: public LLView, public LLSpeakingIndicator, LLMuteListObserver { public: struct Params : public LLInitParam::Block<Params, LLView::Params> @@ -90,7 +91,29 @@ public: //called by mute list virtual void onChange(); + /** + * Implementation of LLSpeakingIndicator interface. + * Behavior is implemented via changing visibility. + * + * If instance is in visible chain now (all parents are visible) it changes visibility + * and notify parent about this. + * + * Otherwise it marks an instance as dirty and stores necessary visibility. + * It will be applied in next draw and parent will be notified. + */ + virtual void switchIndicator(bool switch_on); + private: + + /** + * Notifies parent about changed visibility. + * + * Passes LLSD with "visibility_changed" => <current visibility> value. + * For now it is processed by LLAvatarListItem to update (reshape) its children. + * Implemented fo complete EXT-3976 + */ + void notifyParentVisibilityChanged(); + //static LLColor4 sColorMuted; //static LLColor4 sColorNormal; //static LLColor4 sColorOverdriven; @@ -117,6 +140,10 @@ private: /** uuid of a speaker being monitored */ LLUUID mSpeakerId; + + /** indicates if the instance is dirty and should notify parent */ + bool mIsSwitchDirty; + bool mShouldSwitchOn; }; #endif diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index b547997e7a..0cfe501fab 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -302,7 +302,7 @@ void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id) { LLPanelChatControlPanel::setSessionId(session_id); - mGroupID = LLIMModel::getInstance()->getOtherParticipantID(session_id); + mGroupID = session_id; // for group and Ad-hoc chat we need to include agent into list if(!mParticipantList) diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 550fee71bf..e058b3b326 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -280,6 +280,7 @@ void LLPanelOutfitsInventory::updateListCommands() mListCommands->childSetEnabled("trash_btn", trash_enabled); mListCommands->childSetEnabled("wear_btn", wear_enabled); + mListCommands->childSetVisible("wear_btn", wear_enabled); mListCommands->childSetEnabled("make_outfit_btn", make_outfit_enabled); } diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 03cc870a59..c14b282488 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -532,10 +532,10 @@ BOOL LLPanelPeople::postBuild() friends_panel->childSetAction("add_btn", boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked, this)); friends_panel->childSetAction("del_btn", boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked, this)); - mOnlineFriendList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mOnlineFriendList)); - mAllFriendList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mAllFriendList)); - mNearbyList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mNearbyList)); - mRecentList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mRecentList)); + mOnlineFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1)); + mAllFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1)); + mNearbyList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1)); + mRecentList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1)); mOnlineFriendList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mOnlineFriendList)); mAllFriendList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mAllFriendList)); @@ -1005,12 +1005,15 @@ void LLPanelPeople::onTabSelected(const LLSD& param) mFilterEditor->setLabel(getString("people_filter_label")); } -void LLPanelPeople::onAvatarListDoubleClicked(LLAvatarList* list) +void LLPanelPeople::onAvatarListDoubleClicked(LLUICtrl* ctrl) { - LLUUID clicked_id = list->getSelectedUUID(); - - if (clicked_id.isNull()) + LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(ctrl); + if(!item) + { return; + } + + LLUUID clicked_id = item->getAvatarId(); #if 0 // SJB: Useful for testing, but not currently functional or to spec LLAvatarActions::showProfile(clicked_id); diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index da2c0e368c..7580fdbeef 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -109,7 +109,7 @@ private: void onNearbyViewSortButtonClicked(); void onFriendsViewSortButtonClicked(); void onGroupsViewSortButtonClicked(); - void onAvatarListDoubleClicked(LLAvatarList* list); + void onAvatarListDoubleClicked(LLUICtrl* ctrl); void onAvatarListCommitted(LLAvatarList* list); void onGroupPlusButtonClicked(); void onGroupMinusButtonClicked(); diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp index 7a4dd3569d..e7615929c8 100644 --- a/indra/newview/llpanelpick.cpp +++ b/indra/newview/llpanelpick.cpp @@ -35,24 +35,30 @@ // profile. #include "llviewerprecompiledheaders.h" -#include "llpanel.h" + +#include "llpanelpick.h" + #include "message.h" -#include "llagent.h" -#include "llagentpicksinfo.h" + +#include "llparcel.h" + #include "llbutton.h" +#include "llfloaterreg.h" #include "lliconctrl.h" #include "lllineeditor.h" -#include "llparcel.h" -#include "llviewerparcelmgr.h" +#include "llpanel.h" +#include "llscrollcontainer.h" #include "lltexteditor.h" + +#include "llagent.h" +#include "llagentpicksinfo.h" +#include "llavatarpropertiesprocessor.h" +#include "llfloaterworldmap.h" #include "lltexturectrl.h" #include "lluiconstants.h" +#include "llviewerparcelmgr.h" #include "llviewerregion.h" #include "llworldmap.h" -#include "llfloaterworldmap.h" -#include "llfloaterreg.h" -#include "llavatarpropertiesprocessor.h" -#include "llpanelpick.h" #define XML_PANEL_EDIT_PICK "panel_edit_pick.xml" @@ -93,6 +99,10 @@ LLPanelPickInfo::LLPanelPickInfo() , mPickId(LLUUID::null) , mParcelId(LLUUID::null) , mRequestedId(LLUUID::null) + , mScrollingPanelMinHeight(0) + , mScrollingPanelWidth(0) + , mScrollingPanel(NULL) + , mScrollContainer(NULL) { } @@ -146,9 +156,35 @@ BOOL LLPanelPickInfo::postBuild() childSetAction("show_on_map_btn", boost::bind(&LLPanelPickInfo::onClickMap, this)); childSetAction("back_btn", boost::bind(&LLPanelPickInfo::onClickBack, this)); + mScrollingPanel = getChild<LLPanel>("scroll_content_panel"); + mScrollContainer = getChild<LLScrollContainer>("profile_scroll"); + + mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight(); + mScrollingPanelWidth = mScrollingPanel->getRect().getWidth(); + return TRUE; } +void LLPanelPickInfo::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + LLPanel::reshape(width, height, called_from_parent); + + if (!mScrollContainer || !mScrollingPanel) + return; + + static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); + + S32 scroll_height = mScrollContainer->getRect().getHeight(); + if (mScrollingPanelMinHeight >= scroll_height) + { + mScrollingPanel->reshape(mScrollingPanelWidth, mScrollingPanelMinHeight); + } + else + { + mScrollingPanel->reshape(mScrollingPanelWidth + scrollbar_size, scroll_height); + } +} + void LLPanelPickInfo::processProperties(void* data, EAvatarProcessorType type) { if(APT_PICK_INFO != type) @@ -284,7 +320,6 @@ void LLPanelPickInfo::setPickName(const std::string& name) void LLPanelPickInfo::setPickDesc(const std::string& desc) { childSetValue(XML_DESC, desc); - updateContentPanelRect(); } void LLPanelPickInfo::setPickLocation(const std::string& location) @@ -292,31 +327,6 @@ void LLPanelPickInfo::setPickLocation(const std::string& location) childSetValue(XML_LOCATION, location); } -void LLPanelPickInfo::updateContentPanelRect() -{ - LLTextBox* desc = getChild<LLTextBox>(XML_DESC); - - S32 text_height = desc->getTextPixelHeight(); - LLRect text_rect = desc->getRect(); - - // let text-box height fit text height - text_rect.set(text_rect.mLeft, text_rect.mTop, text_rect.mRight, text_rect.mTop - text_height); - desc->setRect(text_rect); - desc->reshape(text_rect.getWidth(), text_rect.getHeight()); - // force reflow - desc->setText(desc->getText()); - - // bottom of description text-box will be bottom of content panel - desc->localRectToOtherView(desc->getLocalRect(), &text_rect, getChild<LLView>("profile_scroll")); - - LLPanel* content_panel = getChild<LLPanel>("scroll_content_panel"); - LLRect content_rect = content_panel->getRect(); - content_rect.set(content_rect.mLeft, content_rect.mTop, content_rect.mRight, text_rect.mBottom); - // Somehow setRect moves all elements down. - // Single reshape() updates rect and does not move anything. - content_panel->reshape(content_rect.getWidth(), content_rect.getHeight()); -} - void LLPanelPickInfo::onClickMap() { LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal()); diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h index 12b5a116b4..62c3b20c0d 100644 --- a/indra/newview/llpanelpick.h +++ b/indra/newview/llpanelpick.h @@ -43,6 +43,7 @@ class LLIconCtrl; class LLTextureCtrl; +class LLScrollContainer; class LLMessageSystem; class LLAvatarPropertiesObserver; @@ -69,6 +70,8 @@ public: /*virtual*/ BOOL postBuild(); + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); /** @@ -140,15 +143,6 @@ protected: virtual LLVector3d& getPosGlobal() { return mPosGlobal; } /** - * Reshapes content panel to fit all elements. - * - * Assume that description text-box is the last element of panel. - * Reshape text-box to fit text height and then reshape content panel to fit - * text-box bottom. EXT-1326 - */ - void updateContentPanelRect(); - - /** * Callback for "Map" button, opens Map */ void onClickMap(); @@ -162,7 +156,11 @@ protected: protected: - LLTextureCtrl* mSnapshotCtrl; + S32 mScrollingPanelMinHeight; + S32 mScrollingPanelWidth; + LLScrollContainer* mScrollContainer; + LLPanel* mScrollingPanel; + LLTextureCtrl* mSnapshotCtrl; LLUUID mAvatarId; LLVector3d mPosGlobal; diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 0a2217fc51..571745ee02 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -723,7 +723,10 @@ void LLTeleportHistoryPanel::onTeleportHistoryChange(S32 removed_index) if (-1 == removed_index) showTeleportHistory(); // recreate all items else + { replaceItem(removed_index); // replace removed item by most recent + updateVerbs(); + } } void LLTeleportHistoryPanel::replaceItem(S32 removed_index) diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index b6f78d08f1..0a180512ce 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -70,7 +70,7 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* av mSpeakerMgr->addListener(mSpeakerModeratorListener, "update_moderator"); mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData")); - mAvatarListDoubleClickConnection = mAvatarList->setDoubleClickCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, mAvatarList)); + mAvatarListDoubleClickConnection = mAvatarList->setItemDoubleClickCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, _1)); mAvatarListRefreshConnection = mAvatarList->setRefreshCompleteCallback(boost::bind(&LLParticipantList::onAvatarListRefreshed, this, _1, _2)); // Set onAvatarListDoubleClicked as default on_return action. mAvatarListReturnConnection = mAvatarList->setReturnCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, mAvatarList)); @@ -132,10 +132,15 @@ void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible) mAvatarList->setSpeakingIndicatorsVisible(visible); }; -void LLParticipantList::onAvatarListDoubleClicked(LLAvatarList* list) +void LLParticipantList::onAvatarListDoubleClicked(LLUICtrl* ctrl) { - // NOTE(EM): Should we check if there is multiple selection and start conference if it is so? - LLUUID clicked_id = list->getSelectedUUID(); + LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(ctrl); + if(!item) + { + return; + } + + LLUUID clicked_id = item->getAvatarId(); if (clicked_id.isNull() || clicked_id == gAgent.getID()) return; diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h index 70badbc40d..e1b1b5af00 100644 --- a/indra/newview/llparticipantlist.h +++ b/indra/newview/llparticipantlist.h @@ -232,7 +232,7 @@ class LLParticipantList }; private: - void onAvatarListDoubleClicked(LLAvatarList* list); + void onAvatarListDoubleClicked(LLUICtrl* ctrl); void onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param); /** diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index d0a0dd877f..027f3daffb 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -59,17 +59,14 @@ bool LLScreenChannel::mWasStartUpToastShown = false; // LLScreenChannelBase ////////////////////// LLScreenChannelBase::LLScreenChannelBase(const LLUUID& id) : - mOverflowToastPanel(NULL) - ,mToastAlignment(NA_BOTTOM) + mToastAlignment(NA_BOTTOM) ,mCanStoreToasts(true) ,mHiddenToastsNum(0) - ,mOverflowToastHidden(false) ,mHoveredToast(NULL) ,mControlHovering(false) ,mShowToasts(true) { mID = id; - mOverflowFormatString = LLTrans::getString("OverflowInfoChannelString"); mWorldViewRectConnection = gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLScreenChannelBase::updatePositionAndSize, this, _1, _2)); setMouseOpaque( false ); setVisible(FALSE); @@ -217,11 +214,6 @@ void LLScreenChannel::addToast(const LLToast::Params& p) ToastElem new_toast_elem(p); - // reset HIDDEN flags for the Overflow Toast - mOverflowToastHidden = false; - if(mOverflowToastPanel) - mOverflowToastPanel->setIsHidden(false); - new_toast_elem.toast->setOnFadeCallback(boost::bind(&LLScreenChannel::onToastFade, this, _1)); new_toast_elem.toast->setOnToastDestroyedCallback(boost::bind(&LLScreenChannel::onToastDestroyed, this, _1)); if(mControlHovering) @@ -322,8 +314,6 @@ void LLScreenChannel::loadStoredToastsToChannel() if(mStoredToastList.size() == 0) return; - - mOverflowToastHidden = false; for(it = mStoredToastList.begin(); it != mStoredToastList.end(); ++it) { @@ -344,8 +334,6 @@ void LLScreenChannel::loadStoredToastByNotificationIDToChannel(LLUUID id) if( it == mStoredToastList.end() ) return; - mOverflowToastHidden = false; - LLToast* toast = (*it).toast; if(toast->getVisible()) @@ -490,7 +478,7 @@ void LLScreenChannel::showToastsBottom() if(floater && floater->overlapsScreenChannel()) { LLRect world_rect = gViewerWindow->getWorldViewRectScaled(); - if(toast_rect.mTop + getOverflowToastHeight() + toast_margin > world_rect.mTop) + if(toast_rect.mTop > world_rect.mTop) { break; } @@ -526,7 +514,7 @@ void LLScreenChannel::showToastsBottom() } } - if(it != mToastList.rend() && !mOverflowToastHidden) + if(it != mToastList.rend()) { mHiddenToastsNum = 0; for(; it != mToastList.rend(); it++) @@ -535,7 +523,6 @@ void LLScreenChannel::showToastsBottom() (*it).toast->setVisible(FALSE); mHiddenToastsNum++; } - createOverflowToast(bottom, gSavedSettings.getS32("NotificationTipToastLifeTime")); } else { @@ -566,94 +553,6 @@ void LLScreenChannel::showToastsTop() } //-------------------------------------------------------------------------- -void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer) -{ - LLRect toast_rect; - LLToast::Params p; - p.lifetime_secs = timer; - - if(!mOverflowToastPanel) - mOverflowToastPanel = new LLToast(p); - - if(!mOverflowToastPanel) - return; - - mOverflowToastPanel->startFading(); - mOverflowToastPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::onOverflowToastHide, this)); - - LLTextBox* text_box = mOverflowToastPanel->getChild<LLTextBox>("toast_text"); - std::string text = llformat(mOverflowFormatString.c_str(),mHiddenToastsNum); - if(mHiddenToastsNum == 1) - { - text += "."; - } - else - { - text += "s."; - } - - toast_rect = mOverflowToastPanel->getRect(); - mOverflowToastPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true); - toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastGap"), getRect().getWidth(), toast_rect.getHeight()); - mOverflowToastPanel->setRect(toast_rect); - - // don't show overflow toast if there is not enough space for it. - LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get()); - if(floater && floater->overlapsScreenChannel()) - { - LLRect world_rect = gViewerWindow->getWorldViewRectScaled(); - if(toast_rect.mTop > world_rect.mTop) - { - closeOverflowToastPanel(); - return; - } - } - - text_box->setValue(text); - text_box->setVisible(TRUE); - - mOverflowToastPanel->setVisible(TRUE); -} - -//-------------------------------------------------------------------------- -void LLScreenChannel::onOverflowToastHide() -{ - mOverflowToastHidden = true; - - // remove all hidden toasts from channel and save interactive notifications - for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end();) - { - if(!(*it).toast->getVisible()) - { - if((*it).toast->getCanBeStored()) - { - storeToast((*it)); - } - else - { - deleteToast((*it).toast); - } - - it = mToastList.erase(it); - } - else - { - ++it; - } - } -} - -//-------------------------------------------------------------------------- -void LLScreenChannel::closeOverflowToastPanel() -{ - if(mOverflowToastPanel != NULL) - { - mOverflowToastPanel->setVisible(FALSE); - mOverflowToastPanel->stopFading(); - } -} - -//-------------------------------------------------------------------------- void LLScreenChannel::createStartUpToast(S32 notif_num, F32 timer) { LLRect toast_rect; @@ -698,24 +597,6 @@ F32 LLScreenChannel::getHeightRatio() return ratio; } -S32 LLScreenChannel::getOverflowToastHeight() -{ - if(mOverflowToastPanel) - { - return mOverflowToastPanel->getRect().getHeight(); - } - - static S32 height = 0; - if(0 == height) - { - LLToast::Params p; - LLToast* toast = new LLToast(p); - height = toast->getRect().getHeight(); - delete toast; - } - return height; -} - //-------------------------------------------------------------------------- void LLScreenChannel::updateStartUpString(S32 num) { diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h index 054f92096c..88053d87d9 100644 --- a/indra/newview/llscreenchannel.h +++ b/indra/newview/llscreenchannel.h @@ -72,8 +72,7 @@ public: virtual void setToastAlignment(EToastAlignment align) {mToastAlignment = align;} virtual void setChannelAlignment(EChannelAlignment align) {mChannelAlignment = align;} - virtual void setOverflowFormatString ( const std::string& str) { mOverflowFormatString = str; } - + // kill or modify a toast by its ID virtual void killToastByNotificationID(LLUUID id) {}; virtual void modifyToastNotificationByID(LLUUID id, LLSD data) {}; @@ -121,17 +120,13 @@ protected: LLToast* mHoveredToast; bool mCanStoreToasts; bool mDisplayToastsAlways; - bool mOverflowToastHidden; // controls whether a channel shows toasts or not bool mShowToasts; // EToastAlignment mToastAlignment; EChannelAlignment mChannelAlignment; - // attributes for the Overflow Toast S32 mHiddenToastsNum; - LLToast* mOverflowToastPanel; - std::string mOverflowFormatString; // channel's ID LLUUID mID; @@ -192,8 +187,6 @@ public: void removeToastsBySessionID(LLUUID id); // remove all storable toasts from screen and store them void removeAndStoreAllStorableToasts(); - // close the Overflow Toast - void closeOverflowToastPanel(); // close the StartUp Toast void closeStartUpToast(); @@ -261,7 +254,6 @@ private: void onToastHover(LLToast* toast, bool mouse_enter); void onToastFade(LLToast* toast); void onToastDestroyed(LLToast* toast); - void onOverflowToastHide(); void onStartUpToastHide(); // @@ -274,9 +266,6 @@ private: void showToastsCentre(); void showToastsTop(); - // create the Overflow Toast - void createOverflowToast(S32 bottom, F32 timer); - // create the StartUp Toast void createStartUpToast(S32 notif_num, F32 timer); @@ -285,8 +274,6 @@ private: */ static F32 getHeightRatio(); - S32 getOverflowToastHeight(); - // Channel's flags static bool mWasStartUpToastShown; diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp new file mode 100644 index 0000000000..b450d38b5a --- /dev/null +++ b/indra/newview/llspeakingindicatormanager.cpp @@ -0,0 +1,250 @@ +/** + * @file llspeakingindicatormanager.cpp + * @author Mike Antipov + * @brief Implementation of SpeackerIndicatorManager class to process registered LLSpeackerIndicator + * depend on avatars are in the same voice channel. + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llspeakingindicatormanager.h" + + +#include "llagentdata.h" +#include "llvoicechannel.h" +#include "llvoiceclient.h" + +/** + * This class intended to control visibility of avatar speaking indicators depend on whether avatars + * are in the same voice channel. + * + * Speaking indicator should be visible for avatars in the same voice channel. See EXT-3976. + * + * It stores passed instances of LLOutputMonitorCtrl in a multimap by avatar LLUUID. + * It observes changing of voice channel and changing of participant list in voice channel. + * When voice channel or voice participant list is changed it updates visibility of an appropriate + * speaking indicator. + * + * Several indicators can be registered for the same avatar. + */ +class SpeakingIndicatorManager : public LLSingleton<SpeakingIndicatorManager>, LLVoiceClientParticipantObserver +{ + LOG_CLASS(SpeakingIndicatorManager); +public: + + /** + * Stores passed speaking indicator to control its visibility. + * + * Registered indicator is set visible if an appropriate avatar is in the same voice channel with Agent. + * It ignores instances of Agent's indicator. + * + * @param speaker_id LLUUID of an avatar whose speaking indicator is registered. + * @param speaking_indicator instance of the speaking indicator to be registered. + */ + void registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator); + + /** + * Removes passed speaking indicator from observing. + * + * @param speaker_id LLUUID of an avatar whose speaking indicator should be unregistered. + * @param speaking_indicator instance of the speaking indicator to be unregistered. + */ + void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator); + +private: + typedef std::set<LLUUID> speaker_ids_t; + typedef std::multimap<LLUUID, LLSpeakingIndicator*> speaking_indicators_mmap_t; + typedef speaking_indicators_mmap_t::value_type speaking_indicator_value_t; + typedef speaking_indicators_mmap_t::const_iterator indicator_const_iterator; + typedef std::pair<indicator_const_iterator, indicator_const_iterator> indicator_range_t; + + friend class LLSingleton<SpeakingIndicatorManager>; + SpeakingIndicatorManager(); + ~SpeakingIndicatorManager(); + + /** + * Callback to determine when voice channel is changed. + * + * It switches all registered speaking indicators off. + * To reduce overheads only switched on indicators are processed. + */ + void sOnCurrentChannelChanged(const LLUUID& session_id); + + /** + * Callback of changing voice participant list (from LLVoiceClientParticipantObserver). + * + * Switches off indicators had been switched on and switches on indicators of current participants list. + * There is only a few indicators in lists should be switched off/on. + * So, method does not calculate difference between these list it only switches off already + * switched on indicators and switches on indicators of voice channel participants + */ + void onChange(); + + /** + * Changes state of indicators specified by LLUUIDs + * + * @param speakers_uuids - avatars' LLUUIDs whose speaking indicators should be switched + * @param switch_on - if TRUE specified indicator will be switched on, off otherwise. + */ + void switchSpeakerIndicators(const speaker_ids_t& speakers_uuids, BOOL switch_on); + + /** + * Multimap with all registered speaking indicators + */ + speaking_indicators_mmap_t mSpeakingIndicators; + + /** + * LUUIDs of avatar for which we have speaking indicators switched on. + * + * Is used to switch off all previously ON indicators when voice participant list is changed. + * + * @see onChange() + */ + speaker_ids_t mSwitchedIndicatorsOn; +}; + +////////////////////////////////////////////////////////////////////////// +// PUBLIC SECTION +////////////////////////////////////////////////////////////////////////// +void SpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator) +{ + if (speaker_id == gAgentID) return; + + LL_DEBUGS("SpeakingIndicator") << "Registering indicator: " << speaker_id << LL_ENDL; + speaking_indicator_value_t value_type(speaker_id, speaking_indicator); + mSpeakingIndicators.insert(value_type); + + speaker_ids_t speakers_uuids; + BOOL is_in_same_voice = LLVoiceClient::getInstance()->findParticipantByID(speaker_id) != NULL; + + speakers_uuids.insert(speaker_id); + switchSpeakerIndicators(speakers_uuids, is_in_same_voice); +} + +void SpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator) +{ + speaking_indicators_mmap_t::iterator it; + it = mSpeakingIndicators.find(speaker_id); + for (;it != mSpeakingIndicators.end(); ++it) + { + if (it->second == speaking_indicator) + { + mSpeakingIndicators.erase(it); + break; + } + } +} + +////////////////////////////////////////////////////////////////////////// +// PRIVATE SECTION +////////////////////////////////////////////////////////////////////////// +SpeakingIndicatorManager::SpeakingIndicatorManager() +{ + LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&SpeakingIndicatorManager::sOnCurrentChannelChanged, this, _1)); + LLVoiceClient::getInstance()->addObserver(this); +} + +SpeakingIndicatorManager::~SpeakingIndicatorManager() +{ + // Don't use LLVoiceClient::getInstance() here without check + // singleton MAY have already been destroyed. + if(LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->removeObserver(this); + } +} + +void SpeakingIndicatorManager::sOnCurrentChannelChanged(const LLUUID& /*session_id*/) +{ + switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE); + mSwitchedIndicatorsOn.clear(); +} + +void SpeakingIndicatorManager::onChange() +{ + LL_DEBUGS("SpeakingIndicator") << "Voice participant list was changed, updating indicators" << LL_ENDL; + + speaker_ids_t speakers_uuids; + LLVoiceClient::getInstance()->getParticipantsUUIDSet(speakers_uuids); + + LL_DEBUGS("SpeakingIndicator") << "Switching all OFF, count: " << mSwitchedIndicatorsOn.size() << LL_ENDL; + // switch all indicators off + switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE); + mSwitchedIndicatorsOn.clear(); + + LL_DEBUGS("SpeakingIndicator") << "Switching all ON, count: " << speakers_uuids.size() << LL_ENDL; + // then switch current voice participants indicators on + switchSpeakerIndicators(speakers_uuids, TRUE); +} + +void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& speakers_uuids, BOOL switch_on) +{ + speaker_ids_t::const_iterator it_uuid = speakers_uuids.begin(); + for (; it_uuid != speakers_uuids.end(); ++it_uuid) + { + LL_DEBUGS("SpeakingIndicator") << "Looking for indicator: " << *it_uuid << LL_ENDL; + indicator_range_t it_range = mSpeakingIndicators.equal_range(*it_uuid); + indicator_const_iterator it_indicator = it_range.first; + bool was_found = false; + for (; it_indicator != it_range.second; ++it_indicator) + { + was_found = true; + LLSpeakingIndicator* indicator = (*it_indicator).second; + indicator->switchIndicator(switch_on); + } + + if (was_found) + { + LL_DEBUGS("SpeakingIndicator") << mSpeakingIndicators.count(*it_uuid) << " indicators where found" << LL_ENDL; + + if (switch_on) + { + // store switched on indicator to be able switch it off + mSwitchedIndicatorsOn.insert(*it_uuid); + } + } + } +} + +/************************************************************************/ +/* LLSpeakingIndicatorManager namespace implementation */ +/************************************************************************/ + +void LLSpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator) +{ + SpeakingIndicatorManager::instance().registerSpeakingIndicator(speaker_id, speaking_indicator); +} + +void LLSpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator) +{ + SpeakingIndicatorManager::instance().unregisterSpeakingIndicator(speaker_id, speaking_indicator); +} + +// EOF + diff --git a/indra/newview/llspeakingindicatormanager.h b/indra/newview/llspeakingindicatormanager.h new file mode 100644 index 0000000000..ce0158f7d8 --- /dev/null +++ b/indra/newview/llspeakingindicatormanager.h @@ -0,0 +1,67 @@ +/** + * @file llspeakingindicatormanager.h + * @author Mike Antipov + * @brief Interfeace of LLSpeackerIndicator class to be processed depend on avatars are in the same voice channel. + * Also register/unregister methods for this class are declared + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLSPEAKINGINDICATORMANAGER_H +#define LL_LLSPEAKINGINDICATORMANAGER_H + +class LLSpeakingIndicator +{ +public: + virtual void switchIndicator(bool switch_on) = 0; +}; + +// See EXT-3976. +namespace LLSpeakingIndicatorManager +{ + /** + * Stores passed speaking indicator to control its visibility. + * + * Registered indicator is set visible if an appropriate avatar is in the same voice channel with Agent. + * It ignores instances of Agent's indicator. + * + * @param speaker_id LLUUID of an avatar whose speaker indicator is registered. + * @param speaking_indicator instance of the speaker indicator to be registered. + */ + void registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator); + + /** + * Removes passed speaking indicator from observing. + * + * @param speaker_id LLUUID of an avatar whose speaker indicator should be unregistered. + * @param speaking_indicator instance of the speaker indicator to be unregistered. + */ + void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator); +} + +#endif // LL_LLSPEAKINGINDICATORMANAGER_H diff --git a/indra/newview/llviewerhelputil.cpp b/indra/newview/llviewerhelputil.cpp index 5ba4fc834c..ffc5761372 100644 --- a/indra/newview/llviewerhelputil.cpp +++ b/indra/newview/llviewerhelputil.cpp @@ -34,6 +34,7 @@ #include "llviewerprecompiledheaders.h" #include "llviewerhelputil.h" +#include "llagent.h" #include "llsd.h" #include "llstring.h" #include "lluri.h" @@ -63,6 +64,7 @@ std::string LLViewerHelpUtil::buildHelpURL( const std::string &topic) { LLSD substitution; substitution["TOPIC"] = helpURLEncode(topic); + substitution["DEBUG_MODE"] = gAgent.isGodlike() ? "debug" : ""; // get the help URL and expand all of the substitutions // (also adds things like [LANGUAGE], [VERSION], [OS], etc.) diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index f8502821f0..ef596f9297 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1006,6 +1006,8 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id, mInNearbyMediaList(false), mClearCache(false), mBackgroundColor(LLColor4::white), + mNavigateSuspended(false), + mNavigateSuspendedDeferred(false), mIsUpdated(false) { @@ -1696,6 +1698,13 @@ void LLViewerMediaImpl::navigateInternal() // Helpful to have media urls in log file. Shouldn't be spammy. llinfos << "media id= " << mTextureId << " url=" << mMediaURL << " mime_type=" << mMimeType << llendl; + if(mNavigateSuspended) + { + llwarns << "Deferring navigate." << llendl; + mNavigateSuspendedDeferred = true; + return; + } + if(mMimeTypeProbe != NULL) { llwarns << "MIME type probe already in progress -- bailing out." << llendl; @@ -1902,7 +1911,17 @@ void LLViewerMediaImpl::update() return; } + // Make sure a navigate doesn't happen during the idle -- it can cause mMediaSource to get destroyed, which can cause a crash. + setNavigateSuspended(true); + mMediaSource->idle(); + + setNavigateSuspended(false); + + if(mMediaSource == NULL) + { + return; + } if(mMediaSource->isPluginExited()) { @@ -2559,6 +2578,23 @@ void LLViewerMediaImpl::setNavState(EMediaNavState state) } } +void LLViewerMediaImpl::setNavigateSuspended(bool suspend) +{ + if(mNavigateSuspended != suspend) + { + mNavigateSuspended = suspend; + if(!suspend) + { + // We're coming out of suspend. If someone tried to do a navigate while suspended, do one now instead. + if(mNavigateSuspendedDeferred) + { + mNavigateSuspendedDeferred = false; + navigateInternal(); + } + } + } +} + void LLViewerMediaImpl::cancelMimeTypeProbe() { if(mMimeTypeProbe != NULL) diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 8a5cd804aa..668f3b563d 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -326,6 +326,9 @@ public: EMediaNavState getNavState() { return mMediaNavState; } void setNavState(EMediaNavState state); + void setNavigateSuspended(bool suspend); + bool isNavigateSuspended() { return mNavigateSuspended; }; + void cancelMimeTypeProbe(); private: // a single media url with some data and an impl. @@ -372,6 +375,8 @@ private: bool mInNearbyMediaList; // used by LLFloaterNearbyMedia::refreshList() for performance reasons bool mClearCache; LLColor4 mBackgroundColor; + bool mNavigateSuspended; + bool mNavigateSuspendedDeferred; private: BOOL mIsUpdated ; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index d93e2f0a14..7f43213c5d 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -711,6 +711,18 @@ protected: } }; +class LLOpenTaskGroupOffer : public LLInventoryAddedObserver +{ +protected: + /*virtual*/ void done() + { + open_inventory_offer(mAdded, "group_offer"); + mAdded.clear(); + gInventory.removeObserver(this); + delete this; + } +}; + //one global instance to bind them LLOpenTaskOffer* gNewInventoryObserver=NULL; @@ -929,9 +941,6 @@ void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& f case LLAssetType::AT_ANIMATION: LLFloaterReg::showInstance("preview_anim", LLSD(item_id), take_focus); break; - case LLAssetType::AT_GESTURE: - LLFloaterReg::showInstance("preview_gesture", LLSD(item_id), take_focus); - break; case LLAssetType::AT_SCRIPT: LLFloaterReg::showInstance("preview_script", LLSD(item_id), take_focus); break; @@ -1146,6 +1155,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& } break; case IM_GROUP_NOTICE: + opener = new LLOpenTaskGroupOffer; send_auto_receive_response(); break; case IM_TASK_INVENTORY_OFFERED: @@ -5360,8 +5370,24 @@ bool handle_lure_callback(const LLSD& notification, const LLSD& response) it != notification["payload"]["ids"].endArray(); ++it) { + LLUUID target_id = it->asUUID(); + msg->nextBlockFast(_PREHASH_TargetData); - msg->addUUIDFast(_PREHASH_TargetID, it->asUUID()); + msg->addUUIDFast(_PREHASH_TargetID, target_id); + + // Record the offer. + { + std::string target_name; + gCacheName->getFullName(target_id, target_name); + LLSD args; + args["TO_NAME"] = target_name; + + LLSD payload; + payload["from_id"] = target_id; + payload["SESSION_NAME"] = target_name; + payload["SUPPRESS_TOAST"] = true; + LLNotificationsUtil::add("TeleportOfferSent", args, payload); + } } gAgent.sendReliableMessage(); } diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index f3ceb5afb5..30f00f04af 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -5004,6 +5004,17 @@ LLVoiceClient::participantMap *LLVoiceClient::getParticipantList(void) return result; } +void LLVoiceClient::getParticipantsUUIDSet(std::set<LLUUID>& participant_uuids) +{ + if (NULL == mAudioSession) return; + + participantUUIDMap::const_iterator it = mAudioSession->mParticipantsByUUID.begin(), + it_end = mAudioSession->mParticipantsByUUID.end(); + for (; it != it_end; ++it) + { + participant_uuids.insert((*(*it).first)); + } +} LLVoiceClient::participantState *LLVoiceClient::sessionState::findParticipant(const std::string &uri) { diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 724179847d..6231c6ba29 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -354,6 +354,7 @@ static void updatePosition(void); participantState *findParticipantByID(const LLUUID& id); participantMap *getParticipantList(void); + void getParticipantsUUIDSet(std::set<LLUUID>& participant_uuids); typedef std::map<const std::string*, sessionState*, stringMapComparitor> sessionMap; typedef std::set<sessionState*> sessionSet; diff --git a/indra/newview/skins/default/xui/de/floater_build_options.xml b/indra/newview/skins/default/xui/de/floater_build_options.xml index 403965560b..ba4b8a6ae5 100644 --- a/indra/newview/skins/default/xui/de/floater_build_options.xml +++ b/indra/newview/skins/default/xui/de/floater_build_options.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="build options floater" title="RASTER-OPTIONEN">
- <spinner label="Rastereinheit (Meter)" name="GridResolution"/>
+ <spinner label="Raster-Einheiten (Meter)" name="GridResolution"/>
<spinner label="Rastergröße (Meter)" name="GridDrawSize"/>
- <check_box label="An Untereinheiten ausrichten" name="GridSubUnit"/>
- <check_box label="Querschnitte anzeigen" name="GridCrossSection"/>
- <text name="grid_opacity_label" tool_tip="Rasterdeckkraft">
+ <check_box label="Einrasten von Untereinheiten aktivieren" name="GridSubUnit"/>
+ <check_box label="Überschneidungen anzeigen" name="GridCrossSection"/>
+ <text name="grid_opacity_label" tool_tip="Raster-Deckkraft">
Deckkraft:
</text>
<slider label="Rasterdeckkraft" name="GridOpacity"/>
diff --git a/indra/newview/skins/default/xui/de/floater_buy_currency.xml b/indra/newview/skins/default/xui/de/floater_buy_currency.xml index 3c336cc40b..c320e796c2 100644 --- a/indra/newview/skins/default/xui/de/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/de/floater_buy_currency.xml @@ -46,7 +46,7 @@ [AMT] L$
</text>
<text name="currency_links">
- [http://www.secondlife.com/ payment method] | [http://www.secondlife.com/ currency] | [http://www.secondlife.com exchange rate]
+ [http://www.secondlife.com/my/account/payment_method_management.php?lang=de-DE payment method] | [http://www.secondlife.com/my/account/currency.php?lang=de-DE currency] | [http://www.secondlife.com/my/account/exchange_rates.php?lang=de-DE exchange rate]
</text>
<text name="exchange_rate_note">
Geben Sie den Betrag erneut ein, um die aktuellste Umtauschrate anzuzeigen.
diff --git a/indra/newview/skins/default/xui/de/floater_help_browser.xml b/indra/newview/skins/default/xui/de/floater_help_browser.xml index 53bddcced1..2344d6f412 100644 --- a/indra/newview/skins/default/xui/de/floater_help_browser.xml +++ b/indra/newview/skins/default/xui/de/floater_help_browser.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_help_browser" title="HILFE-BROWSER">
<floater.string name="home_page_url">
- http://www.secondlife.com
+ http://de.secondlife.com
</floater.string>
<floater.string name="support_page_url">
- http://support.secondlife.com
+ http://de.secondlife.com/support
</floater.string>
<layout_stack name="stack1">
<layout_panel name="external_controls">
diff --git a/indra/newview/skins/default/xui/de/floater_preferences.xml b/indra/newview/skins/default/xui/de/floater_preferences.xml index 4ec709d508..01fde2e697 100644 --- a/indra/newview/skins/default/xui/de/floater_preferences.xml +++ b/indra/newview/skins/default/xui/de/floater_preferences.xml @@ -5,11 +5,11 @@ <tab_container name="pref core">
<panel label="Allgemein" name="general"/>
<panel label="Grafik" name="display"/>
- <panel label="Datenschutzbestimmungen (EN)" name="im"/>
+ <panel label="Privatsphäre" name="im"/>
<panel label="Sound" name="audio"/>
<panel label="Chat" name="chat"/>
- <panel label="Warnhinweise" name="msgs"/>
- <panel label="Hardware & Web" name="input"/>
+ <panel label="Benachrichtigungen" name="msgs"/>
+ <panel label="Setup" name="input"/>
<panel label="Erweitert" name="advanced1"/>
</tab_container>
</floater>
diff --git a/indra/newview/skins/default/xui/de/menu_hide_navbar.xml b/indra/newview/skins/default/xui/de/menu_hide_navbar.xml index 482cbf37d4..b8bca2f0fd 100644 --- a/indra/newview/skins/default/xui/de/menu_hide_navbar.xml +++ b/indra/newview/skins/default/xui/de/menu_hide_navbar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu name="hide_navbar_menu">
- <menu_item_check label="Navigations-Leiste anzeigen" name="ShowNavbarNavigationPanel"/>
+ <menu_item_check label="Navigationsleiste anzeigen" name="ShowNavbarNavigationPanel"/>
<menu_item_check label="Favoritenleiste anzeigen" name="ShowNavbarFavoritesPanel"/>
</menu>
diff --git a/indra/newview/skins/default/xui/de/menu_navbar.xml b/indra/newview/skins/default/xui/de/menu_navbar.xml index e0639f9b76..9ff37b53dc 100644 --- a/indra/newview/skins/default/xui/de/menu_navbar.xml +++ b/indra/newview/skins/default/xui/de/menu_navbar.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu name="Navbar Menu">
<menu_item_check label="Koordinaten anzeigen" name="Show Coordinates"/>
- <menu_item_check label="Parzellen-Eigenschaften anzeigen" name="Show Parcel Properties"/>
+ <menu_item_check label="Parzelleneigenschaften anzeigen" name="Show Parcel Properties"/>
<menu_item_call label="Landmarke" name="Landmark"/>
<menu_item_call label="Ausschneiden" name="Cut"/>
<menu_item_call label="Kopieren" name="Copy"/>
diff --git a/indra/newview/skins/default/xui/de/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/de/menu_people_nearby_view_sort.xml index b5d3389ce8..e3e7977efd 100644 --- a/indra/newview/skins/default/xui/de/menu_people_nearby_view_sort.xml +++ b/indra/newview/skins/default/xui/de/menu_people_nearby_view_sort.xml @@ -2,7 +2,7 @@ <menu name="menu_group_plus">
<menu_item_check label="Nach letzten Sprechern sortieren" name="sort_by_recent_speakers"/>
<menu_item_check label="Nach Name sortieren" name="sort_name"/>
- <menu_item_check label="Nach Nähe sortieren" name="sort_distance"/>
- <menu_item_check label="Symbole für Personen anzeigen" name="view_icons"/>
- <menu_item_call label="Ignorierte Einwohner & Objekte anzeigen" name="show_blocked_list"/>
+ <menu_item_check label="Nach Entfernung sortieren" name="sort_distance"/>
+ <menu_item_check label="Profilbilder anzeigen" name="view_icons"/>
+ <menu_item_call label="Zeige geblockte Einwohner & Objekte" name="show_blocked_list"/>
</menu>
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index 9a3973ffd3..9780c78e1b 100644 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -253,10 +253,8 @@ Für die gesamte Region ist Schaden aktiviert. Damit Waffen funktionieren, müssen Skripts erlaubt sein.
</notification>
<notification name="MultipleFacesSelected">
- Mehrere Flächen wurden ausgewählt.
-Wenn Sie fortfahren werden auf mehrere Flächen des Objekts unterschiedlichen Medien-Instanzen eingefügt.
-Um Medien nur auf einer Fläche einzufügen, wählen Sie "Textur auswählen" und klicken Sie auf die gewünschte Fläche des Objektes. Klicken Sie dann auf „Hinzufügen".
- <usetemplate ignoretext="Medien werden auf mehreren ausgewählten Flächen eingefügt." name="okcancelignore" notext="Abbrechen" yestext="OK"/>
+ Momentan sind mehrere Seiten ausgewählt. Wenn Sie fortfahren, werden einzelne Medien auf mehreren Seiten des Objektes dargestellt. Um die Medien auf einer einzigen Seite darzustellen, wählen Sie Textur auswählen und klicken Sie auf die gewünschte Seite. Danach klicken Sie Hinzufügen.
+ <usetemplate ignoretext="Die Medien werden auf mehrere ausgewählte Seiten übertragen" name="okcancelignore" notext="Abbrechen" yestext="OK"/>
</notification>
<notification name="WhiteListInvalidatesHomeUrl">
Wenn Sie diesen Eintrag zur Whitelist hinzufügen, dann wird die URL,
@@ -329,8 +327,8 @@ Gebühren werden nicht rückerstattet. <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
</notification>
<notification name="DeleteMedia">
- Sie haben die mit dieser Fläche verknüpften Medien ausgewählt, um diese zu löschen.
-Möchten Sie fortfahren?
+ Sie haben sich entschieden, die Medien auf dieser Seite zu löschen.
+Sind Sie sicher, dass Sie fortfahren wollen?
<usetemplate ignoretext="Bestätigen, bevor ich Medien von einem Objekt entferne." name="okcancelignore" notext="Nein" yestext="Ja"/>
</notification>
<notification name="ClassifiedSave">
diff --git a/indra/newview/skins/default/xui/de/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/de/panel_group_info_sidetray.xml index 677a32275d..fb08cbdda7 100644 --- a/indra/newview/skins/default/xui/de/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/de/panel_group_info_sidetray.xml @@ -1,24 +1,24 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Gruppeninfo" name="GroupInfo">
<panel.string name="default_needs_apply_text">
- Die Registerkarte enthält nicht gespeicherte Änderungen.
+ In der aktuellen Registerkarte befinden sich ungesicherte Änderungen
</panel.string>
<panel.string name="want_apply_text">
- Diese Änderungen speichern?
+ Möchten Sie diese Änderungen speichern?
</panel.string>
<panel.string name="group_join_btn">
- Mitglied werden ([AMOUNT] L$)
+ Beitreten ([AMOUNT]L$)
</panel.string>
<panel.string name="group_join_free">
Kostenlos
</panel.string>
- <text name="group_name" value="(wird geladen...)"/>
- <line_editor label="Neuen Gruppennamen hier eingeben" name="group_name_editor"/>
- <texture_picker label="" name="insignia" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
+ <text name="group_name" value="(Lädt...)"/>
+ <line_editor label="Geben Sie Ihren neuen Gruppennamen hier ein" name="group_name_editor"/>
+ <texture_picker label="" name="insignia" tool_tip="Klicken Sie, um ein Bild auszuwählen"/>
<text name="prepend_founded_by">
Gründer:
</text>
- <name_box initial_value="(wird in Datenbank gesucht)" name="founder_name"/>
+ <name_box initial_value="(empfange)" name="founder_name"/>
<text name="join_cost_text">
Kostenlos
</text>
@@ -27,10 +27,10 @@ <accordion_tab name="group_general_tab" title="Allgemein"/>
<accordion_tab name="group_roles_tab" title="Rollen"/>
<accordion_tab name="group_notices_tab" title="Mitteilungen"/>
- <accordion_tab name="group_land_tab" title="Land/Vermögen"/>
+ <accordion_tab name="group_land_tab" title="Land/Kapital"/>
</accordion>
<panel name="button_row">
- <button label="Bauen" label_selected="Neue Gruppe" name="btn_create"/>
+ <button label="Erstellen" label_selected="Neue Gruppe" name="btn_create"/>
<button label="Speichern" label_selected="Speichern" name="btn_apply"/>
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_media_settings_general.xml b/indra/newview/skins/default/xui/de/panel_media_settings_general.xml index 20771a980b..c5fd4d5be4 100644 --- a/indra/newview/skins/default/xui/de/panel_media_settings_general.xml +++ b/indra/newview/skins/default/xui/de/panel_media_settings_general.xml @@ -1,36 +1,28 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Allgemein" name="Media Settings General">
<text name="home_label">
- Start URL:
+ Home-URL:
</text>
- <line_editor name="home_url" tool_tip="Die Start-URL für diese Medienquelle"/>
+ <text name="home_fails_whitelist_label">
+ (Diese URL befindet sich nicht auf der festgelegten Whitelist)
+ </text>
+ <line_editor name="home_url" tool_tip="Die Home-URL für diese Medienquelle"/>
<text name="preview_label">
Vorschau
</text>
<text name="current_url_label">
- Aktuelle URL:
+ Derzeitige URL:
</text>
- <line_editor name="current_url" tool_tip="Die aktuelle URL für diese Medienquelle" value=""/>
+ <text name="current_url" tool_tip="Die derzeitige URL für diese Medienquelle" value=""/>
<button label="Zurücksetzen" name="current_url_reset_btn"/>
- <text name="controls_label">
- Steuerung:
- </text>
- <combo_box name="controls">
- <combo_item name="Standard">
- Standard
- </combo_item>
- <combo_item name="Mini">
- Mini
- </combo_item>
- </combo_box>
- <check_box initial_value="false" label="Auto-Loop" name="auto_loop"/>
- <check_box initial_value="false" label="Interaktion bei erstem Anklicken" name="first_click_interact"/>
- <check_box initial_value="false" label="Auto-Zoom" name="auto_zoom"/>
- <check_box initial_value="false" label="Medien automatisch wiedergeben" name="auto_play"/>
+ <check_box initial_value="false" label="Automatisch wiederholen" name="auto_loop"/>
+ <check_box initial_value="false" label="Interaktion beim ersten Anklicken" name="first_click_interact"/>
+ <check_box initial_value="false" label="Automatisch zoomen" name="auto_zoom"/>
+ <check_box initial_value="false" label="Medien automatisch abspielen" name="auto_play"/>
<text name="media_setting_note">
- Hinweis: Einwohner können diese Einstellung ausschalten
+ Hinweis: Einwohner können diese Einstellung überschreiben
</text>
- <check_box initial_value="false" label="Medien auf Objektoberfläche automatisch skalieren" name="auto_scale"/>
+ <check_box initial_value="false" label="Medien automatisch auf Objektflächen skalieren" name="auto_scale"/>
<text name="size_label">
Größe:
</text>
diff --git a/indra/newview/skins/default/xui/de/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/de/panel_media_settings_permissions.xml index 0db0be2dcb..d05b0d8808 100644 --- a/indra/newview/skins/default/xui/de/panel_media_settings_permissions.xml +++ b/indra/newview/skins/default/xui/de/panel_media_settings_permissions.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Steuerung" name="Media settings for controls">
- <check_box initial_value="false" label="Naviation & Interaktion deaktivieren" name="perms_owner_interact"/>
- <check_box initial_value="false" label="Steuerleiste ausblenden" name="perms_owner_control"/>
- <check_box initial_value="false" label="Naviation & Interaktion deaktivieren" name="perms_group_interact"/>
- <check_box initial_value="false" label="Steuerleiste ausblenden" name="perms_group_control"/>
- <check_box initial_value="false" label="Naviation & Interaktion deaktivieren" name="perms_anyone_interact"/>
- <check_box initial_value="false" label="Steuerleiste ausblenden" name="perms_anyone_control"/>
+ <check_box initial_value="false" label="Navigation & Interaktivität deaktivieren" name="perms_owner_interact"/>
+ <check_box initial_value="false" label="Kontrollleiste verstecken" name="perms_owner_control"/>
+ <check_box initial_value="false" label="Navigation & Interaktivität deaktivieren" name="perms_group_interact"/>
+ <check_box initial_value="false" label="Kontrollleiste verstecken" name="perms_group_control"/>
+ <check_box initial_value="false" label="Navigation & Interaktivität deaktivieren" name="perms_anyone_interact"/>
+ <check_box initial_value="false" label="Kontrollleiste verstecken" name="perms_anyone_control"/>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_media_settings_security.xml b/indra/newview/skins/default/xui/de/panel_media_settings_security.xml index 2fcd18864d..a5d378f95b 100644 --- a/indra/newview/skins/default/xui/de/panel_media_settings_security.xml +++ b/indra/newview/skins/default/xui/de/panel_media_settings_security.xml @@ -1,6 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Sicherheit" name="Media Settings Security">
- <check_box initial_value="false" label="Nur Zugangz zu festgelegten URLs (nach Präfix) erlauben" name="whitelist_enable"/>
+ <check_box initial_value="false" label="Zugang nur für bestimmte URLs ermöglichen (mittels Präfix)" name="whitelist_enable"/>
+ <text name="home_url_fails_some_items_in_whitelist">
+ Einträge, die auf ungültige Home-URLs hinweisen, sind markiert:
+ </text>
<button label="Hinzufügen" name="whitelist_add"/>
<button label="Löschen" name="whitelist_del"/>
+ <text name="home_url_fails_whitelist">
+ Warnung: Die Home-URL, die in der Registerkarte "Allgemein" angegeben wurde, entspricht nicht den Einträgen auf der Whitelist. Sie wurde deaktiviert, bis ein gültiger Eintrag angegeben wird.
+ </text>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_navigation_bar.xml b/indra/newview/skins/default/xui/de/panel_navigation_bar.xml index 3324556f98..1a67e9e45f 100644 --- a/indra/newview/skins/default/xui/de/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/de/panel_navigation_bar.xml @@ -1,12 +1,15 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="navigation_bar">
<panel name="navigation_panel">
- <button name="back_btn" tool_tip="Zurück zu vorheriger Position"/>
- <button name="forward_btn" tool_tip="Eine Position weiter"/>
- <button name="home_btn" tool_tip="An meinen Heimatort teleportieren"/>
- <location_input label="Ort" name="location_combo"/>
- <search_combo_box label="Suchen" name="search_combo_box" tool_tip="Suchen">
+ <button name="back_btn" tool_tip="Zurück zum vorherigen Standort gehen"/>
+ <button name="forward_btn" tool_tip="Um einen Standort weiter gehen"/>
+ <button name="home_btn" tool_tip="Zu meinem Heimatort teleportieren"/>
+ <location_input label="Standort" name="location_combo"/>
+ <search_combo_box label="Suche" name="search_combo_box" tool_tip="Suche">
<combo_editor label="[SECOND_LIFE] durchsuchen" name="search_combo_editor"/>
</search_combo_box>
</panel>
+ <favorites_bar name="favorite">
+ <chevron_button name=">>" tool_tip="Zeige weitere meiner Favoriten an"/>
+ </favorites_bar>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_general.xml b/indra/newview/skins/default/xui/de/panel_preferences_general.xml index 8e7d586fc3..e5bf1f5806 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_general.xml @@ -4,7 +4,7 @@ Sprache:
</text>
<combo_box name="language_combobox">
- <combo_box.item label="Systemstandard" name="System Default Language"/>
+ <combo_box.item label="Systemvorgabe" name="System Default Language"/>
<combo_box.item label="English (Englisch)" name="English"/>
<combo_box.item label="Danks (Dänisch) - Beta" name="Danish"/>
<combo_box.item label="Deutsch - Beta" name="Deutsch(German)"/>
@@ -18,7 +18,7 @@ <combo_box.item label="Testsprache" name="TestLanguage"/>
</combo_box>
<text name="language_textbox2">
- (Neustart erforderlich)
+ (Erfordert Neustart)
</text>
<text name="maturity_desired_prompt">
Ich möchte auf Inhalt mit folgender Alterseinstufung zugreifen:
@@ -27,40 +27,40 @@ <combo_box name="maturity_desired_combobox">
<combo_box.item label="PG, Mature und Adult" name="Desired_Adult"/>
<combo_box.item label="PG und Mature" name="Desired_Mature"/>
- <combo_box.item label="PG" name="Desired_PG"/>
+ <combo_box.item label="Allgemein" name="Desired_PG"/>
</combo_box>
<text name="start_location_textbox">
- Startposition:
+ Startstandort:
</text>
<combo_box name="start_location_combo">
<combo_box.item label="Mein letzter Standort" name="MyLastLocation" tool_tip="Als Standardeinstellung in letztem Standort anmelden."/>
<combo_box.item label="Mein Heimatort" name="MyHome" tool_tip="Als Standardeinstellung in Zuhauseposition anmelden."/>
</combo_box>
- <check_box initial_value="true" label="Bei Anmeldung anzeigen" name="show_location_checkbox"/>
+ <check_box initial_value="true" label="Beim Anmelden anzeigen" name="show_location_checkbox"/>
<text name="name_tags_textbox">
- Namensschilder:
+ Avatarnamen:
</text>
<radio_group name="Name_Tag_Preference">
<radio_item label="Aus" name="radio"/>
- <radio_item label="Ein" name="radio2"/>
- <radio_item label="Kurz anzeigen" name="radio3"/>
+ <radio_item label="An" name="radio2"/>
+ <radio_item label="Vorübergehend anzeigen" name="radio3"/>
</radio_group>
<check_box label="Meinen Namen anzeigen" name="show_my_name_checkbox1"/>
- <check_box initial_value="true" label="Kleine Namensschilder" name="small_avatar_names_checkbox"/>
+ <check_box initial_value="true" label="Kleine Avatarnamen" name="small_avatar_names_checkbox"/>
<check_box label="Gruppentitel anzeigen" name="show_all_title_checkbox1"/>
<text name="effects_color_textbox">
Meine Effekte:
</text>
<color_swatch label="" name="effect_color_swatch" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
<text name="title_afk_text">
- Timeout für Abwesenheit:
+ Zeit bis zur Abwesenheit:
</text>
<spinner label="" name="afk_timeout_spinner"/>
<text name="seconds_textbox">
Sekunden
</text>
<text name="text_box3">
- Beschäftigt-Modus-Antwort:
+ Antwort, wenn im „Beschäftigt“-Modus:
</text>
<text_editor name="busy_response">
log_in_to_change
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml index 056998c503..221d736cf9 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml @@ -1,26 +1,26 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Kommunikation" name="im">
<panel.string name="log_in_to_change">
- Zum Ändern anmelden
+ Anmelden, um Änderungen vorzunehmen
</panel.string>
- <button label="Cache löschen" name="clear_cache"/>
+ <button label="Verlauf leeren" name="clear_cache"/>
<text name="cache_size_label_l">
- (Positionen, Bilder, Internet, Suchverlauf)
+ (Standorte, Bilder, Web, Suchverlauf)
</text>
- <check_box label="Nur Freunden und Gruppen meinen Online-Status mitteilen" name="online_visibility"/>
- <check_box label="Nur IMs und Anrufe von Freunden oder Gruppen durchstellen" name="voice_call_friends_only_check"/>
- <check_box label="Nach Beendigung von Anrufen Mikrofon abschalten." name="auto_disengage_mic_check"/>
+ <check_box label="Nur Freunde und Gruppen wissen, dass ich online bin" name="online_visibility"/>
+ <check_box label="Nur Freunde und Gruppen können mich anrufen oder mir eine IM schicken" name="voice_call_friends_only_check"/>
+ <check_box label="Mikrofon ausschalten, wenn Anrufe beendet werden" name="auto_disengage_mic_check"/>
<check_box label="Cookies annehmen" name="cookies_enabled"/>
- <check_box label="Medien automatisch wiedergeben" name="autoplay_enabled"/>
- <check_box label="Medien auf Parzelle automatisch wiedergeben" name="parcel_autoplay_enabled"/>
+ <check_box label="Automatisches Abspielen von Medien erlauben" name="autoplay_enabled"/>
+ <check_box label="Medien auf Parzellen automatisch abspielen" name="parcel_autoplay_enabled"/>
<text name="Logs:">
- Logs:
+ Protokolle:
</text>
- <check_box label="Protokoll von Chats "in meiner Nähe" auf meinem Computer speichern" name="log_nearby_chat"/>
- <check_box label="IM-Protokolle auf meinem Computer speichern" name="log_instant_messages"/>
- <check_box label="Zeitangabe hinzufügen" name="show_timestamps_check_im"/>
+ <check_box label="Protokolle von Gesprächen in der Nähe auf meinem Computer speichern" name="log_nearby_chat"/>
+ <check_box label="IM Protokolle auf meinem Computer speichern" name="log_instant_messages"/>
+ <check_box label="Zeitstempel hinzufügen" name="show_timestamps_check_im"/>
<text name="log_path_desc">
- Speicherort für Protokolle
+ Speicherort der Protokolldateien
</text>
<button label="Durchsuchen" label_selected="Durchsuchen" name="log_path_button"/>
<button label="Ignorierte Einwohner/Objekte" name="block_list"/>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml index 662662d132..e37e2734a6 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml @@ -15,32 +15,32 @@ Maximale Bandbreite
</text>
<text name="text_box2">
- kbps
+ kbit/s
</text>
- <check_box label="Benutzerdefinierter Port" name="connection_port_enabled"/>
- <spinner label="Port-Nummer:" name="web_proxy_port"/>
+ <check_box label="Eigener Port" name="connection_port_enabled"/>
+ <spinner label="Portnummer:" name="web_proxy_port"/>
<text name="cache_size_label_l">
- Cache
+ Cachegröße
</text>
<text name="text_box5">
MB
</text>
<button label="Durchsuchen" label_selected="Durchsuchen" name="set_cache"/>
- <button label="Zurücksetzen" label_selected="Festlegen" name="reset_cache"/>
+ <button label="Zurücksetzen" label_selected="Set" name="reset_cache"/>
<text name="Cache location">
- Cache-Ordner
+ Speicherort des Caches
</text>
<text name="Web:">
- Internet:
+ Web:
</text>
<radio_group name="use_external_browser">
- <radio_item label="Integrierten Browser verwenden" name="internal" tool_tip="Den integrierten Browser für Hilfe, Internetlinks, usw. verwenden. Der Browser wird als eigenständiges Fenster in [APP_NAME] geöffnet."/>
- <radio_item label="Meinen Browser verwenden (IE, Firefox)" name="external" tool_tip="Standard-Browser für Hilfe, Weblinks usw. verwenden. Im Vollbildmodus nicht empfohlen."/>
+ <radio_item label="Integrierten Browser verwenden" name="internal" tool_tip="Integrierten Webbrowser verwenden, um die Hilfe, Weblinks usw. anzuzeigen. Dieser Browser öffnet als neues Fenster innerhalb von [APP_NAME]."/>
+ <radio_item label="Meinen Browser verwenden (IE, Firefox)" name="external" tool_tip="Standard Webbrowser des Systems verwenden, um die Hilfe, Weblinks usw. anzuzeigen. Bei Vollbildmodus nicht empfohlen."/>
</radio_group>
- <check_box initial_value="false" label="Web-Proxy" name="web_proxy_enabled"/>
- <line_editor name="web_proxy_editor" tool_tip="Name oder IP-Adresse des Proxys"/>
+ <check_box initial_value="false" label="Web Proxy" name="web_proxy_enabled"/>
+ <line_editor name="web_proxy_editor" tool_tip="Name oder IP Adresse des Proxyservers, den Sie benutzen möchten"/>
<button label="Durchsuchen" label_selected="Durchsuchen" name="set_proxy"/>
<text name="Proxy location">
- Proxy-Standort
+ Proxyadresse
</text>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/de/panel_prim_media_controls.xml index 54e512652e..6d541551b8 100644 --- a/indra/newview/skins/default/xui/de/panel_prim_media_controls.xml +++ b/indra/newview/skins/default/xui/de/panel_prim_media_controls.xml @@ -8,7 +8,7 @@ </string>
<layout_stack name="media_controls">
<layout_panel name="media_address">
- <line_editor name="media_address_url" tool_tip="Medien-URL"/>
+ <line_editor name="media_address_url" tool_tip="Medien URL"/>
<layout_stack name="media_address_url_icons">
<layout_panel>
<icon name="media_whitelist_flag" tool_tip="Whitelist aktiviert"/>
@@ -19,7 +19,7 @@ </layout_stack>
</layout_panel>
<layout_panel name="media_play_position">
- <slider_bar initial_value="0.5" name="media_play_slider" tool_tip="Fortschrittsbalken Filmwiedergabe"/>
+ <slider_bar initial_value="0.5" name="media_play_slider" tool_tip="Fortschritt der Filmwiedergabe"/>
</layout_panel>
<layout_panel name="media_volume">
<button name="media_volume_button" tool_tip="Dieses Medium stummschalten"/>
diff --git a/indra/newview/skins/default/xui/de/panel_teleport_history.xml b/indra/newview/skins/default/xui/de/panel_teleport_history.xml index d4db27b841..cfab9283b9 100644 --- a/indra/newview/skins/default/xui/de/panel_teleport_history.xml +++ b/indra/newview/skins/default/xui/de/panel_teleport_history.xml @@ -7,9 +7,9 @@ <accordion_tab name="3_days_ago" title="Vor 3 Tagen"/>
<accordion_tab name="4_days_ago" title="Vor 4 Tagen"/>
<accordion_tab name="5_days_ago" title="Vor 5 Tagen"/>
- <accordion_tab name="6_days_and_older" title="6 Tage oder älter"/>
- <accordion_tab name="1_month_and_older" title="1 Monat oder älter"/>
- <accordion_tab name="6_months_and_older" title="6 Monate oder älter"/>
+ <accordion_tab name="6_days_and_older" title="6 Tage und älter"/>
+ <accordion_tab name="1_month_and_older" title="1 Monat und älter"/>
+ <accordion_tab name="6_months_and_older" title="6 Monate und älter"/>
</accordion>
<panel label="bottom_panel" name="bottom_panel"/>
</panel>
diff --git a/indra/newview/skins/default/xui/en/floater_script.xml b/indra/newview/skins/default/xui/en/floater_script.xml index f44ba6d873..c3e974d978 100644 --- a/indra/newview/skins/default/xui/en/floater_script.xml +++ b/indra/newview/skins/default/xui/en/floater_script.xml @@ -7,7 +7,6 @@ layout="topleft" left="0" name="script_floater" - help_topic="script_floater" top="0" can_dock="true" can_minimize="true" diff --git a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml index 4642e82c0b..d96f3c5494 100644 --- a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml @@ -17,7 +17,7 @@ layout="topleft" name="copy_gesture"> <on_click - function="Gesture.Action.CopyPast" + function="Gesture.Action.CopyPaste" parameter="copy_gesture" /> <on_enable function="Gesture.EnableAction" @@ -28,7 +28,7 @@ layout="topleft" name="paste"> <on_click - function="Gesture.Action.CopyPast" + function="Gesture.Action.CopyPaste" parameter="paste" /> <on_enable function="Gesture.EnableAction" @@ -39,7 +39,7 @@ layout="topleft" name="copy_uuid"> <on_click - function="Gesture.Action.CopyPast" + function="Gesture.Action.CopyPaste" parameter="copy_uuid" /> <on_enable function="Gesture.EnableAction" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 134a21086a..957b4d74db 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -4987,7 +4987,7 @@ No valid parcel could be found. icon="notify.tga" name="ObjectGiveItem" type="offer"> -An object named [OBJECTFROMNAME] owned by [NAME_SLURL] has given you [OBJECTTYPE]: +An object named [OBJECTFROMNAME] owned by [NAME_SLURL] has given you this [OBJECTTYPE]: [ITEM_SLURL] <form name="form"> <button @@ -5009,7 +5009,7 @@ An object named [OBJECTFROMNAME] owned by [NAME_SLURL] has given you [OBJECTTYPE icon="notify.tga" name="ObjectGiveItemUnknownUser" type="offer"> -An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you [OBJECTTYPE]: +An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you this [OBJECTTYPE]: [ITEM_SLURL] <form name="form"> <button @@ -5031,7 +5031,7 @@ An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you [O icon="notify.tga" name="UserGiveItem" type="offer"> -[NAME_SLURL] has given you [OBJECTTYPE]: +[NAME_SLURL] has given you this [OBJECTTYPE]: [ITEM_SLURL] <form name="form"> <button diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index adaab17dc4..de3de45718 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -103,7 +103,7 @@ min_width="52" name="gesture_panel" user_resize="false"> - <gesture_combo_box + <gesture_combo_list follows="left|right" height="23" label="Gesture" @@ -113,10 +113,10 @@ top="5" width="82" tool_tip="Shows/hides gestures"> - <gesture_combo_box.drop_down_button + <gesture_combo_list.combo_button pad_right="10" use_ellipses="true" /> - </gesture_combo_box> + </gesture_combo_list> </layout_panel> <icon auto_resize="false" diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml index 5c594d3f14..677bdbc3d2 100644 --- a/indra/newview/skins/default/xui/en/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml @@ -7,6 +7,7 @@ left="0" min_height="350" name="panel_classified_info" + help_topic="profile_classified_info" top="0" width="333"> <panel.string diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml index 1fbf7abda9..188ded3dab 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml @@ -9,6 +9,7 @@ left="0" min_height="350" name="panel_edit_classified" + help_topic="profile_edit_classified" top="0" width="333"> <panel.string diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml index d6de5af32d..15eff4b67c 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml @@ -9,6 +9,7 @@ left="0" min_height="350" name="panel_edit_pick" + help_topic="profile_edit_pick" top="0" width="333"> <button @@ -38,28 +39,27 @@ <scroll_container color="DkGray2" follows="all" - height="510" + height="500" layout="topleft" left="10" top_pad="10" name="profile_scroll" - reserve_scroll_corner="false" opaque="true" width="313"> <panel name="scroll_content_panel" - follows="left|top" + follows="left|top|right" min_height="300" layout="topleft" top="0" background_visible="false" - height="510" + height="500" left="0" - width="295"> + width="285"> <texture_picker follows="left|top|right" height="197" - width="290" + width="280" layout="topleft" top="20" left="10" @@ -77,7 +77,7 @@ <text type="string" length="1" - follows="left|top" + follows="left|top|right" height="15" font="SansSerifSmall" font.style="BOLD" @@ -86,7 +86,7 @@ top="215" name="Name:" text_color="white" - width="290"> + width="280"> Title: </text> <line_editor @@ -99,11 +99,11 @@ max_length="63" name="pick_name" text_color="black" - width="290" /> + width="280" /> <text type="string" length="1" - follows="left|top" + follows="left|top|right" height="15" font="SansSerifSmall" font.style="BOLD" @@ -112,13 +112,13 @@ top_pad="20" name="description_label" text_color="white" - width="290"> + width="280"> Description: </text> <text_editor follows="left|top|right" height="100" - width="290" + width="280" hide_scrollbar="false" layout="topleft" left="10" @@ -132,27 +132,26 @@ length="1" font="SansSerifSmall" font.style="BOLD" - follows="left|top" + follows="left|top|right" height="15" layout="topleft" left="10" name="location_label" text_color="white" top_pad="20" - width="290"> + width="280"> Location: </text> <text type="string" length="1" - follows="left|top" + follows="left|top|right" height="50" layout="topleft" left="10" name="pick_location" - right="-10" top_pad="2" - width="290" + width="280" word_wrap="true"> loading... </text> diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml index e096715cee..0d9c2c2162 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml @@ -136,6 +136,7 @@ Maximum 200 per group daily left_pad="3" max_length="63" name="create_subject" + prevalidate_callback="ascii" width="220" /> <text follows="left|top" diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index e5df37e366..df942b1a26 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -186,6 +186,7 @@ height="80"> <text follows="right|bottom" font="SansSerifSmall" +text_color="EmphasisColor" halign="right" height="16" top="12" diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml index 9d00abd2c9..4030c7184a 100644 --- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml @@ -41,6 +41,7 @@ halign="center" follows="all" height="295" label="MY INVENTORY" + help_topic="my_inventory_tab" layout="topleft" left="0" name="All Items" @@ -51,6 +52,7 @@ halign="center" follows="all" height="295" label="RECENT" + help_topic="recent_inventory_tab" layout="topleft" left_delta="0" name="Recent Items" diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml index f68202d287..822e049eec 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml @@ -7,6 +7,7 @@ left="0" min_height="350" name="panel_pick_info" + help_topic="profile_pick_info" top="0" width="333"> <button @@ -40,31 +41,30 @@ left="10" top_pad="10" name="profile_scroll" - reserve_scroll_corner="false" width="313"> <panel name="scroll_content_panel" - follows="left|top" + follows="left|top|right" min_height="300" layout="topleft" top="0" background_visible="false" - height="470" + height="400" left="0" - width="295"> + width="285"> <texture_picker enabled="false" - follows="left|top" + follows="left|top|right" height="197" layout="topleft" left="10" name="pick_snapshot" top="20" - width="290" /> + width="280" /> <text follows="left|top|right" height="35" - width="290" + width="280" layout="topleft" font="SansSerifBig" font.style="BOLD" @@ -75,23 +75,29 @@ value="[name]" use_ellipses="true" /> <text - follows="left|top" + follows="left|top|right" height="25" layout="topleft" left="10" name="pick_location" - width="290" + width="280" word_wrap="true" value="[loading...]" /> - <text - follows="left|top|right" - height="280" + <text_editor + bg_readonly_color="DkGray2" + follows="all" + height="100" + width="280" + hide_scrollbar="false" layout="topleft" left="10" + top_pad="2" + max_length="1023" name="pick_desc" - width="290" + read_only="true" + text_readonly_color="white" value="[description]" - word_wrap="true" /> + wrap="true" /> </panel> </scroll_container> <panel diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml index 1fc553ff36..a2b0adf9d9 100644 --- a/indra/newview/skins/default/xui/en/panel_picks.xml +++ b/indra/newview/skins/default/xui/en/panel_picks.xml @@ -124,7 +124,6 @@ height="25" top_pad="10" name="buttons_cucks" - help_topic="picks_button_tab" width="313"> <button enabled="false" diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml index 51974be854..fb5f9d2ec8 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml @@ -33,7 +33,6 @@ <panel height="25" layout="bottomright" - help_topic="item_button_tab" name="button_panel" left="5" bottom="5" diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml index 4a992dadd9..e18f59ab64 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -401,7 +401,6 @@ top_pad="10" <panel height="30" layout="bottomright" - help_topic="button_tab" name="button_panel" left="5" bottom="2" @@ -414,4 +413,4 @@ top_pad="10" right="-1" width="100" /> </panel> - </panel>
\ No newline at end of file + </panel> diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml index 2dfcdf4a4c..74f97dca4e 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml @@ -518,7 +518,6 @@ <panel height="25" layout="bottomright" - help_topic="button_tab" name="button_panel" left="5" bottom="5" @@ -551,4 +550,4 @@ top="0" width="100" /> </panel> -</panel>
\ No newline at end of file +</panel> diff --git a/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml deleted file mode 100644 index 4229f34c09..0000000000 --- a/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<gesture_combo_box - label="Gestures" - list_position="below" - max_chars="20" - follows="right|top"> - <gesture_combo_box.combo_button name="Combobox Button" - label="" - hover_glow_amount="0.15" - scale_image="true" - image_unselected="ComboButton_Off" - image_selected="ComboButton_Selected" - image_disabled="ComboButton_Disabled" - image_disabled_selected="ComboButton_Disabled_Selected" /> - <gesture_combo_box.drop_down_button name="Drop Down Button" - label="" - halign="center" - hover_glow_amount="0.15" - scale_image="true" - image_selected="PushButton_Selected_Press" - image_pressed="PushButton_Press" - image_pressed_selected="PushButton_Selected_Press" - image_unselected="PushButton_Off" - image_disabled="PushButton_Disabled" - image_disabled_selected="PushButton_Selected_Disabled" /> - <gesture_combo_box.combo_list bg_writeable_color="MenuDefaultBgColor" - scroll_bar_bg_visible="false" /> - <gesture_combo_box.combo_editor name="Combo Text Entry" - select_on_focus="true" /> -</gesture_combo_box> diff --git a/indra/newview/skins/default/xui/en/widgets/gesture_combo_list.xml b/indra/newview/skins/default/xui/en/widgets/gesture_combo_list.xml new file mode 100644 index 0000000000..808683864d --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/gesture_combo_list.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<gesture_combo_list + follows="right|top"> + <gesture_combo_list.combo_button + name="Combolist Button" + label="" + layout="topleft" + halign="center" + hover_glow_amount="0.15" + mouse_opaque="false" + scale_image="true" + image_selected="PushButton_Selected_Press" + image_pressed="PushButton_Press" + image_pressed_selected="PushButton_Selected_Press" + image_unselected="PushButton_Off" + image_disabled="PushButton_Disabled" + image_disabled_selected="PushButton_Selected_Disabled" /> + <gesture_combo_list.combo_list + bg_writeable_color="MenuDefaultBgColor" + scroll_bar_bg_visible="false" /> +</gesture_combo_list> diff --git a/indra/newview/skins/default/xui/es/floater_buy_currency.xml b/indra/newview/skins/default/xui/es/floater_buy_currency.xml index eb25493adc..1ecb813dd1 100644 --- a/indra/newview/skins/default/xui/es/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/es/floater_buy_currency.xml @@ -52,6 +52,9 @@ <text name="total_amount"> [AMT] L$ </text> + <text name="currency_links"> + [http://www.secondlife.com/my/account/payment_method_management.php?lang=es-ES payment method] | [http://www.secondlife.com/my/account/currency.php?lang=es-ES currency] | [http://www.secondlife.com/my/account/exchange_rates.php?lang=es-ES exchange rate] + </text> <text name="purchase_warning_repurchase" right="-10"> Confirmando esta compra sólo compra la moneda. Tendrá que intentar de nuevo la operación. diff --git a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml index e6a49cbc6f..9a92c446f2 100644 --- a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml @@ -46,12 +46,12 @@ [AMT] L$
</text>
<text name="currency_links">
- [http://www.secondlife.com/ payment method] | [http://www.secondlife.com/ currency] | [http://www.secondlife.com exchange rate]
+ [http://www.secondlife.com/my/account/payment_method_management.php?lang=fr-FR payment method] | [http://www.secondlife.com/my/account/currency.php?lang=fr-FR currency] | [http://www.secondlife.com/my/account/exchange_rates.php?lang=fr-FR exchange rate]
</text>
<text name="exchange_rate_note">
Saisissez à nouveau le montant pour voir le taux de change actuel.
</text>
- <text bottom_delta="-64" height="48" name="purchase_warning_repurchase" right="-10">
+ <text name="purchase_warning_repurchase">
La confirmation de cet achat n'achète que des L$, pas l'objet.
</text>
<text bottom_delta="16" name="purchase_warning_notenough">
diff --git a/indra/newview/skins/default/xui/fr/floater_help_browser.xml b/indra/newview/skins/default/xui/fr/floater_help_browser.xml index 0eb3ea3d21..20894d42fc 100644 --- a/indra/newview/skins/default/xui/fr/floater_help_browser.xml +++ b/indra/newview/skins/default/xui/fr/floater_help_browser.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_help_browser" title="NAVIGATEUR D'AIDE">
<floater.string name="home_page_url">
- http://www.secondlife.com
+ http://fr.secondlife.com
</floater.string>
<floater.string name="support_page_url">
- http://support.secondlife.com
+ http://fr.secondlife.com/support
</floater.string>
<layout_stack name="stack1">
<layout_panel name="external_controls">
diff --git a/indra/newview/skins/default/xui/it/floater_buy_currency.xml b/indra/newview/skins/default/xui/it/floater_buy_currency.xml index a22850bc4b..8a59764251 100644 --- a/indra/newview/skins/default/xui/it/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/it/floater_buy_currency.xml @@ -52,10 +52,11 @@ <text name="total_amount"> [AMT]L$ </text> - <text name="purchase_warning_repurchase" height="48" bottom_delta="-64" right="-10"> - Confermando questa operazione si acquisterà solo -la valuta. Per acquistare il bene, dovrai riprovare -l'operazione nuovamente. + <text name="currency_links"> + [http://www.secondlife.com/my/account/payment_method_management.php?lang=it-IT payment method] | [http://www.secondlife.com/my/account/currency.php?lang=it-IT currency] | [http://www.secondlife.com/my/account/exchange_rates.php?lang=it-IT exchange rate] + </text> + <text name="purchase_warning_repurchase"> + Confermando questa operazione si acquisterà solo la valuta. Per acquistare il bene, dovrai riprovare l'operazione nuovamente. </text> <text name="purchase_warning_notenough" bottom_delta="16"> Non stai comprando abbastanza denaro. diff --git a/indra/newview/skins/default/xui/ja/floater_buy_currency.xml b/indra/newview/skins/default/xui/ja/floater_buy_currency.xml index 03cd0f391a..9d49a38982 100644 --- a/indra/newview/skins/default/xui/ja/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/ja/floater_buy_currency.xml @@ -46,7 +46,7 @@ L$ [AMT]
</text>
<text name="currency_links">
- [http://www.secondlife.com/ payment method] | [http://www.secondlife.com/ currency] | [http://www.secondlife.com exchange rate]
+ [http://www.secondlife.com/my/account/payment_method_management.php?lang=ja-JP payment method] | [http://www.secondlife.com/my/account/currency.php?lang=ja-JP currency] | [http://www.secondlife.com/my/account/exchange_rates.php?lang=ja-JP exchange rate]
</text>
<text name="exchange_rate_note">
金額を再入力して最新換算レートを確認します。
diff --git a/indra/newview/skins/default/xui/pt/floater_buy_currency.xml b/indra/newview/skins/default/xui/pt/floater_buy_currency.xml index aac8438fdc..f17c069ecf 100644 --- a/indra/newview/skins/default/xui/pt/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/pt/floater_buy_currency.xml @@ -52,6 +52,9 @@ <text name="total_amount"> L$ [AMT] </text> + <text name="currency_links"> + [http://www.secondlife.com/my/account/payment_method_management.php?lang=pt-BR payment method] | [http://www.secondlife.com/my/account/currency.php?lang=pt-BR currency] | [http://www.secondlife.com/my/account/exchange_rates.php?lang=pt-BR exchange rate] + </text> <text name="purchase_warning_repurchase"> Confirmando esta compra só compra a moeda. Você precisará tentar novamente a operação. diff --git a/indra/newview/tests/llviewerhelputil_test.cpp b/indra/newview/tests/llviewerhelputil_test.cpp index ec612c4606..d7dd199722 100644 --- a/indra/newview/tests/llviewerhelputil_test.cpp +++ b/indra/newview/tests/llviewerhelputil_test.cpp @@ -78,9 +78,21 @@ static void substitute_string(std::string &input, const std::string &search, con } } +class LLAgent +{ +public: + LLAgent() {} + ~LLAgent() {} + BOOL isGodlike() const { return FALSE; } +private: + int dummy; +}; +LLAgent gAgent; + std::string LLWeb::expandURLSubstitutions(const std::string &url, const LLSD &default_subs) { + (void)gAgent.isGodlike(); // ref symbol to stop compiler from stripping it std::string new_url = url; substitute_string(new_url, "[TOPIC]", default_subs["TOPIC"].asString()); substitute_string(new_url, "[VERSION]", gVersion); @@ -91,6 +103,7 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url, return new_url; } + //---------------------------------------------------------------------------- namespace tut |