summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/llevents.h12
-rw-r--r--indra/llcommon/tests/lluri_test.cpp35
-rw-r--r--indra/llimage/llimagebmp.cpp2
-rw-r--r--indra/llmath/lloctree.h16
-rw-r--r--indra/llrender/llfontfreetype.cpp2
-rw-r--r--indra/llrender/llfontgl.cpp6
-rw-r--r--indra/llui/llui.cpp12
-rw-r--r--indra/llwindow/llwindowmacosx.cpp5
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/llappviewer.cpp10
-rw-r--r--indra/newview/llcommandlineparser.cpp36
-rw-r--r--indra/newview/llcontrolavatar.cpp44
-rw-r--r--indra/newview/llglsandbox.cpp37
-rw-r--r--indra/newview/llnamelistctrl.cpp43
-rw-r--r--indra/newview/llpanelgrouproles.cpp62
-rw-r--r--indra/newview/llpanelgrouproles.h4
-rw-r--r--indra/newview/llpreviewnotecard.cpp3
-rw-r--r--indra/newview/llpreviewscript.cpp2
-rw-r--r--indra/newview/lltoolpie.cpp66
-rw-r--r--indra/newview/llurldispatcher.cpp51
-rw-r--r--indra/newview/llviewermenu.cpp6
-rw-r--r--indra/newview/llvoicevivox.cpp5
-rw-r--r--indra/newview/llvosky.cpp2
-rw-r--r--indra/newview/llwlparamset.cpp18
-rw-r--r--indra/newview/llwlparamset.h8
-rw-r--r--indra/newview/llworldmapview.cpp7
-rw-r--r--indra/newview/skins/default/xui/da/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_about_land.xml6
-rw-r--r--indra/newview/skins/default/xui/de/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_roles.xml12
-rw-r--r--indra/newview/skins/default/xui/en/panel_script_ed.xml4
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml4
-rw-r--r--indra/newview/skins/default/xui/es/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/it/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/strings.xml2
38 files changed, 421 insertions, 116 deletions
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h
index 5d60c63810..62d97007ac 100644
--- a/indra/llcommon/llevents.h
+++ b/indra/llcommon/llevents.h
@@ -582,11 +582,12 @@ public:
/// Generate a distinct name for a listener -- see listen()
static std::string inventName(const std::string& pfx="listener");
-private:
- friend class LLEventPumps;
/// flush queued events
virtual void flush() {}
+private:
+ friend class LLEventPumps;
+
virtual void reset();
@@ -675,12 +676,14 @@ public:
virtual ~LLEventMailDrop() {}
/// Post an event to all listeners
- virtual bool post(const LLSD& event);
+ virtual bool post(const LLSD& event) override;
+ /// Remove any history stored in the mail drop.
+ virtual void flush() override { mEventHistory.clear(); LLEventStream::flush(); };
protected:
virtual LLBoundListener listen_impl(const std::string& name, const LLEventListener&,
const NameList& after,
- const NameList& before);
+ const NameList& before) override;
private:
typedef std::list<LLSD> EventList;
@@ -703,7 +706,6 @@ public:
/// Post an event to all listeners
virtual bool post(const LLSD& event);
-private:
/// flush queued events
virtual void flush();
diff --git a/indra/llcommon/tests/lluri_test.cpp b/indra/llcommon/tests/lluri_test.cpp
index 4c64f15ca7..1a4c6641b9 100644
--- a/indra/llcommon/tests/lluri_test.cpp
+++ b/indra/llcommon/tests/lluri_test.cpp
@@ -383,6 +383,41 @@ namespace tut
ensure_equals("query", u.query(), "redirect-http-hack=secondlife:///app/login?first_name=Callum&last_name=Linden&location=specify&grid=vaak&region=/Morris/128/128&web_login_key=efaa4795-c2aa-4c58-8966-763c27931e78");
ensure_equals("query map element", u.queryMap()["redirect-http-hack"].asString(), "secondlife:///app/login?first_name=Callum&last_name=Linden&location=specify&grid=vaak&region=/Morris/128/128&web_login_key=efaa4795-c2aa-4c58-8966-763c27931e78");
}
+
+ template<> template<>
+ void URITestObject::test<20>()
+ {
+ set_test_name("escapePathAndData uri test");
+
+ // Basics scheme:[//authority]path[?query][#fragment]
+ ensure_equals(LLURI::escapePathAndData("dirname?query"),
+ "dirname?query");
+ ensure_equals(LLURI::escapePathAndData("dirname?query=data"),
+ "dirname?query=data");
+ ensure_equals(LLURI::escapePathAndData("host://dirname/subdir name?query#fragment"),
+ "host://dirname/subdir%20name?query#fragment");
+ ensure_equals(LLURI::escapePathAndData("host://dirname/subdir name?query=some@>data#fragment"),
+ "host://dirname/subdir%20name?query=some@%3Edata#fragment");
+ ensure_equals(LLURI::escapePathAndData("host://dir[name/subdir name?query=some[data#fra[gment"),
+ "host://dir[name/subdir%20name?query=some%5Bdata#fra[gment");
+ ensure_equals(LLURI::escapePathAndData("mailto:zero@ll.com"),
+ "mailto:zero@ll.com");
+ // pre-escaped
+ ensure_equals(LLURI::escapePathAndData("host://dirname/subdir%20name"),
+ "host://dirname/subdir%20name");
+
+ // data:[<mediatype>][;base64],<data>
+ ensure_equals(LLURI::escapePathAndData("data:,Hello, World!"),
+ "data:,Hello%2C%20World%21");
+ ensure_equals(LLURI::escapePathAndData("data:text/html,<h1>Hello, World!</h1>"),
+ "data:text/html,%3Ch1%3EHello%2C%20World%21%3C%2Fh1%3E");
+ // pre-escaped
+ ensure_equals(LLURI::escapePathAndData("data:text/html,%3Ch1%3EHello%2C%20World!</h1>"),
+ "data:text/html,%3Ch1%3EHello%2C%20World%21%3C%2Fh1%3E");
+ // assume that base64 does not need escaping
+ ensure_equals(LLURI::escapePathAndData("data:image;base64,SGVs/bG8sIFd/vcmxkIQ%3D%3D!-&*?="),
+ "data:image;base64,SGVs/bG8sIFd/vcmxkIQ%3D%3D!-&*?=");
+ }
}
diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp
index 867b2bb47b..90b7272efa 100644
--- a/indra/llimage/llimagebmp.cpp
+++ b/indra/llimage/llimagebmp.cpp
@@ -181,7 +181,7 @@ bool LLImageBMP::updateData()
}
}
else
- if( 12 <= header.mSize && 64 <= header.mSize )
+ if( 12 <= header.mSize && header.mSize <= 64 )
{
setLastError("OS/2 2.x BMP files are not supported");
return false;
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index 280d2653d3..0e2f62f9db 100644
--- a/indra/llmath/lloctree.h
+++ b/indra/llmath/lloctree.h
@@ -401,7 +401,7 @@ public:
child->insert(data);
}
}
- else
+ else if (parent)
{
//it's not in here, give it to the root
OCT_ERRS << "Octree insertion failed, starting over from root!" << LL_ENDL;
@@ -416,6 +416,13 @@ public:
node->insert(data);
}
+ else
+ {
+ // It's not in here, and we are root.
+ // LLOctreeRoot::insert() should have expanded
+ // root by now, something is wrong
+ OCT_ERRS << "Octree insertion failed! Root expansion failed." << LL_ENDL;
+ }
return false;
}
@@ -763,10 +770,15 @@ public:
{
LLOctreeNode<T>::insert(data);
}
- else
+ else if (node->isInside(data->getPositionGroup()))
{
node->insert(data);
}
+ else
+ {
+ // calling node->insert(data) will return us to root
+ OCT_ERRS << "Failed to insert data at child node" << LL_ENDL;
+ }
}
else if (this->getChildCount() == 0)
{
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index e9d852c288..c41730ebaa 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -245,13 +245,11 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
if(mFTFace->style_flags & FT_STYLE_FLAG_BOLD)
{
mStyle |= LLFontGL::BOLD;
- mStyle &= ~LLFontGL::NORMAL;
}
if(mFTFace->style_flags & FT_STYLE_FLAG_ITALIC)
{
mStyle |= LLFontGL::ITALIC;
- mStyle &= ~LLFontGL::NORMAL;
}
return TRUE;
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index b79615e730..86a4c35e6d 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -870,10 +870,6 @@ void LLFontGL::destroyAllGL()
U8 LLFontGL::getStyleFromString(const std::string &style)
{
S32 ret = 0;
- if (style.find("NORMAL") != style.npos)
- {
- ret |= NORMAL;
- }
if (style.find("BOLD") != style.npos)
{
ret |= BOLD;
@@ -893,7 +889,7 @@ U8 LLFontGL::getStyleFromString(const std::string &style)
std::string LLFontGL::getStringFromStyle(U8 style)
{
std::string style_string;
- if (style & NORMAL)
+ if (style == NORMAL)
{
style_string += "|NORMAL";
}
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index a1b31fd5cc..52190a1473 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -236,10 +236,14 @@ void LLUI::dirtyRect(LLRect rect)
//static
void LLUI::setMousePositionScreen(S32 x, S32 y)
{
- S32 screen_x, screen_y;
- screen_x = ll_round((F32)x * getScaleFactor().mV[VX]);
- screen_y = ll_round((F32)y * getScaleFactor().mV[VY]);
-
+#if defined(LL_DARWIN)
+ S32 screen_x = ll_round(((F32)x * getScaleFactor().mV[VX]) / LLView::getWindow()->getSystemUISize());
+ S32 screen_y = ll_round(((F32)y * getScaleFactor().mV[VY]) / LLView::getWindow()->getSystemUISize());
+#else
+ S32 screen_x = ll_round((F32)x * getScaleFactor().mV[VX]);
+ S32 screen_y = ll_round((F32)y * getScaleFactor().mV[VY]);
+#endif
+
LLView::getWindow()->setCursorPosition(LLCoordGL(screen_x, screen_y).convert());
}
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 6dec131a34..3554f90be8 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -382,7 +382,10 @@ void callWindowFocus()
void callWindowUnfocus()
{
- gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation);
+ if ( gWindowImplementation && gWindowImplementation->getCallbacks() )
+ {
+ gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation);
+ }
}
void callWindowHide()
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index ca06394388..bee9433817 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.2.2
+6.2.3
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index d0fbf17d81..be5611899a 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3100,17 +3100,11 @@ LLSD LLAppViewer::getViewerInfo() const
}
// return a URL to the release notes for this viewer, such as:
- // http://wiki.secondlife.com/wiki/Release_Notes/Second Life Beta Viewer/2.1.0.123456
+ // https://releasenotes.secondlife.com/viewer/2.1.0.123456.html
std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL");
if (! LLStringUtil::endsWith(url, "/"))
url += "/";
- std::string channel = LLVersionInfo::getChannel();
- if (LLStringUtil::endsWith(boost::to_lower_copy(channel), " edu")) // Release Notes url shouldn't include the EDU parameter
- {
- boost::erase_tail(channel, 4);
- }
- url += LLURI::escape(channel) + "/";
- url += LLURI::escape(LLVersionInfo::getVersion());
+ url += LLURI::escape(LLVersionInfo::getVersion()) + ".html";
info["VIEWER_RELEASE_NOTES_URL"] = url;
diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp
index 90a5483dc9..fe14bc081f 100644
--- a/indra/newview/llcommandlineparser.cpp
+++ b/indra/newview/llcommandlineparser.cpp
@@ -374,12 +374,40 @@ bool LLCommandLineParser::parseCommandLine(int argc, char **argv)
bool LLCommandLineParser::parseCommandLineString(const std::string& str)
{
+ std::string cmd_line_string("");
+ if (!str.empty())
+ {
+ bool add_last_c = true;
+ S32 last_c_pos = str.size() - 1; //don't get out of bounds on pos+1, last char will be processed separately
+ for (S32 pos = 0; pos < last_c_pos; ++pos)
+ {
+ cmd_line_string.append(&str[pos], 1);
+ if (str[pos] == '\\')
+ {
+ cmd_line_string.append("\\", 1);
+ if (str[pos + 1] == '\\')
+ {
+ ++pos;
+ add_last_c = (pos != last_c_pos);
+ }
+ }
+ }
+ if (add_last_c)
+ {
+ cmd_line_string.append(&str[last_c_pos], 1);
+ if (str[last_c_pos] == '\\')
+ {
+ cmd_line_string.append("\\", 1);
+ }
+ }
+ }
+
// Split the string content into tokens
- const char* escape_chars = "\\";
- const char* separator_chars = "\r\n ";
- const char* quote_chars = "\"'";
+ const char* escape_chars = "\\";
+ const char* separator_chars = "\r\n ";
+ const char* quote_chars = "\"'";
boost::escaped_list_separator<char> sep(escape_chars, separator_chars, quote_chars);
- boost::tokenizer< boost::escaped_list_separator<char> > tok(str, sep);
+ boost::tokenizer< boost::escaped_list_separator<char> > tok(cmd_line_string, sep);
std::vector<std::string> tokens;
// std::copy(tok.begin(), tok.end(), std::back_inserter(tokens));
for(boost::tokenizer< boost::escaped_list_separator<char> >::iterator i = tok.begin();
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index 0f02c23cb0..d24dac385f 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -566,27 +566,49 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
LLVector4a* normal,
LLVector4a* tangent)
{
- LLViewerObject* hit = NULL;
+ if (!mRootVolp)
+ {
+ return NULL;
+ }
- if (lineSegmentBoundingBox(start, end))
- {
- LLVector4a local_end = end;
- LLVector4a local_intersection;
+ LLViewerObject* hit = NULL;
- if (mRootVolp &&
- mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
+ if (lineSegmentBoundingBox(start, end))
+ {
+ LLVector4a local_end = end;
+ LLVector4a local_intersection;
+ if (mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
{
*intersection = local_intersection;
}
-
hit = mRootVolp;
}
- }
-
- return hit;
+ else
+ {
+ std::vector<LLVOVolume*> volumes;
+ getAnimatedVolumes(volumes);
+
+ for (std::vector<LLVOVolume*>::iterator vol_it = volumes.begin(); vol_it != volumes.end(); ++vol_it)
+ {
+ LLVOVolume *volp = *vol_it;
+ if (mRootVolp != volp && volp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
+ {
+ local_end = local_intersection;
+ if (intersection)
+ {
+ *intersection = local_intersection;
+ }
+ hit = volp;
+ break;
+ }
+ }
+ }
+ }
+
+ return hit;
}
// virtual
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index a9b15fc8b6..fea01786f3 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -1005,7 +1005,10 @@ F32 gpu_benchmark()
//number of samples to take
const S32 samples = 64;
-
+
+ //time limit, allocation operations shouldn't take longer then 30 seconds, same for actual benchmark.
+ const F32 time_limit = 30;
+
ShaderProfileHelper initProfile;
std::vector<LLRenderTarget> dest(count);
@@ -1023,12 +1026,14 @@ F32 gpu_benchmark()
gGL.setColorMask(true, true);
LLGLDepthTest depth(GL_FALSE);
+ LLTimer alloc_timer;
+ alloc_timer.start();
for (U32 i = 0; i < count; ++i)
{
//allocate render targets and textures
if (!dest[i].allocate(res, res, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true))
{
- LL_WARNS() << "Failed to allocate render target." << LL_ENDL;
+ LL_WARNS("Benchmark") << "Failed to allocate render target." << LL_ENDL;
// abandon the benchmark test
delete[] pixels;
return -1.f;
@@ -1040,12 +1045,20 @@ F32 gpu_benchmark()
if (!texHolder.bind(i))
{
// can use a dummy value mDummyTexUnit = new LLTexUnit(-1);
- LL_WARNS() << "Failed to bind tex unit." << LL_ENDL;
+ LL_WARNS("Benchmark") << "Failed to bind tex unit." << LL_ENDL;
// abandon the benchmark test
delete[] pixels;
return -1.f;
}
LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA, res,res,GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ if (alloc_timer.getElapsedTimeF32() > time_limit)
+ {
+ // abandon the benchmark test
+ LL_WARNS("Benchmark") << "Allocation operation took longer then 30 seconds, stopping." << LL_ENDL;
+ delete[] pixels;
+ return -1.f;
+ }
}
delete [] pixels;
@@ -1055,7 +1068,7 @@ F32 gpu_benchmark()
if (!buff->allocateBuffer(3, 0, true))
{
- LL_WARNS() << "Failed to allocate buffer during benchmark." << LL_ENDL;
+ LL_WARNS("Benchmark") << "Failed to allocate buffer during benchmark." << LL_ENDL;
// abandon the benchmark test
return -1.f;
}
@@ -1065,7 +1078,7 @@ F32 gpu_benchmark()
if (! buff->getVertexStrider(v))
{
- LL_WARNS() << "GL LLVertexBuffer::getVertexStrider() returned false, "
+ LL_WARNS("Benchmark") << "GL LLVertexBuffer::getVertexStrider() returned false, "
<< "buff->getMappedData() is"
<< (buff->getMappedData()? " not" : "")
<< " NULL" << LL_ENDL;
@@ -1086,7 +1099,8 @@ F32 gpu_benchmark()
buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
glFinish();
- for (S32 c = -1; c < samples; ++c)
+ F32 time_passed = 0; // seconds
+ for (S32 c = -1; c < samples && time_passed < time_limit; ++c)
{
LLTimer timer;
timer.start();
@@ -1103,6 +1117,7 @@ F32 gpu_benchmark()
glFinish();
F32 time = timer.getElapsedTimeF32();
+ time_passed += time;
if (c >= 0) // <-- ignore the first sample as it tends to be artificially slow
{
@@ -1117,12 +1132,12 @@ F32 gpu_benchmark()
F32 gbps = results[results.size()/2];
- LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to CPU timers" << LL_ENDL;
-
+ LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to CPU timers, " << (F32)results.size() << " tests took " << time_passed << " seconds" << LL_ENDL;
+
#if LL_DARWIN
if (gbps > 512.f)
{
- LL_WARNS() << "Memory bandwidth is improbably high and likely incorrect; discarding result." << LL_ENDL;
+ LL_WARNS("Benchmark") << "Memory bandwidth is improbably high and likely incorrect; discarding result." << LL_ENDL;
//OSX is probably lying, discard result
return -1.f;
}
@@ -1131,11 +1146,11 @@ F32 gpu_benchmark()
F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f;
F32 seconds = ms/1000.f;
- F64 samples_drawn = res*res*count*samples;
+ F64 samples_drawn = res*res*count*results.size();
F32 samples_sec = (samples_drawn/1000000000.0)/seconds;
gbps = samples_sec*8;
- LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query" << LL_ENDL;
+ LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;
return gbps;
}
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 62e0e2d077..d7c5364fba 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -34,6 +34,7 @@
#include "llcachename.h"
#include "llfloater.h"
#include "llfloaterreg.h"
+#include "llfloatersnapshot.h" // gSnapshotFloaterView
#include "llinventory.h"
#include "llscrolllistitem.h"
#include "llscrolllistcell.h"
@@ -236,24 +237,30 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
// Spawn at right side of cell
LLPointer<LLUIImage> icon = LLUI::getUIImage("Info_Small");
- LLCoordGL pos( sticky_rect.mRight - info_icon_size, sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight())/2 );
-
- // Should we show a group or an avatar inspector?
- bool is_group = hit_item->isGroup();
- bool is_experience = hit_item->isExperience();
-
- LLToolTip::Params params;
- params.background_visible( false );
- params.click_callback( boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group, is_experience) );
- params.delay_time(0.0f); // spawn instantly on hover
- params.image( icon );
- params.message("");
- params.padding(0);
- params.pos(pos);
- params.sticky_rect(sticky_rect);
-
- LLToolTipMgr::getInstance()->show(params);
- handled = TRUE;
+ S32 screenX = sticky_rect.mRight - info_icon_size;
+ S32 screenY = sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight()) / 2;
+ LLCoordGL pos(screenX, screenY);
+
+ LLFloater* snapshot_floatr = gSnapshotFloaterView->getFrontmostClosableFloater();
+ if (!snapshot_floatr || !snapshot_floatr->getRect().pointInRect(screenX + icon->getWidth(), screenY))
+ {
+ // Should we show a group or an avatar inspector?
+ bool is_group = hit_item->isGroup();
+ bool is_experience = hit_item->isExperience();
+
+ LLToolTip::Params params;
+ params.background_visible(false);
+ params.click_callback(boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group, is_experience));
+ params.delay_time(0.0f); // spawn instantly on hover
+ params.image(icon);
+ params.message("");
+ params.padding(0);
+ params.pos(pos);
+ params.sticky_rect(sticky_rect);
+
+ LLToolTipMgr::getInstance()->show(params);
+ handled = TRUE;
+ }
}
}
}
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 52a13304df..0efb234015 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1962,6 +1962,7 @@ LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab()
mRoleDescription(NULL),
mMemberVisibleCheck(NULL),
mDeleteRoleButton(NULL),
+ mCopyRoleButton(NULL),
mCreateRoleButton(NULL),
mFirstOpen(TRUE),
mHasRoleChange(FALSE)
@@ -2012,6 +2013,14 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root)
mCreateRoleButton->setClickedCallback(onCreateRole, this);
mCreateRoleButton->setEnabled(FALSE);
}
+
+ mCopyRoleButton =
+ parent->getChild<LLButton>("role_copy", recurse);
+ if ( mCopyRoleButton )
+ {
+ mCopyRoleButton->setClickedCallback(onCopyRole, this);
+ mCopyRoleButton->setEnabled(FALSE);
+ }
mDeleteRoleButton =
parent->getChild<LLButton>("role_delete", recurse);
@@ -2226,6 +2235,7 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc)
mRoleTitle->clear();
setFooterEnabled(FALSE);
mDeleteRoleButton->setEnabled(FALSE);
+ mCopyRoleButton->setEnabled(FALSE);
}
}
@@ -2336,6 +2346,7 @@ void LLPanelGroupRolesSubTab::handleRoleSelect()
mSelectedRole = item->getUUID();
buildMembersList();
+ mCopyRoleButton->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_CREATE));
can_delete = can_delete && gAgent.hasPowerInGroup(mGroupID,
GP_ROLE_DELETE);
mDeleteRoleButton->setEnabled(can_delete);
@@ -2662,6 +2673,57 @@ void LLPanelGroupRolesSubTab::handleCreateRole()
}
// static
+void LLPanelGroupRolesSubTab::onCopyRole(void* user_data)
+{
+ LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
+ if (!self) return;
+
+ self->handleCopyRole();
+}
+
+void LLPanelGroupRolesSubTab::handleCopyRole()
+{
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
+
+ if (!gdatap) return;
+
+ LLScrollListItem* role_item = mRolesList->getFirstSelected();
+ if (!role_item || role_item->getUUID().isNull())
+ {
+ return;
+ }
+
+ LLRoleData rd;
+ if (!gdatap->getRoleData(role_item->getUUID(), rd))
+ {
+ return;
+ }
+
+ LLUUID new_role_id;
+ new_role_id.generate();
+ rd.mRoleName += "(Copy)";
+ gdatap->createRole(new_role_id,rd);
+
+ mRolesList->deselectAllItems(TRUE);
+ LLSD row;
+ row["id"] = new_role_id;
+ row["columns"][0]["column"] = "name";
+ row["columns"][0]["value"] = rd.mRoleName;
+ mRolesList->addElement(row, ADD_BOTTOM, this);
+ mRolesList->selectByID(new_role_id);
+
+ // put focus on name field and select its contents
+ if(mRoleName)
+ {
+ mRoleName->setFocus(TRUE);
+ mRoleName->onTabInto();
+ gFocusMgr.triggerFocusFlash();
+ }
+
+ notifyObservers();
+}
+
+// static
void LLPanelGroupRolesSubTab::onDeleteRole(void* user_data)
{
LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index aafbd242cb..459b77703f 100644
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -269,6 +269,9 @@ public:
static void onCreateRole(void*);
void handleCreateRole();
+ static void onCopyRole(void*);
+ void handleCopyRole();
+
static void onDeleteRole(void*);
void handleDeleteRole();
@@ -296,6 +299,7 @@ protected:
LLCheckBoxCtrl* mMemberVisibleCheck;
LLButton* mDeleteRoleButton;
LLButton* mCreateRoleButton;
+ LLButton* mCopyRoleButton;
LLUUID mSelectedRole;
BOOL mHasRoleChange;
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index f012d99adf..1533a27469 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -44,6 +44,7 @@
#include "roles_constants.h"
#include "llscrollbar.h"
#include "llselectmgr.h"
+#include "lltrans.h"
#include "llviewertexteditor.h"
#include "llvfile.h"
#include "llviewerinventory.h"
@@ -767,7 +768,7 @@ void LLPreviewNotecard::openInExternalEditor()
{
if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error.
{
- msg = getString("external_editor_not_set");
+ msg = LLTrans::getString("ExternalEditorNotSet");
}
else
{
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 76a21077ba..f1bb0bc27d 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -1052,7 +1052,7 @@ void LLScriptEdCore::openInExternalEditor()
{
if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error.
{
- msg = getString("external_editor_not_set");
+ msg = LLTrans::getString("ExternalEditorNotSet");
}
else
{
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 697db01d11..2a87bce134 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -113,19 +113,59 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
mMouseDownY = y;
LLTimer pick_timer;
BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
- mPick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged);
- LLViewerObject *object = mPick.getObject();
- LLViewerObject *parent = object ? object->getRootEdit() : NULL;
- if (!object
- || object->isAttachment()
- || object->getClickAction() == CLICK_ACTION_DISABLED
- || (!useClickAction(mask, object, parent) && !object->flagHandleTouch() && !(parent && parent->flagHandleTouch())))
- {
- // Unless we are hovering over actionable visible object
- // left mouse down always picks transparent (but see handleMouseUp).
- // Also see LLToolPie::handleHover() - priorities are a bit different there.
- // Todo: we need a more consistent set of rules to work with
- mPick = gViewerWindow->pickImmediate(x, y, TRUE /*transparent*/, pick_rigged);
+ LLPickInfo transparent_pick = gViewerWindow->pickImmediate(x, y, TRUE /*includes transparent*/, pick_rigged);
+ LLPickInfo visible_pick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged);
+ LLViewerObject *transp_object = transparent_pick.getObject();
+ LLViewerObject *visible_object = visible_pick.getObject();
+
+ // Current set of priorities
+ // 1. Transparent attachment pick
+ // 2. Transparent actionable pick
+ // 3. Visible attachment pick (e.x we click on attachment under invisible floor)
+ // 4. Visible actionable pick
+ // 5. Transparent pick (e.x. movement on transparent object/floor, our default pick)
+ // left mouse down always picks transparent (but see handleMouseUp).
+ // Also see LLToolPie::handleHover() - priorities are a bit different there.
+ // Todo: we need a more consistent set of rules to work with
+ if (transp_object == visible_object || !visible_object)
+ {
+ // Note: if transparent object is null, then visible object is also null
+ // since transparent pick includes non-tranpsarent one.
+ // !transparent_object check will be covered by transparent_object == visible_object.
+ mPick = transparent_pick;
+ }
+ else
+ {
+ // Select between two non-null picks
+ LLViewerObject *transp_parent = transp_object->getRootEdit();
+ LLViewerObject *visible_parent = visible_object->getRootEdit();
+ if (transp_object->isAttachment())
+ {
+ // 1. Transparent attachment
+ mPick = transparent_pick;
+ }
+ else if (transp_object->getClickAction() != CLICK_ACTION_DISABLED
+ && (useClickAction(mask, transp_object, transp_parent) || transp_object->flagHandleTouch() || (transp_parent && transp_parent->flagHandleTouch())))
+ {
+ // 2. Transparent actionable pick
+ mPick = transparent_pick;
+ }
+ else if (visible_object->isAttachment())
+ {
+ // 3. Visible attachment pick
+ mPick = visible_pick;
+ }
+ else if (visible_object->getClickAction() != CLICK_ACTION_DISABLED
+ && (useClickAction(mask, visible_object, visible_parent) || visible_object->flagHandleTouch() || (visible_parent && visible_parent->flagHandleTouch())))
+ {
+ // 4. Visible actionable pick
+ mPick = visible_pick;
+ }
+ else
+ {
+ // 5. Default: transparent
+ mPick = transparent_pick;
+ }
}
LL_INFOS() << "pick_rigged is " << (S32) pick_rigged << " pick time elapsed " << pick_timer.getElapsedTimeF32() << LL_ENDL;
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 78268944fc..da31e4f542 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -47,6 +47,7 @@
// library includes
#include "llnotificationsutil.h"
#include "llsd.h"
+#include "stringize.h"
static LLURLDispatcherListener sURLDispatcherListener;
@@ -255,14 +256,23 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const LLSLURL&
// Teleportation links are handled here because they are tightly coupled
// to SLURL parsing and sim-fragment parsing
-class LLTeleportHandler : public LLCommandHandler
+class LLTeleportHandler : public LLCommandHandler, public LLEventAPI
{
public:
// Teleport requests *must* come from a trusted browser
// inside the app, otherwise a malicious web page could
// cause a constant teleport loop. JC
- LLTeleportHandler() : LLCommandHandler("teleport", UNTRUSTED_THROTTLE) { }
-
+ LLTeleportHandler() :
+ LLCommandHandler("teleport", UNTRUSTED_THROTTLE),
+ LLEventAPI("LLTeleportHandler", "Low-level teleport API")
+ {
+ LLEventAPI::add("teleport",
+ "Teleport to specified [\"regionname\"] at\n"
+ "specified region-relative [\"x\"], [\"y\"], [\"z\"].\n"
+ "If [\"regionname\"] omitted, teleport to GLOBAL\n"
+ "coordinates [\"x\"], [\"y\"], [\"z\"].",
+ &LLTeleportHandler::from_event);
+ }
bool handle(const LLSD& tokens, const LLSD& query_map,
LLMediaCtrl* web)
@@ -293,6 +303,41 @@ public:
return true;
}
+ void from_event(const LLSD& params) const
+ {
+ Response response(LLSD(), params);
+ if (params.has("regionname"))
+ {
+ // region specified, coordinates (if any) are region-local
+ LLVector3 local_pos(
+ params.has("x")? params["x"].asReal() : 128,
+ params.has("y")? params["y"].asReal() : 128,
+ params.has("z")? params["z"].asReal() : 0);
+ std::string regionname(params["regionname"]);
+ std::string destination(LLSLURL(regionname, local_pos).getSLURLString());
+ // have to resolve region's global coordinates first
+ teleport_via_slapp(regionname, destination);
+ response["message"] = "Teleporting to " + destination;
+ }
+ else // no regionname
+ {
+ // coordinates are global, and at least (x, y) are required
+ if (! (params.has("x") && params.has("y")))
+ {
+ return response.error("Specify either regionname or global (x, y)");
+ }
+ LLVector3d global_pos(params["x"].asReal(), params["y"].asReal(),
+ params["z"].asReal());
+ gAgent.teleportViaLocation(global_pos);
+ LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
+ if (instance)
+ {
+ instance->trackLocation(global_pos);
+ }
+ response["message"] = STRINGIZE("Teleporting to global " << global_pos);
+ }
+ }
+
static void teleport_via_slapp(std::string region_name, std::string callback_url)
{
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 2b9f0f642e..52b2c631fa 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -4751,6 +4751,12 @@ void handle_take()
category_id.setNull();
}
+ // check inbox
+ const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
+ if (category_id == inbox_id || gInventory.isObjectDescendentOf(category_id, inbox_id))
+ {
+ category_id.setNull();
+ }
}
}
if(category_id.isNull())
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index ae4b065333..e10ba77e16 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -1480,6 +1480,11 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
LLSD timeoutResult(LLSDMap("session", "timeout"));
+ // We are about to start a whole new session. Anything that MIGHT still be in our
+ // maildrop is going to be stale and cause us much wailing and gnashing of teeth.
+ // Just flush it all out and start new.
+ voicePump.flush();
+
// It appears that I need to wait for BOTH the SessionGroup.AddSession response and the SessionStateChangeEvent with state 4
// before continuing from this state. They can happen in either order, and if I don't wait for both, things can get stuck.
// For now, the SessionGroup.AddSession response handler sets mSessionHandle and the SessionStateChangeEvent handler transitions to stateSessionJoined.
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index c131cb886f..1e631a2272 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -630,7 +630,7 @@ void LLVOSky::initAtmospherics(void)
dome_radius = LLWLParamManager::getInstance()->getDomeRadius();
dome_offset_ratio = LLWLParamManager::getInstance()->getDomeOffset();
sunlight_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("sunlight_color", error));
- ambient = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("ambient", error));
+ ambient = LLColor3(LLWLParamManager::getInstance()->mCurParams.getAmbient());
//lightnorm = LLWLParamManager::getInstance()->mCurParams.getVector("lightnorm", error);
gamma = LLWLParamManager::getInstance()->mCurParams.getFloat("gamma", error);
blue_density = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_density", error));
diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp
index 066cb9a0ac..cd7a32abdd 100644
--- a/indra/newview/llwlparamset.cpp
+++ b/indra/newview/llwlparamset.cpp
@@ -284,6 +284,11 @@ void LLWLParamSet::setEastAngle(float val)
mParamValues["east_angle"] = val;
}
+void LLWLParamSet::setAmbient(const LLVector4& val)
+{
+ set("ambient", val);
+}
+
void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight)
{
// set up the iterators
@@ -379,6 +384,19 @@ void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight)
setSunAngle((1 - weight) * srcSunAngle + weight * destSunAngle);
setEastAngle((1 - weight) * srcEastAngle + weight * destEastAngle);
+
+ // ambient
+
+ LLVector4 srcAmbient = src.getAmbient();
+ LLVector4 destAmbient = dest.getAmbient();
+ LLVector4 rsltAmbient;
+
+ for (int i = 0; i < LENGTHOFVECTOR4; ++i)
+ {
+ rsltAmbient.mV[i] = srcAmbient.mV[i] + ((destAmbient.mV[i] - srcAmbient.mV[i]) * weight);
+ }
+
+ setAmbient(rsltAmbient);
// now setup the sun properly
diff --git a/indra/newview/llwlparamset.h b/indra/newview/llwlparamset.h
index 6e5f1d3a4b..9874f0f2e0 100644
--- a/indra/newview/llwlparamset.h
+++ b/indra/newview/llwlparamset.h
@@ -136,6 +136,9 @@ public:
void setEastAngle(F32 val);
F32 getEastAngle();
+
+ void setAmbient(const LLVector4& val);
+ LLVector4 getAmbient();
@@ -207,6 +210,11 @@ inline F32 LLWLParamSet::getEastAngle() {
return (F32) mParamValues["east_angle"].asReal();
}
+inline LLVector4 LLWLParamSet::getAmbient() {
+ bool error;
+ return mParamValues.has("ambient") ? getVector("ambient", error) : LLVector4(0.5f, 0.75f, 1.0f, 1.19f);
+}
+
inline void LLWLParamSet::setEnableCloudScrollX(bool val) {
mParamValues["enable_cloud_scroll"][0] = val;
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index b27257a262..a1a9643739 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -887,14 +887,9 @@ void LLWorldMapView::drawFrustum()
F32 half_width_pixels = half_width_meters * meters_to_pixels;
// Compute the frustum coordinates. Take the UI scale into account.
-#if defined(LL_DARWIN)
- F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor");
- F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX) * ui_scale_factor) * LLUI::getScaleFactor().mV[VX];
- F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * ui_scale_factor) * LLUI::getScaleFactor().mV[VY];
-#else
F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX) * LLUI::getScaleFactor().mV[VX]);
F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * LLUI::getScaleFactor().mV[VY]);
-#endif
+
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml
index 74d160dfae..eee3dc2c77 100644
--- a/indra/newview/skins/default/xui/da/strings.xml
+++ b/indra/newview/skins/default/xui/da/strings.xml
@@ -432,7 +432,7 @@ Prøv venligst om lidt igen.
Noter om version
</string>
<string name="RELEASE_NOTES_BASE_URL">
- http://wiki.secondlife.com/wiki/Release_Notes/
+ https://releasenotes.secondlife.com/viewer/
</string>
<string name="LoadingData">
Henter...
diff --git a/indra/newview/skins/default/xui/de/floater_about_land.xml b/indra/newview/skins/default/xui/de/floater_about_land.xml
index 57a48f7906..4dd64cba2a 100644
--- a/indra/newview/skins/default/xui/de/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/de/floater_about_land.xml
@@ -370,8 +370,8 @@ Nur große Parzellen können in der Suche aufgeführt werden.
<text name="landing_point">
Landepunkt: [LANDING]
</text>
- <button label="Festlegen" label_selected="Festlegen" left="234" name="Set" right="-88" tool_tip="Legt Ihren Standort als Landepunkt fest, an dem Besucher ankommen. Legt die Position Ihres Avatars innerhalb dieser Parzelle fest." width="70"/>
- <button label="Löschen" label_selected="Löschen" left="312" name="Clear" tool_tip="Landepunkt löschen" width="70"/>
+ <button label="Festlegen" label_selected="Festlegen" name="Set" tool_tip="Legt Ihren Standort als Landepunkt fest, an dem Besucher ankommen. Legt die Position Ihres Avatars innerhalb dieser Parzelle fest." width="70"/>
+ <button label="Löschen" label_selected="Löschen" name="Clear" tool_tip="Landepunkt löschen" width="70"/>
<text name="Teleport Routing: ">
Teleport-Route:
</text>
@@ -442,7 +442,7 @@ Nur große Parzellen können in der Suche aufgeführt werden.
<panel.string name="estate_override">
Eine oder mehrere dieser Optionen gelten auf Grundbesitzebene
</panel.string>
- <check_box label="Alle Besucher sind zugelassen (Bei Deaktivierung dieser Option werden Bannlinien generiert)" name="public_access"/>
+ <check_box label="Alle Besucher sind zugelassen" tool_tip="Bei Deaktivierung dieser Option werden Bannlinien generiert" name="public_access"/>
<check_box label="Muss 18+ sein [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Nur Einwohner, die mindestens 18 Jahre alt sind, können diese Parzelle betreten. Weitere Informationen finden Sie unter [SUPPORT_SITE]."/>
<check_box label="Muss über Zahlungsinfo in Datei [ESTATE_PAYMENT_LIMIT] verfügen" name="limit_payment" tool_tip="Um diese Parzelle besuchen zu können, müssen Einwohner Zahlungsinformationen hinterlegt haben. Weitere Informationen finden Sie auf [SUPPORT_SITE]."/>
<check_box label="Gruppe [GROUP] ohne Beschränkungen zulassen" name="GroupCheck" tool_tip="Gruppe im Register „Allgemein“ festlegen."/>
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index db51e0a6e8..0fa4ec9aff 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -651,7 +651,7 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
Versionshinweise
</string>
<string name="RELEASE_NOTES_BASE_URL">
- http://wiki.secondlife.com/wiki/Release_Notes/
+ https://releasenotes.secondlife.com/viewer/
</string>
<string name="LoadingData">
Wird geladen...
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index 51c7f62503..9f853fd960 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1916,6 +1916,7 @@ Only large parcels can be listed in search.
layout="topleft"
left="8"
name="public_access"
+ tool_tip=""
label="Anyone can visit (Unchecking this will create ban lines)"
top_pad="10"
width="278" />
diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
index 714d4166c0..f15f79e9aa 100644
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -212,7 +212,15 @@ clicking on their names.
layout="topleft"
left="0"
name="role_create"
- width="120" />
+ width="100" />
+ <button
+ follows="top|left"
+ height="23"
+ label="Copy Role"
+ layout="topleft"
+ left_pad="10"
+ name="role_copy"
+ width="100" />
<button
height="23"
follows="top|left"
@@ -220,7 +228,7 @@ clicking on their names.
layout="topleft"
left_pad="10"
name="role_delete"
- width="120" />
+ width="100" />
</panel>
<panel
border="false"
diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
index c56a5e17cd..ed37e9e2cc 100644
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -28,10 +28,6 @@
name="Title">
Script: [NAME]
</panel.string>
- <panel.string
- name="external_editor_not_set">
- Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting.
- </panel.string>
<menu_bar
bg_visible="false"
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 1e4ab75d66..8fa339a946 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -321,7 +321,7 @@ Please try logging in again in a minute.</string>
<string name="ReleaseNotes">Release Notes</string>
<!-- Always mark translate="false" for strings that are nothing but URLs, as they don't need translation. -->
- <string name="RELEASE_NOTES_BASE_URL" translate="false">http://wiki.secondlife.com/wiki/Release_Notes/</string>
+ <string name="RELEASE_NOTES_BASE_URL" translate="false">https://releasenotes.secondlife.com/viewer/</string>
<!-- Indicates something is being loaded. Maybe should be merged with RetrievingData -->
<string name="LoadingData">Loading...</string>
@@ -3936,7 +3936,7 @@ Please check http://status.secondlifegrid.net to see if there is a known problem
<string name="EmptyOutfitText">There are no items in this outfit</string>
<!-- External editor status codes -->
- <string name="ExternalEditorNotSet">Select an editor using the ExternalEditor setting.</string>
+ <string name="ExternalEditorNotSet">Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting.</string>
<string name="ExternalEditorNotFound">Cannot find the external editor you specified.
Try enclosing path to the editor with double quotes.
(e.g. "/path to my/editor" "%s")</string>
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index 2b8d34859a..c9bfbd6610 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -643,7 +643,7 @@ Intenta iniciar sesión de nuevo en unos instantes.
Notas de la versión
</string>
<string name="RELEASE_NOTES_BASE_URL">
- http://wiki.secondlife.com/wiki/Release_Notes/
+ https://releasenotes.secondlife.com/viewer/
</string>
<string name="LoadingData">
Cargando...
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index ab106a9ba8..959494545a 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -652,7 +652,7 @@ Veuillez réessayer de vous connecter dans une minute.
Notes de version
</string>
<string name="RELEASE_NOTES_BASE_URL">
- http://wiki.secondlife.com/wiki/Release_Notes/
+ https://releasenotes.secondlife.com/viewer/
</string>
<string name="LoadingData">
Chargement...
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index 948f5984df..9265ce9ec6 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -648,7 +648,7 @@ Prova ad accedere nuovamente tra un minuto.
Note sulla versione
</string>
<string name="RELEASE_NOTES_BASE_URL">
- http://wiki.secondlife.com/wiki/Release_Notes/
+ https://releasenotes.secondlife.com/viewer/
</string>
<string name="LoadingData">
In caricamento...
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index 20dcedaa2a..1e123eb619 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -651,7 +651,7 @@ support@secondlife.com にお問い合わせください。
リリースノート
</string>
<string name="RELEASE_NOTES_BASE_URL">
- http://wiki.secondlife.com/wiki/Release_Notes/
+ https://releasenotes.secondlife.com/viewer/
</string>
<string name="LoadingData">
ローディング...
diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml
index cd5639711f..cccc70a92a 100644
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -608,7 +608,7 @@ Aguarde um minuto antes que tentar logar-se novamente.
Notas de versão
</string>
<string name="RELEASE_NOTES_BASE_URL">
- http://wiki.secondlife.com/wiki/Release_Notes/
+ https://releasenotes.secondlife.com/viewer/
</string>
<string name="LoadingData">
Carregando...