diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h index 853c427a1..ca6d76a98 100644 --- a/indra/llcommon/llregistry.h +++ b/indra/llcommon/llregistry.h @@ -307,6 +307,8 @@ public: virtual ~StaticRegistrar() {} StaticRegistrar(ref_const_key_t key, ref_const_value_t value) { + if(!singleton_t::instance().mStaticScope) + mStaticScope = new ScopedRegistrar(); singleton_t::instance().mStaticScope->add(key, value); } }; @@ -336,7 +338,7 @@ protected: virtual void initSingleton() { - mStaticScope = new ScopedRegistrar(); + //mStaticScope = new ScopedRegistrar(); } virtual ~LLRegistrySingleton() diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index dc452d1ef..fc5484433 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -56,6 +56,7 @@ bool LLPluginClassMedia::init_impl(void) { // Queue up the media init message -- it will be sent after all the currently queued messages. LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "init"); + message.setValue("target", mTarget); sendMessage(message); return true; @@ -246,16 +247,18 @@ unsigned char* LLPluginClassMedia::getBitsData() void LLPluginClassMedia::setSize(int width, int height) { - if (width <= 0 || height <= 0) - { - width = height = -1; - } - if (mSetMediaWidth != width || mSetMediaHeight != height) + if((width > 0) && (height > 0)) { mSetMediaWidth = width; mSetMediaHeight = height; - setSizeInternal(); } + else + { + mSetMediaWidth = -1; + mSetMediaHeight = -1; + } + + setSizeInternal(); } void LLPluginClassMedia::setSizeInternal(void) diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index f5bb0b5e8..f5950aff3 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -78,13 +78,12 @@ void LLPanel::init() setTabStop(FALSE); mVisibleSignal = NULL; - - mCommitCallbackRegistrar = false; - mEnableCallbackRegistrar = false; } LLPanel::LLPanel() -: mRectControl() +: mRectControl(), + mCommitCallbackRegistrar(false), + mEnableCallbackRegistrar(false) { init(); setName(std::string("panel")); @@ -92,7 +91,9 @@ LLPanel::LLPanel() LLPanel::LLPanel(const std::string& name) : LLUICtrl(name), - mRectControl() + mRectControl(), + mCommitCallbackRegistrar(false), + mEnableCallbackRegistrar(false) { init(); } @@ -100,7 +101,9 @@ LLPanel::LLPanel(const std::string& name) LLPanel::LLPanel(const std::string& name, const LLRect& rect, BOOL bordered) : LLUICtrl(name,rect), - mRectControl() + mRectControl(), + mCommitCallbackRegistrar(false), + mEnableCallbackRegistrar(false) { init(); if (bordered) @@ -112,7 +115,9 @@ LLPanel::LLPanel(const std::string& name, const LLRect& rect, BOOL bordered) LLPanel::LLPanel(const std::string& name, const std::string& rect_control, BOOL bordered) : LLUICtrl(name, LLUI::sConfigGroup->getRect(rect_control)), - mRectControl( rect_control ) + mRectControl( rect_control ), + mCommitCallbackRegistrar(false), + mEnableCallbackRegistrar(false) { init(); if (bordered) diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index a90263dba..3fcd5ab1d 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -492,9 +492,9 @@ void LLUICtrl::initFromXML(LLXMLNodePtr node, LLView* parent) if (func) { if(child_node->getAttributeString("parameter",attrib_str)) - setCommitCallback(boost::bind((*func), this, LLSD(attrib_str))); + setValidateCallback(boost::bind((*func), this, LLSD(attrib_str))); else - setCommitCallback(commit_signal_t::slot_type(*func)); + setValidateCallback(enable_signal_t::slot_type(*func)); } } } diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index 085954448..d2d5fa585 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -41,6 +41,17 @@ #include "lluuid.h" #include "lldiriterator.h" +#include "stringize.h" +#include +#include +#include +#include +#include +#include +#include + +using boost::assign::list_of; +using boost::assign::map_list_of; #if LL_WINDOWS #include "lldir_win32.h" @@ -86,12 +97,17 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask) std::string fullpath; S32 result; + // File masks starting with "/" will match nothing, so we consider them invalid. + if (LLStringUtil::startsWith(mask, getDirDelimiter())) + { + llwarns << "Invalid file mask: " << mask << llendl; + llassert(!"Invalid file mask"); + } + LLDirIterator iter(dirname, mask); while (iter.next(filename)) { - fullpath = dirname; - fullpath += getDirDelimiter(); - fullpath += filename; + fullpath = add(dirname, filename); if(LLFile::isdir(fullpath)) { @@ -259,12 +275,12 @@ std::string LLDir::buildSLOSCacheDir() const } else { - res = getOSUserAppDir() + mDirDelimiter + "cache_sg1"; + res = add(getOSUserAppDir(), "cache_sg1"); } } else { - res = getOSCacheDir() + mDirDelimiter + "SingularityViewer"; + res = add(getOSCacheDir(), "SingularityViewer"); } return res; } @@ -312,6 +328,39 @@ const std::string &LLDir::getLLPluginDir() const return mLLPluginDir; } +static std::string ELLPathToString(ELLPath location) +{ + typedef std::map ELLPathMap; +#define ENT(symbol) (symbol, #symbol) + static const ELLPathMap sMap = map_list_of + ENT(LL_PATH_NONE) + ENT(LL_PATH_USER_SETTINGS) + ENT(LL_PATH_APP_SETTINGS) + ENT(LL_PATH_PER_SL_ACCOUNT) // returns/expands to blank string if we don't know the account name yet + ENT(LL_PATH_CACHE) + ENT(LL_PATH_CHARACTER) + ENT(LL_PATH_HELP) + ENT(LL_PATH_LOGS) + ENT(LL_PATH_TEMP) + ENT(LL_PATH_SKINS) + ENT(LL_PATH_TOP_SKIN) + ENT(LL_PATH_CHAT_LOGS) + ENT(LL_PATH_PER_ACCOUNT_CHAT_LOGS) + ENT(LL_PATH_USER_SKIN) + ENT(LL_PATH_LOCAL_ASSETS) + ENT(LL_PATH_EXECUTABLE) + ENT(LL_PATH_DEFAULT_SKIN) + ENT(LL_PATH_FONTS) + ENT(LL_PATH_LAST) + ; +#undef ENT + + ELLPathMap::const_iterator found = sMap.find(location); + if (found != sMap.end()) + return found->second; + return STRINGIZE("Invalid ELLPath value " << location); +} + std::string LLDir::getExpandedFilename(ELLPath location, const std::string& filename) const { return getExpandedFilename(location, "", filename); @@ -403,45 +452,29 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd llassert(0); } - std::string filename = in_filename; - if (!subdir2.empty()) - { - filename = add(subdir2, filename); - } - - if (!subdir1.empty()) - { - filename = add(subdir1, filename); - } - if (prefix.empty()) { - llwarns << "prefix is empty, possible bad filename" << llendl; - } - - std::string expanded_filename; - if (!filename.empty()) - { - if (!prefix.empty()) - { - expanded_filename = add(prefix, filename); - } - else - { - expanded_filename = filename; - } - } - else if (!prefix.empty()) - { - // Directory only, no file name. - expanded_filename = prefix; - } - else - { - expanded_filename.assign(""); + llwarns << ELLPathToString(location) + << ", '" << subdir1 << "', '" << subdir2 << "', '" << in_filename + << "': prefix is empty, possible bad filename" << llendl; } - //llinfos << "*** EXPANDED FILENAME: <" << expanded_filename << ">" << llendl; + std::string expanded_filename = add(add(prefix, subdir1), subdir2); + if (expanded_filename.empty() && in_filename.empty()) + { + return ""; + } + // Use explicit concatenation here instead of another add() call. Callers + // passing in_filename as "" expect to obtain a pathname ending with + // mDirSeparator so they can later directly concatenate with a specific + // filename. A caller using add() doesn't care, but there's still code + // loose in the system that uses std::string::operator+(). + expanded_filename += mDirDelimiter; + expanded_filename += in_filename; + + LL_DEBUGS("LLDir") << ELLPathToString(location) + << ", '" << subdir1 << "', '" << subdir2 << "', '" << in_filename + << "' => '" << expanded_filename << "'" << LL_ENDL; return expanded_filename; } diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp index 3d7818338..0fd4615b4 100644 --- a/indra/mac_updater/mac_updater.cpp +++ b/indra/mac_updater/mac_updater.cpp @@ -1133,9 +1133,7 @@ void *updatethreadproc(void*) llinfos << "Clearing cache..." << llendl; - char mask[LL_MAX_PATH]; /* Flawfinder: ignore */ - snprintf(mask, LL_MAX_PATH, "%s*.*", gDirUtilp->getDirDelimiter().c_str()); - gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask); + gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),"*.*"); llinfos << "Clear complete." << llendl; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index c71c132bc..0da5098d0 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -455,7 +455,6 @@ set(viewer_SOURCE_FILES llurl.cpp llurldispatcher.cpp llurlhistory.cpp - llurlsimstring.cpp llurlwhitelist.cpp lluserauth.cpp llvectorperfoptions.cpp @@ -957,7 +956,6 @@ set(viewer_HEADER_FILES llurl.h llurldispatcher.h llurlhistory.h - llurlsimstring.h llurlwhitelist.h lluserauth.h llvectorperfoptions.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index fd0109f61..cef6e295d 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2224,6 +2224,17 @@ This should be as low as possible, but too low may break functionality F32 Value 0.075 + + AudioStreamingMedia + + Comment + Enable streaming + Persist + 1 + Type + Boolean + Value + 1 AudioStreamingMusic @@ -2691,23 +2702,23 @@ This should be as low as possible, but too low may break functionality Value 0 - PluginAttachDebuggerToPlugins + BrowserEnableJSObject Comment - Opens a terminal window with a debugger and attach it, every time a new SLPlugin process is started. + (WARNING: Advanced feature. Use if you are aware of the implications). Enable or disable the viewer to Javascript bridge object. Persist - 1 + 0 Type Boolean Value - 0 + 0 BlockAvatarAppearanceMessages - - Comment - Ignores appearance messages (for simulating Ruth) - Persist - 1 + + Comment + Ignores appearance messages (for simulating Ruth) + Persist + 1 Type Boolean Value @@ -3769,17 +3780,6 @@ This should be as low as possible, but too low may break functionality - CmdLineRegionURI - - Comment - URL of region to connect to through Agent Domain. - Persist - 0 - Type - String - Value - - ColorPaletteEntry01 Comment @@ -5419,6 +5419,17 @@ This should be as low as possible, but too low may break functionality Value 0 + DisableExternalBrowser + + Comment + Disable opening an external browser. + Persist + 1 + Type + Boolean + Value + 0 + DisableRendering Comment @@ -6014,17 +6025,6 @@ This should be as low as possible, but too low may break functionality Value 1 - FirstLoginThisInstall - - Comment - Specifies that you have not successfully logged in since you installed the latest update - Persist - 1 - Type - Boolean - Value - 1 - FirstName Comment @@ -6069,6 +6069,17 @@ This should be as low as possible, but too low may break functionality Value 1 + FirstLoginThisInstall + + Comment + Specifies that you have not successfully logged in since you installed the latest update + Persist + 1 + Type + Boolean + Value + 1 + FixedWeather Comment @@ -9109,16 +9120,16 @@ This should be as low as possible, but too low may break functionality Value 0 - LoginLastLocation + LoginLocation Comment - Login at same location you last logged out + Default Login location ('last', 'home') preference Persist 1 Type - Boolean + String Value - 1 + last LoginPage @@ -9435,13 +9446,68 @@ This should be as low as possible, but too low may break functionality Persist 1 Type - Boolean - Value - 0 - - MemoryFailurePreventionEnabled - - Comment + Boolean + Value + 1 + + MediaPerformanceManagerDebug + + Comment + Whether to show debug data for the media performance manager in the nearby media list. + Persist + 1 + Type + Boolean + Value + 0 + + MediaShowOnOthers + + Comment + Whether or not to show media on other avatars + Persist + 1 + Type + Boolean + Value + 0 + + MediaShowOutsideParcel + + Comment + Whether or not to show media from outside the current parcel + Persist + 1 + Type + Boolean + Value + 1 + + MediaShowWithinParcel + + Comment + Whether or not to show media within the current parcel + Persist + 1 + Type + Boolean + Value + 1 + + MediaTentativeAutoPlay + + Comment + This is a tentative flag that may be temporarily set off by the user, until she teleports + Persist + 0 + Type + Boolean + Value + 1 + + MemoryFailurePreventionEnabled + + Comment If set, the viewer will quit to avoid crash when memory failure happens Persist 1 @@ -10426,6 +10492,86 @@ This should be as low as possible, but too low may break functionality Value 1 + PluginAttachDebuggerToPlugins + + Comment + If true, attach a debugger session to each plugin process as it's launched. + Persist + 1 + Type + Boolean + Value + 0 + + PluginInstancesCPULimit + + Comment + Amount of total plugin CPU usage before inworld plugins start getting turned down to "slideshow" priority. Set to 0 to disable this check. + Persist + 1 + Type + F32 + Value + 0.9 + + + PlainTextChatHistory + + Comment + Enable/Disable plain text chat history style + Persist + 1 + Type + Boolean + Value + 0 + + + PluginInstancesLow + + Comment + Limit on the number of inworld media plugins that will run at "low" priority + Persist + 1 + Type + U32 + Value + 4 + + PluginInstancesNormal + + Comment + Limit on the number of inworld media plugins that will run at "normal" or higher priority + Persist + 1 + Type + U32 + Value + 2 + + PluginInstancesTotal + + Comment + Hard limit on the number of plugins that will be instantiated at once for inworld media + Persist + 1 + Type + U32 + Value + 8 + + + PluginUseReadThread + + Comment + Use a separate thread to read incoming messages from plugins + Persist + 1 + Type + Boolean + Value + 0 + PlayTypingSound Comment @@ -10629,6 +10775,94 @@ This should be as low as possible, but too low may break functionality + PrimMediaMasterEnabled + + Comment + Whether or not Media on a Prim is enabled. + Persist + 1 + Type + Boolean + Value + 1 + + PrimMediaControlsUseHoverControlSet + + Comment + Whether or not hovering over prim media uses minimal "hover" controls or the authored control set. + Persist + 1 + Type + Boolean + Value + 0 + + PrimMediaDragNDrop + + Comment + Enable drag and drop of URLs onto prim faces + Persist + 1 + Type + Boolean + Value + 1 + + PrimMediaMaxRetries + + Comment + Maximum number of retries for media queries. + Persist + 1 + Type + U32 + Value + 4 + + PrimMediaRequestQueueDelay + + Comment + Timer delay for fetching media from the queue (in seconds). + Persist + 1 + Type + F32 + Value + 1.0 + + PrimMediaRetryTimerDelay + + Comment + Timer delay for retrying on media queries (in seconds). + Persist + 1 + Type + F32 + Value + 5.0 + + PrimMediaMaxSortedQueueSize + + Comment + Maximum number of objects the viewer will load media for initially + Persist + 1 + Type + U32 + Value + 100000 + + PrimMediaMaxRoundRobinQueueSize + + Comment + Maximum number of objects the viewer will continuously update media for + Persist + 1 + Type + U32 + Value + 100000 + PreviewAnimRect Comment @@ -10937,6 +11171,50 @@ This should be as low as possible, but too low may break functionality Value 1.0 + WebContentWindowLimit + + Comment + Maximum number of web browser windows that can be open at once in the Web content floater (0 for no limit) + Persist + 1 + Type + S32 + Value + 5 + + MediaRollOffRate + + Comment + Multiplier to change rate of media attenuation + Persist + 1 + Type + F32 + Value + 0.125 + + MediaRollOffMin + + Comment + Adjusts the distance at which media attentuation starts + Persist + 1 + Type + F32 + Value + 5.0 + + MediaRollOffMax + + Comment + Distance at which media volume is set to 0 + Persist + 1 + Type + F32 + Value + 30.0 + RecentItemsSortOrder Comment diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 34255feba..68e048e3a 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -980,6 +980,8 @@ bool LLAppViewer::init() LLEnvManagerNew::instance().usePrefs(); gGLActive = FALSE; + LLViewerMedia::initClass(); + LL_INFOS("InitInfo") << "Viewer media initialized." << LL_ENDL ; return true; } @@ -1706,8 +1708,7 @@ bool LLAppViewer::cleanup() if (mPurgeOnExit) { llinfos << "Purging all cache files on exit" << llendflush; - std::string mask = gDirUtilp->getDirDelimiter() + "*.*"; - gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask); + gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),"*.*"); } removeMarkerFile(); // Any crashes from here on we'll just have to ignore @@ -2669,8 +2670,7 @@ void LLAppViewer::cleanupSavedSettings() void LLAppViewer::removeCacheFiles(const std::string& file_mask) { - std::string mask = gDirUtilp->getDirDelimiter() + file_mask; - gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), mask); + gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), file_mask); } void LLAppViewer::writeSystemInfo() diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 29f8cfe8e..ce64710fa 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -459,7 +459,7 @@ gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **succ std::string url = slurl; LLMediaCtrl* web = NULL; const bool trusted_browser = false; - if (LLURLDispatcher::dispatch(url, web, trusted_browser)) + if (LLURLDispatcher::dispatch(url, "", web, trusted_browser)) { // bring window to foreground, as it has just been "launched" from a URL // todo: hmm, how to get there from here? diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 3518e3d39..029b0953e 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -475,7 +475,7 @@ OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) LLMediaCtrl* web = NULL; const bool trusted_browser = false; - LLURLDispatcher::dispatch(url, web, trusted_browser); + LLURLDispatcher::dispatch(url, "", web, trusted_browser); } return(result); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 0d71bc3f4..5ccb1f7e6 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -488,7 +488,7 @@ bool LLAppViewerWin32::initHardwareTest() if (OSBTN_NO== button) { LL_INFOS("AppInit") << "User quitting after failed DirectX 9 detection" << LL_ENDL; - LLWeb::loadURLExternal(DIRECTX_9_URL); + LLWeb::loadURLExternal(DIRECTX_9_URL, false); return false; } gSavedSettings.setWarning("AboutDirectX9", FALSE); diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 354c8d7d9..cb185e0eb 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -134,9 +134,7 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) : }*/ - LLRect border_rect( 0, getRect().getHeight() + 2, getRect().getWidth() + 2, 0 ); - mBorder = new LLViewBorder( std::string("web control border"), border_rect, LLViewBorder::BEVEL_IN ); - addChild( mBorder ); + //LLRect border_rect( 0, getRect().getHeight() + 2, getRect().getWidth() + 2, 0 ); } LLMediaCtrl::~LLMediaCtrl() @@ -152,10 +150,13 @@ LLMediaCtrl::~LLMediaCtrl() // void LLMediaCtrl::setBorderVisible( BOOL border_visible ) { - if ( mBorder ) + if(border_visible && !mBorder) { - mBorder->setVisible( border_visible ); - }; + mBorder = new LLViewBorder( std::string("web control border"), getLocalRect(), LLViewBorder::BEVEL_IN ); + addChild( mBorder ); + } + if(mBorder) + mBorder->setVisible(border_visible); }; //////////////////////////////////////////////////////////////////////////////// @@ -705,7 +706,6 @@ LLPluginClassMedia* LLMediaCtrl::getMediaPlugin() // void LLMediaCtrl::draw() { - if ( gRestoreGL == 1 ) { LLRect r = getRect(); diff --git a/indra/newview/llpanelgeneral.cpp b/indra/newview/llpanelgeneral.cpp index a2b998ef4..a044ac1a9 100644 --- a/indra/newview/llpanelgeneral.cpp +++ b/indra/newview/llpanelgeneral.cpp @@ -61,7 +61,11 @@ BOOL LLPanelGeneral::postBuild() LLComboBox* namesystem_combobox = getChild("namesystem_combobox"); namesystem_combobox->setCurrentByIndex(gSavedSettings.getS32("PhoenixNameSystem")); - childSetValue("default_start_location", gSavedSettings.getBOOL("LoginLastLocation") ? "MyLastLocation" : "MyHome"); + std::string login_location = gSavedSettings.getString("LoginLocation"); + if(login_location != "last" && login_location != "home") + login_location = "last"; + + childSetValue("default_start_location", login_location); childSetValue("show_location_checkbox", gSavedSettings.getBOOL("ShowStartLocation")); childSetValue("show_all_title_checkbox", gSavedSettings.getBOOL("RenderHideGroupTitleAll")); childSetValue("language_is_public", gSavedSettings.getBOOL("LanguageIsPublic")); @@ -147,7 +151,7 @@ void LLPanelGeneral::apply() } } - gSavedSettings.setBOOL("LoginLastLocation", childGetValue("default_start_location").asString() == "MyLastLocation"); + gSavedSettings.setString("LoginLocation", childGetValue("default_start_location").asString()); gSavedSettings.setBOOL("ShowStartLocation", childGetValue("show_location_checkbox")); gSavedSettings.setBOOL("RenderHideGroupTitleAll", childGetValue("show_all_title_checkbox")); gSavedSettings.setBOOL("LanguageIsPublic", childGetValue("language_is_public")); diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index 7180799a4..6de4efe27 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -38,7 +38,7 @@ struct LLOfferInfo; -const F32 UPDATE_MEMBERS_SECONDS_PER_FRAME = 0.005; // 5ms +const F32 UPDATE_MEMBERS_SECONDS_PER_FRAME = 0.005f; // 5ms // Forward declares class LLPanelGroupTab; diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 497d04af7..537c3c977 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -108,7 +108,7 @@ static bool nameSplit(const std::string& full, std::string& first, std::string& first = fragments[0]; if (fragments.size() == 1) { - if (gHippoGridManager->getConnectedGrid()->isAurora()) + if (gHippoGridManager->getCurrentGrid()->isAurora()) last = ""; else last = "Resident"; @@ -183,6 +183,8 @@ class LLIamHereLogin : public LLHTTPClient::ResponderHeadersOnly { if (mParent) { + if(200 <= status && status < 300) + llinfos << "Found site" << llendl; mParent->setSiteIsAlive(200 <= status && status < 300); } } @@ -276,7 +278,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, LLSLURL defaultStart(defaultStartLocation); if ( defaultStart.isSpatial() ) { - LLStartUp::setStartSLURL(defaultStart); + LLStartUp::setStartSLURL(defaultStart); // calls onUpdateStartSLURL } else { @@ -284,36 +286,13 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, LLSLURL homeStart(LLSLURL::SIM_LOCATION_HOME); LLStartUp::setStartSLURL(homeStart); } + start_slurl = LLStartUp::getStartSLURL(); // calls onUpdateStartSLURL } else { LLPanelLogin::onUpdateStartSLURL(start_slurl); // updates grid if needed } - // The XML file loads the combo with the following labels: - // 0 - "My Home" - // 1 - "My Last Location" - // 2 - "" - - BOOL login_last = gSavedSettings.getBOOL("LoginLastLocation"); - std::string sim_string = start_slurl.getRegion(); - if (!sim_string.empty()) - { - // Replace "" with this region name - location_combo->remove(2); - location_combo->add( sim_string ); - location_combo->setTextEntry(sim_string); - location_combo->setCurrentByIndex( 2 ); - } - else if (login_last) - { - location_combo->setCurrentByIndex( 1 ); - } - else - { - location_combo->setCurrentByIndex( 0 ); - } - childSetAction("connect_btn", onClickConnect, this); setDefaultBtn("connect_btn"); @@ -342,16 +321,13 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, // get the web browser control LLMediaCtrl* web_browser = getChild("login_html"); web_browser->addObserver(this); + web_browser->setBackgroundColor(LLColor4::black); reshapeBrowser(); - childSetVisible("create_new_account_text", - !gHippoGridManager->getConnectedGrid()->getRegisterUrl().empty()); - childSetVisible("forgot_password_text", - !gHippoGridManager->getConnectedGrid()->getPasswordUrl().empty()); - loadLoginPage(); + refreshLoginPage(); } void LLPanelLogin::setSiteIsAlive( bool alive ) @@ -374,6 +350,8 @@ void LLPanelLogin::setSiteIsAlive( bool alive ) { // hide browser control (revealing default one) web_browser->setVisible( FALSE ); + std::string str = LLWeb::escapeURL("data:text/html,"); + web_browser->navigateTo( str, "text/html" ); } } } @@ -402,8 +380,8 @@ void LLPanelLogin::reshapeBrowser() LLRect rect = gViewerWindow->getWindowRectScaled(); LLRect html_rect; html_rect.setCenterAndSize( - rect.getCenterX() - 2, rect.getCenterY() + 40, - rect.getWidth() + 6, rect.getHeight() - 78 ); + rect.getCenterX() /*- 2*/, rect.getCenterY() + 40, + rect.getWidth() /*+ 6*/, rect.getHeight() - 78 ); web_browser->setRect( html_rect ); web_browser->reshape( html_rect.getWidth(), html_rect.getHeight(), TRUE ); reshape( rect.getWidth(), rect.getHeight(), 1 ); @@ -761,7 +739,7 @@ void LLPanelLogin::onUpdateStartSLURL(const LLSLURL& new_start_slurl) switch ( new_slurl_type ) { case LLSLURL::LOCATION: - { + { location_combo->setCurrentByIndex( 2 ); location_combo->setTextEntry(new_start_slurl.getLocationString()); } @@ -845,7 +823,7 @@ void LLPanelLogin::loadLoginPage() sInstance->updateGridCombo(); - std::string login_page_str = gHippoGridManager->getConnectedGrid()->getLoginPage(); + std::string login_page_str = gHippoGridManager->getCurrentGrid()->getLoginPage(); if (login_page_str.empty()) { sInstance->setSiteIsAlive(false); @@ -876,10 +854,10 @@ void LLPanelLogin::loadLoginPage() // Grid - if (gHippoGridManager->getConnectedGrid()->isSecondLife()) { + if (gHippoGridManager->getCurrentGrid()->isSecondLife()) { // find second life grid from login URI // yes, this is heuristic, but hey, it is just to get the right login page... - std::string tmp = gHippoGridManager->getConnectedGrid()->getLoginUri(); + std::string tmp = gHippoGridManager->getCurrentGrid()->getLoginUri(); int i = tmp.find(".lindenlab.com"); if (i != std::string::npos) { tmp = tmp.substr(0, i); @@ -892,11 +870,11 @@ void LLPanelLogin::loadLoginPage() } } } - else if (gHippoGridManager->getConnectedGrid()->isOpenSimulator()) + else if (gHippoGridManager->getCurrentGrid()->isOpenSimulator()) { - params["grid"] = gHippoGridManager->getConnectedGrid()->getGridNick(); + params["grid"] = gHippoGridManager->getCurrentGrid()->getGridNick(); } - else if (gHippoGridManager->getConnectedGrid()->getPlatform() == HippoGridInfo::PLATFORM_AURORA) + else if (gHippoGridManager->getCurrentGrid()->getPlatform() == HippoGridInfo::PLATFORM_AURORA) { params["grid"] = LLViewerLogin::getInstance()->getGridLabel(); } @@ -970,7 +948,7 @@ void LLPanelLogin::onClickConnect(void *) } else { - if (gHippoGridManager->getConnectedGrid()->getRegisterUrl().empty()) { + if (gHippoGridManager->getCurrentGrid()->getRegisterUrl().empty()) { LLNotificationsUtil::add("MustHaveAccountToLogInNoLinks"); } else { LLNotificationsUtil::add("MustHaveAccountToLogIn", LLSD(), LLSD(), @@ -1001,7 +979,7 @@ bool LLPanelLogin::newAccountAlertCallback(const LLSD& notification, const LLSD& // static void LLPanelLogin::onClickNewAccount() { - const std::string &url = gHippoGridManager->getConnectedGrid()->getRegisterUrl(); + const std::string &url = gHippoGridManager->getCurrentGrid()->getRegisterUrl(); if (!url.empty()) { llinfos << "Going to account creation URL." << llendl; LLWeb::loadURLExternal(url); @@ -1030,7 +1008,7 @@ void LLPanelLogin::onClickForgotPassword() { if (sInstance ) { - const std::string &url = gHippoGridManager->getConnectedGrid()->getPasswordUrl(); + const std::string &url = gHippoGridManager->getCurrentGrid()->getPasswordUrl(); if (!url.empty()) { LLWeb::loadURLExternal(url); } else { @@ -1059,17 +1037,31 @@ void LLPanelLogin::refreshLoginPage() sInstance->updateGridCombo(); sInstance->childSetVisible("create_new_account_text", - !gHippoGridManager->getConnectedGrid()->getRegisterUrl().empty()); + !gHippoGridManager->getCurrentGrid()->getRegisterUrl().empty()); sInstance->childSetVisible("forgot_password_text", - !gHippoGridManager->getConnectedGrid()->getPasswordUrl().empty()); + !gHippoGridManager->getCurrentGrid()->getPasswordUrl().empty()); - // kick off a request to grab the url manually - gResponsePtr = LLIamHereLogin::build(sInstance); + std::string login_page = gHippoGridManager->getCurrentGrid()->getLoginPage(); + if (!login_page.empty()) + { + LLMediaCtrl* web_browser = sInstance->getChild("login_html"); + if (web_browser->getCurrentNavUrl() != login_page) + { + if(gResponsePtr) + gResponsePtr->setParent(0); //Tell our previous responder that we no longer require its result. + gResponsePtr.reset(); //Deref previous responder - std::string login_page = gHippoGridManager->getConnectedGrid()->getLoginPage(); - if (!login_page.empty()) { - LLHTTPClient::head(login_page, gResponsePtr.get()); - } else { + llinfos << "Firing off lookup for " << login_page << llendl; + // kick off a request to grab the url manually + gResponsePtr = LLIamHereLogin::build(sInstance); + LLHTTPClient::head(login_page, gResponsePtr.get()); + } + } + else + { + if(gResponsePtr) + gResponsePtr->setParent(0); //Tell our previous responder that we no longer require its result. + gResponsePtr.reset(); //Deref previous responder sInstance->setSiteIsAlive(false); } } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index cba7a27ef..0bf520a8b 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -403,8 +403,6 @@ bool idle_startup() static bool show_connect_box = true; - static bool samename = false; - // HACK: These are things from the main loop that usually aren't done // until initialization is complete, but need to be done here for things // to work. @@ -1096,9 +1094,9 @@ bool idle_startup() /*std::string location; LLPanelLogin::getLocation( location ); LLURLSimString::setString( location ); - + */ // END TODO - LLPanelLogin::close();*/ + LLPanelLogin::close(); } //For HTML parsing in text boxes. @@ -1305,26 +1303,31 @@ bool idle_startup() progress += 0.02f; display_startup(); + LLSLURL start_slurl = LLStartUp::getStartSLURL(); std::stringstream start; - if (LLURLSimString::parse()) + LLSLURL::SLURL_TYPE start_slurl_type = start_slurl.getType(); + switch ( start_slurl_type ) { + case LLSLURL::LOCATION: + { // a startup URL was specified std::stringstream unescaped_start; unescaped_start << "uri:" - << LLURLSimString::sInstance.mSimName << "&" - << LLURLSimString::sInstance.mX << "&" - << LLURLSimString::sInstance.mY << "&" - << LLURLSimString::sInstance.mZ; + << start_slurl.getRegion() << "&" + << start_slurl.getPosition().mV[VX] << "&" + << start_slurl.getPosition().mV[VY] << "&" + << start_slurl.getPosition().mV[VZ]; start << xml_escape_string(unescaped_start.str()); - - } - else if (gSavedSettings.getBOOL("LoginLastLocation")) - { - start << "last"; - } - else - { + } + break; + case LLSLURL::HOME_LOCATION: start << "home"; + break; + case LLSLURL::LAST_LOCATION: + start << "last"; + break; + default: + break; } char hashed_mac_string[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */ diff --git a/indra/newview/llurlsimstring.cpp b/indra/newview/llurlsimstring.cpp deleted file mode 100644 index 200345cae..000000000 --- a/indra/newview/llurlsimstring.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/** - * @file llurlsimstring.cpp (was llsimurlstring.cpp) - * @brief Handles "SLURL fragments" like Ahern/123/45 for - * startup processing, login screen, prefs, etc. - * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llurlsimstring.h" - -#include "llpanellogin.h" -#include "llviewercontrol.h" - -#include // curl_unescape, curl_free -#ifdef DEBUG_CURLIO -#include "debug_libcurl.h" -#endif - -//static -LLURLSimString LLURLSimString::sInstance; -std::string LLURLSimString::sLocationStringHome("My Home"); -std::string LLURLSimString::sLocationStringLast("My Last Location"); - -// "secondlife://simname/x/y/z" -> "simname/x/y/z" -// (actually .*//foo -> foo) -// static -void LLURLSimString::setString(const std::string& sim_string) -{ - sInstance.mSimString.clear(); - sInstance.mSimName.clear(); - sInstance.mParseState = NOT_PARSED; - if (sim_string == sLocationStringHome) - { - gSavedSettings.setBOOL("LoginLastLocation", FALSE); - } - else if (sim_string == sLocationStringLast) - { - gSavedSettings.setBOOL("LoginLastLocation", TRUE); - } - else - { - char* curlstr = curl_unescape(sim_string.c_str(), sim_string.size()); - std::string tstring = std::string(curlstr); - curl_free(curlstr); - std::string::size_type idx = tstring.find("//"); - idx = (idx == std::string::npos) ? 0 : idx+2; - sInstance.mSimString = tstring.substr(idx); - } -} - -// "/100" -> 100 -// static -std::string::size_type LLURLSimString::parseGridIdx(const std::string& in_string, - std::string::size_type idx0, - std::string::size_type* res) -{ - if (idx0 == std::string::npos || in_string[idx0] != '/') - { - return std::string::npos; // parse error - } - idx0++; - std::string::size_type idx1 = in_string.find_first_of('/', idx0); - std::string::size_type len = (idx1 == std::string::npos) ? std::string::npos : idx1-idx0; - std::string tstring = in_string.substr(idx0,len); - if (!tstring.empty()) - { - std::string::size_type val = atoi(tstring.c_str()); - *res = val; - } - return idx1; -} - -// "simname/x/y/z" -> mSimName = simname, mX = x, mY = y, mZ = z -// static -bool LLURLSimString::parse() -{ - if (sInstance.mParseState == NOT_SET) - { - return false; - } - if (sInstance.mParseState == NOT_PARSED) - { - if (parse(sInstance.mSimString, - &sInstance.mSimName, - &sInstance.mX, - &sInstance.mY, - &sInstance.mZ)) - { - sInstance.mParseState = PARSE_OK; - } - else - { - sInstance.mParseState = PARSE_FAIL; - } - } - return (sInstance.mParseState == PARSE_OK); -} - -// static -bool LLURLSimString::parse(const std::string& sim_string, - std::string *region_name, - S32 *x, S32 *y, S32 *z) -{ - // strip any bogus initial '/' - std::string::size_type idx0 = sim_string.find_first_not_of('/'); - if (idx0 == std::string::npos) idx0 = 0; - - std::string::size_type idx1 = sim_string.find_first_of('/', idx0); - std::string::size_type len = (idx1 == std::string::npos) ? std::string::npos : idx1-idx0; - std::string tstring = sim_string.substr(idx0,len); - *region_name = unescapeRegionName(tstring); - if (!region_name->empty()) - { - // return position data if found. otherwise leave passed-in values alone. (DEV-18380) -MG - if (idx1 != std::string::npos) - { - std::string::size_type xs = *x, ys = *y, zs = *z; - idx1 = parseGridIdx(sim_string, idx1, &xs); - idx1 = parseGridIdx(sim_string, idx1, &ys); - idx1 = parseGridIdx(sim_string, idx1, &zs); - *x = xs; - *y = ys; - *z = zs; - } - - return true; - } - else - { - return false; - } -} - -// static -std::string LLURLSimString::getURL() -{ - std::string url; - if (sInstance.mParseState == PARSE_OK) - { - url = llformat("secondlife://%s/%d/%d/%d/", - sInstance.mSimName.c_str(), - sInstance.mX, - sInstance.mY, - sInstance.mZ); - } - return url; -} - -// static -std::string LLURLSimString::unescapeRegionName(std::string region_name) -{ - std::string result; - char* curlstr = curl_unescape(region_name.c_str(), region_name.size()); - result = std::string(curlstr); - curl_free(curlstr); - return result; -} diff --git a/indra/newview/llurlsimstring.h b/indra/newview/llurlsimstring.h deleted file mode 100644 index ea56da47b..000000000 --- a/indra/newview/llurlsimstring.h +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @file llsimurlstring.h - * @brief Handles "SLURL fragments" like Ahern/123/45 for - * startup processing, login screen, prefs, etc. - * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ -#ifndef LLSIMURLSTRING_H -#define LLSIMURLSTRING_H - -#include "llstring.h" - -class LLURLSimString -{ -public: - enum { NOT_SET=0, NOT_PARSED=1, PARSE_OK=2, PARSE_FAIL=-1 }; - - static void setString(const std::string& url); - // Accepts all sorts of fragments: - // secondlife://RegionName/1/2/ - // sl://RegionName/1/2/3/ - // //Ahern/123/45/ - // Ahern - - static bool parse(); - // Returns true if we have an URL fragment in the static instance - // (and it parsed correctly, which is basically always because - // any bare region string is a valid fragment). - - static bool parse(const std::string& sim_string, std::string *region_name, S32 *x, S32 *y, S32 *z); - // Parse a sim string "Ahern/1/2" and return location data, - // doesn't affect static instance. - - static std::string getURL(); - // Get the canonical URL secondlife://RegionName/123/45/6/ - - static std::string unescapeRegionName(std::string region_name); - // Does URL unescaping, in particular %20 -> space - - LLURLSimString() : mX(128), mY(128), mZ(0), mParseState(NOT_PARSED) {} - -private: - static std::string::size_type parseGridIdx(const std::string& in_string, - std::string::size_type idx0, - std::string::size_type* res); - -public: - static LLURLSimString sInstance; - static std::string sLocationStringHome; - static std::string sLocationStringLast; - -public: - std::string mSimString; // "name/x/y/z" - std::string mSimName; - S32 mX,mY,mZ; - S32 mParseState; -}; - -#endif diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 6965181db..c45680685 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -3046,8 +3046,8 @@ void LLViewerMediaImpl::setVisible(bool visible) if(plugin && plugin->isPluginExited()) { destroyMediaSource(); + plugin = NULL; } - if(!plugin) { createMediaSource(); @@ -3716,11 +3716,10 @@ void LLViewerMediaImpl::setPriority(EPriority priority) mPreviousMediaTime = plugin->getCurrentTime(); destroyMediaSource(); + plugin = NULL; } } - - if(plugin) { if(mPriority >= PRIORITY_LOW) diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index b875555e7..298640e74 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -185,9 +185,7 @@ void LLViewerTextureList::doPreloadImages() static std::string get_texture_list_name() { - //return std::string("texture_list_") + gSavedSettings.getString("LoginLocation") + ".xml"; - bool login_last = gSavedSettings.getBOOL("LoginLastLocation"); - return std::string("texture_list_") + (login_last?"last":"home") + ".xml"; + return std::string("texture_list_") + gSavedSettings.getString("LoginLocation") + ".xml"; } void LLViewerTextureList::doPrefetchImages() diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index a39530724..2e05207cc 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -521,7 +521,7 @@ bool LLWaterParamManager::removeParamSet(const std::string& name, bool delete_fr bool LLWaterParamManager::isSystemPreset(const std::string& preset_name) const { // *TODO: file system access is excessive here. - return gDirUtilp->fileExists(getSysDir() + LLWeb::curlEscape(preset_name) + ".xml"); + return gDirUtilp->fileExists(getSysDir() + LLURI::escape(preset_name) + ".xml"); } void LLWaterParamManager::getPresetNames(preset_name_list_t& presets) const diff --git a/indra/newview/skins/default/xui/en-us/notifications.xml b/indra/newview/skins/default/xui/en-us/notifications.xml index df6bf0b47..411f43122 100644 --- a/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/indra/newview/skins/default/xui/en-us/notifications.xml @@ -2771,6 +2771,15 @@ Please choose the male or female avatar. You can change your mind later. notext="Female" yestext="Male"/> + +Could not teleport to [SLURL] as it's on a different grid ([GRID]) than the current grid ([CURRENT_GRID]). Please close your viewer and try again. + fail + + + + -God summon user to your location? +God summon Resident to your location?
Join me in [REGION] @@ -7353,6 +7365,16 @@ The SLurl you clicked on is not supported. A SLurl was received from an untrusted browser and has been blocked for your security. + + security +Multiple SLurls were received from an untrusted browser within a short period. +They will be blocked for a few seconds for your security. + + - My Home - My Last Location + My Home + My Last Location diff --git a/indra/newview/skins/default/xui/es/panel_preferences_general.xml b/indra/newview/skins/default/xui/es/panel_preferences_general.xml index 8eab840fc..c2e473990 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_general.xml @@ -1,10 +1,10 @@ - + Mi Base - + Mi Última Ubicación diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml index 3629f63e6..e5b200812 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml @@ -1,8 +1,8 @@ - Domicile - Dernier emplacement + Domicile + Dernier emplacement diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_general.xml b/indra/newview/skins/default/xui/pt/panel_preferences_general.xml index 60ccd0edd..bdb315fd7 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_general.xml @@ -1,10 +1,10 @@ - + Minha Casa - + Minha Última Localidade