summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.hgtags1
-rwxr-xr-xdoc/contributions.txt1
-rw-r--r--indra/CMakeLists.txt10
-rw-r--r--indra/cmake/00-Common.cmake2
-rw-r--r--indra/llaudio/llvorbisencode.h2
-rw-r--r--indra/llcommon/llstring.h11
-rw-r--r--indra/llcommon/lluri.cpp98
-rw-r--r--indra/llcommon/lluri.h8
-rw-r--r--indra/llcommon/tests/lluri_test.cpp35
-rw-r--r--indra/llcorehttp/_httplibcurl.cpp3
-rw-r--r--indra/llimage/llimagebmp.cpp2
-rw-r--r--indra/llmath/lloctree.h16
-rw-r--r--indra/llmessage/lliosocket.cpp2
-rw-r--r--indra/llmessage/llproxy.cpp8
-rw-r--r--indra/llrender/llfontfreetype.cpp122
-rw-r--r--indra/llrender/llfontfreetype.h9
-rw-r--r--indra/llrender/llfontgl.cpp20
-rw-r--r--indra/llrender/llfontgl.h4
-rw-r--r--indra/llrender/llfontregistry.cpp107
-rw-r--r--indra/llrender/llfontregistry.h4
-rw-r--r--indra/llui/lltextbox.cpp1
-rw-r--r--indra/llui/lltransutil.cpp2
-rw-r--r--indra/llwindow/llwindowmacosx-objc.h6
-rw-r--r--indra/llwindow/llwindowmacosx-objc.mm6
-rw-r--r--indra/llwindow/llwindowmacosx.cpp5
-rw-r--r--indra/llwindow/llwindowwin32.cpp13
-rw-r--r--indra/media_plugins/cef/media_plugin_cef.cpp14
-rw-r--r--indra/newview/CMakeLists.txt8
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/commands.xml10
-rw-r--r--indra/newview/app_settings/settings_per_account.xml11
-rw-r--r--indra/newview/app_settings/toolbars.xml1
-rw-r--r--indra/newview/installers/windows/installer_template.nsi9
-rwxr-xr-xindra/newview/installers/windows/lang_de.nsibin13014 -> 6560 bytes
-rw-r--r--indra/newview/llagent.cpp7
-rw-r--r--indra/newview/llagent.h2
-rw-r--r--indra/newview/llappviewer.cpp140
-rw-r--r--indra/newview/llcommandlineparser.cpp36
-rw-r--r--indra/newview/llcontrolavatar.cpp44
-rw-r--r--indra/newview/llfacebookconnect.cpp714
-rw-r--r--indra/newview/llfacebookconnect.h116
-rw-r--r--indra/newview/llfasttimerview.cpp48
-rw-r--r--indra/newview/llfasttimerview.h4
-rw-r--r--indra/newview/llfloaterfacebook.cpp1132
-rw-r--r--indra/newview/llfloaterfacebook.h185
-rw-r--r--indra/newview/llfloaterland.cpp22
-rw-r--r--indra/newview/llfloaterland.h2
-rw-r--r--indra/newview/llfloatermodelpreview.cpp12
-rw-r--r--indra/newview/llfloatermodelpreview.h4
-rw-r--r--indra/newview/llfloateroutfitsnapshot.cpp2
-rw-r--r--indra/newview/llfloatersnapshot.cpp5
-rw-r--r--indra/newview/llfloatertools.cpp5
-rw-r--r--indra/newview/llfloaterwebcontent.cpp22
-rw-r--r--indra/newview/llglsandbox.cpp37
-rw-r--r--indra/newview/llgroupmgr.cpp4
-rw-r--r--indra/newview/llgroupmgr.h5
-rw-r--r--indra/newview/llinventorybridge.cpp66
-rw-r--r--indra/newview/llinventorybridge.h28
-rw-r--r--indra/newview/llinventoryfilter.cpp17
-rw-r--r--indra/newview/llinventoryfilter.h14
-rw-r--r--indra/newview/llinventorymodel.cpp8
-rw-r--r--indra/newview/llmachineid.cpp42
-rw-r--r--indra/newview/llnamelistctrl.cpp43
-rw-r--r--indra/newview/llnotificationscripthandler.cpp1
-rw-r--r--indra/newview/llpanelexperiencepicker.cpp3
-rw-r--r--indra/newview/llpanelgroupinvite.cpp19
-rw-r--r--indra/newview/llpanelgrouproles.cpp62
-rw-r--r--indra/newview/llpanelgrouproles.h4
-rw-r--r--indra/newview/llpanellogin.cpp34
-rw-r--r--indra/newview/llpanelmaininventory.cpp11
-rw-r--r--indra/newview/llpanelobjectinventory.cpp102
-rw-r--r--indra/newview/llpanelobjectinventory.h6
-rw-r--r--indra/newview/llpanelpeople.cpp86
-rw-r--r--indra/newview/llpanelpeople.h7
-rw-r--r--indra/newview/llpanelpeoplemenus.cpp33
-rw-r--r--indra/newview/llpanelpeoplemenus.h13
-rw-r--r--indra/newview/llpanelplaceprofile.cpp12
-rw-r--r--indra/newview/llpanelsnapshotoptions.cpp15
-rw-r--r--indra/newview/llpreviewnotecard.cpp167
-rw-r--r--indra/newview/llpreviewnotecard.h31
-rw-r--r--indra/newview/llpreviewscript.cpp19
-rw-r--r--indra/newview/llpreviewscript.h18
-rw-r--r--indra/newview/llsearchableui.cpp19
-rw-r--r--indra/newview/llsearchableui.h2
-rw-r--r--indra/newview/llselectmgr.cpp51
-rw-r--r--indra/newview/llselectmgr.h2
-rw-r--r--indra/newview/llsidepanelinventory.cpp15
-rw-r--r--indra/newview/llsnapshotlivepreview.cpp5
-rw-r--r--indra/newview/llsurfacepatch.cpp2
-rw-r--r--indra/newview/lltexturefetch.cpp4
-rw-r--r--indra/newview/lltexturefetch.h1
-rw-r--r--indra/newview/lltoolcomp.cpp2
-rw-r--r--indra/newview/lltoolpie.cpp59
-rw-r--r--indra/newview/lltranslate.cpp64
-rw-r--r--indra/newview/lltranslate.h3
-rw-r--r--indra/newview/lltwitterconnect.cpp44
-rw-r--r--indra/newview/llurldispatcher.cpp51
-rw-r--r--indra/newview/llviewerdisplay.cpp7
-rw-r--r--indra/newview/llviewerfloaterreg.cpp3
-rw-r--r--indra/newview/llviewerkeyboard.cpp10
-rw-r--r--indra/newview/llviewermedia.cpp19
-rw-r--r--indra/newview/llviewermenu.cpp12
-rw-r--r--indra/newview/llviewermessage.cpp2
-rw-r--r--indra/newview/llviewerregion.cpp1
-rw-r--r--indra/newview/llviewertexture.cpp5
-rw-r--r--indra/newview/llviewertexturelist.cpp2
-rw-r--r--indra/newview/llviewerwindow.cpp3
-rw-r--r--indra/newview/llvlcomposition.cpp11
-rw-r--r--indra/newview/llvoicevivox.cpp26
-rw-r--r--indra/newview/pipeline.cpp1
-rw-r--r--indra/newview/skins/default/textures/textures.xml10
-rw-r--r--indra/newview/skins/default/xui/de/floater_about_land.xml8
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml11
-rw-r--r--indra/newview/skins/default/xui/en/floater_ban_duration.xml6
-rw-r--r--indra/newview/skins/default/xui/en/floater_experienceprofile.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_facebook.xml95
-rw-r--r--indra/newview/skins/default/xui/en/floater_fast_timers.xml13
-rw-r--r--indra/newview/skins/default/xui/en/floater_gesture.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml39
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_proxy.xml8
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_notecard.xml12
-rw-r--r--indra/newview/skins/default/xui/en/floater_report_abuse.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_snapshot.xml12
-rw-r--r--indra/newview/skins/default/xui/en/fonts.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml10
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_facebook_friends.xml73
-rw-r--r--indra/newview/skins/default/xui/en/panel_facebook_photo.xml168
-rw-r--r--indra/newview/skins/default/xui/en/panel_facebook_place.xml113
-rw-r--r--indra/newview/skins/default/xui/en/panel_facebook_status.xml130
-rw-r--r--indra/newview/skins/default/xui/en/panel_flickr_photo.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_roles.xml12
-rw-r--r--indra/newview/skins/default/xui/en/panel_landmark_info.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_login_first.xml3
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml19
-rw-r--r--indra/newview/skins/default/xui/en/panel_postcard_message.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_script_ed.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_options.xml17
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_profile.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_twitter_photo.xml1
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml21
-rw-r--r--indra/newview/skins/default/xui/en/widgets/person_view.xml10
-rw-r--r--indra/newview/skins/default/xui/fr/notifications.xml2
145 files changed, 1549 insertions, 3662 deletions
diff --git a/.hgtags b/.hgtags
index 07fdce592b..a4fb6ce9f8 100755
--- a/.hgtags
+++ b/.hgtags
@@ -552,3 +552,4 @@ ec09daf1899c1c01c4ba0ba950fae572f2a612a8 6.2.2-release
ab2ec5c5423b277d23fd0511ce50c15123ff2e03 6.2.3-release
67297f9902857e357570c44722ad84de3aff974e 6.2.4-release
9777aec6dc4a30a24537297ac040861ce16b82ae 6.3.0-release
+ece699718f163921717bb95a6131e94af4c4138f 6.3.1-release
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 3e8f65fa54..58d711470e 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -1073,6 +1073,7 @@ Nicky Dasmijn
MAINT-6665
SL-10291
SL-10293
+ SL-11061
Nicky Perian
OPEN-1
STORM-1087
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 6c20a813ba..62a8f3f003 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -3,8 +3,8 @@
# cmake_minimum_required should appear before any
# other commands to guarantee full compatibility
# with the version specified
-## prior to 3.4, the Windows manifest handling was missing
-cmake_minimum_required(VERSION 3.4.0 FATAL_ERROR)
+## 3.8 added VS_DEBUGGER_WORKING_DIRECTORY support
+cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR)
set(ROOT_PROJECT_NAME "SecondLife" CACHE STRING
"The root project/makefile/solution name. Defaults to SecondLife.")
@@ -83,6 +83,12 @@ add_dependencies(viewer secondlife-bin)
add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL)
+# sets the 'startup project' for debugging from visual studio.
+set_property(
+ DIRECTORY ${VIEWER_PREFIX}
+ PROPERTY VS_STARTUP_PROJECT secondlife-bin
+ )
+
if (LL_TESTS)
# Define after the custom targets are created so
# individual apps can add themselves as dependencies
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 40fc706a99..03da30649a 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -151,6 +151,8 @@ endif (LINUX)
if (DARWIN)
+ # Warnings should be fatal -- thanks, Nicky Perian, for spotting reversed default
+ set(CLANG_DISABLE_FATAL_WARNINGS OFF)
set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
set(DARWIN_extra_cstar_flags "-Wno-unused-local-typedef -Wno-deprecated-declarations")
diff --git a/indra/llaudio/llvorbisencode.h b/indra/llaudio/llvorbisencode.h
index 6b22a2cb59..7372765075 100644
--- a/indra/llaudio/llvorbisencode.h
+++ b/indra/llaudio/llvorbisencode.h
@@ -40,7 +40,7 @@ const S32 LLVORBISENC_UNSUPPORTED_WORD_SIZE = 9; // unsupported word size
const S32 LLVORBISENC_CLIP_TOO_LONG = 10; // source file is too long
const S32 LLVORBISENC_CHUNK_SIZE_ERR = 11; // chunk size is wrong
-const F32 LLVORBIS_CLIP_MAX_TIME = 10.0f;
+const F32 LLVORBIS_CLIP_MAX_TIME = 30.0f;
const U8 LLVORBIS_CLIP_MAX_CHANNELS = 2;
const U32 LLVORBIS_CLIP_SAMPLE_RATE = 44100;
const U32 LLVORBIS_CLIP_MAX_SAMPLES_PER_CHANNEL = (U32)(LLVORBIS_CLIP_MAX_TIME * LLVORBIS_CLIP_SAMPLE_RATE);
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 30bec3a6f8..b619a9e48c 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -1735,7 +1735,8 @@ bool LLStringUtilBase<T>::startsWith(
const string_type& substr)
{
if(string.empty() || (substr.empty())) return false;
- if(0 == string.find(substr)) return true;
+ if (substr.length() > string.length()) return false;
+ if (0 == string.compare(0, substr.length(), substr)) return true;
return false;
}
@@ -1746,9 +1747,11 @@ bool LLStringUtilBase<T>::endsWith(
const string_type& substr)
{
if(string.empty() || (substr.empty())) return false;
- std::string::size_type idx = string.rfind(substr);
- if(std::string::npos == idx) return false;
- return (idx == (string.size() - substr.size()));
+ size_t sub_len = substr.length();
+ size_t str_len = string.length();
+ if (sub_len > str_len) return false;
+ if (0 == string.compare(str_len - sub_len, sub_len, substr)) return true;
+ return false;
}
// static
diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp
index 758b98e143..9942bc0cf8 100644
--- a/indra/llcommon/lluri.cpp
+++ b/indra/llcommon/lluri.cpp
@@ -173,6 +173,19 @@ namespace
"-._~";
return s;
}
+ const std::string path()
+ {
+ static const std::string s =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789"
+ "$-_.+"
+ "!*'(),"
+ "{}|\\^~[]`"
+ "<>#%"
+ ";/?:@&=";
+ return s;
+ }
const std::string sub_delims()
{
static const std::string s = "!$&'()*+,;=";
@@ -187,6 +200,12 @@ namespace
{ return LLURI::escape(s, unreserved() + ":@!$'()*+,"); } // sub_delims - "&;=" + ":@"
std::string escapeQueryValue(const std::string& s)
{ return LLURI::escape(s, unreserved() + ":@!$'()*+,="); } // sub_delims - "&;" + ":@"
+ std::string escapeUriQuery(const std::string& s)
+ { return LLURI::escape(s, unreserved() + ":@?&$;*+=%/"); }
+ std::string escapeUriData(const std::string& s)
+ { return LLURI::escape(s, unreserved() + "%"); }
+ std::string escapeUriPath(const std::string& s)
+ { return LLURI::escape(s, path()); }
}
//static
@@ -202,6 +221,85 @@ std::string LLURI::escape(const std::string& str)
return escape(str, default_allowed, true);
}
+//static
+std::string LLURI::escapePathAndData(const std::string &str)
+{
+ std::string result;
+
+ const std::string data_marker = "data:";
+ if (str.compare(0, data_marker.length(), data_marker) == 0)
+ {
+ // This is not url, but data, data part needs to be properly escaped
+ // data part is separated by ',' from header. Minimal data uri is "data:,"
+ // See "data URI scheme"
+ size_t separator = str.find(',');
+ if (separator != std::string::npos)
+ {
+ size_t header_size = separator + 1;
+ std::string header = str.substr(0, header_size);
+ // base64 is url-safe
+ if (header.find("base64") != std::string::npos)
+ {
+ // assume url-safe data
+ result = str;
+ }
+ else
+ {
+ std::string data = str.substr(header_size, str.length() - header_size);
+
+ // Notes: File can be partially pre-escaped, that's why escaping ignores '%'
+ // It somewhat limits user from displaying strings like "%20" in text
+ // but that's how viewer worked for a while and user can double-escape it
+
+
+ // Header doesn't need escaping
+ result = header + escapeUriData(data);
+ }
+ }
+ }
+ else
+ {
+ // try processing it as path with query separator
+ // The query component is indicated by the first question
+ // mark("?") character and terminated by a number sign("#")
+ size_t delim_pos = str.find('?');
+ if (delim_pos == std::string::npos)
+ {
+ // alternate separator
+ delim_pos = str.find(';');
+ }
+
+ if (delim_pos != std::string::npos)
+ {
+ size_t path_size = delim_pos + 1;
+ std::string query;
+ std::string fragment;
+
+ size_t fragment_pos = str.find('#');
+ if (fragment_pos != std::string::npos)
+ {
+ query = str.substr(path_size, fragment_pos - path_size);
+ fragment = str.substr(fragment_pos);
+ }
+ else
+ {
+ query = str.substr(path_size);
+ }
+
+ std::string path = str.substr(0, path_size);
+
+ result = escapeUriPath(path) + escapeUriQuery(query) + escapeUriPath(fragment);
+ }
+ }
+
+ if (result.empty())
+ {
+ // Not a known scheme or no data part, try just escaping as Uri path
+ result = escapeUriPath(str);
+ }
+ return result;
+}
+
LLURI::LLURI()
{
}
diff --git a/indra/llcommon/lluri.h b/indra/llcommon/lluri.h
index 9e44cc7da2..b8fca0ca51 100644
--- a/indra/llcommon/lluri.h
+++ b/indra/llcommon/lluri.h
@@ -158,6 +158,14 @@ public:
bool is_allowed_sorted = false);
/**
+ * @brief Break string into data part and path or sheme
+ * and escape path (if present) and data.
+ * Data part is not allowed to have path related symbols
+ * @param str The raw URI to escape.
+ */
+ static std::string escapePathAndData(const std::string &str);
+
+ /**
* @brief unescape an escaped URI string.
*
* @param str The escped URI to unescape.
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/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp
index abd304f6a5..975ce8a4d5 100644
--- a/indra/llcorehttp/_httplibcurl.cpp
+++ b/indra/llcorehttp/_httplibcurl.cpp
@@ -355,7 +355,8 @@ bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode
}
if (op->mStatus)
{
- int http_status(HTTP_OK);
+ // note: CURLINFO_RESPONSE_CODE requires a long - https://curl.haxx.se/libcurl/c/CURLINFO_RESPONSE_CODE.html
+ long http_status(HTTP_OK);
if (handle)
{
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/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index b15b98db80..7caf0766b7 100644
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -265,7 +265,7 @@ LLSocket::~LLSocket()
void LLSocket::setBlocking(S32 timeout)
{
// set up the socket options
- ll_apr_warn_status(apr_socket_timeout_set(mSocket, timeout));
+ ll_apr_warn_status(apr_socket_timeout_set(mSocket, timeout)); // Sets both receive and send timeout SO_RCVTIMEO, SO_SNDTIMEO
ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_NONBLOCK, 0));
ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_SNDBUF, LL_SEND_BUFFER_SIZE));
ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_RCVBUF, LL_RECV_BUFFER_SIZE));
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index 5730a36267..dea03aab85 100644
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -473,7 +473,8 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou
rv = apr_socket_send(apr_socket, dataout, &outlen);
if (APR_SUCCESS != rv)
{
- LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << LL_ENDL;
+ char buf[MAX_STRING];
+ LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL;
ll_apr_warn_status(rv);
}
else if (expected_len != outlen)
@@ -483,13 +484,16 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou
rv = -1;
}
+ ms_sleep(1);
+
if (APR_SUCCESS == rv)
{
expected_len = maxinlen;
rv = apr_socket_recv(apr_socket, datain, &maxinlen);
if (rv != APR_SUCCESS)
{
- LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << LL_ENDL;
+ char buf[MAX_STRING];
+ LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL;
ll_apr_warn_status(rv);
}
else if (expected_len < maxinlen)
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index ab668dc192..c41730ebaa 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -157,7 +157,7 @@ void ft_close_cb(FT_Stream stream) {
}
#endif
-BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback)
+BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n)
{
// Don't leak face objects. This is also needed to deal with
// changed font file names.
@@ -168,40 +168,8 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
}
int error;
-
#ifdef LL_WINDOWS
- pFileStream = new llifstream(filename, std::ios::binary);
- if (pFileStream->is_open())
- {
- std::streampos beg = pFileStream->tellg();
- pFileStream->seekg(0, std::ios::end);
- std::streampos end = pFileStream->tellg();
- std::size_t file_size = end - beg;
- pFileStream->seekg(0, std::ios::beg);
-
- pFtStream = new LLFT_Stream();
- pFtStream->base = 0;
- pFtStream->pos = 0;
- pFtStream->size = file_size;
- pFtStream->descriptor.pointer = pFileStream;
- pFtStream->read = ft_read_cb;
- pFtStream->close = ft_close_cb;
-
- FT_Open_Args args;
- args.flags = FT_OPEN_STREAM;
- args.stream = (FT_StreamRec*)pFtStream;
-
- error = FT_Open_Face(gFTLibrary,
- &args,
- 0,
- &mFTFace);
- }
- else
- {
- delete pFileStream;
- pFileStream = NULL;
- return FALSE;
- }
+ error = ftOpenFace(filename, face_n);
#else
error = FT_New_Face( gFTLibrary,
filename.c_str(),
@@ -212,11 +180,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
if (error)
{
#ifdef LL_WINDOWS
- pFileStream->close();
- delete pFileStream;
- delete pFtStream;
- pFileStream = NULL;
- pFtStream = NULL;
+ clearFontStreams();
#endif
return FALSE;
}
@@ -235,11 +199,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
// Clean up freetype libs.
FT_Done_Face(mFTFace);
#ifdef LL_WINDOWS
- pFileStream->close();
- delete pFileStream;
- delete pFtStream;
- pFileStream = NULL;
- pFtStream = NULL;
+ clearFontStreams();
#endif
mFTFace = NULL;
return FALSE;
@@ -285,18 +245,88 @@ 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;
}
+S32 LLFontFreetype::getNumFaces(const std::string& filename)
+{
+ if (mFTFace)
+ {
+ FT_Done_Face(mFTFace);
+ mFTFace = NULL;
+ }
+
+ S32 num_faces = 1;
+
+#ifdef LL_WINDOWS
+ int error = ftOpenFace(filename, 0);
+
+ if (error)
+ {
+ return 0;
+ }
+ else
+ {
+ num_faces = mFTFace->num_faces;
+ }
+
+ FT_Done_Face(mFTFace);
+ clearFontStreams();
+ mFTFace = NULL;
+#endif
+
+ return num_faces;
+}
+
+#ifdef LL_WINDOWS
+S32 LLFontFreetype::ftOpenFace(const std::string& filename, S32 face_n)
+{
+ S32 error = -1;
+ pFileStream = new llifstream(filename, std::ios::binary);
+ if (pFileStream->is_open())
+ {
+ std::streampos beg = pFileStream->tellg();
+ pFileStream->seekg(0, std::ios::end);
+ std::streampos end = pFileStream->tellg();
+ std::size_t file_size = end - beg;
+ pFileStream->seekg(0, std::ios::beg);
+
+ pFtStream = new LLFT_Stream();
+ pFtStream->base = 0;
+ pFtStream->pos = 0;
+ pFtStream->size = file_size;
+ pFtStream->descriptor.pointer = pFileStream;
+ pFtStream->read = ft_read_cb;
+ pFtStream->close = ft_close_cb;
+
+ FT_Open_Args args;
+ args.flags = FT_OPEN_STREAM;
+ args.stream = (FT_StreamRec*)pFtStream;
+ error = FT_Open_Face(gFTLibrary, &args, face_n, &mFTFace);
+ }
+ return error;
+}
+
+void LLFontFreetype::clearFontStreams()
+{
+ if (pFileStream)
+ {
+ pFileStream->close();
+ }
+ delete pFileStream;
+ delete pFtStream;
+ pFileStream = NULL;
+ pFtStream = NULL;
+}
+#endif
+
void LLFontFreetype::setFallbackFonts(const font_vector_t &font)
{
mFallbackFonts = font;
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index aadebf5e70..1afe84e770 100644
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
@@ -84,7 +84,14 @@ public:
// is_fallback should be true for fallback fonts that aren't used
// to render directly (Unicode backup, primarily)
- BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback);
+ BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n = 0);
+
+ S32 getNumFaces(const std::string& filename);
+
+#ifdef LL_WINDOWS
+ S32 ftOpenFace(const std::string& filename, S32 face_n);
+ void clearFontStreams();
+#endif
typedef std::vector<LLPointer<LLFontFreetype> > font_vector_t;
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 8cd18c5fa1..86a4c35e6d 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -89,14 +89,24 @@ void LLFontGL::destroyGL()
mFontFreetype->destroyGL();
}
-BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback)
+BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n)
{
if(mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
{
mFontFreetype = new LLFontFreetype;
}
- return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback);
+ return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback, face_n);
+}
+
+S32 LLFontGL::getNumFaces(const std::string& filename)
+{
+ if (mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
+ {
+ mFontFreetype = new LLFontFreetype;
+ }
+
+ return mFontFreetype->getNumFaces(filename);
}
static LLTrace::BlockTimerStatHandle FTM_RENDER_FONTS("Fonts");
@@ -860,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;
@@ -883,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/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 7d0e53f60f..10891faed9 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -87,7 +87,9 @@ public:
void destroyGL();
- BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback);
+ BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback, S32 face_n = 0);
+
+ S32 getNumFaces(const std::string& filename);
S32 render(const LLWString &text, S32 begin_offset,
const LLRect& rect,
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index 3c829596ce..dbe71e2882 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -44,6 +44,8 @@ using std::map;
bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc);
bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node);
+const std::string MACOSX_FONT_PATH_LIBRARY = "/Library/Fonts/";
+
LLFontDescriptor::LLFontDescriptor():
mStyle(0)
{
@@ -61,6 +63,16 @@ LLFontDescriptor::LLFontDescriptor(const std::string& name,
}
LLFontDescriptor::LLFontDescriptor(const std::string& name,
+ const std::string& size,
+ const U8 style,
+ const string_vec_t& file_names,
+ const string_vec_t& ft_collection_listections) :
+ LLFontDescriptor(name, size, style, file_names)
+{
+ mFontCollectionsList = ft_collection_listections;
+}
+
+LLFontDescriptor::LLFontDescriptor(const std::string& name,
const std::string& size,
const U8 style):
mName(name),
@@ -162,7 +174,7 @@ LLFontDescriptor LLFontDescriptor::normalize() const
if (removeSubString(new_name,"Italic"))
new_style |= LLFontGL::ITALIC;
- return LLFontDescriptor(new_name,new_size,new_style,getFileNames());
+ return LLFontDescriptor(new_name,new_size,new_style,getFileNames(),getFontCollectionsList());
}
LLFontRegistry::LLFontRegistry(bool create_gl_textures)
@@ -213,6 +225,7 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
success = success || init_succ;
}
}
+
//if (success)
// dump();
@@ -260,6 +273,16 @@ bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc)
{
std::string font_file_name = child->getTextContents();
desc.getFileNames().push_back(font_file_name);
+
+ if (child->hasAttribute("load_collection"))
+ {
+ BOOL col = FALSE;
+ child->getAttributeBOOL("load_collection", col);
+ if (col)
+ {
+ desc.getFontCollectionsList().push_back(font_file_name);
+ }
+ }
}
else if (child->hasName("os"))
{
@@ -306,8 +329,15 @@ bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node)
match_file_names.insert(match_file_names.begin(),
desc.getFileNames().begin(),
desc.getFileNames().end());
+
+ string_vec_t collections_list = match_desc->getFontCollectionsList();
+ collections_list.insert(collections_list.begin(),
+ desc.getFontCollectionsList().begin(),
+ desc.getFontCollectionsList().end());
+
LLFontDescriptor new_desc = *match_desc;
new_desc.getFileNames() = match_file_names;
+ new_desc.getFontCollectionsList() = collections_list;
registry->mFontMap.erase(*match_desc);
registry->mFontMap[new_desc] = NULL;
}
@@ -393,6 +423,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
// Build list of font names to look for.
// Files specified for this font come first, followed by those from the default descriptor.
string_vec_t file_names = match_desc->getFileNames();
+ string_vec_t ft_collection_list = match_desc->getFontCollectionsList();
string_vec_t default_file_names;
LLFontDescriptor default_desc("default",s_template_string,0);
const LLFontDescriptor *match_default_desc = getMatchingFontDesc(default_desc);
@@ -401,6 +432,9 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
file_names.insert(file_names.end(),
match_default_desc->getFileNames().begin(),
match_default_desc->getFileNames().end());
+ ft_collection_list.insert(ft_collection_list.end(),
+ match_default_desc->getFontCollectionsList().begin(),
+ match_default_desc->getFontCollectionsList().end());
}
// Add ultimate fallback list - generated dynamically on linux,
@@ -433,39 +467,62 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
file_name_it != file_names.end();
++file_name_it)
{
- LLFontGL *fontp = new LLFontGL;
- std::string font_path = local_path + *file_name_it;
+ LLFontGL *fontp = NULL;
+ string_vec_t font_paths;
+ font_paths.push_back(local_path + *file_name_it);
+ font_paths.push_back(sys_path + *file_name_it);
+#if LL_DARWIN
+ font_paths.push_back(MACOSX_FONT_PATH_LIBRARY + *file_name_it);
+#endif
+
+ bool is_ft_collection = (std::find(ft_collection_list.begin(), ft_collection_list.end(), *file_name_it) != ft_collection_list.end());
// *HACK: Fallback fonts don't render, so we can use that to suppress
// creation of OpenGL textures for test apps. JC
BOOL is_fallback = !is_first_found || !mCreateGLTextures;
F32 extra_scale = (is_fallback)?fallback_scale:1.0;
- if (!fontp->loadFace(font_path, extra_scale * point_size,
- LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback))
+ F32 point_size_scale = extra_scale * point_size;
+ bool is_font_loaded = false;
+ for(string_vec_t::iterator font_paths_it = font_paths.begin();
+ font_paths_it != font_paths.end();
+ ++font_paths_it)
{
- font_path = sys_path + *file_name_it;
-
- if (!fontp->loadFace(font_path, extra_scale * point_size,
- LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback))
+ fontp = new LLFontGL;
+ S32 num_faces = is_ft_collection ? fontp->getNumFaces(*font_paths_it) : 1;
+ for (S32 i = 0; i < num_faces; i++)
{
- LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << " from path " << local_path << LL_ENDL;
- delete fontp;
- fontp = NULL;
+ if (fontp == NULL)
+ {
+ fontp = new LLFontGL;
+ }
+ if (fontp->loadFace(*font_paths_it, point_size_scale,
+ LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback, i))
+ {
+ is_font_loaded = true;
+ if (is_first_found)
+ {
+ result = fontp;
+ is_first_found = false;
+ }
+ else
+ {
+ fontlist.push_back(fontp->mFontFreetype);
+ delete fontp;
+ fontp = NULL;
+ }
+ }
+ else
+ {
+ delete fontp;
+ fontp = NULL;
+ }
}
+ if (is_font_loaded) break;
}
-
- if(fontp)
+ if(!is_font_loaded)
{
- if (is_first_found)
- {
- result = fontp;
- is_first_found = false;
- }
- else
- {
- fontlist.push_back(fontp->mFontFreetype);
- delete fontp;
- fontp = NULL;
- }
+ LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << LL_ENDL;
+ delete fontp;
+ fontp = NULL;
}
}
diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h
index 177eb6c8a5..e30c81c630 100644
--- a/indra/llrender/llfontregistry.h
+++ b/indra/llrender/llfontregistry.h
@@ -40,6 +40,7 @@ public:
LLFontDescriptor();
LLFontDescriptor(const std::string& name, const std::string& size, const U8 style);
LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const string_vec_t& file_names);
+ LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const string_vec_t& file_names, const string_vec_t& font_collections);
LLFontDescriptor normalize() const;
bool operator<(const LLFontDescriptor& b) const;
@@ -52,6 +53,8 @@ public:
void setSize(const std::string& size) { mSize = size; }
const std::vector<std::string>& getFileNames() const { return mFileNames; }
std::vector<std::string>& getFileNames() { return mFileNames; }
+ const std::vector<std::string>& getFontCollectionsList() const { return mFontCollectionsList; }
+ std::vector<std::string>& getFontCollectionsList() { return mFontCollectionsList; }
const U8 getStyle() const { return mStyle; }
void setStyle(U8 style) { mStyle = style; }
@@ -59,6 +62,7 @@ private:
std::string mName;
std::string mSize;
string_vec_t mFileNames;
+ string_vec_t mFontCollectionsList;
U8 mStyle;
};
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 01fe82e45d..9faff1278d 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -122,6 +122,7 @@ void LLTextBox::setEnabled(BOOL enabled)
LLTextBase::setReadOnly(read_only);
updateSegments();
}
+ LLTextBase::setEnabled(enabled);
}
void LLTextBox::setText(const LLStringExplicit& text , const LLStyle::Params& input_params )
diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp
index 220cee4c90..b1534bb5e4 100644
--- a/indra/llui/lltransutil.cpp
+++ b/indra/llui/lltransutil.cpp
@@ -44,7 +44,7 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<s
bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root, LLDir::ALL_SKINS);
if (!success)
{
- LL_ERRS() << "Couldn't load string table " << xml_filename << LL_ENDL;
+ LL_ERRS() << "Couldn't load string table " << xml_filename << ". Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
return false;
}
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 10bd3cbb91..99af161102 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -110,9 +110,9 @@ void glSwapBuffers(void* context);
CGLContextObj getCGLContextObj(GLViewRef view);
unsigned long getVramSize(GLViewRef view);
float getDeviceUnitSize(GLViewRef view);
-const CGPoint getContentViewBoundsPosition(NSWindowRef window);
-const CGSize getContentViewBoundsSize(NSWindowRef window);
-const CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view);
+CGPoint getContentViewBoundsPosition(NSWindowRef window);
+CGSize getContentViewBoundsSize(NSWindowRef window);
+CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view);
void getWindowSize(NSWindowRef window, float* size);
void setWindowSize(NSWindowRef window, int width, int height);
void getCursorPos(NSWindowRef window, float* pos);
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 8fece7c5c7..f895c17643 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -258,17 +258,17 @@ float getDeviceUnitSize(GLViewRef view)
return [(LLOpenGLView*)view convertSizeToBacking:NSMakeSize(1, 1)].width;
}
-const CGPoint getContentViewBoundsPosition(NSWindowRef window)
+CGPoint getContentViewBoundsPosition(NSWindowRef window)
{
return [[(LLNSWindow*)window contentView] bounds].origin;
}
-const CGSize getContentViewBoundsSize(NSWindowRef window)
+CGSize getContentViewBoundsSize(NSWindowRef window)
{
return [[(LLNSWindow*)window contentView] bounds].size;
}
-const CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view)
+CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view)
{
return [(NSOpenGLView*)view convertRectToBacking:[[(LLNSWindow*)window contentView] bounds]].size;
}
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/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 985bd79d13..e05f507506 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -741,6 +741,17 @@ void LLWindowWin32::restore()
SetFocus(mWindowHandle);
}
+bool destroy_window_handler(HWND &hWnd)
+{
+ __try
+ {
+ return DestroyWindow(hWnd);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ return false;
+ }
+}
// close() destroys all OS-specific code associated with a window.
// Usually called from LLWindowManager::destroyWindow()
@@ -814,7 +825,7 @@ void LLWindowWin32::close()
ShowWindow(mWindowHandle, SW_HIDE);
// This causes WM_DESTROY to be sent *immediately*
- if (!DestroyWindow(mWindowHandle))
+ if (!destroy_window_handler(mWindowHandle))
{
OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),
mCallbacks->translateString("MBShutdownErr"),
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 2a8eb20af9..eead92fd8e 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -531,7 +531,12 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
}
// now we can set page zoom factor
- mCEFLib->setPageZoom(message_in.getValueReal("factor"));
+ F32 factor = (F32)message_in.getValueReal("factor");
+#if LL_DARWIN
+ //temporary fix for SL-10473: issue with displaying checkboxes on Mojave
+ factor*=1.001;
+#endif
+ mCEFLib->setPageZoom(factor);
// Plugin gets to decide the texture parameters to use.
mDepth = 4;
@@ -736,6 +741,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
if (message_name == "set_page_zoom_factor")
{
F32 factor = (F32)message_in.getValueReal("factor");
+#if LL_DARWIN
+ //temporary fix for SL-10473: issue with displaying checkboxes on Mojave
+ factor*=1.001;
+#endif
mCEFLib->setPageZoom(factor);
}
if (message_name == "browse_stop")
@@ -813,7 +822,8 @@ void MediaPluginCEF::keyEvent(dullahan::EKeyEvent key_event, LLSD native_key_dat
// adding new code below in unicodeInput means we don't send ascii chars
// here too or we get double key presses on a mac.
bool esc_key = (event_umodchars == 27);
- if (esc_key || ((unsigned char)event_chars < 0x10 || (unsigned char)event_chars >= 0x7f ))
+ bool tab_key_up = (event_umodchars == 9) && (key_event == dullahan::EKeyEvent::KE_KEY_UP);
+ if ((esc_key || ((unsigned char)event_chars < 0x10 || (unsigned char)event_chars >= 0x7f )) && !tab_key_up)
{
mCEFLib->nativeKeyboardEventOSX(key_event, event_modifiers,
event_keycode, event_chars,
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index b36a55d7eb..447994d83e 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -201,7 +201,6 @@ set(viewer_SOURCE_FILES
llexperiencelog.cpp
llexternaleditor.cpp
llface.cpp
- llfacebookconnect.cpp
llfasttimerview.cpp
llfavoritesbar.cpp
llfeaturemanager.cpp
@@ -245,7 +244,6 @@ set(viewer_SOURCE_FILES
llfloaterexperiencepicker.cpp
llfloaterexperienceprofile.cpp
llfloaterexperiences.cpp
- llfloaterfacebook.cpp
llfloaterflickr.cpp
llfloaterfonttest.cpp
llfloatergesture.cpp
@@ -830,7 +828,6 @@ set(viewer_HEADER_FILES
llexperiencelog.h
llexternaleditor.h
llface.h
- llfacebookconnect.h
llfasttimerview.h
llfavoritesbar.h
llfeaturemanager.h
@@ -874,7 +871,6 @@ set(viewer_HEADER_FILES
llfloaterexperiencepicker.h
llfloaterexperienceprofile.h
llfloaterexperiences.h
- llfloaterfacebook.h
llfloaterflickr.h
llfloaterfonttest.h
llfloatergesture.h
@@ -1885,12 +1881,12 @@ if (WINDOWS)
# sets the 'working directory' for debugging from visual studio.
# Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865)
- if ((NOT UNATTENDED) AND (${CMAKE_VERSION} VERSION_GREATER "3.7.2"))
+ if (NOT UNATTENDED)
set_property(
TARGET ${VIEWER_BINARY_NAME}
PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
)
- endif ((NOT UNATTENDED) AND (${CMAKE_VERSION} VERSION_GREATER "3.7.2"))
+ endif (NOT UNATTENDED)
if (PACKAGE)
add_custom_command(
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index dc0208aba8..91e4a9f262 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.3.1
+6.3.2
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 412d3a53b3..cab0c523b2 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -228,16 +228,6 @@
is_running_function="Floater.IsOpen"
is_running_parameters="snapshot"
/>
- <command name="facebook"
- available_in_toybox="true"
- icon="Command_Facebook_Icon"
- label_ref="Command_Facebook_Label"
- tooltip_ref="Command_Facebook_Tooltip"
- execute_function="Floater.ToggleOrBringToFront"
- execute_parameters="facebook"
- is_running_function="Floater.IsOpen"
- is_running_parameters="facebook"
- />
<command name="flickr"
available_in_toybox="true"
icon="Command_Flickr_Icon"
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 3d4bd659f1..8f4ca6c633 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -414,5 +414,16 @@
<key>Value</key>
<string>Snapshot</string>
</map>
+ <key>ExperienceSearchMaturity</key>
+ <map>
+ <key>Comment</key>
+ <string>Setting for the user's preferred Max Content rating for Experiences search (Default rating is General)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>2</integer>
+ </map>
</map>
</llsd>
diff --git a/indra/newview/app_settings/toolbars.xml b/indra/newview/app_settings/toolbars.xml
index 36e4eb91fd..eec0d81e8b 100644
--- a/indra/newview/app_settings/toolbars.xml
+++ b/indra/newview/app_settings/toolbars.xml
@@ -21,7 +21,6 @@
<command name="voice"/>
<command name="minimap"/>
<command name="snapshot"/>
- <command name="facebook"/>
</left_toolbar>
<right_toolbar
button_display_mode="icons_only">
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index d1d5301efe..8838b6d0be 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -346,6 +346,11 @@ Call CheckWillUninstallV2 # Check if Second Life is already installed
StrCmp $DO_UNINSTALL_V2 "" PRESERVE_DONE
PRESERVE_DONE:
+# Viewer had "SLLauncher" for some time and we was seting "IsHostApp" for viewer, make sure to clean it up
+DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp"
+DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "NoStartPage"
+ClearErrors
+
Call RemoveProgFilesOnInst # Remove existing files to prevent certain errors when running the new version of the viewer
# This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py
@@ -417,7 +422,7 @@ WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" '"$INSTDIR\$
# URL param must be last item passed to viewer, it ignores subsequent params to avoid parameter injection attacks.
WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$VIEWER_EXE" -url "%1"'
-WriteRegStr HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp" ""
+WriteRegStr HKEY_CLASSES_ROOT "Applications\$INSTEXE" "IsHostApp" ""
##WriteRegStr HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}" "NoStartPage" ""
# Write out uninstaller
@@ -464,7 +469,7 @@ DeleteRegKey SHELL_CONTEXT "${INSTNAME_KEY}"
DeleteRegKey SHELL_CONTEXT "${MSCURRVER_KEY}\Uninstall\$INSTNAME"
# BUG-2707 Remove entry that disabled SEHOP
DeleteRegKey SHELL_CONTEXT "${MSNTCURRVER_KEY}\Image File Execution Options\$VIEWER_EXE"
-##DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE"
+DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE"
DeleteRegKey HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}"
# Clean up shortcuts
diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi
index 8bb20476b3..eebcf027a8 100755
--- a/indra/newview/installers/windows/lang_de.nsi
+++ b/indra/newview/installers/windows/lang_de.nsi
Binary files differ
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 9f0c923253..8b2d591da5 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -743,7 +743,7 @@ BOOL LLAgent::getFlying() const
//-----------------------------------------------------------------------------
// setFlying()
//-----------------------------------------------------------------------------
-void LLAgent::setFlying(BOOL fly)
+void LLAgent::setFlying(BOOL fly, BOOL fail_sound)
{
if (isAgentAvatarValid())
{
@@ -772,7 +772,10 @@ void LLAgent::setFlying(BOOL fly)
// parcel doesn't let you start fly
// gods can always fly
// and it's OK if you're already flying
- make_ui_sound("UISndBadKeystroke");
+ if (fail_sound)
+ {
+ make_ui_sound("UISndBadKeystroke");
+ }
return;
}
if( !was_flying )
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index b1b39b637e..ea6f68c482 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -337,7 +337,7 @@ private:
//--------------------------------------------------------------------
public:
BOOL getFlying() const;
- void setFlying(BOOL fly);
+ void setFlying(BOOL fly, BOOL fail_sound = FALSE);
static void toggleFlying();
static bool enableFlying();
BOOL canFly(); // Does this parcel allow you to fly?
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 56e8cc8ff4..be5611899a 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2439,9 +2439,9 @@ bool LLAppViewer::initConfiguration()
bool set_defaults = true;
if(!loadSettingsFromDirectory("Default", set_defaults))
{
- std::ostringstream msg;
- msg << "Unable to load default settings file. The installation may be corrupted.";
- OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
+ OSMessageBox(
+ "Unable to load default settings file. The installation may be corrupted.",
+ LLStringUtil::null,OSMB_OK);
return false;
}
@@ -2562,7 +2562,7 @@ bool LLAppViewer::initConfiguration()
if(gSavedSettings.getBOOL("DisableCrashLogger"))
{
LL_WARNS() << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << LL_ENDL;
- LLAppViewer::instance()->disableCrashlogger();
+ disableCrashlogger();
}
// Handle initialization from settings.
@@ -2579,7 +2579,7 @@ bool LLAppViewer::initConfiguration()
LL_INFOS() << msg.str() << LL_ENDL;
OSMessageBox(
- msg.str().c_str(),
+ msg.str(),
LLStringUtil::null,
OSMB_OK);
@@ -2689,7 +2689,34 @@ bool LLAppViewer::initConfiguration()
ll_init_fail_log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "test_failures.log"));
}
+ const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
+ if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
+ {
+ // Examining "Language" may not suffice -- see LLUI::getLanguage()
+ // logic. Unfortunately LLUI::getLanguage() doesn't yet do us much
+ // good because we haven't yet called LLUI::initClass().
+ gDirUtilp->setSkinFolder(skinfolder->getValue().asString(),
+ gSavedSettings.getString("Language"));
+ }
+
+ if (gSavedSettings.getBOOL("SpellCheck"))
+ {
+ std::list<std::string> dict_list;
+ std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
+ boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
+ if (!dict_list.empty())
+ {
+ LLSpellChecker::setUseSpellCheck(dict_list.front());
+ dict_list.pop_front();
+ LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
+ }
+ }
+
// Handle slurl use. NOTE: Don't let SL-55321 reappear.
+ // This initial-SLURL logic, up through the call to
+ // sendURLToOtherInstance(), must precede LLSplashScreen::show() --
+ // because if sendURLToOtherInstance() succeeds, we take a fast exit,
+ // SKIPPING the splash screen and everything else.
// *FIX: This init code should be made more robust to prevent
// the issue SL-55321 from returning. One thought is to allow
@@ -2734,6 +2761,27 @@ bool LLAppViewer::initConfiguration()
}
}
+ // NextLoginLocation is set as a side effect of LLStartUp::setStartSLURL()
+ std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
+ if ( !nextLoginLocation.empty() )
+ {
+ LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL;
+ LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
+ }
+ else if ( ( clp.hasOption("login") || clp.hasOption("autologin"))
+ && gSavedSettings.getString("CmdLineLoginLocation").empty())
+ {
+ // If automatic login from command line with --login switch
+ // init StartSLURL location.
+ std::string start_slurl_setting = gSavedSettings.getString("LoginLocation");
+ LL_DEBUGS("AppInit") << "start slurl setting '" << start_slurl_setting << "'" << LL_ENDL;
+ LLStartUp::setStartSLURL(LLSLURL(start_slurl_setting));
+ }
+ else
+ {
+ // the login location will be set by the login panel (see LLPanelLogin)
+ }
+
//RN: if we received a URL, hand it off to the existing instance.
// don't call anotherInstanceRunning() when doing URL handoff, as
// it relies on checking a marker file which will not work when running
@@ -2749,30 +2797,6 @@ bool LLAppViewer::initConfiguration()
}
}
- const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
- if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
- {
- // Examining "Language" may not suffice -- see LLUI::getLanguage()
- // logic. Unfortunately LLUI::getLanguage() doesn't yet do us much
- // good because we haven't yet called LLUI::initClass().
- gDirUtilp->setSkinFolder(skinfolder->getValue().asString(),
- gSavedSettings.getString("Language"));
- }
-
- if (gSavedSettings.getBOOL("SpellCheck"))
- {
- std::list<std::string> dict_list;
- std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
- boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
- if (!dict_list.empty())
- {
- LLSpellChecker::setUseSpellCheck(dict_list.front());
- dict_list.pop_front();
- LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
- }
- }
-
-
// Display splash screen. Must be after above check for previous
// crash as this dialog is always frontmost.
std::string splash_msg;
@@ -2804,30 +2828,15 @@ bool LLAppViewer::initConfiguration()
}
LLStringUtil::truncate(gWindowTitle, 255);
- //RN: if we received a URL, hand it off to the existing instance.
- // don't call anotherInstanceRunning() when doing URL handoff, as
- // it relies on checking a marker file which will not work when running
- // out of different directories
-
- if (LLStartUp::getStartSLURL().isValid() &&
- (gSavedSettings.getBOOL("SLURLPassToOtherInstance")))
- {
- if (sendURLToOtherInstance(LLStartUp::getStartSLURL().getSLURLString()))
- {
- // successfully handed off URL to existing instance, exit
- return false;
- }
- }
-
//
// Check for another instance of the app running
+ // This happens AFTER LLSplashScreen::show(). That may or may not be
+ // important.
//
if (mSecondInstance && !gSavedSettings.getBOOL("AllowMultipleViewers"))
{
- std::ostringstream msg;
- msg << LLTrans::getString("MBAlreadyRunning");
OSMessageBox(
- msg.str(),
+ LLTrans::getString("MBAlreadyRunning"),
LLStringUtil::null,
OSMB_OK);
return false;
@@ -2845,27 +2854,6 @@ bool LLAppViewer::initConfiguration()
}
}
- // NextLoginLocation is set from the command line option
- std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
- if ( !nextLoginLocation.empty() )
- {
- LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL;
- LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
- }
- else if ( ( clp.hasOption("login") || clp.hasOption("autologin"))
- && gSavedSettings.getString("CmdLineLoginLocation").empty())
- {
- // If automatic login from command line with --login switch
- // init StartSLURL location.
- std::string start_slurl_setting = gSavedSettings.getString("LoginLocation");
- LL_DEBUGS("AppInit") << "start slurl setting '" << start_slurl_setting << "'" << LL_ENDL;
- LLStartUp::setStartSLURL(LLSLURL(start_slurl_setting));
- }
- else
- {
- // the login location will be set by the login panel (see LLPanelLogin)
- }
-
gLastRunVersion = gSavedSettings.getString("LastRunVersion");
loadColorSettings();
@@ -2889,7 +2877,14 @@ bool LLAppViewer::initConfiguration()
// keeps growing, necessitating a method all its own.
void LLAppViewer::initStrings()
{
- LLTransUtil::parseStrings("strings.xml", default_trans_args);
+ std::string strings_file = "strings.xml";
+ std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file);
+ if (strings_path_full.empty() || !LLFile::isfile(strings_path_full))
+ {
+ // initial check to make sure files are there failed
+ LL_ERRS() << "Viewer failed to find localization and UI files. Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
+ }
+ LLTransUtil::parseStrings(strings_file, default_trans_args);
LLTransUtil::parseLanguageStrings("language_settings.xml");
// parseStrings() sets up the LLTrans substitution table. Add this one item.
@@ -3174,6 +3169,10 @@ LLSD LLAppViewer::getViewerInfo() const
substitution["datetime"] = (S32)(gVFS ? gVFS->creationTime() : 0);
info["VFS_TIME"] = LLTrans::getString("AboutTime", substitution);
+#if LL_DARWIN
+ info["HIDPI"] = gHiDPISupport;
+#endif
+
// Libraries
info["J2C_VERSION"] = LLImageJ2C::getEngineInfo();
@@ -3316,6 +3315,9 @@ std::string LLAppViewer::getViewerInfoString(bool default_string) const
}
support << "\n" << LLTrans::getString("AboutOGL", args, default_string);
support << "\n\n" << LLTrans::getString("AboutSettings", args, default_string);
+#if LL_DARWIN
+ support << "\n" << LLTrans::getString("AboutOSXHiDPI", args, default_string);
+#endif
support << "\n\n" << LLTrans::getString("AboutLibs", args, default_string);
if (info.has("COMPILER"))
{
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/llfacebookconnect.cpp b/indra/newview/llfacebookconnect.cpp
deleted file mode 100644
index 43b01fa2f1..0000000000
--- a/indra/newview/llfacebookconnect.cpp
+++ /dev/null
@@ -1,714 +0,0 @@
-/**
- * @file llfacebookconnect.h
- * @author Merov, Cho, Gil
- * @brief Connection to Facebook Service
- *
- * $LicenseInfo:firstyear=2013&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2013, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfacebookconnect.h"
-#include "llflickrconnect.h"
-#include "lltwitterconnect.h"
-
-#include "llagent.h"
-#include "llcallingcard.h" // for LLAvatarTracker
-#include "llcommandhandler.h"
-#include "llnotificationsutil.h"
-#include "llurlaction.h"
-#include "llimagepng.h"
-#include "llimagejpeg.h"
-#include "lltrans.h"
-#include "llevents.h"
-#include "llviewerregion.h"
-#include "llviewercontrol.h"
-
-#include "llfloaterwebcontent.h"
-#include "llfloaterreg.h"
-#include "llcorehttputil.h"
-
-boost::scoped_ptr<LLEventPump> LLFacebookConnect::sStateWatcher(new LLEventStream("FacebookConnectState"));
-boost::scoped_ptr<LLEventPump> LLFacebookConnect::sInfoWatcher(new LLEventStream("FacebookConnectInfo"));
-boost::scoped_ptr<LLEventPump> LLFacebookConnect::sContentWatcher(new LLEventStream("FacebookConnectContent"));
-
-// Local functions
-void log_facebook_connect_error(const std::string& request, U32 status, const std::string& reason, const std::string& code, const std::string& description)
-{
- // Note: 302 (redirect) is *not* an error that warrants logging
- if (status != 302)
- {
- LL_WARNS("FacebookConnect") << request << " request failed with a " << status << " " << reason << ". Reason: " << code << " (" << description << ")" << LL_ENDL;
- }
-}
-
-void toast_user_for_facebook_success()
-{
- LLSD args;
- args["MESSAGE"] = LLTrans::getString("facebook_post_success");
- LLNotificationsUtil::add("FacebookConnect", args);
-}
-
-LLCore::HttpHeaders::ptr_t get_headers()
-{
- LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
- // The DebugSlshareLogTag mechanism is intended to trigger slshare-service
- // debug logging. slshare-service is coded to respond to an X-debug-tag
- // header by engaging debug logging for that request only. This way a
- // developer need not muck with the slshare-service image to engage debug
- // logging. Moreover, the value of X-debug-tag is embedded in each such
- // log line so the developer can quickly find the log lines pertinent to
- // THIS session.
- std::string logtag(gSavedSettings.getString("DebugSlshareLogTag"));
- if (! logtag.empty())
- {
- httpHeaders->append("X-debug-tag", logtag);
- }
- return httpHeaders;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-class LLFacebookConnectHandler : public LLCommandHandler
-{
-public:
- LLFacebookConnectHandler() : LLCommandHandler("fbc", UNTRUSTED_THROTTLE) { }
-
- bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
- {
- if (tokens.size() >= 1)
- {
- if (tokens[0].asString() == "connect")
- {
- if (tokens.size() >= 2 && tokens[1].asString() == "flickr")
- {
- // this command probably came from the flickr_web browser, so close it
- LLFloaterReg::hideInstance("flickr_web");
-
- // connect to flickr
- if (query_map.has("oauth_token"))
- {
- LLFlickrConnect::instance().connectToFlickr(query_map["oauth_token"], query_map.get("oauth_verifier"));
- }
- return true;
- }
- else if (tokens.size() >= 2 && tokens[1].asString() == "twitter")
- {
- // this command probably came from the twitter_web browser, so close it
- LLFloaterReg::hideInstance("twitter_web");
-
- // connect to twitter
- if (query_map.has("oauth_token"))
- {
- LLTwitterConnect::instance().connectToTwitter(query_map["oauth_token"], query_map.get("oauth_verifier"));
- }
- return true;
- }
- else //if (tokens.size() >= 2 && tokens[1].asString() == "facebook")
- {
- // this command probably came from the fbc_web browser, so close it
- LLFloaterReg::hideInstance("fbc_web");
-
- // connect to facebook
- if (query_map.has("code"))
- {
- LLFacebookConnect::instance().connectToFacebook(query_map["code"], query_map.get("state"));
- }
- return true;
- }
- }
- }
- return false;
- }
-};
-LLFacebookConnectHandler gFacebookConnectHandler;
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFacebookConnect::facebookConnectCoro(std::string authCode, std::string authState)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- LLSD putData;
- if (!authCode.empty())
- {
- putData["code"] = authCode;
- }
- if (!authState.empty())
- {
- putData["state"] = authState;
- }
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->putAndSuspend(httpRequest, getFacebookConnectURL("/connection"), putData, httpOpts, get_headers());
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- if (!status)
- {
- if (status == LLCore::HttpStatus(HTTP_FOUND))
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openFacebookWeb(location);
- }
- }
- }
- else
- {
- LL_INFOS("FacebookConnect") << "Connect successful. " << LL_ENDL;
- setConnectionState(LLFacebookConnect::FB_CONNECTED);
- }
-
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-bool LLFacebookConnect::testShareStatus(LLSD &result)
-{
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (status)
- return true;
-
- if (status == LLCore::HttpStatus(HTTP_FOUND))
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openFacebookWeb(location);
- }
- }
- if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
- {
- LL_DEBUGS("FacebookConnect") << "Not connected. " << LL_ENDL;
- connectToFacebook();
- }
- else
- {
- LL_WARNS("FacebookConnect") << "HTTP Status error " << status.toString() << LL_ENDL;
- setConnectionState(LLFacebookConnect::FB_POST_FAILED);
- log_facebook_connect_error("Share", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- return false;
-}
-
-void LLFacebookConnect::facebookShareCoro(std::string route, LLSD share)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->postAndSuspend(httpRequest, getFacebookConnectURL(route, true), share, httpOpts, get_headers());
-
- if (testShareStatus(result))
- {
- toast_user_for_facebook_success();
- LL_DEBUGS("FacebookConnect") << "Post successful. " << LL_ENDL;
- setConnectionState(LLFacebookConnect::FB_POSTED);
- }
-}
-
-void LLFacebookConnect::facebookShareImageCoro(std::string route, LLPointer<LLImageFormatted> image, std::string caption)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpHeaders::ptr_t httpHeaders(get_headers());
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- std::string imageFormat;
- if (dynamic_cast<LLImagePNG*>(image.get()))
- {
- imageFormat = "png";
- }
- else if (dynamic_cast<LLImageJPEG*>(image.get()))
- {
- imageFormat = "jpg";
- }
- else
- {
- LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
- return;
- }
-
- // All this code is mostly copied from LLWebProfile::post()
- static const std::string boundary = "----------------------------0123abcdefab";
-
- std::string contentType = "multipart/form-data; boundary=" + boundary;
- httpHeaders->append("Content-Type", contentType.c_str());
-
- LLCore::BufferArray::ptr_t raw = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); //
- LLCore::BufferArrayStream body(raw.get());
-
- // *NOTE: The order seems to matter.
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"caption\"\r\n\r\n"
- << caption << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
- << "Content-Type: image/" << imageFormat << "\r\n\r\n";
-
- // Insert the image data.
- // *FIX: Treating this as a string will probably screw it up ...
- U8* image_data = image->getData();
- for (S32 i = 0; i < image->getDataSize(); ++i)
- {
- body << image_data[i];
- }
-
- body << "\r\n--" << boundary << "--\r\n";
-
- setConnectionState(LLFacebookConnect::FB_POSTING);
-
- LLSD result = httpAdapter->postAndSuspend(httpRequest, getFacebookConnectURL(route, true), raw, httpOpts, httpHeaders);
-
- if (testShareStatus(result))
- {
- toast_user_for_facebook_success();
- LL_DEBUGS("FacebookConnect") << "Post successful. " << LL_ENDL;
- setConnectionState(LLFacebookConnect::FB_POSTED);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFacebookConnect::facebookDisconnectCoro()
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->deleteAndSuspend(httpRequest, getFacebookConnectURL("/connection"), httpOpts, get_headers());
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- if (!status && (status != LLCore::HttpStatus(HTTP_FOUND)))
- {
- LL_WARNS("FacebookConnect") << "Failed to disconnect:" << status.toTerseString() << LL_ENDL;
- setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
- log_facebook_connect_error("Disconnect", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- else
- {
- LL_DEBUGS("FacebookConnect") << "Facebook Disconnect successful. " << LL_ENDL;
- clearInfo();
- clearContent();
- //Notify state change
- setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
- }
-
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFacebookConnect::facebookConnectedCheckCoro(bool autoConnect)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
-
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, getFacebookConnectURL("/connection", true), httpOpts, get_headers());
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- if ( status == LLCore::HttpStatus(HTTP_NOT_FOUND) )
- {
- LL_DEBUGS("FacebookConnect") << "Not connected. " << LL_ENDL;
- if (autoConnect)
- {
- connectToFacebook();
- }
- else
- {
- setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
- }
- }
- else
- {
- LL_WARNS("FacebookConnect") << "Failed to test connection:" << status.toTerseString() << LL_ENDL;
-
- setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
- log_facebook_connect_error("Connected", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- }
- else
- {
- LL_DEBUGS("FacebookConnect") << "Connect successful. " << LL_ENDL;
- setConnectionState(LLFacebookConnect::FB_CONNECTED);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFacebookConnect::facebookConnectInfoCoro()
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, getFacebookConnectURL("/info", true), httpOpts, get_headers());
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (status == LLCore::HttpStatus(HTTP_FOUND))
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openFacebookWeb(location);
- }
- }
- else if (!status)
- {
- LL_WARNS("FacebookConnect") << "Facebook Info failed: " << status.toString() << LL_ENDL;
- log_facebook_connect_error("Info", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- else
- {
- LL_INFOS("FacebookConnect") << "Facebook: Info received" << LL_ENDL;
- result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
- storeInfo(result);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFacebookConnect::facebookConnectFriendsCoro()
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, getFacebookConnectURL("/friends", true), httpOpts, get_headers());
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (status == LLCore::HttpStatus(HTTP_FOUND))
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openFacebookWeb(location);
- }
- }
- else if (!status)
- {
- LL_WARNS("FacebookConnect") << "Facebook Friends failed: " << status.toString() << LL_ENDL;
- log_facebook_connect_error("Info", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- else
- {
- LL_INFOS("FacebookConnect") << "Facebook: Friends received" << LL_ENDL;
- result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
- LLSD content = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT];
- storeContent(content);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-LLFacebookConnect::LLFacebookConnect()
-: mConnectionState(FB_NOT_CONNECTED),
- mConnected(false),
- mInfo(),
- mContent(),
- mRefreshInfo(false),
- mRefreshContent(false),
- mReadFromMaster(false)
-{
-}
-
-void LLFacebookConnect::openFacebookWeb(std::string url)
-{
- LLFloaterWebContent::Params p;
- p.url(url);
- p.show_chrome(true);
- p.allow_back_forward_navigation(false);
- p.clean_browser(true);
- LLFloater *floater = LLFloaterReg::showInstance("fbc_web", p);
- //the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems).
- //So when showing the internal web browser, set focus to it's containing floater "fbc_web". When a mouse event
- //occurs on the "webbrowser" panel part of the floater, a mouse cursor will properly show and the "webbrowser" will gain focus.
- //fbc_web floater contains the "webbrowser" panel. JIRA: ACME-744
- gFocusMgr.setKeyboardFocus( floater );
-
- //LLUrlAction::openURLExternal(url);
-}
-
-std::string LLFacebookConnect::getFacebookConnectURL(const std::string& route, bool include_read_from_master)
-{
- std::string url("");
- LLViewerRegion *regionp = gAgent.getRegion();
- if (regionp)
- {
- //url = "http://pdp15.lindenlab.com/fbc/agent/" + gAgentID.asString(); // TEMPORARY FOR TESTING - CHO
- url = regionp->getCapability("FacebookConnect");
- url += route;
-
- if (include_read_from_master && mReadFromMaster)
- {
- url += "?read_from_master=true";
- }
- }
- return url;
-}
-
-void LLFacebookConnect::connectToFacebook(const std::string& auth_code, const std::string& auth_state)
-{
- setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
-
- LLCoros::instance().launch("LLFacebookConnect::facebookConnectCoro",
- boost::bind(&LLFacebookConnect::facebookConnectCoro, this, auth_code, auth_state));
-}
-
-void LLFacebookConnect::disconnectFromFacebook()
-{
- LLCoros::instance().launch("LLFacebookConnect::facebookDisconnectCoro",
- boost::bind(&LLFacebookConnect::facebookDisconnectCoro, this));
-}
-
-void LLFacebookConnect::checkConnectionToFacebook(bool auto_connect)
-{
- setConnectionState(LLFacebookConnect::FB_DISCONNECTING);
-
- LLCoros::instance().launch("LLFacebookConnect::facebookConnectedCheckCoro",
- boost::bind(&LLFacebookConnect::facebookConnectedCheckCoro, this, auto_connect));
-}
-
-void LLFacebookConnect::loadFacebookInfo()
-{
- if(mRefreshInfo)
- {
- LLCoros::instance().launch("LLFacebookConnect::facebookConnectInfoCoro",
- boost::bind(&LLFacebookConnect::facebookConnectInfoCoro, this));
- }
-}
-
-void LLFacebookConnect::loadFacebookFriends()
-{
- if(mRefreshContent)
- {
- LLCoros::instance().launch("LLFacebookConnect::facebookConnectFriendsCoro",
- boost::bind(&LLFacebookConnect::facebookConnectFriendsCoro, this));
- }
-}
-
-void LLFacebookConnect::postCheckin(const std::string& location, const std::string& name,
- const std::string& description, const std::string& image, const std::string& message)
-{
- setConnectionState(LLFacebookConnect::FB_POSTING);
-
- LLSD body;
- if (!location.empty())
- {
- body["location"] = location;
- }
- if (!name.empty())
- {
- body["name"] = name;
- }
- if (!description.empty())
- {
- body["description"] = description;
- }
- if (!image.empty())
- {
- body["image"] = image;
- }
- if (!message.empty())
- {
- body["message"] = message;
- }
-
- LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro",
- boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/checkin", body));
-}
-
-void LLFacebookConnect::sharePhoto(const std::string& image_url, const std::string& caption)
-{
- setConnectionState(LLFacebookConnect::FB_POSTING);
-
- LLSD body;
- body["image"] = image_url;
- body["caption"] = caption;
-
- LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro",
- boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/photo", body));
-}
-
-void LLFacebookConnect::sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption)
-{
- setConnectionState(LLFacebookConnect::FB_POSTING);
-
- LLCoros::instance().launch("LLFacebookConnect::facebookShareImageCoro",
- boost::bind(&LLFacebookConnect::facebookShareImageCoro, this, "/share/photo", image, caption));
-}
-
-void LLFacebookConnect::updateStatus(const std::string& message)
-{
- LLSD body;
- body["message"] = message;
-
- setConnectionState(LLFacebookConnect::FB_POSTING);
-
- LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro",
- boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/wall", body));
-}
-
-void LLFacebookConnect::storeInfo(const LLSD& info)
-{
- mInfo = info;
- mRefreshInfo = false;
-
- sInfoWatcher->post(info);
-}
-
-const LLSD& LLFacebookConnect::getInfo() const
-{
- return mInfo;
-}
-
-void LLFacebookConnect::clearInfo()
-{
- mInfo = LLSD();
-}
-
-void LLFacebookConnect::storeContent(const LLSD& content)
-{
- mContent = content;
- mRefreshContent = false;
-
- sContentWatcher->post(content);
-}
-
-const LLSD& LLFacebookConnect::getContent() const
-{
- return mContent;
-}
-
-void LLFacebookConnect::clearContent()
-{
- mContent = LLSD();
-}
-
-void LLFacebookConnect::setDataDirty()
-{
- mRefreshInfo = true;
- mRefreshContent = true;
-}
-
-void LLFacebookConnect::setConnectionState(LLFacebookConnect::EConnectionState connection_state)
-{
- if(connection_state == FB_CONNECTED)
- {
- mReadFromMaster = true;
- setConnected(true);
- setDataDirty();
- }
- else if(connection_state == FB_NOT_CONNECTED)
- {
- setConnected(false);
- }
- else if(connection_state == FB_POSTED)
- {
- mReadFromMaster = false;
- }
-
- if (mConnectionState != connection_state)
- {
- // set the connection state before notifying watchers
- mConnectionState = connection_state;
-
- LLSD state_info;
- state_info["enum"] = connection_state;
- sStateWatcher->post(state_info);
- }
-}
-
-void LLFacebookConnect::setConnected(bool connected)
-{
- mConnected = connected;
-}
diff --git a/indra/newview/llfacebookconnect.h b/indra/newview/llfacebookconnect.h
deleted file mode 100644
index 7fd4070f54..0000000000
--- a/indra/newview/llfacebookconnect.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/**
- * @file llfacebookconnect.h
- * @author Merov, Cho, Gil
- * @brief Connection to Facebook Service
- *
- * $LicenseInfo:firstyear=2013&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2013, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLFACEBOOKCONNECT_H
-#define LL_LLFACEBOOKCONNECT_H
-
-#include "llsingleton.h"
-#include "llimage.h"
-#include "llcoros.h"
-#include "lleventcoro.h"
-
-class LLEventPump;
-
-/**
- * @class LLFacebookConnect
- *
- * Manages authentication to, and interaction with, a web service allowing the
- * the viewer to get Facebook OpenGraph data.
- */
-class LLFacebookConnect : public LLSingleton<LLFacebookConnect>
-{
- LLSINGLETON(LLFacebookConnect);
- ~LLFacebookConnect() {};
- LOG_CLASS(LLFacebookConnect);
-public:
- enum EConnectionState
- {
- FB_NOT_CONNECTED = 0,
- FB_CONNECTION_IN_PROGRESS = 1,
- FB_CONNECTED = 2,
- FB_CONNECTION_FAILED = 3,
- FB_POSTING = 4,
- FB_POSTED = 5,
- FB_POST_FAILED = 6,
- FB_DISCONNECTING = 7,
- FB_DISCONNECT_FAILED = 8
- };
-
- void connectToFacebook(const std::string& auth_code = "", const std::string& auth_state = ""); // Initiate the complete FB connection. Please use checkConnectionToFacebook() in normal use.
- void disconnectFromFacebook(); // Disconnect from the FBC service.
- void checkConnectionToFacebook(bool auto_connect = false); // Check if an access token is available on the FBC service. If not, call connectToFacebook().
-
- void loadFacebookInfo();
- void loadFacebookFriends();
- void postCheckin(const std::string& location, const std::string& name, const std::string& description, const std::string& picture, const std::string& message);
- void sharePhoto(const std::string& image_url, const std::string& caption);
- void sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption);
- void updateStatus(const std::string& message);
-
- void storeInfo(const LLSD& info);
- const LLSD& getInfo() const;
- void clearInfo();
- void storeContent(const LLSD& content);
- const LLSD& getContent() const;
- void clearContent();
- void setDataDirty();
-
- void setConnectionState(EConnectionState connection_state);
- void setConnected(bool connected);
- bool isConnected() { return mConnected; }
- bool isTransactionOngoing() { return ((mConnectionState == FB_CONNECTION_IN_PROGRESS) || (mConnectionState == FB_POSTING) || (mConnectionState == FB_DISCONNECTING)); }
- EConnectionState getConnectionState() { return mConnectionState; }
-
- void openFacebookWeb(std::string url);
-
-private:
-
- std::string getFacebookConnectURL(const std::string& route = "", bool include_read_from_master = false);
-
- EConnectionState mConnectionState;
- BOOL mConnected;
- LLSD mInfo;
- LLSD mContent;
- bool mRefreshInfo;
- bool mRefreshContent;
- bool mReadFromMaster;
-
- static boost::scoped_ptr<LLEventPump> sStateWatcher;
- static boost::scoped_ptr<LLEventPump> sInfoWatcher;
- static boost::scoped_ptr<LLEventPump> sContentWatcher;
-
- bool testShareStatus(LLSD &results);
- void facebookConnectCoro(std::string authCode, std::string authState);
- void facebookConnectedCheckCoro(bool autoConnect);
- void facebookDisconnectCoro();
- void facebookShareCoro(std::string route, LLSD share);
- void facebookShareImageCoro(std::string route, LLPointer<LLImageFormatted> image, std::string caption);
- void facebookConnectInfoCoro();
- void facebookConnectFriendsCoro();
-};
-
-#endif // LL_LLFACEBOOKCONNECT_H
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index f68e63cb96..d90f03b403 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -43,6 +43,7 @@
#include "llsdserialize.h"
#include "lltooltip.h"
#include "llbutton.h"
+#include "llscrollbar.h"
#include "llappviewer.h"
#include "llviewertexturelist.h"
@@ -128,7 +129,8 @@ void LLFastTimerView::setPauseState(bool pause_state)
BOOL LLFastTimerView::postBuild()
{
LLButton& pause_btn = getChildRef<LLButton>("pause_btn");
-
+ mScrollBar = getChild<LLScrollbar>("scroll_vert");
+
pause_btn.setCommitCallback(boost::bind(&LLFastTimerView::onPause, this));
return TRUE;
}
@@ -183,7 +185,7 @@ BOOL LLFastTimerView::handleDoubleClick(S32 x, S32 y, MASK mask)
BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
{
- if (x < mBarRect.mLeft)
+ if (x < mScrollBar->getRect().mLeft)
{
BlockTimerStatHandle* idp = getLegendID(y);
if (idp)
@@ -284,7 +286,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
}
}
}
- else if (x < mBarRect.mLeft)
+ else if (x < mScrollBar->getRect().mLeft)
{
BlockTimerStatHandle* timer_id = getLegendID(y);
if (timer_id)
@@ -335,7 +337,7 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)
else
{
// tooltips for timer legend
- if (x < mBarRect.mLeft)
+ if (x < mScrollBar->getRect().mLeft)
{
BlockTimerStatHandle* idp = getLegendID(y);
if (idp)
@@ -352,11 +354,19 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)
BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- setPauseState(true);
- mScrollIndex = llclamp( mScrollIndex + clicks,
- 0,
- llmin((S32)mRecording.getNumRecordedPeriods(), (S32)mRecording.getNumRecordedPeriods() - MAX_VISIBLE_HISTORY));
- return TRUE;
+ if (x < mBarRect.mLeft)
+ {
+ // Inside mScrollBar and list of timers
+ mScrollBar->handleScrollWheel(x,y,clicks);
+ }
+ else
+ {
+ setPauseState(true);
+ mScrollIndex = llclamp(mScrollIndex + clicks,
+ 0,
+ llmin((S32)mRecording.getNumRecordedPeriods(), (S32)mRecording.getNumRecordedPeriods() - MAX_VISIBLE_HISTORY));
+ }
+ return TRUE;
}
static BlockTimerStatHandle FTM_RENDER_TIMER("Timers");
@@ -1197,6 +1207,7 @@ void LLFastTimerView::drawLegend()
{
LLLocalClipRect clip(mLegendRect);
S32 cur_line = 0;
+ S32 scroll_offset = 0; // element's y offset from top of the inner scroll's rect
ft_display_idx.clear();
std::map<BlockTimerStatHandle*, S32> display_line;
for (block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME);
@@ -1204,10 +1215,24 @@ void LLFastTimerView::drawLegend()
++it)
{
BlockTimerStatHandle* idp = (*it);
+ // Needed to figure out offsets and parenting
display_line[idp] = cur_line;
- ft_display_idx.push_back(idp);
cur_line++;
+ if (scroll_offset < mScrollBar->getDocPos())
+ {
+ // only offset for visible items
+ scroll_offset += TEXT_HEIGHT + 2;
+ if (idp->getTreeNode().mCollapsed)
+ {
+ it.skipDescendants();
+ }
+ continue;
+ }
+
+ // used for mouse clicks
+ ft_display_idx.push_back(idp);
+ // Actual draw, first bar (square), then text
x = MARGIN;
LLRect bar_rect(x, y, x + TEXT_HEIGHT, y - TEXT_HEIGHT);
@@ -1281,11 +1306,14 @@ void LLFastTimerView::drawLegend()
y -= (TEXT_HEIGHT + 2);
+ scroll_offset += TEXT_HEIGHT + 2;
if (idp->getTreeNode().mCollapsed)
{
it.skipDescendants();
}
}
+ // Recalculate scroll size
+ mScrollBar->setDocSize(scroll_offset - mLegendRect.getHeight());
}
}
diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h
index 3e30bd86ba..ff65f8da07 100644
--- a/indra/newview/llfasttimerview.h
+++ b/indra/newview/llfasttimerview.h
@@ -33,6 +33,8 @@
#include "lltracerecording.h"
#include <deque>
+class LLScrollbar;
+
class LLFastTimerView : public LLFloater
{
public:
@@ -142,6 +144,8 @@ private:
mLegendRect;
LLFrameTimer mHighlightTimer;
LLTrace::PeriodicRecording mRecording;
+
+ LLScrollbar* mScrollBar;
};
#endif
diff --git a/indra/newview/llfloaterfacebook.cpp b/indra/newview/llfloaterfacebook.cpp
deleted file mode 100644
index e84cbc289f..0000000000
--- a/indra/newview/llfloaterfacebook.cpp
+++ /dev/null
@@ -1,1132 +0,0 @@
-/**
-* @file llfloaterfacebook.cpp
-* @brief Implementation of llfloaterfacebook
-* @author Gilbert@lindenlab.com
-*
-* $LicenseInfo:firstyear=2013&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2013, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
-* $/LicenseInfo$
-*/
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterfacebook.h"
-
-#include "llagent.h"
-#include "llagentui.h"
-#include "llcheckboxctrl.h"
-#include "llcombobox.h"
-#include "llfacebookconnect.h"
-#include "llfloaterbigpreview.h"
-#include "llfloaterreg.h"
-#include "lliconctrl.h"
-#include "llimagefiltersmanager.h"
-#include "llresmgr.h" // LLLocale
-#include "llsdserialize.h"
-#include "llloadingindicator.h"
-#include "llslurl.h"
-#include "lltrans.h"
-#include "llsnapshotlivepreview.h"
-#include "llviewerregion.h"
-#include "llviewercontrol.h"
-#include "llviewermedia.h"
-#include "lltabcontainer.h"
-#include "llavatarlist.h"
-#include "llpanelpeoplemenus.h"
-#include "llaccordionctrl.h"
-#include "llaccordionctrltab.h"
-
-static LLPanelInjector<LLFacebookStatusPanel> t_panel_status("llfacebookstatuspanel");
-static LLPanelInjector<LLFacebookPhotoPanel> t_panel_photo("llfacebookphotopanel");
-static LLPanelInjector<LLFacebookCheckinPanel> t_panel_checkin("llfacebookcheckinpanel");
-static LLPanelInjector<LLFacebookFriendsPanel> t_panel_friends("llfacebookfriendspanel");
-
-const std::string DEFAULT_CHECKIN_LOCATION_URL = "http://maps.secondlife.com/";
-const std::string DEFAULT_CHECKIN_ICON_URL = "http://map.secondlife.com.s3.amazonaws.com/map_placeholder.png";
-const std::string DEFAULT_CHECKIN_QUERY_PARAMETERS = "?sourceid=slshare_checkin&utm_source=facebook&utm_medium=checkin&utm_campaign=slshare";
-const std::string DEFAULT_PHOTO_QUERY_PARAMETERS = "?sourceid=slshare_photo&utm_source=facebook&utm_medium=photo&utm_campaign=slshare";
-
-const S32 MAX_QUALITY = 100; // Max quality value for jpeg images
-const S32 MIN_QUALITY = 0; // Min quality value for jpeg images
-const S32 TARGET_DATA_SIZE = 950000; // Size of the image (compressed) we're trying to send to Facebook
-
-std::string get_map_url()
-{
- LLVector3d center_agent;
- LLViewerRegion *regionp = gAgent.getRegion();
- if (regionp)
- {
- center_agent = regionp->getCenterGlobal();
- }
- int x_pos = center_agent[0] / 256.0;
- int y_pos = center_agent[1] / 256.0;
- std::string map_url = gSavedSettings.getString("CurrentMapServerURL") + llformat("map-1-%d-%d-objects.jpg", x_pos, y_pos);
- return map_url;
-}
-
-// Compute target jpeg quality : see https://wiki.lindenlab.com/wiki/Facebook_Image_Quality for details
-S32 compute_jpeg_quality(S32 width, S32 height)
-{
- F32 target_compression_ratio = (F32)(width * height * 3) / (F32)(TARGET_DATA_SIZE);
- S32 quality = (S32)(110.0f - (2.0f * target_compression_ratio));
- return llclamp(quality, MIN_QUALITY, MAX_QUALITY);
-}
-
-///////////////////////////
-//LLFacebookStatusPanel//////
-///////////////////////////
-
-LLFacebookStatusPanel::LLFacebookStatusPanel() :
- mMessageTextEditor(NULL),
- mPostButton(NULL),
- mCancelButton(NULL),
- mAccountCaptionLabel(NULL),
- mAccountNameLabel(NULL),
- mPanelButtons(NULL),
- mConnectButton(NULL),
- mDisconnectButton(NULL)
-{
- mCommitCallbackRegistrar.add("SocialSharing.Connect", boost::bind(&LLFacebookStatusPanel::onConnect, this));
- mCommitCallbackRegistrar.add("SocialSharing.Disconnect", boost::bind(&LLFacebookStatusPanel::onDisconnect, this));
-
- setVisibleCallback(boost::bind(&LLFacebookStatusPanel::onVisibilityChange, this, _2));
-
- mCommitCallbackRegistrar.add("SocialSharing.SendStatus", boost::bind(&LLFacebookStatusPanel::onSend, this));
-}
-
-BOOL LLFacebookStatusPanel::postBuild()
-{
- mAccountCaptionLabel = getChild<LLTextBox>("account_caption_label");
- mAccountNameLabel = getChild<LLTextBox>("account_name_label");
- mPanelButtons = getChild<LLUICtrl>("panel_buttons");
- mConnectButton = getChild<LLUICtrl>("connect_btn");
- mDisconnectButton = getChild<LLUICtrl>("disconnect_btn");
-
- mMessageTextEditor = getChild<LLUICtrl>("status_message");
- mPostButton = getChild<LLUICtrl>("post_status_btn");
- mCancelButton = getChild<LLUICtrl>("cancel_status_btn");
-
- return LLPanel::postBuild();
-}
-
-void LLFacebookStatusPanel::draw()
-{
- LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState();
-
- //Disable the 'disconnect' button and the 'use another account' button when disconnecting in progress
- bool disconnecting = connection_state == LLFacebookConnect::FB_DISCONNECTING;
- mDisconnectButton->setEnabled(!disconnecting);
-
- //Disable the 'connect' button when a connection is in progress
- bool connecting = connection_state == LLFacebookConnect::FB_CONNECTION_IN_PROGRESS;
- mConnectButton->setEnabled(!connecting);
-
- if (mMessageTextEditor && mPostButton && mCancelButton)
- {
- bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing());
- std::string message = mMessageTextEditor->getValue().asString();
- mMessageTextEditor->setEnabled(no_ongoing_connection);
- mCancelButton->setEnabled(no_ongoing_connection);
- mPostButton->setEnabled(no_ongoing_connection && !message.empty());
- }
-
- LLPanel::draw();
-}
-
-void LLFacebookStatusPanel::onSend()
-{
- LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookStatusPanel"); // just in case it is already listening
- LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookStatusPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectStateChange, this, _1));
-
- // Connect to Facebook if necessary and then post
- if (LLFacebookConnect::instance().isConnected())
- {
- sendStatus();
- }
- else
- {
- LLFacebookConnect::instance().checkConnectionToFacebook(true);
- }
-}
-
-bool LLFacebookStatusPanel::onFacebookConnectStateChange(const LLSD& data)
-{
- switch (data.get("enum").asInteger())
- {
- case LLFacebookConnect::FB_CONNECTED:
- sendStatus();
- break;
-
- case LLFacebookConnect::FB_POSTED:
- LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookStatusPanel");
- clearAndClose();
- break;
- }
-
- return false;
-}
-
-bool LLFacebookStatusPanel::onFacebookConnectAccountStateChange(const LLSD& data)
-{
- if (LLFacebookConnect::instance().isConnected())
- {
- //In process of disconnecting so leave the layout as is
- if (data.get("enum").asInteger() != LLFacebookConnect::FB_DISCONNECTING)
- {
- showConnectedLayout();
- }
- }
- else
- {
- showDisconnectedLayout();
- }
-
- return false;
-}
-
-void LLFacebookStatusPanel::sendStatus()
-{
- std::string message = mMessageTextEditor->getValue().asString();
- if (!message.empty())
- {
- LLFacebookConnect::instance().updateStatus(message);
- }
-}
-
-void LLFacebookStatusPanel::onVisibilityChange(BOOL visible)
-{
- if (visible)
- {
- LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookAccountPanel");
- LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookAccountPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectAccountStateChange, this, _1));
-
- LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLFacebookAccountPanel");
- LLEventPumps::instance().obtain("FacebookConnectInfo").listen("LLFacebookAccountPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectInfoChange, this));
-
- //Connected
- if (LLFacebookConnect::instance().isConnected())
- {
- showConnectedLayout();
- }
- //Check if connected (show disconnected layout in meantime)
- else
- {
- showDisconnectedLayout();
- }
- if ((LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_NOT_CONNECTED) ||
- (LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_CONNECTION_FAILED))
- {
- LLFacebookConnect::instance().checkConnectionToFacebook();
- }
- }
- else
- {
- LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookAccountPanel");
- LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLFacebookAccountPanel");
- }
-}
-
-bool LLFacebookStatusPanel::onFacebookConnectInfoChange()
-{
- LLSD info = LLFacebookConnect::instance().getInfo();
- std::string clickable_name;
-
- //Strings of format [http://www.somewebsite.com Click Me] become clickable text
- if (info.has("link") && info.has("name"))
- {
- clickable_name = "[" + info["link"].asString() + " " + info["name"].asString() + "]";
- }
-
- mAccountNameLabel->setText(clickable_name);
-
- return false;
-}
-
-void LLFacebookStatusPanel::showConnectButton()
-{
- if (!mConnectButton->getVisible())
- {
- mConnectButton->setVisible(TRUE);
- mDisconnectButton->setVisible(FALSE);
- }
-}
-
-void LLFacebookStatusPanel::hideConnectButton()
-{
- if (mConnectButton->getVisible())
- {
- mConnectButton->setVisible(FALSE);
- mDisconnectButton->setVisible(TRUE);
- }
-}
-
-void LLFacebookStatusPanel::showDisconnectedLayout()
-{
- mAccountCaptionLabel->setText(getString("facebook_disconnected"));
- mAccountNameLabel->setText(std::string(""));
- showConnectButton();
-}
-
-void LLFacebookStatusPanel::showConnectedLayout()
-{
- LLFacebookConnect::instance().loadFacebookInfo();
-
- mAccountCaptionLabel->setText(getString("facebook_connected"));
- hideConnectButton();
-}
-
-void LLFacebookStatusPanel::onConnect()
-{
- LLFacebookConnect::instance().checkConnectionToFacebook(true);
-}
-
-void LLFacebookStatusPanel::onDisconnect()
-{
- LLFacebookConnect::instance().disconnectFromFacebook();
-}
-
-void LLFacebookStatusPanel::clearAndClose()
-{
- mMessageTextEditor->setValue("");
-
- LLFloater* floater = getParentByType<LLFloater>();
- if (floater)
- {
- floater->closeFloater();
- }
-}
-
-///////////////////////////
-//LLFacebookPhotoPanel///////
-///////////////////////////
-
-LLFacebookPhotoPanel::LLFacebookPhotoPanel() :
- mResolutionComboBox(NULL),
- mRefreshBtn(NULL),
- mBtnPreview(NULL),
- mWorkingLabel(NULL),
- mThumbnailPlaceholder(NULL),
- mCaptionTextBox(NULL),
- mPostButton(NULL),
- mBigPreviewFloater(NULL),
- mQuality(MAX_QUALITY)
-{
- mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLFacebookPhotoPanel::onSend, this));
- mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", boost::bind(&LLFacebookPhotoPanel::onClickNewSnapshot, this));
- mCommitCallbackRegistrar.add("SocialSharing.BigPreview", boost::bind(&LLFacebookPhotoPanel::onClickBigPreview, this));
-}
-
-LLFacebookPhotoPanel::~LLFacebookPhotoPanel()
-{
- if (mPreviewHandle.get())
- {
- mPreviewHandle.get()->die();
- }
-}
-
-BOOL LLFacebookPhotoPanel::postBuild()
-{
- setVisibleCallback(boost::bind(&LLFacebookPhotoPanel::onVisibilityChange, this, _2));
-
- mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox");
- mResolutionComboBox->setValue("[i1200,i630]"); // hardcoded defaults ftw!
- mResolutionComboBox->setCommitCallback(boost::bind(&LLFacebookPhotoPanel::updateResolution, this, TRUE));
- mFilterComboBox = getChild<LLUICtrl>("filters_combobox");
- mFilterComboBox->setCommitCallback(boost::bind(&LLFacebookPhotoPanel::updateResolution, this, TRUE));
- mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
- mBtnPreview = getChild<LLButton>("big_preview_btn");
- mWorkingLabel = getChild<LLUICtrl>("working_lbl");
- mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
- mCaptionTextBox = getChild<LLUICtrl>("photo_caption");
- mPostButton = getChild<LLUICtrl>("post_photo_btn");
- mCancelButton = getChild<LLUICtrl>("cancel_photo_btn");
- mBigPreviewFloater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
-
- // Update filter list
- std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
- LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
- for (U32 i = 0; i < filter_list.size(); i++)
- {
- filterbox->add(filter_list[i]);
- }
-
- return LLPanel::postBuild();
-}
-
-// virtual
-S32 LLFacebookPhotoPanel::notify(const LLSD& info)
-{
- if (info.has("snapshot-updating"))
- {
- // Disable the Post button and whatever else while the snapshot is not updated
- // updateControls();
- return 1;
- }
-
- if (info.has("snapshot-updated"))
- {
- // Enable the send/post/save buttons.
- updateControls();
-
- // The refresh button is initially hidden. We show it after the first update,
- // i.e. after snapshot is taken
- LLUICtrl * refresh_button = getRefreshBtn();
- if (!refresh_button->getVisible())
- {
- refresh_button->setVisible(true);
- }
- return 1;
- }
-
- return 0;
-}
-
-void LLFacebookPhotoPanel::draw()
-{
- LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
-
- // Enable interaction only if no transaction with the service is on-going (prevent duplicated posts)
- bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing());
- mCancelButton->setEnabled(no_ongoing_connection);
- mCaptionTextBox->setEnabled(no_ongoing_connection);
- mResolutionComboBox->setEnabled(no_ongoing_connection);
- mFilterComboBox->setEnabled(no_ongoing_connection);
- mRefreshBtn->setEnabled(no_ongoing_connection);
- mBtnPreview->setEnabled(no_ongoing_connection);
-
- // Reassign the preview floater if we have the focus and the preview exists
- if (hasFocus() && isPreviewVisible())
- {
- attachPreview();
- }
-
- // Toggle the button state as appropriate
- bool preview_active = (isPreviewVisible() && mBigPreviewFloater->isFloaterOwner(getParentByType<LLFloater>()));
- mBtnPreview->setToggleState(preview_active);
-
- // Display the thumbnail if one is available
- if (previewp && previewp->getThumbnailImage())
- {
- const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect();
- const S32 thumbnail_w = previewp->getThumbnailWidth();
- const S32 thumbnail_h = previewp->getThumbnailHeight();
-
- // calc preview offset within the preview rect
- const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2;
- const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2;
- S32 offset_x = thumbnail_rect.mLeft + local_offset_x;
- S32 offset_y = thumbnail_rect.mBottom + local_offset_y;
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- // Apply floater transparency to the texture unless the floater is focused.
- F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
- LLColor4 color = LLColor4::white;
- gl_draw_scaled_image(offset_x, offset_y,
- thumbnail_w, thumbnail_h,
- previewp->getThumbnailImage(), color % alpha);
- }
-
- // Update the visibility of the working (computing preview) label
- mWorkingLabel->setVisible(!(previewp && previewp->getSnapshotUpToDate()));
-
- // Enable Post if we have a preview to send and no on going connection being processed
- mPostButton->setEnabled(no_ongoing_connection && (previewp && previewp->getSnapshotUpToDate()));
-
- // Draw the rest of the panel on top of it
- LLPanel::draw();
-}
-
-LLSnapshotLivePreview* LLFacebookPhotoPanel::getPreviewView()
-{
- LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
- return previewp;
-}
-
-void LLFacebookPhotoPanel::onVisibilityChange(BOOL visible)
-{
- if (visible)
- {
- if (mPreviewHandle.get())
- {
- LLSnapshotLivePreview* preview = getPreviewView();
- if (preview)
- {
- LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
- preview->updateSnapshot(TRUE);
- }
- }
- else
- {
- LLRect full_screen_rect = getRootView()->getRect();
- LLSnapshotLivePreview::Params p;
- p.rect(full_screen_rect);
- LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
- mPreviewHandle = previewp->getHandle();
- mQuality = MAX_QUALITY;
-
- previewp->setContainer(this);
- previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB);
- previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_JPEG);
- previewp->setSnapshotQuality(mQuality, false);
- previewp->setThumbnailSubsampled(TRUE); // We want the preview to reflect the *saved* image
- previewp->setAllowRenderUI(FALSE); // We do not want the rendered UI in our snapshots
- previewp->setAllowFullScreenPreview(FALSE); // No full screen preview in SL Share mode
- previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect());
-
- updateControls();
- }
- }
-}
-
-void LLFacebookPhotoPanel::onClickNewSnapshot()
-{
- LLSnapshotLivePreview* previewp = getPreviewView();
- if (previewp)
- {
- previewp->updateSnapshot(TRUE);
- }
-}
-
-void LLFacebookPhotoPanel::onClickBigPreview()
-{
- // Toggle the preview
- if (isPreviewVisible())
- {
- LLFloaterReg::hideInstance("big_preview");
- }
- else
- {
- attachPreview();
- LLFloaterReg::showInstance("big_preview");
- }
-}
-
-bool LLFacebookPhotoPanel::isPreviewVisible()
-{
- return (mBigPreviewFloater && mBigPreviewFloater->getVisible());
-}
-
-void LLFacebookPhotoPanel::attachPreview()
-{
- if (mBigPreviewFloater)
- {
- LLSnapshotLivePreview* previewp = getPreviewView();
- mBigPreviewFloater->setPreview(previewp);
- mBigPreviewFloater->setFloaterOwner(getParentByType<LLFloater>());
- }
-}
-
-void LLFacebookPhotoPanel::onSend()
-{
- LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookPhotoPanel"); // just in case it is already listening
- LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookPhotoPanel", boost::bind(&LLFacebookPhotoPanel::onFacebookConnectStateChange, this, _1));
-
- // Connect to Facebook if necessary and then post
- if (LLFacebookConnect::instance().isConnected())
- {
- sendPhoto();
- }
- else
- {
- LLFacebookConnect::instance().checkConnectionToFacebook(true);
- }
-}
-
-bool LLFacebookPhotoPanel::onFacebookConnectStateChange(const LLSD& data)
-{
- switch (data.get("enum").asInteger())
- {
- case LLFacebookConnect::FB_CONNECTED:
- sendPhoto();
- break;
-
- case LLFacebookConnect::FB_POSTED:
- LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookPhotoPanel");
- clearAndClose();
- break;
- }
-
- return false;
-}
-
-void LLFacebookPhotoPanel::sendPhoto()
-{
- // Get the caption
- std::string caption = mCaptionTextBox->getValue().asString();
-
- // Get the image
- LLSnapshotLivePreview* previewp = getPreviewView();
-
- // Post to Facebook
- LLFacebookConnect::instance().sharePhoto(previewp->getFormattedImage(), caption);
-
- updateControls();
-}
-
-void LLFacebookPhotoPanel::clearAndClose()
-{
- mCaptionTextBox->setValue("");
-
- LLFloater* floater = getParentByType<LLFloater>();
- if (floater)
- {
- floater->closeFloater();
- if (mBigPreviewFloater)
- {
- mBigPreviewFloater->closeOnFloaterOwnerClosing(floater);
- }
- }
-}
-
-void LLFacebookPhotoPanel::updateControls()
-{
- LLSnapshotLivePreview* previewp = getPreviewView();
- BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
-
- // *TODO: Separate maximum size for Web images from postcards
- LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL;
-
- updateResolution(FALSE);
-}
-
-void LLFacebookPhotoPanel::updateResolution(BOOL do_update)
-{
- LLComboBox* combobox = static_cast<LLComboBox *>(mResolutionComboBox);
- LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
-
- std::string sdstring = combobox->getSelectedValue();
- LLSD sdres;
- std::stringstream sstream(sdstring);
- LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
-
- S32 width = sdres[0];
- S32 height = sdres[1];
-
- // Note : index 0 of the filter drop down is assumed to be "No filter" in whichever locale
- std::string filter_name = (filterbox->getCurrentIndex() ? filterbox->getSimple() : "");
-
- LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
- if (previewp && combobox->getCurrentIndex() >= 0)
- {
- S32 original_width = 0, original_height = 0;
- previewp->getSize(original_width, original_height);
-
- if (width == 0 || height == 0)
- {
- // take resolution from current window size
- LL_DEBUGS() << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << LL_ENDL;
- previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
- }
- else
- {
- // use the resolution from the selected pre-canned drop-down choice
- LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
- previewp->setSize(width, height);
- }
-
- checkAspectRatio(width);
-
- previewp->getSize(width, height);
-
- // Recompute quality setting
- mQuality = compute_jpeg_quality(width, height);
- previewp->setSnapshotQuality(mQuality, false);
-
- if (original_width != width || original_height != height)
- {
- previewp->setSize(width, height);
- if (do_update)
- {
- previewp->updateSnapshot(TRUE);
- updateControls();
- }
- }
- // Get the old filter, compare to the current one "filter_name" and set if changed
- std::string original_filter = previewp->getFilter();
- if (original_filter != filter_name)
- {
- previewp->setFilter(filter_name);
- if (do_update)
- {
- previewp->updateSnapshot(FALSE, TRUE);
- updateControls();
- }
- }
- }
-}
-
-void LLFacebookPhotoPanel::checkAspectRatio(S32 index)
-{
- LLSnapshotLivePreview *previewp = getPreviewView();
-
- BOOL keep_aspect = FALSE;
-
- if (0 == index) // current window size
- {
- keep_aspect = TRUE;
- }
- else // predefined resolution
- {
- keep_aspect = FALSE;
- }
-
- if (previewp)
- {
- previewp->mKeepAspectRatio = keep_aspect;
- }
-}
-
-LLUICtrl* LLFacebookPhotoPanel::getRefreshBtn()
-{
- return mRefreshBtn;
-}
-
-////////////////////////
-//LLFacebookCheckinPanel//
-////////////////////////
-
-LLFacebookCheckinPanel::LLFacebookCheckinPanel() :
- mMapUrl(""),
- mReloadingMapTexture(false)
-{
- mCommitCallbackRegistrar.add("SocialSharing.SendCheckin", boost::bind(&LLFacebookCheckinPanel::onSend, this));
-}
-
-BOOL LLFacebookCheckinPanel::postBuild()
-{
- // Keep pointers to widgets so we don't traverse the UI hierarchy too often
- mPostButton = getChild<LLUICtrl>("post_place_btn");
- mCancelButton = getChild<LLUICtrl>("cancel_place_btn");
- mMessageTextEditor = getChild<LLUICtrl>("place_caption");
- mMapLoadingIndicator = getChild<LLUICtrl>("map_loading_indicator");
- mMapPlaceholder = getChild<LLIconCtrl>("map_placeholder");
- mMapDefault = getChild<LLIconCtrl>("map_default");
- mMapCheckBox = getChild<LLCheckBoxCtrl>("add_place_view_cb");
-
- return LLPanel::postBuild();
-}
-
-void LLFacebookCheckinPanel::draw()
-{
- bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing());
- mPostButton->setEnabled(no_ongoing_connection);
- mCancelButton->setEnabled(no_ongoing_connection);
- mMessageTextEditor->setEnabled(no_ongoing_connection);
- mMapCheckBox->setEnabled(no_ongoing_connection);
-
- std::string map_url = get_map_url();
- // Did we change location?
- if (map_url != mMapUrl)
- {
- mMapUrl = map_url;
- // Load the map tile
- mMapTexture = LLViewerTextureManager::getFetchedTextureFromUrl(mMapUrl, FTT_MAP_TILE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- mMapTexture->setBoostLevel(LLGLTexture::BOOST_MAP);
- mReloadingMapTexture = true;
- // In the meantime, put the "loading" indicator on, hide the tile map and disable the checkbox
- mMapLoadingIndicator->setVisible(true);
- mMapPlaceholder->setVisible(false);
- }
- // Are we done loading the map tile?
- if (mReloadingMapTexture && mMapTexture->isFullyLoaded())
- {
- // Don't do it again next time around
- mReloadingMapTexture = false;
- // Convert the map texture to the appropriate image object
- LLPointer<LLUIImage> ui_image = new LLUIImage(mMapUrl, mMapTexture);
- // Load the map widget with the correct map tile image
- mMapPlaceholder->setImage(ui_image);
- // Now hide the loading indicator, bring the tile in view and reenable the checkbox with its previous value
- mMapLoadingIndicator->setVisible(false);
- mMapPlaceholder->setVisible(true);
- }
- // Show the default icon if that's the checkbox value (the real one...)
- // This will hide/show the loading indicator and/or tile underneath
- mMapDefault->setVisible(!(mMapCheckBox->get()));
-
- LLPanel::draw();
-}
-
-void LLFacebookCheckinPanel::onSend()
-{
- LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookCheckinPanel"); // just in case it is already listening
- LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookCheckinPanel", boost::bind(&LLFacebookCheckinPanel::onFacebookConnectStateChange, this, _1));
-
- // Connect to Facebook if necessary and then post
- if (LLFacebookConnect::instance().isConnected())
- {
- sendCheckin();
- }
- else
- {
- LLFacebookConnect::instance().checkConnectionToFacebook(true);
- }
-}
-
-bool LLFacebookCheckinPanel::onFacebookConnectStateChange(const LLSD& data)
-{
- switch (data.get("enum").asInteger())
- {
- case LLFacebookConnect::FB_CONNECTED:
- sendCheckin();
- break;
-
- case LLFacebookConnect::FB_POSTED:
- LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookCheckinPanel");
- clearAndClose();
- break;
- }
-
- return false;
-}
-
-void LLFacebookCheckinPanel::sendCheckin()
-{
- // Get the location SLURL
- LLSLURL slurl;
- LLAgentUI::buildSLURL(slurl);
- std::string slurl_string = slurl.getSLURLString();
-
- // Use a valid http:// URL if the scheme is secondlife://
- LLURI slurl_uri(slurl_string);
- if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
- {
- slurl_string = DEFAULT_CHECKIN_LOCATION_URL;
- }
-
- // Add query parameters so Google Analytics can track incoming clicks!
- slurl_string += DEFAULT_CHECKIN_QUERY_PARAMETERS;
-
- // Get the region name
- std::string region_name("");
- LLViewerRegion *regionp = gAgent.getRegion();
- if (regionp)
- {
- region_name = regionp->getName();
- }
-
- // Get the region description
- std::string description;
- LLAgentUI::buildLocationString(description, LLAgentUI::LOCATION_FORMAT_NORMAL_COORDS, gAgent.getPositionAgent());
-
- // Optionally add the region map view
- bool add_map_view = mMapCheckBox->getValue().asBoolean();
- std::string map_url = (add_map_view ? get_map_url() : DEFAULT_CHECKIN_ICON_URL);
-
- // Get the caption
- std::string caption = mMessageTextEditor->getValue().asString();
-
- // Post to Facebook
- LLFacebookConnect::instance().postCheckin(slurl_string, region_name, description, map_url, caption);
-}
-
-void LLFacebookCheckinPanel::clearAndClose()
-{
- mMessageTextEditor->setValue("");
-
- LLFloater* floater = getParentByType<LLFloater>();
- if (floater)
- {
- floater->closeFloater();
- }
-}
-
-///////////////////////////
-//LLFacebookFriendsPanel//////
-///////////////////////////
-
-LLFacebookFriendsPanel::LLFacebookFriendsPanel() :
- mFriendsStatusCaption(NULL),
- mSecondLifeFriends(NULL),
- mSuggestedFriends(NULL)
-{
-}
-
-LLFacebookFriendsPanel::~LLFacebookFriendsPanel()
-{
- LLAvatarTracker::instance().removeObserver(this);
-}
-
-BOOL LLFacebookFriendsPanel::postBuild()
-{
- mFriendsStatusCaption = getChild<LLTextBox>("facebook_friends_status");
-
- mSecondLifeFriends = getChild<LLAvatarList>("second_life_friends");
- mSecondLifeFriends->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
-
- mSuggestedFriends = getChild<LLAvatarList>("suggested_friends");
- mSuggestedFriends->setContextMenu(&LLPanelPeopleMenus::gSuggestedFriendsContextMenu);
-
- setVisibleCallback(boost::bind(&LLFacebookFriendsPanel::updateFacebookList, this, _2));
-
- LLAvatarTracker::instance().addObserver(this);
-
- return LLPanel::postBuild();
-}
-
-bool LLFacebookFriendsPanel::updateSuggestedFriendList()
-{
- const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
- uuid_vec_t& second_life_friends = mSecondLifeFriends->getIDs();
- second_life_friends.clear();
- uuid_vec_t& suggested_friends = mSuggestedFriends->getIDs();
- suggested_friends.clear();
-
- //Add suggested friends
- LLSD friends = LLFacebookConnect::instance().getContent();
- for (LLSD::array_const_iterator i = friends.beginArray(); i != friends.endArray(); ++i)
- {
- LLUUID agent_id = (*i).asUUID();
- if (agent_id.notNull())
- {
- bool second_life_buddy = av_tracker.isBuddy(agent_id);
- if (second_life_buddy)
- {
- second_life_friends.push_back(agent_id);
- }
- else
- {
- //FB+SL but not SL friend
- suggested_friends.push_back(agent_id);
- }
- }
- }
-
- //Force a refresh when there aren't any filter matches (prevent displaying content that shouldn't display)
- mSecondLifeFriends->setDirty(true, !mSecondLifeFriends->filterHasMatches());
- mSuggestedFriends->setDirty(true, !mSuggestedFriends->filterHasMatches());
- showFriendsAccordionsIfNeeded();
-
- return false;
-}
-
-void LLFacebookFriendsPanel::showFriendsAccordionsIfNeeded()
-{
- // Show / hide the status text : needs to be done *before* showing / hidding the accordions
- if (!mSecondLifeFriends->filterHasMatches() && !mSuggestedFriends->filterHasMatches())
- {
- // Show some explanation text if the lists are empty...
- mFriendsStatusCaption->setVisible(true);
- if (LLFacebookConnect::instance().isConnected())
- {
- //...you're connected to FB but have no friends :(
- mFriendsStatusCaption->setText(getString("facebook_friends_empty"));
- }
- else
- {
- //...you're not connected to FB
- mFriendsStatusCaption->setText(getString("facebook_friends_no_connected"));
- }
- // Hide the lists
- getChild<LLAccordionCtrl>("friends_accordion")->setVisible(false);
- getChild<LLAccordionCtrlTab>("tab_second_life_friends")->setVisible(false);
- getChild<LLAccordionCtrlTab>("tab_suggested_friends")->setVisible(false);
- }
- else
- {
- // We have something in the lists, hide the explanatory text
- mFriendsStatusCaption->setVisible(false);
-
- // Show the lists
- LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("friends_accordion");
- accordion->setVisible(true);
-
- // Expand and show accordions if needed, else - hide them
- getChild<LLAccordionCtrlTab>("tab_second_life_friends")->setVisible(mSecondLifeFriends->filterHasMatches());
- getChild<LLAccordionCtrlTab>("tab_suggested_friends")->setVisible(mSuggestedFriends->filterHasMatches());
-
- // Rearrange accordions
- accordion->arrange();
- }
-}
-
-void LLFacebookFriendsPanel::changed(U32 mask)
-{
- if (mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE))
- {
- LLFacebookConnect::instance().loadFacebookFriends();
- updateFacebookList(true);
- }
-}
-
-
-void LLFacebookFriendsPanel::updateFacebookList(bool visible)
-{
- if (visible)
- {
- // We want this to be called to fetch the friends list once a connection is established
- LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookFriendsPanel");
- LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookFriendsPanel", boost::bind(&LLFacebookFriendsPanel::onConnectedToFacebook, this, _1));
-
- // We then want this to be called to update the displayed lists once the list of friends is received
- LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLFacebookFriendsPanel"); // just in case it is already listening
- LLEventPumps::instance().obtain("FacebookConnectContent").listen("LLFacebookFriendsPanel", boost::bind(&LLFacebookFriendsPanel::updateSuggestedFriendList, this));
-
- // Try to connect to Facebook
- if ((LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_NOT_CONNECTED) ||
- (LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_CONNECTION_FAILED))
- {
- LLFacebookConnect::instance().checkConnectionToFacebook();
- }
- // Loads FB friends
- if (LLFacebookConnect::instance().isConnected())
- {
- LLFacebookConnect::instance().loadFacebookFriends();
- }
- // Sort the FB friends and update the lists
- updateSuggestedFriendList();
- }
-}
-
-bool LLFacebookFriendsPanel::onConnectedToFacebook(const LLSD& data)
-{
- LLSD::Integer connection_state = data.get("enum").asInteger();
-
- if (connection_state == LLFacebookConnect::FB_CONNECTED)
- {
- LLFacebookConnect::instance().loadFacebookFriends();
- }
- else if (connection_state == LLFacebookConnect::FB_NOT_CONNECTED)
- {
- updateSuggestedFriendList();
- }
-
- return false;
-}
-
-////////////////////////
-//LLFloaterFacebook///////
-////////////////////////
-
-LLFloaterFacebook::LLFloaterFacebook(const LLSD& key) : LLFloater(key),
- mFacebookPhotoPanel(NULL),
- mStatusErrorText(NULL),
- mStatusLoadingText(NULL),
- mStatusLoadingIndicator(NULL)
-{
- mCommitCallbackRegistrar.add("SocialSharing.Cancel", boost::bind(&LLFloaterFacebook::onCancel, this));
-}
-
-void LLFloaterFacebook::onClose(bool app_quitting)
-{
- LLFloaterBigPreview* big_preview_floater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
- if (big_preview_floater)
- {
- big_preview_floater->closeOnFloaterOwnerClosing(this);
- }
- LLFloater::onClose(app_quitting);
-}
-
-void LLFloaterFacebook::onCancel()
-{
- LLFloaterBigPreview* big_preview_floater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
- if (big_preview_floater)
- {
- big_preview_floater->closeOnFloaterOwnerClosing(this);
- }
- closeFloater();
-}
-
-BOOL LLFloaterFacebook::postBuild()
-{
- // Keep tab of the Photo Panel
- mFacebookPhotoPanel = static_cast<LLFacebookPhotoPanel*>(getChild<LLUICtrl>("panel_facebook_photo"));
- // Connection status widgets
- mStatusErrorText = getChild<LLTextBox>("connection_error_text");
- mStatusLoadingText = getChild<LLTextBox>("connection_loading_text");
- mStatusLoadingIndicator = getChild<LLUICtrl>("connection_loading_indicator");
- return LLFloater::postBuild();
-}
-
-void LLFloaterFacebook::showPhotoPanel()
-{
- LLTabContainer* parent = dynamic_cast<LLTabContainer*>(mFacebookPhotoPanel->getParent());
- if (!parent)
- {
- LL_WARNS() << "Cannot find panel container" << LL_ENDL;
- return;
- }
-
- parent->selectTabPanel(mFacebookPhotoPanel);
-}
-
-void LLFloaterFacebook::draw()
-{
- if (mStatusErrorText && mStatusLoadingText && mStatusLoadingIndicator)
- {
- mStatusErrorText->setVisible(false);
- mStatusLoadingText->setVisible(false);
- mStatusLoadingIndicator->setVisible(false);
- LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState();
- std::string status_text;
-
- switch (connection_state)
- {
- case LLFacebookConnect::FB_NOT_CONNECTED:
- // No status displayed when first opening the panel and no connection done
- case LLFacebookConnect::FB_CONNECTED:
- // When successfully connected, no message is displayed
- case LLFacebookConnect::FB_POSTED:
- // No success message to show since we actually close the floater after successful posting completion
- break;
- case LLFacebookConnect::FB_CONNECTION_IN_PROGRESS:
- // Connection loading indicator
- mStatusLoadingText->setVisible(true);
- status_text = LLTrans::getString("SocialFacebookConnecting");
- mStatusLoadingText->setValue(status_text);
- mStatusLoadingIndicator->setVisible(true);
- break;
- case LLFacebookConnect::FB_POSTING:
- // Posting indicator
- mStatusLoadingText->setVisible(true);
- status_text = LLTrans::getString("SocialFacebookPosting");
- mStatusLoadingText->setValue(status_text);
- mStatusLoadingIndicator->setVisible(true);
- break;
- case LLFacebookConnect::FB_CONNECTION_FAILED:
- // Error connecting to the service
- mStatusErrorText->setVisible(true);
- status_text = LLTrans::getString("SocialFacebookErrorConnecting");
- mStatusErrorText->setValue(status_text);
- break;
- case LLFacebookConnect::FB_POST_FAILED:
- // Error posting to the service
- mStatusErrorText->setVisible(true);
- status_text = LLTrans::getString("SocialFacebookErrorPosting");
- mStatusErrorText->setValue(status_text);
- break;
- case LLFacebookConnect::FB_DISCONNECTING:
- // Disconnecting loading indicator
- mStatusLoadingText->setVisible(true);
- status_text = LLTrans::getString("SocialFacebookDisconnecting");
- mStatusLoadingText->setValue(status_text);
- mStatusLoadingIndicator->setVisible(true);
- break;
- case LLFacebookConnect::FB_DISCONNECT_FAILED:
- // Error disconnecting from the service
- mStatusErrorText->setVisible(true);
- status_text = LLTrans::getString("SocialFacebookErrorDisconnecting");
- mStatusErrorText->setValue(status_text);
- break;
- }
- }
- LLFloater::draw();
-}
-
diff --git a/indra/newview/llfloaterfacebook.h b/indra/newview/llfloaterfacebook.h
deleted file mode 100644
index a4ca666b20..0000000000
--- a/indra/newview/llfloaterfacebook.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
-* @file llfloaterfacebook.h
-* @brief Header file for llfloaterfacebook
-* @author Gilbert@lindenlab.com
-*
-* $LicenseInfo:firstyear=2013&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2013, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
-* $/LicenseInfo$
-*/
-#ifndef LL_LLFLOATERFACEBOOK_H
-#define LL_LLFLOATERFACEBOOK_H
-
-#include "llcallingcard.h"
-#include "llfloater.h"
-#include "lltextbox.h"
-#include "llviewertexture.h"
-
-class LLIconCtrl;
-class LLCheckBoxCtrl;
-class LLSnapshotLivePreview;
-class LLAvatarList;
-class LLFloaterBigPreview;
-
-class LLFacebookStatusPanel : public LLPanel
-{
-public:
- LLFacebookStatusPanel();
- BOOL postBuild();
- void draw();
- void onSend();
- bool onFacebookConnectStateChange(const LLSD& data);
- bool onFacebookConnectAccountStateChange(const LLSD& data);
-
- void sendStatus();
- void clearAndClose();
-
-private:
- void onVisibilityChange(BOOL new_visibility);
- bool onFacebookConnectInfoChange();
- void onConnect();
- void onUseAnotherAccount();
- void onDisconnect();
-
- void showConnectButton();
- void hideConnectButton();
- void showDisconnectedLayout();
- void showConnectedLayout();
-
- LLTextBox * mAccountCaptionLabel;
- LLTextBox * mAccountNameLabel;
- LLUICtrl * mPanelButtons;
- LLUICtrl * mConnectButton;
- LLUICtrl * mDisconnectButton;
- LLUICtrl* mMessageTextEditor;
- LLUICtrl* mPostButton;
- LLUICtrl* mCancelButton;
-};
-
-class LLFacebookPhotoPanel : public LLPanel
-{
-public:
- LLFacebookPhotoPanel();
- ~LLFacebookPhotoPanel();
-
- BOOL postBuild();
- void draw();
-
- LLSnapshotLivePreview* getPreviewView();
- void onVisibilityChange(BOOL new_visibility);
- void onClickBigPreview();
- void onClickNewSnapshot();
- void onSend();
- S32 notify(const LLSD& info);
- bool onFacebookConnectStateChange(const LLSD& data);
-
- void sendPhoto();
- void clearAndClose();
-
- void updateControls();
- void updateResolution(BOOL do_update);
- void checkAspectRatio(S32 index);
- LLUICtrl* getRefreshBtn();
-
-private:
- bool isPreviewVisible();
- void attachPreview();
-
- LLHandle<LLView> mPreviewHandle;
-
- LLUICtrl * mResolutionComboBox;
- LLUICtrl * mFilterComboBox;
- LLUICtrl * mRefreshBtn;
- LLUICtrl * mWorkingLabel;
- LLUICtrl * mThumbnailPlaceholder;
- LLUICtrl * mCaptionTextBox;
- LLUICtrl * mPostButton;
- LLUICtrl * mCancelButton;
- LLButton * mBtnPreview;
-
- LLFloaterBigPreview * mBigPreviewFloater;
-
- S32 mQuality; // Compression quality
-};
-
-class LLFacebookCheckinPanel : public LLPanel
-{
-public:
- LLFacebookCheckinPanel();
- BOOL postBuild();
- void draw();
- void onSend();
- bool onFacebookConnectStateChange(const LLSD& data);
-
- void sendCheckin();
- void clearAndClose();
-
-private:
- std::string mMapUrl;
- LLPointer<LLViewerFetchedTexture> mMapTexture;
- LLUICtrl* mPostButton;
- LLUICtrl* mCancelButton;
- LLUICtrl* mMessageTextEditor;
- LLUICtrl* mMapLoadingIndicator;
- LLIconCtrl* mMapPlaceholder;
- LLIconCtrl* mMapDefault;
- LLCheckBoxCtrl* mMapCheckBox;
- bool mReloadingMapTexture;
-};
-
-class LLFacebookFriendsPanel : public LLPanel, public LLFriendObserver
-{
-public:
- LLFacebookFriendsPanel();
- ~LLFacebookFriendsPanel();
- BOOL postBuild();
- virtual void changed(U32 mask);
-
-private:
- bool updateSuggestedFriendList();
- void showFriendsAccordionsIfNeeded();
- void updateFacebookList(bool visible);
- bool onConnectedToFacebook(const LLSD& data);
-
- LLTextBox * mFriendsStatusCaption;
- LLAvatarList* mSecondLifeFriends;
- LLAvatarList* mSuggestedFriends;
-};
-
-class LLFloaterFacebook : public LLFloater
-{
-public:
- LLFloaterFacebook(const LLSD& key);
- BOOL postBuild();
- void draw();
- void onClose(bool app_quitting);
- void onCancel();
-
- void showPhotoPanel();
-
-private:
- LLFacebookPhotoPanel* mFacebookPhotoPanel;
- LLTextBox* mStatusErrorText;
- LLTextBox* mStatusLoadingText;
- LLUICtrl* mStatusLoadingIndicator;
-};
-
-#endif // LL_LLFLOATERFACEBOOK_H
-
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 7f2e8fd82a..3098c6d118 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -1877,6 +1877,7 @@ LLPanelLandOptions::LLPanelLandOptions(LLParcelSelectionHandle& parcel)
mLandingTypeCombo(NULL),
mSnapshotCtrl(NULL),
mLocationText(NULL),
+ mSeeAvatarsText(NULL),
mSetBtn(NULL),
mClearBtn(NULL),
mMatureCtrl(NULL),
@@ -1923,6 +1924,14 @@ BOOL LLPanelLandOptions::postBuild()
mSeeAvatarsCtrl = getChild<LLCheckBoxCtrl>( "SeeAvatarsCheck");
childSetCommitCallback("SeeAvatarsCheck", onCommitAny, this);
+ mSeeAvatarsText = getChild<LLTextBox>("allow_see_label");
+ if (mSeeAvatarsText)
+ {
+ mSeeAvatarsText->setShowCursorHand(false);
+ mSeeAvatarsText->setSoundFlags(LLView::MOUSE_UP);
+ mSeeAvatarsText->setClickedCallback(boost::bind(&toggleSeeAvatars, this));
+ }
+
mCheckShowDirectory = getChild<LLCheckBoxCtrl>( "ShowDirectoryCheck");
childSetCommitCallback("ShowDirectoryCheck", onCommitAny, this);
@@ -2016,6 +2025,7 @@ void LLPanelLandOptions::refresh()
mSeeAvatarsCtrl->set(TRUE);
mSeeAvatarsCtrl->setEnabled(FALSE);
+ mSeeAvatarsText->setEnabled(FALSE);
mLandingTypeCombo->setCurrentByIndex(0);
mLandingTypeCombo->setEnabled(FALSE);
@@ -2074,6 +2084,7 @@ void LLPanelLandOptions::refresh()
mSeeAvatarsCtrl->set(parcel->getSeeAVs());
mSeeAvatarsCtrl->setEnabled(can_change_options && parcel->getHaveNewParcelLimitData());
+ mSeeAvatarsText->setEnabled(can_change_options && parcel->getHaveNewParcelLimitData());
BOOL can_change_landing_point = LLViewerParcelMgr::isParcelModifiableByAgent(parcel,
GP_LAND_SET_LANDING_POINT);
@@ -2364,7 +2375,16 @@ void LLPanelLandOptions::onClickClear(void* userdata)
self->refresh();
}
-
+void LLPanelLandOptions::toggleSeeAvatars(void* userdata)
+{
+ LLPanelLandOptions* self = (LLPanelLandOptions*)userdata;
+ if (self)
+ {
+ self->getChild<LLCheckBoxCtrl>("SeeAvatarsCheck")->toggle();
+ self->getChild<LLCheckBoxCtrl>("SeeAvatarsCheck")->setBtnFocus();
+ self->onCommitAny(NULL, userdata);
+ }
+}
//---------------------------------------------------------------------------
// LLPanelLandAccess
//---------------------------------------------------------------------------
diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h
index e846d42666..0c49d78a20 100644
--- a/indra/newview/llfloaterland.h
+++ b/indra/newview/llfloaterland.h
@@ -327,6 +327,7 @@ private:
static void onCommitAny(LLUICtrl* ctrl, void *userdata);
static void onClickSet(void* userdata);
static void onClickClear(void* userdata);
+ static void toggleSeeAvatars(void* userdata);
private:
LLCheckBoxCtrl* mCheckEditObjects;
@@ -345,6 +346,7 @@ private:
LLTextureCtrl* mSnapshotCtrl;
LLTextBox* mLocationText;
+ LLTextBox* mSeeAvatarsText;
LLButton* mSetBtn;
LLButton* mClearBtn;
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 4f1ea4a89e..cb58cfdd0a 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -325,6 +325,8 @@ BOOL LLFloaterModelPreview::postBuild()
childSetCommitCallback("import_scale", onImportScaleCommit, this);
childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this);
+ getChild<LLLineEditor>("description_form")->setKeystrokeCallback(boost::bind(&LLFloaterModelPreview::onDescriptionKeystroke, this, _1), NULL);
+
getChild<LLCheckBoxCtrl>("show_edges")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
getChild<LLCheckBoxCtrl>("show_physics")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
getChild<LLCheckBoxCtrl>("show_textures")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
@@ -520,6 +522,16 @@ void LLFloaterModelPreview::onClickCalculateBtn()
mUploadBtn->setEnabled(false);
}
+void LLFloaterModelPreview::onDescriptionKeystroke(LLUICtrl* ctrl)
+{
+ // Workaround for SL-4186, server doesn't allow name changes after 'calculate' stage
+ LLLineEditor* input = static_cast<LLLineEditor*>(ctrl);
+ if (input->isDirty()) // dirty will be reset after commit
+ {
+ toggleCalculateButton(true);
+ }
+}
+
//static
void LLFloaterModelPreview::onImportScaleCommit(LLUICtrl*,void* userdata)
{
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 7ec6a58ac7..edc90d1695 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -137,7 +137,9 @@ protected:
friend class LLModelPreview;
friend class LLMeshFilePicker;
friend class LLPhysicsDecomp;
-
+
+ void onDescriptionKeystroke(LLUICtrl*);
+
static void onImportScaleCommit(LLUICtrl*, void*);
static void onPelvisOffsetCommit(LLUICtrl*, void*);
static void onUploadJointsCommit(LLUICtrl*,void*);
diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index d80793f9e4..bfcd1b8b47 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -30,9 +30,7 @@
#include "llfloateroutfitsnapshot.h"
#include "llagent.h"
-#include "llfacebookconnect.h"
#include "llfloaterreg.h"
-#include "llfloaterfacebook.h"
#include "llfloaterflickr.h"
#include "llfloatertwitter.h"
#include "llimagefiltersmanager.h"
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index a7931137b0..2798e375c7 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -28,9 +28,7 @@
#include "llfloatersnapshot.h"
-#include "llfacebookconnect.h"
#include "llfloaterreg.h"
-#include "llfloaterfacebook.h"
#include "llfloaterflickr.h"
#include "llfloatertwitter.h"
#include "llimagefiltersmanager.h"
@@ -1242,11 +1240,10 @@ BOOL LLFloaterSnapshot::isWaitingState()
BOOL LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized)
{
- LLFloaterFacebook* floater_facebook = LLFloaterReg::findTypedInstance<LLFloaterFacebook>("facebook");
LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr");
LLFloaterTwitter* floater_twitter = LLFloaterReg::findTypedInstance<LLFloaterTwitter>("twitter");
- if (!initialized && !floater_facebook && !floater_flickr && !floater_twitter)
+ if (!initialized && !floater_flickr && !floater_twitter)
return FALSE;
BOOL changed = FALSE;
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index ee4fdbe9a5..c2c15ee12b 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -514,11 +514,6 @@ void LLFloaterTools::refresh()
selection_info << getString("status_selectcount", selection_args);
getChild<LLTextBox>("selection_count")->setText(selection_info.str());
-
- bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty();
- childSetVisible("selection_count", have_selection);
- childSetVisible("remaining_capacity", have_selection);
- childSetVisible("selection_empty", !have_selection);
}
diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp
index 3b17368445..13953d6be5 100644
--- a/indra/newview/llfloaterwebcontent.cpp
+++ b/indra/newview/llfloaterwebcontent.cpp
@@ -30,7 +30,6 @@
#include "lliconctrl.h"
#include "llfloaterreg.h"
#include "llhttpconstants.h"
-#include "llfacebookconnect.h"
#include "llflickrconnect.h"
#include "lltwitterconnect.h"
#include "lllayoutstack.h"
@@ -289,17 +288,7 @@ void LLFloaterWebContent::onOpen(const LLSD& key)
//virtual
void LLFloaterWebContent::onClose(bool app_quitting)
{
- // If we close the web browsing window showing the facebook login, we need to signal to this object that the connection will not happen
- // MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
- LLFloater* fbc_web = LLFloaterReg::findInstance("fbc_web");
- if (fbc_web == this)
- {
- if (!LLFacebookConnect::instance().isConnected())
- {
- LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_FAILED);
- }
- }
- // Same with Flickr
+ // If we close the web browsing window showing the Flickr login, we need to signal to this object that the connection will not happen
// MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
LLFloater* flickr_web = LLFloaterReg::findInstance("flickr_web");
if (flickr_web == this)
@@ -309,7 +298,7 @@ void LLFloaterWebContent::onClose(bool app_quitting)
LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
}
}
- // And Twitter
+ // Same with Twitter
// MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
LLFloater* twitter_web = LLFloaterReg::findInstance("twitter_web");
if (twitter_web == this)
@@ -380,13 +369,6 @@ void LLFloaterWebContent::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent
// The browser instance wants its window closed.
closeFloater();
}
- else if(event == MEDIA_EVENT_GEOMETRY_CHANGE)
- {
- if (mCurrentURL.find("facebook.com/dialog/oauth") == std::string::npos) // HACK to fix ACME-1317 - Cho
- {
- geometryChanged(self->getGeometryX(), self->getGeometryY(), self->getGeometryWidth(), self->getGeometryHeight());
- }
- }
else if(event == MEDIA_EVENT_STATUS_TEXT_CHANGED )
{
const std::string text = self->getStatusText();
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/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 152d0eddcd..088d052533 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -2137,6 +2137,7 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
static U32 lastGroupMemberRequestFrame = 0;
// Have we requested the information already this frame?
+ // Todo: make this per group, we can invite to one group and simultaneously be checking another one
if ((lastGroupMemberRequestFrame == gFrameCount) || (mMemberRequestInFlight))
return;
@@ -2166,6 +2167,9 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
return;
}
+ LLGroupMgrGroupData* group_datap = createGroupData(group_id); //make sure group exists
+ group_datap->mMemberRequestID.generate(); // mark as pending
+
lastGroupMemberRequestFrame = gFrameCount;
LLCoros::instance().launch("LLGroupMgr::groupMembersRequestCoro",
diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h
index 940ef6eea1..cf9735e38a 100644
--- a/indra/newview/llgroupmgr.h
+++ b/indra/newview/llgroupmgr.h
@@ -258,6 +258,11 @@ public:
bool isRoleMemberDataComplete() { return mRoleMemberDataComplete; }
bool isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; }
+ bool isMemberDataPending() { return mMemberRequestID.notNull(); }
+ bool isRoleDataPending() { return mRoleDataRequestID.notNull(); }
+ bool isRoleMemberDataPending() { return (mRoleMembersRequestID.notNull() || mPendingRoleMemberRequest); }
+ bool isGroupTitlePending() { return mTitlesRequestID.notNull(); }
+
bool isSingleMemberNotOwner();
F32 getAccessTime() const { return mAccessTime; }
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 074b0c9c14..a50a66a8ce 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1399,13 +1399,6 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
// Only should happen for broken links.
new_listener = new LLLinkItemBridge(inventory, root, uuid);
break;
- case LLAssetType::AT_MESH:
- if(!(inv_type == LLInventoryType::IT_MESH))
- {
- LL_WARNS() << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << LL_ENDL;
- }
- new_listener = new LLMeshBridge(inventory, root, uuid);
- break;
case LLAssetType::AT_UNKNOWN:
new_listener = new LLUnknownItemBridge(inventory, root, uuid);
break;
@@ -2101,7 +2094,9 @@ BOOL LLItemBridge::isItemCopyable() const
LLViewerInventoryItem* item = getItem();
if (item)
{
- // Can't copy worn objects. DEV-15183
+ // Can't copy worn objects.
+ // Worn objects are tied to their inworld conterparts
+ // Copy of modified worn object will return object with obsolete asset and inventory
if(get_is_item_worn(mUUID))
{
return FALSE;
@@ -6830,58 +6825,6 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
hide_context_entries(menu, items, disabled_items);
}
-// +=================================================+
-// | LLMeshBridge |
-// +=================================================+
-
-LLUIImagePtr LLMeshBridge::getIcon() const
-{
- return LLInventoryIcon::getIcon(LLAssetType::AT_MESH, LLInventoryType::IT_MESH, 0, FALSE);
-}
-
-void LLMeshBridge::openItem()
-{
- LLViewerInventoryItem* item = getItem();
-
- if (item)
- {
- // open mesh
- }
-}
-
-void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
-{
- LL_DEBUGS() << "LLMeshBridge::buildContextMenu()" << LL_ENDL;
- std::vector<std::string> items;
- std::vector<std::string> disabled_items;
-
- if(isItemInTrash())
- {
- items.push_back(std::string("Purge Item"));
- if (!isItemRemovable())
- {
- disabled_items.push_back(std::string("Purge Item"));
- }
-
- items.push_back(std::string("Restore Item"));
- }
- else if (isMarketplaceListingsFolder())
- {
- addMarketplaceContextMenuOptions(flags, items, disabled_items);
- items.push_back(std::string("Properties"));
- getClipboardEntries(false, items, disabled_items, flags);
- }
- else
- {
- items.push_back(std::string("Properties"));
-
- getClipboardEntries(true, items, disabled_items, flags);
- }
-
- addLinkReplaceMenuOption(items, disabled_items);
- hide_context_entries(menu, items, disabled_items);
-}
-
// +=================================================+
// | LLLinkBridge |
@@ -7358,8 +7301,7 @@ bool LLFolderViewGroupedItemBridge::canWearSelected(uuid_vec_t item_ids)
for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it)
{
LLViewerInventoryItem* item = gInventory.getItem(*it);
- LLAssetType::EType asset_type = item->getType();
- if (!item || (asset_type >= LLAssetType::AT_COUNT) || (asset_type <= LLAssetType::AT_NONE))
+ if (!item || (item->getType() >= LLAssetType::AT_COUNT) || (item->getType() <= LLAssetType::AT_NONE))
{
return false;
}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index ce06e8fffc..f4df566fa6 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -603,23 +603,6 @@ protected:
static std::string sPrefix;
};
-
-class LLMeshBridge : public LLItemBridge
-{
- friend class LLInvFVBridge;
-public:
- virtual LLUIImagePtr getIcon() const;
- virtual void openItem();
- virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
-
-protected:
- LLMeshBridge(LLInventoryPanel* inventory,
- LLFolderView* root,
- const LLUUID& uuid) :
- LLItemBridge(inventory, root, uuid) {}
-};
-
-
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInvFVBridgeAction
//
@@ -650,17 +633,6 @@ protected:
LLInventoryModel* mModel;
};
-class LLMeshBridgeAction: public LLInvFVBridgeAction
-{
- friend class LLInvFVBridgeAction;
-public:
- virtual void doIt() ;
- virtual ~LLMeshBridgeAction(){}
-protected:
- LLMeshBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
-
-};
-
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Recent Inventory Panel related classes
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 9193613e9f..16385928b4 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -58,6 +58,7 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p)
mHoursAgo(p.hours_ago),
mDateSearchDirection(p.date_search_direction),
mShowFolderState(p.show_folder_state),
+ mFilterCreatorType(p.creator_type),
mPermissions(p.permissions),
mFilterTypes(p.types),
mFilterUUID(p.uuid),
@@ -78,8 +79,7 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)
mCurrentGeneration(0),
mFirstRequiredGeneration(0),
mFirstSuccessGeneration(0),
- mSearchType(SEARCHTYPE_NAME),
- mFilterCreatorType(FILTERCREATOR_ALL)
+ mSearchType(SEARCHTYPE_NAME)
{
// copy mFilterOps into mDefaultFilterOps
markDefault();
@@ -489,7 +489,7 @@ bool LLInventoryFilter::checkAgainstCreator(const LLFolderViewModelItemInventory
{
if (!listener) return TRUE;
const BOOL is_folder = listener->getInventoryType() == LLInventoryType::IT_CATEGORY;
- switch(mFilterCreatorType)
+ switch (mFilterOps.mFilterCreatorType)
{
case FILTERCREATOR_SELF:
if(is_folder) return FALSE;
@@ -601,9 +601,9 @@ void LLInventoryFilter::setSearchType(ESearchType type)
void LLInventoryFilter::setFilterCreator(EFilterCreatorType type)
{
- if(mFilterCreatorType != type)
+ if (mFilterOps.mFilterCreatorType != type)
{
- mFilterCreatorType = type;
+ mFilterOps.mFilterCreatorType = type;
setModified();
}
}
@@ -1194,6 +1194,7 @@ void LLInventoryFilter::toParams(Params& params) const
params.filter_ops.hours_ago = getHoursAgo();
params.filter_ops.date_search_direction = getDateSearchDirection();
params.filter_ops.show_folder_state = getShowFolderState();
+ params.filter_ops.creator_type = getFilterCreatorType();
params.filter_ops.permissions = getFilterPermissions();
params.substring = getFilterSubString();
params.since_logoff = isSinceLogoff();
@@ -1216,6 +1217,7 @@ void LLInventoryFilter::fromParams(const Params& params)
setHoursAgo(params.filter_ops.hours_ago);
setDateSearchDirection(params.filter_ops.date_search_direction);
setShowFolderState(params.filter_ops.show_folder_state);
+ setFilterCreator(params.filter_ops.creator_type);
setFilterPermissions(params.filter_ops.permissions);
setFilterSubString(params.substring);
setDateRangeLastLogoff(params.since_logoff);
@@ -1278,6 +1280,11 @@ LLInventoryFilter::EFolderShow LLInventoryFilter::getShowFolderState() const
return mFilterOps.mShowFolderState;
}
+LLInventoryFilter::EFilterCreatorType LLInventoryFilter::getFilterCreatorType() const
+{
+ return mFilterOps.mFilterCreatorType;
+}
+
bool LLInventoryFilter::isTimedOut()
{
return mFilterTime.hasExpired();
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 01754ed023..4a1fec8454 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -126,6 +126,7 @@ public:
Optional<U32> date_search_direction;
Optional<EFolderShow> show_folder_state;
Optional<PermissionMask> permissions;
+ Optional<EFilterCreatorType> creator_type;
Params()
: types("filter_types", FILTERTYPE_OBJECT),
@@ -138,6 +139,7 @@ public:
hours_ago("hours_ago", 0),
date_search_direction("date_search_direction", FILTERDATEDIRECTION_NEWER),
show_folder_state("show_folder_state", SHOW_NON_EMPTY_FOLDERS),
+ creator_type("creator_type", FILTERCREATOR_ALL),
permissions("permissions", PERM_NONE)
{}
};
@@ -156,8 +158,9 @@ public:
U32 mHoursAgo;
U32 mDateSearchDirection;
- EFolderShow mShowFolderState;
- PermissionMask mPermissions;
+ EFolderShow mShowFolderState;
+ PermissionMask mPermissions;
+ EFilterCreatorType mFilterCreatorType;
};
struct Params : public LLInitParam::Block<Params>
@@ -202,7 +205,6 @@ public:
void setSearchType(ESearchType type);
ESearchType getSearchType() { return mSearchType; }
void setFilterCreator(EFilterCreatorType type);
- EFilterCreatorType getFilterCreator() { return mFilterCreatorType; }
void setFilterSubString(const std::string& string);
const std::string& getFilterSubString(BOOL trim = FALSE) const;
@@ -243,8 +245,9 @@ public:
// +-------------------------------------------------------------------+
// + Presentation
// +-------------------------------------------------------------------+
- void setShowFolderState( EFolderShow state);
- EFolderShow getShowFolderState() const;
+ void setShowFolderState( EFolderShow state);
+ EFolderShow getShowFolderState() const;
+ EFilterCreatorType getFilterCreatorType() const;
void setEmptyLookupMessage(const std::string& message);
std::string getEmptyLookupMessage() const;
@@ -324,7 +327,6 @@ private:
std::string mEmptyLookupMessage;
ESearchType mSearchType;
- EFilterCreatorType mFilterCreatorType;
};
#endif
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index b140c7c38e..c49d61df31 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -888,14 +888,6 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
return mask;
}
- // We're hiding mesh types
-#if 0
- if (item->getType() == LLAssetType::AT_MESH)
- {
- return mask;
- }
-#endif
-
LLPointer<LLViewerInventoryItem> old_item = getItem(item->getUUID());
LLPointer<LLViewerInventoryItem> new_item;
if(old_item)
diff --git a/indra/newview/llmachineid.cpp b/indra/newview/llmachineid.cpp
index b0ee8e7fcb..51127928d1 100644
--- a/indra/newview/llmachineid.cpp
+++ b/indra/newview/llmachineid.cpp
@@ -65,11 +65,11 @@ public:
S32 LLMachineID::init()
{
- memset(static_unique_id,0,sizeof(static_unique_id));
+ size_t len = sizeof(static_unique_id);
+ memset(static_unique_id, 0, len);
S32 ret_code = 0;
#if LL_WINDOWS
# pragma comment(lib, "wbemuuid.lib")
- size_t len = sizeof(static_unique_id);
// algorithm to detect BIOS serial number found at:
// http://msdn.microsoft.com/en-us/library/aa394077%28VS.85%29.aspx
@@ -217,17 +217,27 @@ S32 LLMachineID::init()
// Get the value of the Name property
hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);
+ if (FAILED(hr))
+ {
+ LL_WARNS() << "Failed to get SerialNumber. Error code = 0x" << hex << hres << LL_ENDL;
+ pclsObj->Release();
+ pclsObj = NULL;
+ continue;
+ }
LL_INFOS("AppInit") << " Serial Number : " << vtProp.bstrVal << LL_ENDL;
+
// use characters in the returned Serial Number to create a byte array of size len
BSTR serialNumber ( vtProp.bstrVal);
+ unsigned int serial_size = SysStringLen(serialNumber);
unsigned int j = 0;
- while( vtProp.bstrVal[j] != 0)
+
+ while (j < serial_size && vtProp.bstrVal[j] != 0)
{
for (unsigned int i = 0; i < len; i++)
{
- if (vtProp.bstrVal[j] == 0)
+ if (j >= serial_size || vtProp.bstrVal[j] == 0)
break;
-
+
static_unique_id[i] = (unsigned int)(static_unique_id[i] + serialNumber[j]);
j++;
}
@@ -254,16 +264,8 @@ S32 LLMachineID::init()
ret_code = LLUUID::getNodeID(staticPtr);
#endif
has_static_unique_id = true;
- return ret_code;
-}
-
-S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
-{
- if (has_static_unique_id)
- {
- memcpy ( unique_id, &static_unique_id, len);
- LL_INFOS_ONCE("AppInit") << "UniqueID: 0x";
+ LL_INFOS("AppInit") << "UniqueID: 0x";
// Code between here and LL_ENDL is not executed unless the LL_DEBUGS
// actually produces output
for (size_t i = 0; i < len; ++i)
@@ -271,11 +273,21 @@ S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
// Copy each char to unsigned int to hexify. Sending an unsigned
// char to a std::ostream tries to represent it as a char, not
// what we want here.
- unsigned byte = unique_id[i];
+ unsigned byte = static_unique_id[i];
LL_CONT << std::hex << std::setw(2) << std::setfill('0') << byte;
}
// Reset default output formatting to avoid nasty surprises!
LL_CONT << std::dec << std::setw(0) << std::setfill(' ') << LL_ENDL;
+
+ return ret_code;
+}
+
+
+S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
+{
+ if (has_static_unique_id)
+ {
+ memcpy ( unique_id, &static_unique_id, len);
return 1;
}
return 0;
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/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index fef0631fa6..ba831ab2ed 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -35,7 +35,6 @@
#include "llnotificationmanager.h"
#include "llnotifications.h"
#include "llscriptfloater.h"
-#include "llfacebookconnect.h"
#include "llavatarname.h"
#include "llavatarnamecache.h"
diff --git a/indra/newview/llpanelexperiencepicker.cpp b/indra/newview/llpanelexperiencepicker.cpp
index a7f2dbafa2..80aeee6da1 100644
--- a/indra/newview/llpanelexperiencepicker.cpp
+++ b/indra/newview/llpanelexperiencepicker.cpp
@@ -89,7 +89,7 @@ BOOL LLPanelExperiencePicker::postBuild()
childSetAction(BTN_PROFILE, boost::bind(&LLPanelExperiencePicker::onBtnProfile, this));
getChildView(BTN_PROFILE)->setEnabled(FALSE);
- getChild<LLComboBox>(TEXT_MATURITY)->setCurrentByIndex(2);
+ getChild<LLComboBox>(TEXT_MATURITY)->setCurrentByIndex(gSavedPerAccountSettings.getU32("ExperienceSearchMaturity"));
getChild<LLComboBox>(TEXT_MATURITY)->setCommitCallback(boost::bind(&LLPanelExperiencePicker::onMaturity, this));
getChild<LLUICtrl>(TEXT_EDIT)->setFocus(TRUE);
@@ -381,6 +381,7 @@ void LLPanelExperiencePicker::filterContent()
void LLPanelExperiencePicker::onMaturity()
{
+ gSavedPerAccountSettings.setU32("ExperienceSearchMaturity", getChild<LLComboBox>(TEXT_MATURITY)->getCurrentIndex());
if(mResponse.has("experience_keys") && mResponse["experience_keys"].beginArray() != mResponse["experience_keys"].endArray())
{
filterContent();
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index 82ea8377de..d6b66ee622 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -606,11 +606,30 @@ void LLPanelGroupInvite::updateLists()
{
if (!mPendingUpdate)
{
+ // Note: this will partially fail if some requests are already in progress
LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID);
LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID);
LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mImplementation->mGroupID);
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID);
}
+ else if (gdatap)
+ {
+ // restart requests that were interrupted/dropped/failed to start
+ if (!gdatap->isRoleDataPending() && !gdatap->isRoleDataComplete())
+ {
+ LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID);
+ }
+ if (!gdatap->isRoleMemberDataPending() && !gdatap->isRoleMemberDataComplete())
+ {
+ LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mImplementation->mGroupID);
+ }
+ // sendCapGroupMembersRequest has a per frame send limitation that could have
+ // interrupted previous request
+ if (!gdatap->isMemberDataPending() && !gdatap->isMemberDataComplete())
+ {
+ LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID);
+ }
+ }
mPendingUpdate = TRUE;
}
else
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/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 142dea83e2..e253557797 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -178,7 +178,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
mPasswordModified = FALSE;
- LLPanelLogin::sInstance = this;
+ sInstance = this;
LLView* login_holder = gViewerWindow->getLoginPanelHolder();
if (login_holder)
@@ -234,29 +234,44 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
current_grid,
ADD_TOP);
- server_choice_combo->selectFirstItem();
+ server_choice_combo->selectFirstItem();
LLSLURL start_slurl(LLStartUp::getStartSLURL());
+ // The StartSLURL might have been set either by an explicit command-line
+ // argument (CmdLineLoginLocation) or by default.
+ // current_grid might have been set either by an explicit command-line
+ // argument (CmdLineGridChoice) or by default.
+ // If the grid specified by StartSLURL is the same as current_grid, the
+ // distinction is moot.
+ // If we have an explicit command-line SLURL, use that.
+ // If we DON'T have an explicit command-line SLURL but we DO have an
+ // explicit command-line grid, which is different from the default SLURL's
+ // -- do NOT override the explicit command-line grid with the grid from
+ // the default SLURL!
+ bool force_grid{ start_slurl.getGrid() != current_grid &&
+ gSavedSettings.getString("CmdLineLoginLocation").empty() &&
+ ! gSavedSettings.getString("CmdLineGridChoice").empty() };
if ( !start_slurl.isSpatial() ) // has a start been established by the command line or NextLoginLocation ?
{
// no, so get the preference setting
std::string defaultStartLocation = gSavedSettings.getString("LoginLocation");
LL_INFOS("AppInit")<<"default LoginLocation '"<<defaultStartLocation<<"'"<<LL_ENDL;
LLSLURL defaultStart(defaultStartLocation);
- if ( defaultStart.isSpatial() )
+ if ( defaultStart.isSpatial() && ! force_grid )
{
LLStartUp::setStartSLURL(defaultStart);
}
else
{
- LL_INFOS("AppInit")<<"no valid LoginLocation, using home"<<LL_ENDL;
+ LL_INFOS("AppInit") << (force_grid? "--grid specified" : "no valid LoginLocation")
+ << ", using home" << LL_ENDL;
LLSLURL homeStart(LLSLURL::SIM_LOCATION_HOME);
LLStartUp::setStartSLURL(homeStart);
}
}
- else
+ else if (! force_grid)
{
- LLPanelLogin::onUpdateStartSLURL(start_slurl); // updates grid if needed
+ onUpdateStartSLURL(start_slurl); // updates grid if needed
}
childSetAction("connect_btn", onClickConnect, this);
@@ -380,7 +395,7 @@ void LLPanelLogin::setFocus(BOOL b)
{
if(b)
{
- LLPanelLogin::giveFocus();
+ giveFocus();
}
else
{
@@ -748,7 +763,10 @@ void LLPanelLogin::closePanel()
{
if (sInstance)
{
- LLPanelLogin::sInstance->getParent()->removeChild( LLPanelLogin::sInstance );
+ if (LLPanelLogin::sInstance->getParent())
+ {
+ LLPanelLogin::sInstance->getParent()->removeChild(LLPanelLogin::sInstance);
+ }
delete sInstance;
sInstance = NULL;
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index db9d61c637..f63e604927 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -885,7 +885,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
U32 hours = mFilter->getHoursAgo();
U32 date_search_direction = mFilter->getDateSearchDirection();
- LLInventoryFilter::EFilterCreatorType filter_creator = mFilter->getFilterCreator();
+ LLInventoryFilter::EFilterCreatorType filter_creator = mFilter->getFilterCreatorType();
bool show_created_by_me = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_SELF));
bool show_created_by_others = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_OTHERS));
@@ -898,7 +898,6 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
getChild<LLUICtrl>("check_clothing")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
getChild<LLUICtrl>("check_gesture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
getChild<LLUICtrl>("check_landmark")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
- getChild<LLUICtrl>("check_mesh")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MESH));
getChild<LLUICtrl>("check_notecard")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
getChild<LLUICtrl>("check_object")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
getChild<LLUICtrl>("check_script")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
@@ -954,12 +953,6 @@ void LLFloaterInventoryFinder::draw()
filtered_by_all_types = FALSE;
}
- if (!getChild<LLUICtrl>("check_mesh")->getValue())
- {
- filter &= ~(0x1 << LLInventoryType::IT_MESH);
- filtered_by_all_types = FALSE;
- }
-
if (!getChild<LLUICtrl>("check_notecard")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
@@ -1108,7 +1101,6 @@ void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
self->getChild<LLUICtrl>("check_clothing")->setValue(TRUE);
self->getChild<LLUICtrl>("check_gesture")->setValue(TRUE);
self->getChild<LLUICtrl>("check_landmark")->setValue(TRUE);
- self->getChild<LLUICtrl>("check_mesh")->setValue(TRUE);
self->getChild<LLUICtrl>("check_notecard")->setValue(TRUE);
self->getChild<LLUICtrl>("check_object")->setValue(TRUE);
self->getChild<LLUICtrl>("check_script")->setValue(TRUE);
@@ -1128,7 +1120,6 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
self->getChild<LLUICtrl>("check_clothing")->setValue(FALSE);
self->getChild<LLUICtrl>("check_gesture")->setValue(FALSE);
self->getChild<LLUICtrl>("check_landmark")->setValue(FALSE);
- self->getChild<LLUICtrl>("check_mesh")->setValue(FALSE);
self->getChild<LLUICtrl>("check_notecard")->setValue(FALSE);
self->getChild<LLUICtrl>("check_object")->setValue(FALSE);
self->getChild<LLUICtrl>("check_script")->setValue(FALSE);
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index cd1875e995..6702dae4d6 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1122,92 +1122,6 @@ LLUIImagePtr LLTaskWearableBridge::getIcon() const
}
///----------------------------------------------------------------------------
-/// Class LLTaskMeshBridge
-///----------------------------------------------------------------------------
-
-class LLTaskMeshBridge : public LLTaskInvFVBridge
-{
-public:
- LLTaskMeshBridge(
- LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name);
-
- virtual LLUIImagePtr getIcon() const;
- virtual void openItem();
- virtual void performAction(LLInventoryModel* model, std::string action);
- virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
-};
-
-LLTaskMeshBridge::LLTaskMeshBridge(
- LLPanelObjectInventory* panel,
- const LLUUID& uuid,
- const std::string& name) :
- LLTaskInvFVBridge(panel, uuid, name)
-{
-}
-
-LLUIImagePtr LLTaskMeshBridge::getIcon() const
-{
- return LLInventoryIcon::getIcon(LLAssetType::AT_MESH, LLInventoryType::IT_MESH, 0, FALSE);
-}
-
-void LLTaskMeshBridge::openItem()
-{
- // open mesh
-}
-
-
-// virtual
-void LLTaskMeshBridge::performAction(LLInventoryModel* model, std::string action)
-{
- if (action == "mesh action")
- {
- LLInventoryItem* item = findItem();
- if(item)
- {
- // do action
- }
- }
- LLTaskInvFVBridge::performAction(model, action);
-}
-
-void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
-{
- LLInventoryItem* item = findItem();
- std::vector<std::string> items;
- std::vector<std::string> disabled_items;
- if(!item)
- {
- hide_context_entries(menu, items, disabled_items);
- return;
- }
-
- items.push_back(std::string("Task Open"));
- if (!isItemCopyable())
- {
- disabled_items.push_back(std::string("Task Open"));
- }
-
- items.push_back(std::string("Task Properties"));
- if ((flags & FIRST_SELECTED_ITEM) == 0)
- {
- disabled_items.push_back(std::string("Task Properties"));
- }
- if(isItemRenameable())
- {
- items.push_back(std::string("Task Rename"));
- }
- if(isItemRemovable())
- {
- items.push_back(std::string("Task Remove"));
- }
-
-
- hide_context_entries(menu, items, disabled_items);
-}
-
-///----------------------------------------------------------------------------
/// LLTaskInvFVBridge impl
//----------------------------------------------------------------------------
@@ -1288,11 +1202,6 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory*
object_id,
object_name);
break;
- case LLAssetType::AT_MESH:
- new_bridge = new LLTaskMeshBridge(panel,
- object_id,
- object_name);
- break;
default:
LL_INFOS() << "Unhandled inventory type (llassetstorage.h): "
<< (S32)type << LL_ENDL;
@@ -1498,7 +1407,14 @@ void LLPanelObjectInventory::updateInventory()
mIsInventoryEmpty = TRUE;
}
- mHaveInventory = TRUE;
+ mHaveInventory = !mIsInventoryEmpty || !objectp->isInventoryDirty();
+ if (objectp->isInventoryDirty())
+ {
+ // Inventory is dirty, yet we received inventoryChanged() callback.
+ // User changed something during ongoing request.
+ // Rerequest. It will clear dirty flag and won't create dupplicate requests.
+ objectp->requestInventory();
+ }
}
else
{
@@ -1768,7 +1684,7 @@ void LLPanelObjectInventory::deleteAllChildren()
BOOL LLPanelObjectInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg)
{
- if (mFolders && mHaveInventory)
+ if (mFolders)
{
LLFolderViewItem* folderp = mFolders->getNextFromChild(NULL);
if (!folderp)
diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h
index d700c8f4cf..7b9ecfb8f3 100644
--- a/indra/newview/llpanelobjectinventory.h
+++ b/indra/newview/llpanelobjectinventory.h
@@ -106,9 +106,9 @@ private:
LLUUID mTaskUUID;
LLUUID mAttachmentUUID;
- BOOL mHaveInventory;
- BOOL mIsInventoryEmpty;
- BOOL mInventoryNeedsUpdate;
+ BOOL mHaveInventory; // 'Loading' label and used for initial request
+ BOOL mIsInventoryEmpty; // 'Empty' label
+ BOOL mInventoryNeedsUpdate; // for idle, set on changed callback
LLFolderViewModelInventory mInventoryViewModel;
};
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 617ca05281..be174475e1 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -54,7 +54,6 @@
#include "llcallingcard.h" // for LLAvatarTracker
#include "llcallbacklist.h"
#include "llerror.h"
-#include "llfacebookconnect.h"
#include "llfloateravatarpicker.h"
#include "llfriendcard.h"
#include "llgroupactions.h"
@@ -537,7 +536,6 @@ public:
LLPanelPeople::LLPanelPeople()
: LLPanel(),
- mTryToConnectToFacebook(true),
mTabContainer(NULL),
mOnlineFriendList(NULL),
mAllFriendList(NULL),
@@ -645,11 +643,9 @@ BOOL LLPanelPeople::postBuild()
// updater is active only if panel is visible to user.
friends_tab->setVisibleCallback(boost::bind(&Updater::setActive, mFriendListUpdater, _2));
friends_tab->setVisibleCallback(boost::bind(&LLPanelPeople::removePicker, this));
- friends_tab->setVisibleCallback(boost::bind(&LLPanelPeople::updateFacebookList, this, _2));
mOnlineFriendList = friends_tab->getChild<LLAvatarList>("avatars_online");
mAllFriendList = friends_tab->getChild<LLAvatarList>("avatars_all");
- mSuggestedFriends = friends_tab->getChild<LLAvatarList>("suggested_friends");
mOnlineFriendList->setNoItemsCommentText(getString("no_friends_online"));
mOnlineFriendList->setShowIcons("FriendsListShowIcons");
mOnlineFriendList->showPermissions("FriendsListShowPermissions");
@@ -685,7 +681,6 @@ BOOL LLPanelPeople::postBuild()
mRecentList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
mAllFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
mOnlineFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
- mSuggestedFriends->setContextMenu(&LLPanelPeopleMenus::gSuggestedFriendsContextMenu);
setSortOrder(mRecentList, (ESortOrder)gSavedSettings.getU32("RecentPeopleSortOrder"), false);
setSortOrder(mAllFriendList, (ESortOrder)gSavedSettings.getU32("FriendsSortOrder"), false);
@@ -764,7 +759,7 @@ void LLPanelPeople::updateFriendListHelpText()
// Seems sometimes all_friends can be empty because of issue with Inventory loading (clear cache, slow connection...)
// So, lets check all lists to avoid overlapping the text with online list. See EXT-6448.
- bool any_friend_exists = mAllFriendList->filterHasMatches() || mOnlineFriendList->filterHasMatches() || mSuggestedFriends->filterHasMatches();
+ bool any_friend_exists = mAllFriendList->filterHasMatches() || mOnlineFriendList->filterHasMatches();
no_friends_text->setVisible(!any_friend_exists);
if (no_friends_text->getVisible())
{
@@ -831,40 +826,9 @@ void LLPanelPeople::updateFriendList()
mAllFriendList->setDirty(true, !mAllFriendList->filterHasMatches());
//update trash and other buttons according to a selected item
updateButtons();
- updateSuggestedFriendList();
showFriendsAccordionsIfNeeded();
}
-bool LLPanelPeople::updateSuggestedFriendList()
-{
- const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
- uuid_vec_t& suggested_friends = mSuggestedFriends->getIDs();
- suggested_friends.clear();
-
- //Add suggested friends
- LLSD friends = LLFacebookConnect::instance().getContent();
- for (LLSD::array_const_iterator i = friends.beginArray(); i != friends.endArray(); ++i)
- {
- LLUUID agent_id = (*i).asUUID();
- bool second_life_buddy = agent_id.notNull() ? av_tracker.isBuddy(agent_id) : false;
-
- if(!second_life_buddy)
- {
- //FB+SL but not SL friend
- if (agent_id.notNull())
- {
- suggested_friends.push_back(agent_id);
- }
- }
- }
-
- //Force a refresh when there aren't any filter matches (prevent displaying content that shouldn't display)
- mSuggestedFriends->setDirty(true, !mSuggestedFriends->filterHasMatches());
- showFriendsAccordionsIfNeeded();
-
- return false;
-}
-
void LLPanelPeople::updateNearbyList()
{
if (!mNearbyList)
@@ -888,51 +852,6 @@ void LLPanelPeople::updateRecentList()
mRecentList->setDirty();
}
-bool LLPanelPeople::onConnectedToFacebook(const LLSD& data)
-{
- LLSD::Integer connection_state = data.get("enum").asInteger();
-
- if (connection_state == LLFacebookConnect::FB_CONNECTED)
- {
- LLFacebookConnect::instance().loadFacebookFriends();
- }
- else if(connection_state == LLFacebookConnect::FB_NOT_CONNECTED)
- {
- updateSuggestedFriendList();
- };
-
- return false;
-}
-
-void LLPanelPeople::updateFacebookList(bool visible)
-{
- if (visible)
- {
- LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLPanelPeople"); // just in case it is already listening
- LLEventPumps::instance().obtain("FacebookConnectContent").listen("LLPanelPeople", boost::bind(&LLPanelPeople::updateSuggestedFriendList, this));
-
- LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLPanelPeople"); // just in case it is already listening
- LLEventPumps::instance().obtain("FacebookConnectState").listen("LLPanelPeople", boost::bind(&LLPanelPeople::onConnectedToFacebook, this, _1));
-
- if (LLFacebookConnect::instance().isConnected())
- {
- LLFacebookConnect::instance().loadFacebookFriends();
- }
- else if(mTryToConnectToFacebook)
- {
- LLFacebookConnect::instance().checkConnectionToFacebook();
- mTryToConnectToFacebook = false;
- }
-
- updateSuggestedFriendList();
- }
- else
- {
- LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLPanelPeople");
- LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLPanelPeople");
- }
-}
-
void LLPanelPeople::updateButtons()
{
std::string cur_tab = getActiveTabName();
@@ -1151,11 +1070,9 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string)
mOnlineFriendList->setNameFilter(filter);
mAllFriendList->setNameFilter(filter);
- mSuggestedFriends->setNameFilter(filter);
setAccordionCollapsedByUser("tab_online", false);
setAccordionCollapsedByUser("tab_all", false);
- setAccordionCollapsedByUser("tab_suggested_friends", false);
showFriendsAccordionsIfNeeded();
// restore accordion tabs state _after_ all manipulations
@@ -1600,7 +1517,6 @@ void LLPanelPeople::showFriendsAccordionsIfNeeded()
// Expand and show accordions if needed, else - hide them
showAccordion("tab_online", mOnlineFriendList->filterHasMatches());
showAccordion("tab_all", mAllFriendList->filterHasMatches());
- showAccordion("tab_suggested_friends", mSuggestedFriends->filterHasMatches());
// Rearrange accordions
LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("friends_accordion");
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index c72c4fc08a..14205cebe2 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -57,8 +57,6 @@ public:
// when voice is available
/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
- bool mTryToConnectToFacebook;
-
// internals
class Updater;
@@ -80,10 +78,8 @@ private:
// methods indirectly called by the updaters
void updateFriendListHelpText();
void updateFriendList();
- bool updateSuggestedFriendList();
void updateNearbyList();
void updateRecentList();
- void updateFacebookList(bool visible);
bool isItemsFreeOfFriends(const uuid_vec_t& uuids);
@@ -131,8 +127,6 @@ private:
void onFriendListRefreshComplete(LLUICtrl*ctrl, const LLSD& param);
- bool onConnectedToFacebook(const LLSD& data);
-
void setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed);
void setAccordionCollapsedByUser(const std::string& name, bool collapsed);
bool isAccordionCollapsedByUser(LLUICtrl* acc_tab);
@@ -141,7 +135,6 @@ private:
LLTabContainer* mTabContainer;
LLAvatarList* mOnlineFriendList;
LLAvatarList* mAllFriendList;
- LLAvatarList* mSuggestedFriends;
LLAvatarList* mNearbyList;
LLAvatarList* mRecentList;
LLGroupList* mGroupList;
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index 65769ff526..42cecc9986 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -52,7 +52,6 @@ namespace LLPanelPeopleMenus
PeopleContextMenu gPeopleContextMenu;
NearbyPeopleContextMenu gNearbyPeopleContextMenu;
-SuggestedFriendsContextMenu gSuggestedFriendsContextMenu;
//== PeopleContextMenu ===============================================================
@@ -413,36 +412,4 @@ void NearbyPeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
hide_context_entries(menu, items, disabled_items);
}
-//== SuggestedFriendsContextMenu ===============================================================
-
-LLContextMenu* SuggestedFriendsContextMenu::createMenu()
-{
- // set up the callbacks for all of the avatar menu items
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
- LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
- LLContextMenu* menu;
-
- // Set up for one person selected menu
- const LLUUID& id = mUUIDs.front();
- registrar.add("Avatar.Profile", boost::bind(&LLAvatarActions::showProfile, id));
- registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, id));
-
- // create the context menu from the XUI
- menu = createFromFile("menu_people_nearby.xml");
- buildContextMenu(*menu, 0x0);
-
- return menu;
-}
-
-void SuggestedFriendsContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
-{
- menuentry_vec_t items;
- menuentry_vec_t disabled_items;
-
- items.push_back(std::string("view_profile"));
- items.push_back(std::string("add_friend"));
-
- hide_context_entries(menu, items, disabled_items);
-}
-
} // namespace LLPanelPeopleMenus
diff --git a/indra/newview/llpanelpeoplemenus.h b/indra/newview/llpanelpeoplemenus.h
index 5ed20e0064..3bc1f8caf7 100644
--- a/indra/newview/llpanelpeoplemenus.h
+++ b/indra/newview/llpanelpeoplemenus.h
@@ -62,21 +62,8 @@ protected:
/*virtual*/ void buildContextMenu(class LLMenuGL& menu, U32 flags);
};
-/**
- * Menu used in the suggested friends list.
- */
-class SuggestedFriendsContextMenu : public PeopleContextMenu
-{
-public:
- /*virtual*/ LLContextMenu * createMenu();
-
-protected:
- /*virtual*/ void buildContextMenu(class LLMenuGL& menu, U32 flags);
-};
-
extern PeopleContextMenu gPeopleContextMenu;
extern NearbyPeopleContextMenu gNearbyPeopleContextMenu;
-extern SuggestedFriendsContextMenu gSuggestedFriendsContextMenu;
} // namespace LLPanelPeopleMenus
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index 610b3a6396..104316e253 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -563,11 +563,8 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
mSaleToText->setText(getString("anyone"));
}
- const U8* sign = (U8*)getString("price_text").c_str();
- const U8* sqm = (U8*)getString("area_text").c_str();
-
- mSalesPriceText->setText(llformat("%s%d ", sign, parcel->getSalePrice()));
- mAreaText->setText(llformat("%d %s", area, sqm));
+ mSalesPriceText->setText(llformat("%s%d ", getString("price_text").c_str(), parcel->getSalePrice()));
+ mAreaText->setText(llformat("%d %s", area, getString("area_text").c_str()));
mTrafficText->setText(llformat("%.0f", dwell));
// Can't have more than region max tasks, regardless of parcel
@@ -575,10 +572,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
S32 primitives = llmin(ll_round(parcel->getMaxPrimCapacity() * parcel->getParcelPrimBonus()),
(S32)region->getMaxTasks());
- const U8* available = (U8*)getString("available").c_str();
- const U8* allocated = (U8*)getString("allocated").c_str();
-
- mPrimitivesText->setText(llformat("%d %s, %d %s", primitives, available, parcel->getPrimCount(), allocated));
+ mPrimitivesText->setText(llformat("%d %s, %d %s", primitives, getString("available").c_str(), parcel->getPrimCount(), getString("allocated").c_str()));
if (parcel->getAllowOtherScripts())
{
diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp
index 95c14e4226..23747a8efd 100644
--- a/indra/newview/llpanelsnapshotoptions.cpp
+++ b/indra/newview/llpanelsnapshotoptions.cpp
@@ -32,7 +32,6 @@
#include "llfloatersnapshot.h" // FIXME: create a snapshot model
#include "llfloaterreg.h"
-#include "llfloaterfacebook.h"
#include "llfloaterflickr.h"
#include "llfloatertwitter.h"
@@ -59,7 +58,6 @@ private:
void onSaveToEmail();
void onSaveToInventory();
void onSaveToComputer();
- void onSendToFacebook();
void onSendToTwitter();
void onSendToFlickr();
@@ -74,7 +72,6 @@ LLPanelSnapshotOptions::LLPanelSnapshotOptions()
mCommitCallbackRegistrar.add("Snapshot.SaveToEmail", boost::bind(&LLPanelSnapshotOptions::onSaveToEmail, this));
mCommitCallbackRegistrar.add("Snapshot.SaveToInventory", boost::bind(&LLPanelSnapshotOptions::onSaveToInventory, this));
mCommitCallbackRegistrar.add("Snapshot.SaveToComputer", boost::bind(&LLPanelSnapshotOptions::onSaveToComputer, this));
- mCommitCallbackRegistrar.add("Snapshot.SendToFacebook", boost::bind(&LLPanelSnapshotOptions::onSendToFacebook, this));
mCommitCallbackRegistrar.add("Snapshot.SendToTwitter", boost::bind(&LLPanelSnapshotOptions::onSendToTwitter, this));
mCommitCallbackRegistrar.add("Snapshot.SendToFlickr", boost::bind(&LLPanelSnapshotOptions::onSendToFlickr, this));
LLGlobalEconomy::getInstance()->addObserver(this);
@@ -138,18 +135,6 @@ void LLPanelSnapshotOptions::onSaveToComputer()
openPanel("panel_snapshot_local");
}
-void LLPanelSnapshotOptions::onSendToFacebook()
-{
- LLFloaterReg::hideInstance("snapshot");
-
- LLFloaterFacebook* facebook_floater = dynamic_cast<LLFloaterFacebook*>(LLFloaterReg::getInstance("facebook"));
- if (facebook_floater)
- {
- facebook_floater->showPhotoPanel();
- }
- LLFloaterReg::showInstance("facebook");
-}
-
void LLPanelSnapshotOptions::onSendToTwitter()
{
LLFloaterReg::hideInstance("snapshot");
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index d4a8bbdf45..1533a27469 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -32,6 +32,7 @@
#include "llagent.h"
#include "lldraghandle.h"
+#include "llexternaleditor.h"
#include "llviewerwindow.h"
#include "llbutton.h"
#include "llfloaterreg.h"
@@ -43,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"
@@ -63,7 +65,8 @@
// Default constructor
LLPreviewNotecard::LLPreviewNotecard(const LLSD& key) //const LLUUID& item_id,
- : LLPreview( key )
+ : LLPreview( key ),
+ mLiveFile(NULL)
{
const LLInventoryItem *item = getItem();
if (item)
@@ -74,13 +77,14 @@ LLPreviewNotecard::LLPreviewNotecard(const LLSD& key) //const LLUUID& item_id,
LLPreviewNotecard::~LLPreviewNotecard()
{
+ delete mLiveFile;
}
BOOL LLPreviewNotecard::postBuild()
{
- LLViewerTextEditor *ed = getChild<LLViewerTextEditor>("Notecard Editor");
- ed->setNotecardInfo(mItemUUID, mObjectID, getKey());
- ed->makePristine();
+ mEditor = getChild<LLViewerTextEditor>("Notecard Editor");
+ mEditor->setNotecardInfo(mItemUUID, mObjectID, getKey());
+ mEditor->makePristine();
childSetAction("Save", onClickSave, this);
getChildView("lock")->setVisible( FALSE);
@@ -88,6 +92,8 @@ BOOL LLPreviewNotecard::postBuild()
childSetAction("Delete", onClickDelete, this);
getChildView("Delete")->setEnabled(false);
+ childSetAction("Edit", onClickEdit, this);
+
const LLInventoryItem* item = getItem();
childSetCommitCallback("desc", LLPreview::onText, this);
@@ -408,6 +414,16 @@ void LLPreviewNotecard::onClickDelete(void* user_data)
}
}
+// static
+void LLPreviewNotecard::onClickEdit(void* user_data)
+{
+ LLPreviewNotecard* preview = (LLPreviewNotecard*)user_data;
+ if (preview)
+ {
+ preview->openInExternalEditor();
+ }
+}
+
struct LLSaveNotecardInfo
{
LLPreviewNotecard* mSelf;
@@ -468,7 +484,7 @@ void LLPreviewNotecard::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUI
}
}
-bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
+bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem, bool sync)
{
LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor");
@@ -487,7 +503,10 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
}
editor->makePristine();
-
+ if (sync)
+ {
+ syncExternal();
+ }
const LLInventoryItem* item = getItem();
// save it out to database
if (item)
@@ -566,6 +585,18 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
return true;
}
+void LLPreviewNotecard::syncExternal()
+{
+ // Sync with external editor.
+ std::string tmp_file = getTmpFileName();
+ llstat s;
+ if (LLFile::stat(tmp_file, &s) == 0) // file exists
+ {
+ if (mLiveFile) mLiveFile->ignoreNextUpdate();
+ writeToFile(tmp_file);
+ }
+}
+
void LLPreviewNotecard::deleteNotecard()
{
LLNotificationsUtil::add("DeleteNotecard", LLSD(), LLSD(), boost::bind(&LLPreviewNotecard::handleConfirmDeleteDialog,this, _1, _2));
@@ -714,4 +745,128 @@ bool LLPreviewNotecard::handleConfirmDeleteDialog(const LLSD& notification, cons
return false;
}
+void LLPreviewNotecard::openInExternalEditor()
+{
+ delete mLiveFile; // deletes file
+
+ // Save the notecard to a temporary file.
+ std::string filename = getTmpFileName();
+ writeToFile(filename);
+
+ // Start watching file changes.
+ mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLPreviewNotecard::onExternalChange, this, _1));
+ mLiveFile->addToEventTimer();
+
+ // Open it in external editor.
+ {
+ LLExternalEditor ed;
+ LLExternalEditor::EErrorCode status;
+ std::string msg;
+
+ status = ed.setCommand("LL_SCRIPT_EDITOR");
+ if (status != LLExternalEditor::EC_SUCCESS)
+ {
+ if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error.
+ {
+ msg = LLTrans::getString("ExternalEditorNotSet");
+ }
+ else
+ {
+ msg = LLExternalEditor::getErrorMessage(status);
+ }
+
+ LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg));
+ return;
+ }
+
+ status = ed.run(filename);
+ if (status != LLExternalEditor::EC_SUCCESS)
+ {
+ msg = LLExternalEditor::getErrorMessage(status);
+ LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg));
+ }
+ }
+}
+
+bool LLPreviewNotecard::onExternalChange(const std::string& filename)
+{
+ if (!loadNotecardText(filename))
+ {
+ return false;
+ }
+
+ // Disable sync to avoid recursive load->save->load calls.
+ saveIfNeeded(NULL, false);
+ return true;
+}
+
+bool LLPreviewNotecard::loadNotecardText(const std::string& filename)
+{
+ if (filename.empty())
+ {
+ LL_WARNS() << "Empty file name" << LL_ENDL;
+ return false;
+ }
+
+ LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
+ if (!file)
+ {
+ LL_WARNS() << "Error opening " << filename << LL_ENDL;
+ return false;
+ }
+
+ // read in the whole file
+ fseek(file, 0L, SEEK_END);
+ size_t file_length = (size_t)ftell(file);
+ fseek(file, 0L, SEEK_SET);
+ char* buffer = new char[file_length + 1];
+ size_t nread = fread(buffer, 1, file_length, file);
+ if (nread < file_length)
+ {
+ LL_WARNS() << "Short read" << LL_ENDL;
+ }
+ buffer[nread] = '\0';
+ fclose(file);
+
+ mEditor->setText(LLStringExplicit(buffer));
+ delete[] buffer;
+
+ return true;
+}
+
+bool LLPreviewNotecard::writeToFile(const std::string& filename)
+{
+ LLFILE* fp = LLFile::fopen(filename, "wb");
+ if (!fp)
+ {
+ LL_WARNS() << "Unable to write to " << filename << LL_ENDL;
+ return false;
+ }
+
+ std::string utf8text = mEditor->getText();
+
+ if (utf8text.size() == 0)
+ {
+ utf8text = " ";
+ }
+
+ fputs(utf8text.c_str(), fp);
+ fclose(fp);
+ return true;
+}
+
+
+std::string LLPreviewNotecard::getTmpFileName()
+{
+ std::string notecard_id = mObjectID.asString() + "_" + mItemUUID.asString();
+
+ // Use MD5 sum to make the file name shorter and not exceed maximum path length.
+ char notecard_id_hash_str[33]; /* Flawfinder: ignore */
+ LLMD5 notecard_id_hash((const U8 *)notecard_id.c_str());
+ notecard_id_hash.hex_digest(notecard_id_hash_str);
+
+ return std::string(LLFile::tmpdir()) + "sl_notecard_" + notecard_id_hash_str + ".txt";
+}
+
+
// EOF
diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h
index 46a6d0ef50..d9c14815c1 100644
--- a/indra/newview/llpreviewnotecard.h
+++ b/indra/newview/llpreviewnotecard.h
@@ -29,6 +29,7 @@
#include "llpreview.h"
#include "llassetstorage.h"
+#include "llpreviewscript.h"
#include "lliconctrl.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -47,18 +48,18 @@ public:
virtual ~LLPreviewNotecard();
bool saveItem();
- void setObjectID(const LLUUID& object_id);
+ void setObjectID(const LLUUID& object_id) override;
// llview
- virtual void draw();
- virtual BOOL handleKeyHere(KEY key, MASK mask);
- virtual void setEnabled( BOOL enabled );
+ void draw() override;
+ BOOL handleKeyHere(KEY key, MASK mask) override;
+ void setEnabled( BOOL enabled ) override;
// llfloater
- virtual BOOL canClose();
+ BOOL canClose() override;
// llpanel
- virtual BOOL postBuild();
+ BOOL postBuild() override;
// reach into the text editor, and grab the drag item
const LLInventoryItem* getDragItem();
@@ -72,11 +73,13 @@ public:
// asset system. :(
void refreshFromInventory(const LLUUID& item_id = LLUUID::null);
+ void syncExternal();
+
protected:
- void updateTitleButtons();
- virtual void loadAsset();
- bool saveIfNeeded(LLInventoryItem* copyitem = NULL);
+ void updateTitleButtons() override;
+ void loadAsset() override;
+ bool saveIfNeeded(LLInventoryItem* copyitem = NULL, bool sync = true);
void deleteNotecard();
@@ -89,6 +92,8 @@ protected:
static void onClickDelete(void* data);
+ static void onClickEdit(void* data);
+
static void onSaveComplete(const LLUUID& asset_uuid,
void* user_data,
S32 status, LLExtStat ext_status);
@@ -99,6 +104,12 @@ protected:
static void finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId);
static void finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId);
+ void openInExternalEditor();
+ bool onExternalChange(const std::string& filename);
+ bool loadNotecardText(const std::string& filename);
+ bool writeToFile(const std::string& filename);
+ std::string getTmpFileName();
+
protected:
LLViewerTextEditor* mEditor;
LLButton* mSaveBtn;
@@ -106,6 +117,8 @@ protected:
LLUUID mAssetID;
LLUUID mObjectID;
+
+ LLLiveLSLFile* mLiveFile;
};
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 9431914ba3..f1bb0bc27d 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -41,7 +41,6 @@
#include "llinventorymodel.h"
#include "llkeyboard.h"
#include "lllineeditor.h"
-#include "lllivefile.h"
#include "llhelp.h"
#include "llnotificationsutil.h"
#include "llresmgr.h"
@@ -120,22 +119,6 @@ static bool have_script_upload_cap(LLUUID& object_id)
/// ---------------------------------------------------------------------------
/// LLLiveLSLFile
/// ---------------------------------------------------------------------------
-class LLLiveLSLFile : public LLLiveFile
-{
-public:
- typedef boost::function<bool (const std::string& filename)> change_callback_t;
-
- LLLiveLSLFile(std::string file_path, change_callback_t change_cb);
- ~LLLiveLSLFile();
-
- void ignoreNextUpdate() { mIgnoreNextUpdate = true; }
-
-protected:
- /*virtual*/ bool loadFile();
-
- change_callback_t mOnChangeCallback;
- bool mIgnoreNextUpdate;
-};
LLLiveLSLFile::LLLiveLSLFile(std::string file_path, change_callback_t change_cb)
: mOnChangeCallback(change_cb)
@@ -1069,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/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 69cf9d9158..74e4c00d43 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -34,6 +34,7 @@
#include "lliconctrl.h"
#include "llframetimer.h"
#include "llfloatergotoline.h"
+#include "lllivefile.h"
#include "llsyntaxid.h"
class LLLiveLSLFile;
@@ -53,6 +54,23 @@ class LLScriptEdContainer;
class LLFloaterGotoLine;
class LLFloaterExperienceProfile;
+class LLLiveLSLFile : public LLLiveFile
+{
+public:
+ typedef boost::function<bool(const std::string& filename)> change_callback_t;
+
+ LLLiveLSLFile(std::string file_path, change_callback_t change_cb);
+ ~LLLiveLSLFile();
+
+ void ignoreNextUpdate() { mIgnoreNextUpdate = true; }
+
+protected:
+ /*virtual*/ bool loadFile();
+
+ change_callback_t mOnChangeCallback;
+ bool mIgnoreNextUpdate;
+};
+
// Inner, implementation class. LLPreviewScript and LLLiveLSLEditor each own one of these.
class LLScriptEdCore : public LLPanel
{
diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp
index de90896548..93143eb33f 100644
--- a/indra/newview/llsearchableui.cpp
+++ b/indra/newview/llsearchableui.cpp
@@ -125,17 +125,13 @@ void ll::statusbar::SearchableItem::setNotHighlighted( )
}
}
-bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter )
+bool ll::statusbar::SearchableItem::hightlightAndHide(LLWString const &aFilter, bool hide)
{
- if( mMenu && !mMenu->getVisible() && !mWasHiddenBySearch )
+ if ((mMenu && !mMenu->getVisible() && !mWasHiddenBySearch) || dynamic_cast<LLMenuItemTearOffGL*>(mMenu))
return false;
setNotHighlighted( );
- bool bVisible(false);
- for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr )
- bVisible |= (*itr)->hightlightAndHide( aFilter );
-
if( aFilter.empty() )
{
if( mCtrl )
@@ -143,17 +139,22 @@ bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter
return true;
}
+ bool bHighlighted(!hide);
if( mLabel.find( aFilter ) != LLWString::npos )
{
if( mCtrl )
mCtrl->setHighlighted( true );
- return true;
+ bHighlighted = true;
}
- if( mCtrl && !bVisible )
+ bool bVisible(false);
+ for (tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr)
+ bVisible |= (*itr)->hightlightAndHide(aFilter, !bHighlighted);
+
+ if (mCtrl && !bVisible && !bHighlighted)
{
mWasHiddenBySearch = true;
mMenu->setVisible(FALSE);
}
- return bVisible;
+ return bVisible || bHighlighted;
}
diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h
index 42b2866fb6..9741557e49 100644
--- a/indra/newview/llsearchableui.h
+++ b/indra/newview/llsearchableui.h
@@ -107,7 +107,7 @@ namespace ll
SearchableItem();
void setNotHighlighted( );
- bool hightlightAndHide( LLWString const &aFilter );
+ bool hightlightAndHide( LLWString const &aFilter, bool hide = true );
};
struct SearchData
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 816515426a..90f8f84ea4 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -3864,6 +3864,14 @@ BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& r
return TRUE;
}
+BOOL LLSelectMgr::isSelfAvatarSelected()
+{
+ if (mAllowSelectAvatar)
+ {
+ return (getSelection()->getObjectCount() == 1) && (getSelection()->getFirstRootObject() == gAgentAvatarp);
+ }
+ return FALSE;
+}
//--------------------------------------------------------------------
// Duplicate objects
@@ -3886,6 +3894,17 @@ void LLSelectMgr::selectDuplicate(const LLVector3& offset, BOOL select_copy)
make_ui_sound("UISndInvalidOp");
return;
}
+ if (!canDuplicate())
+ {
+ LLSelectNode* node = getSelection()->getFirstRootNode(NULL, true);
+ if (node)
+ {
+ LLSD args;
+ args["OBJ_NAME"] = node->mName;
+ LLNotificationsUtil::add("NoCopyPermsNoObject", args);
+ return;
+ }
+ }
LLDuplicateData data;
data.offset = offset;
@@ -6765,8 +6784,28 @@ void LLSelectMgr::pauseAssociatedAvatars()
mSelectedObjects->mSelectType = getSelectTypeForObject(object);
+ bool is_attached = false;
if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT &&
- isAgentAvatarValid() && object->getParent() != NULL)
+ isAgentAvatarValid())
+ {
+ // Selection can be obsolete, confirm that this is an attachment
+ LLViewerObject* parent = (LLViewerObject*)object->getParent();
+ while (parent != NULL)
+ {
+ if (parent->isAvatar())
+ {
+ is_attached = true;
+ break;
+ }
+ else
+ {
+ parent = (LLViewerObject*)parent->getParent();
+ }
+ }
+ }
+
+
+ if (is_attached)
{
if (object->isAnimatedObject())
{
@@ -6784,14 +6823,12 @@ void LLSelectMgr::pauseAssociatedAvatars()
mPauseRequests.push_back(gAgentAvatarp->requestPause());
}
}
- else
+ else if (object && object->isAnimatedObject() && object->getControlAvatar())
{
- if (object && object->isAnimatedObject() && object->getControlAvatar())
- {
- // Is a non-attached animated object. Pause the control avatar.
- mPauseRequests.push_back(object->getControlAvatar()->requestPause());
- }
+ // Is a non-attached animated object. Pause the control avatar.
+ mPauseRequests.push_back(object->getControlAvatar()->requestPause());
}
+
}
}
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index ce0fee8803..3e8bfdb00e 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -714,6 +714,8 @@ public:
LLPermissions* findObjectPermissions(const LLViewerObject* object);
+ BOOL isSelfAvatarSelected();
+
void selectDelete(); // Delete on simulator
void selectForceDelete(); // just delete, no into trash
void selectDuplicate(const LLVector3& offset, BOOL select_copy); // Duplicate on simulator
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 689734e36a..ea7e649792 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -564,6 +564,7 @@ void LLSidepanelInventory::updateVerbs()
mWearBtn->setEnabled(FALSE);
mPlayBtn->setVisible(FALSE);
mPlayBtn->setEnabled(FALSE);
+ mPlayBtn->setToolTip(std::string(""));
mTeleportBtn->setVisible(FALSE);
mTeleportBtn->setEnabled(FALSE);
mShopBtn->setVisible(TRUE);
@@ -588,11 +589,23 @@ void LLSidepanelInventory::updateVerbs()
mShopBtn->setVisible(FALSE);
break;
case LLInventoryType::IT_SOUND:
+ mPlayBtn->setVisible(TRUE);
+ mPlayBtn->setEnabled(TRUE);
+ mPlayBtn->setToolTip(LLTrans::getString("InventoryPlaySoundTooltip"));
+ mShopBtn->setVisible(FALSE);
+ break;
case LLInventoryType::IT_GESTURE:
+ mPlayBtn->setVisible(TRUE);
+ mPlayBtn->setEnabled(TRUE);
+ mPlayBtn->setToolTip(LLTrans::getString("InventoryPlayGestureTooltip"));
+ mShopBtn->setVisible(FALSE);
+ break;
case LLInventoryType::IT_ANIMATION:
mPlayBtn->setVisible(TRUE);
mPlayBtn->setEnabled(TRUE);
- mShopBtn->setVisible(FALSE);
+ mPlayBtn->setEnabled(TRUE);
+ mPlayBtn->setToolTip(LLTrans::getString("InventoryPlayAnimationTooltip"));
+ mShopBtn->setVisible(FALSE);
break;
case LLInventoryType::IT_LANDMARK:
mTeleportBtn->setVisible(TRUE);
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index 5a40af14a3..f5fea9dece 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -34,7 +34,6 @@
#include "lleconomy.h"
#include "llfloaterperms.h"
#include "llfloaterreg.h"
-#include "llfloaterfacebook.h"
#include "llfloaterflickr.h"
#include "llfloatertwitter.h"
#include "llimagefilter.h"
@@ -572,7 +571,7 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
if (mThumbnailSubsampled)
{
- // The thumbnail is be a subsampled version of the preview (used in SL Share previews, i.e. Flickr, Twitter, Facebook)
+ // The thumbnail is be a subsampled version of the preview (used in SL Share previews, i.e. Flickr, Twitter)
raw->resize( mPreviewImage->getWidth(),
mPreviewImage->getHeight(),
mPreviewImage->getComponents());
@@ -638,7 +637,7 @@ LLViewerTexture* LLSnapshotLivePreview::getBigThumbnailImage()
if (raw)
{
- // The big thumbnail is a new filtered version of the preview (used in SL Share previews, i.e. Flickr, Twitter, Facebook)
+ // The big thumbnail is a new filtered version of the preview (used in SL Share previews, i.e. Flickr, Twitter)
mBigThumbnailWidth = mPreviewImage->getWidth();
mBigThumbnailHeight = mPreviewImage->getHeight();
raw->resize( mBigThumbnailWidth,
diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp
index d28a7cc048..f6cf714db4 100644
--- a/indra/newview/llsurfacepatch.cpp
+++ b/indra/newview/llsurfacepatch.cpp
@@ -99,7 +99,7 @@ void LLSurfacePatch::dirty()
}
else
{
- LL_WARNS() << "No viewer object for this surface patch!" << LL_ENDL;
+ LL_WARNS("Terrain") << "No viewer object for this surface patch!" << LL_ENDL;
}
mDirtyZStats = TRUE;
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index c9133338fb..f6cb787156 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -66,6 +66,7 @@ bool LLTextureFetchDebugger::sDebuggerEnabled = false ;
LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheHit("texture_cache_hit");
LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheAttempt("texture_cache_attempt");
+LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > LLTextureFetch::sCacheHitRate("texture_cache_hits");
LLTrace::SampleStatHandle<F32Seconds> LLTextureFetch::sCacheReadLatency("texture_cache_read_latency");
LLTrace::SampleStatHandle<F32Seconds> LLTextureFetch::sTexDecodeLatency("texture_decode_latency");
@@ -1311,6 +1312,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
LL_DEBUGS(LOG_TXT) << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()
<< " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight())
<< " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL;
+ record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(1));
}
else
{
@@ -1326,7 +1328,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
LL_DEBUGS(LOG_TXT) << mID << ": Not in Cache" << LL_ENDL;
setState(LOAD_FROM_NETWORK);
}
-
+ record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(0));
// fall through
}
}
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index a01c01847e..cdf8868597 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -312,6 +312,7 @@ public:
static LLTrace::SampleStatHandle<F32Seconds> sCacheReadLatency;
static LLTrace::SampleStatHandle<F32Seconds> sTexDecodeLatency;
static LLTrace::SampleStatHandle<F32Seconds> sTexFetchLatency;
+ static LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > sCacheHitRate;
private:
LLMutex mQueueMutex; //to protect mRequestMap and mCommands only
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index 392c103d7c..f9c327b46e 100644
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -267,7 +267,7 @@ BOOL LLToolCompTranslate::handleHover(S32 x, S32 y, MASK mask)
BOOL LLToolCompTranslate::handleMouseDown(S32 x, S32 y, MASK mask)
{
mMouseDown = TRUE;
- gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE);
+ gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE, LLFloaterReg::instanceVisible("build"));
return TRUE;
}
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index f184b22ccb..2a87bce134 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -111,9 +111,64 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
mMouseOutsideSlop = FALSE;
mMouseDownX = x;
mMouseDownY = y;
+ LLTimer pick_timer;
+ BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
+ 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;
- //left mouse down always picks transparent (but see handleMouseUp)
- mPick = gViewerWindow->pickImmediate(x, y, TRUE, FALSE);
mPick.mKeyMask = mask;
mMouseButtonDown = true;
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index 1936e24761..e424983cf8 100644
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -38,8 +38,12 @@
#include "llcoros.h"
#include "reader.h"
#include "llcorehttputil.h"
+#include "llurlregistry.h"
+static const std::string BING_NOTRANSLATE_OPENING_TAG("<div class=\"notranslate\">");
+static const std::string BING_NOTRANSLATE_CLOSING_TAG("</div>");
+
/**
* Handler of an HTTP machine translation service.
*
@@ -99,6 +103,8 @@ public:
*/
virtual bool isConfigured() const = 0;
+ virtual LLTranslate::EService getCurrentService() = 0;
+
virtual void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc) = 0;
virtual void translateMessage(LanguagePair_t fromTo, std::string msg, LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure);
@@ -248,6 +254,8 @@ public:
std::string& err_msg) const;
/*virtual*/ bool isConfigured() const;
+ /*virtual*/ LLTranslate::EService getCurrentService() { return LLTranslate::EService::SERVICE_GOOGLE; }
+
/*virtual*/ void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc);
private:
@@ -409,6 +417,8 @@ public:
std::string& err_msg) const;
/*virtual*/ bool isConfigured() const;
+ /*virtual*/ LLTranslate::EService getCurrentService() { return LLTranslate::EService::SERVICE_BING; }
+
/*virtual*/ void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc);
private:
static std::string getAPIKey();
@@ -520,7 +530,59 @@ void LLTranslate::translateMessage(const std::string &from_lang, const std::stri
{
LLTranslationAPIHandler& handler = getPreferredHandler();
- handler.translateMessage(LLTranslationAPIHandler::LanguagePair_t(from_lang, to_lang), mesg, success, failure);
+ handler.translateMessage(LLTranslationAPIHandler::LanguagePair_t(from_lang, to_lang), addNoTranslateTags(mesg), success, failure);
+}
+
+std::string LLTranslate::addNoTranslateTags(std::string mesg)
+{
+ if (getPreferredHandler().getCurrentService() != SERVICE_BING)
+ {
+ return mesg;
+ }
+
+ std::string upd_msg(mesg);
+ LLUrlMatch match;
+ S32 dif = 0;
+ //surround all links (including SLURLs) with 'no-translate' tags to prevent unnecessary translation
+ while (LLUrlRegistry::instance().findUrl(mesg, match))
+ {
+ upd_msg.insert(dif + match.getStart(), BING_NOTRANSLATE_OPENING_TAG);
+ upd_msg.insert(dif + BING_NOTRANSLATE_OPENING_TAG.size() + match.getEnd() + 1, BING_NOTRANSLATE_CLOSING_TAG);
+ mesg.erase(match.getStart(), match.getEnd() - match.getStart());
+ dif += match.getEnd() - match.getStart() + BING_NOTRANSLATE_OPENING_TAG.size() + BING_NOTRANSLATE_CLOSING_TAG.size();
+ }
+ return upd_msg;
+}
+
+std::string LLTranslate::removeNoTranslateTags(std::string mesg)
+{
+ if (getPreferredHandler().getCurrentService() != SERVICE_BING)
+ {
+ return mesg;
+ }
+ std::string upd_msg(mesg);
+ LLUrlMatch match;
+ S32 opening_tag_size = BING_NOTRANSLATE_OPENING_TAG.size();
+ S32 closing_tag_size = BING_NOTRANSLATE_CLOSING_TAG.size();
+ S32 dif = 0;
+ //remove 'no-translate' tags we added to the links before
+ while (LLUrlRegistry::instance().findUrl(mesg, match))
+ {
+ if (upd_msg.substr(dif + match.getStart() - opening_tag_size, opening_tag_size) == BING_NOTRANSLATE_OPENING_TAG)
+ {
+ upd_msg.erase(dif + match.getStart() - opening_tag_size, opening_tag_size);
+ dif -= opening_tag_size;
+
+ if (upd_msg.substr(dif + match.getEnd() + 1, closing_tag_size) == BING_NOTRANSLATE_CLOSING_TAG)
+ {
+ upd_msg.replace(dif + match.getEnd() + 1, closing_tag_size, " ");
+ dif -= closing_tag_size - 1;
+ }
+ }
+ mesg.erase(match.getStart(), match.getUrl().size());
+ dif += match.getUrl().size();
+ }
+ return upd_msg;
}
/*static*/
diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h
index bf431cdfbb..e0722fbd83 100644
--- a/indra/newview/lltranslate.h
+++ b/indra/newview/lltranslate.h
@@ -91,6 +91,9 @@ public :
*/
static bool isTranslationConfigured();
+ static std::string addNoTranslateTags(std::string mesg);
+ static std::string removeNoTranslateTags(std::string mesg);
+
private:
static LLTranslationAPIHandler& getPreferredHandler();
static LLTranslationAPIHandler& getHandler(EService service);
diff --git a/indra/newview/lltwitterconnect.cpp b/indra/newview/lltwitterconnect.cpp
index 5d598aaebe..b2d2fa9d77 100644
--- a/indra/newview/lltwitterconnect.cpp
+++ b/indra/newview/lltwitterconnect.cpp
@@ -28,6 +28,7 @@
#include "llviewerprecompiledheaders.h"
#include "lltwitterconnect.h"
+#include "llflickrconnect.h"
#include "llagent.h"
#include "llcallingcard.h" // for LLAvatarTracker
@@ -65,6 +66,49 @@ void toast_user_for_twitter_success()
LLNotificationsUtil::add("TwitterConnect", args);
}
+class LLTwitterConnectHandler : public LLCommandHandler
+{
+public:
+ LLTwitterConnectHandler() : LLCommandHandler("fbc", UNTRUSTED_THROTTLE) {}
+
+ bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
+ {
+ if (tokens.size() >= 1)
+ {
+ if (tokens[0].asString() == "connect")
+ {
+ if (tokens.size() >= 2 && tokens[1].asString() == "twitter")
+ {
+ // this command probably came from the twitter_web browser, so close it
+ LLFloaterReg::hideInstance("twitter_web");
+
+ // connect to twitter
+ if (query_map.has("oauth_token"))
+ {
+ LLTwitterConnect::instance().connectToTwitter(query_map["oauth_token"], query_map.get("oauth_verifier"));
+ }
+ return true;
+ }
+ else if (tokens.size() >= 2 && tokens[1].asString() == "flickr")
+ {
+ // this command probably came from the flickr_web browser, so close it
+ LLFloaterReg::hideInstance("flickr_web");
+
+ // connect to flickr
+ if (query_map.has("oauth_token"))
+ {
+ LLFlickrConnect::instance().connectToFlickr(query_map["oauth_token"], query_map.get("oauth_verifier"));
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+};
+LLTwitterConnectHandler gTwitterConnectHandler;
+
+
///////////////////////////////////////////////////////////////////////////////
//
void LLTwitterConnect::twitterConnectCoro(std::string requestToken, std::string oauthVerifier)
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/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 64f6123f5d..e2554bc9bc 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -237,6 +237,7 @@ void display_stats()
static LLTrace::BlockTimerStatHandle FTM_PICK("Picking");
static LLTrace::BlockTimerStatHandle FTM_RENDER("Render");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_HUD("Render HUD");
static LLTrace::BlockTimerStatHandle FTM_UPDATE_SKY("Update Sky");
static LLTrace::BlockTimerStatHandle FTM_UPDATE_DYNAMIC_TEXTURES("Update Dynamic Textures");
static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE("Update Images");
@@ -568,6 +569,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (gDisconnected)
{
LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected");
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
render_ui();
swap();
}
@@ -1293,7 +1295,8 @@ void render_ui(F32 zoom_factor, int subfield)
{
gPipeline.renderBloom(gSnapshot, zoom_factor, subfield);
}
-
+
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD);
render_hud_elements();
render_hud_attachments();
}
@@ -1308,8 +1311,6 @@ void render_ui(F32 zoom_factor, int subfield)
gGL.color4f(1,1,1,1);
if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
-
if (!gDisconnected)
{
render_ui_3d();
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index f4db81c826..193ee17912 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -67,7 +67,6 @@
#include "llfloaterexperiences.h"
#include "llfloaterexperiencepicker.h"
#include "llfloaterevent.h"
-#include "llfloaterfacebook.h"
#include "llfloaterflickr.h"
#include "llfloaterfonttest.h"
#include "llfloatergesture.h"
@@ -355,11 +354,9 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
LLFloaterReg::add("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
- LLFloaterReg::add("fbc_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
LLFloaterReg::add("flickr_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
LLFloaterReg::add("twitter_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
- LLFloaterReg::add("facebook", "floater_facebook.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFacebook>);
LLFloaterReg::add("flickr", "floater_flickr.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFlickr>);
LLFloaterReg::add("twitter", "floater_twitter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTwitter>);
LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>);
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index b89e1497a1..e930eb20d3 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -64,7 +64,12 @@ LLViewerKeyboard gViewerKeyboard;
void agent_jump( EKeystate s )
{
- if( KEYSTATE_UP == s ) return;
+ static BOOL first_fly_attempt(TRUE);
+ if (KEYSTATE_UP == s)
+ {
+ first_fly_attempt = TRUE;
+ return;
+ }
F32 time = gKeyboard->getCurKeyElapsedTime();
S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount());
@@ -77,7 +82,8 @@ void agent_jump( EKeystate s )
}
else
{
- gAgent.setFlying(TRUE);
+ gAgent.setFlying(TRUE, first_fly_attempt);
+ first_fly_attempt = FALSE;
gAgent.moveUp(1);
}
}
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index d8745b1eca..a27a083a2a 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1707,7 +1707,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
// HACK: we always try to keep a spare running webkit plugin around to improve launch times.
// If a spare was already created before PluginAttachDebuggerToPlugins was set, don't use it.
- // Do not use a spare if launching with full viewer control (e.g. Facebook, Twitter and few others)
+ // Do not use a spare if launching with full viewer control (e.g. Twitter and few others)
if ((plugin_basename == "media_plugin_cef") &&
!gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins") && !clean_browser)
{
@@ -1901,21 +1901,8 @@ void LLViewerMediaImpl::loadURI()
// trim whitespace from front and back of URL - fixes EXT-5363
LLStringUtil::trim( mMediaURL );
- // *HACK: we don't know if the URI coming in is properly escaped
- // (the contract doesn't specify whether it is escaped or not.
- // but LLQtWebKit expects it to be, so we do our best to encode
- // special characters)
- // The strings below were taken right from http://www.ietf.org/rfc/rfc1738.txt
- // Note especially that '%' and '/' are there.
- std::string uri = LLURI::escape(mMediaURL,
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
- "0123456789"
- "$-_.+"
- "!*'(),"
- "{}|\\^~[]`"
- "<>#%"
- ";/?:@&=",
- false);
+ // URI often comes unescaped
+ std::string uri = LLURI::escapePathAndData(mMediaURL);
{
// Do not log the query parts
LLURI u(uri);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index ba68ce4cf4..52b2c631fa 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -54,7 +54,6 @@
#include "lldaycyclemanager.h"
#include "lldebugview.h"
#include "llenvmanager.h"
-#include "llfacebookconnect.h"
#include "llfilepicker.h"
#include "llfirstuse.h"
#include "llfloaterabout.h"
@@ -4066,10 +4065,8 @@ void near_sit_down_point(BOOL success, void *)
if (success)
{
gAgent.setFlying(FALSE);
+ gAgent.clearControlFlags(AGENT_CONTROL_STAND_UP); // might have been set by autopilot
gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND);
-
- // Might be first sit
- //LLFirstUse::useSit();
}
}
@@ -4754,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())
@@ -9207,7 +9210,6 @@ void initialize_menus()
enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1));
view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");
- enable.add("Object.EnableDuplicate", boost::bind(&LLSelectMgr::canDuplicate, LLSelectMgr::getInstance()));
view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse");
enable.add("Avatar.EnableMute", boost::bind(&enable_object_mute));
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index e50c8ee9f0..c8f75c79c4 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2415,7 +2415,7 @@ void translateSuccess(LLChat chat, LLSD toastArgs, std::string originalMsg, std:
&& ((detected_language.empty()) || (expectLang != detected_language))
&& (LLStringUtil::compareInsensitive(translation, originalMsg) != 0))
{
- chat.mText += " (" + translation + ")";
+ chat.mText += " (" + LLTranslate::removeNoTranslateTags(translation) + ")";
}
LLNotificationsUI::LLNotificationManager::instance().onChat(chat, toastArgs);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 439f675a2d..5b227c641b 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -2895,7 +2895,6 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("EstateAccess");
capabilityNames.append("EstateChangeInfo");
capabilityNames.append("EventQueueGet");
- capabilityNames.append("FacebookConnect");
capabilityNames.append("FlickrConnect");
capabilityNames.append("TwitterConnect");
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 68a9994bee..a81b3aaef9 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1219,6 +1219,7 @@ void LLViewerFetchedTexture::loadFromFastCache()
F32 cachReadTime = fastCacheTimer.getElapsedTimeF32();
add(LLTextureFetch::sCacheHit, 1.0);
+ record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(1));
sample(LLTextureFetch::sCacheReadLatency, cachReadTime);
mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
@@ -1251,6 +1252,10 @@ void LLViewerFetchedTexture::loadFromFastCache()
addToCreateTexture();
}
}
+ else
+ {
+ record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(0));
+ }
}
void LLViewerFetchedTexture::setForSculpt()
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 4308405c64..06524847d1 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -512,7 +512,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
if (boost_priority != LLViewerTexture::BOOST_ALM && imagep->getBoostLevel() == LLViewerTexture::BOOST_ALM)
{
// Workaround: we need BOOST_ALM texture for something, 'rise' to NONE
- imagep->setDecodePriority(LLViewerTexture::BOOST_NONE);
+ imagep->setBoostLevel(LLViewerTexture::BOOST_NONE);
}
LLViewerFetchedTexture *texture = imagep.get();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index e4f3b9bae4..4c6a3dd33d 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -3819,7 +3819,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
BOOL draw_handles = TRUE;
- if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move)
+ if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isSelfAvatarSelected())
{
draw_handles = FALSE;
}
@@ -4734,6 +4734,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
{
// Required for showing the GUI in snapshots and performing bloom composite overlay
// Call even if show_ui is FALSE
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
render_ui(scale_factor, subfield);
swap();
}
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index c4430f4308..c63c5f6b23 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -99,6 +99,8 @@ void LLVLComposition::setDetailTextureID(S32 corner, const LLUUID& id)
{
return;
}
+ // This is terrain texture, but we are not setting it as BOOST_TERRAIN
+ // since we will be manipulating it later as needed.
mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id);
mDetailTextures[corner]->setNoDelete() ;
mRawImages[corner] = NULL;
@@ -241,6 +243,7 @@ BOOL LLVLComposition::generateComposition()
}
mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
mDetailTextures[i]->setMinDiscardLevel(ddiscard);
+ mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE); // priority
return FALSE;
}
}
@@ -287,7 +290,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
{
mDetailTextures[i]->destroyRawImage() ;
}
- LL_DEBUGS() << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << LL_ENDL;
+ LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << " Discard: " << ddiscard << LL_ENDL;
return FALSE;
}
@@ -323,12 +326,12 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
if (x_end > mWidth)
{
- LL_WARNS() << "x end > width" << LL_ENDL;
+ LL_WARNS("Terrain") << "x end > width" << LL_ENDL;
x_end = mWidth;
}
if (y_end > mWidth)
{
- LL_WARNS() << "y end > width" << LL_ENDL;
+ LL_WARNS("Terrain") << "y end > width" << LL_ENDL;
y_end = mWidth;
}
@@ -358,7 +361,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
if (tex_comps != st_comps)
{
- LL_WARNS() << "Base texture comps != input texture comps" << LL_ENDL;
+ LL_WARNS("Terrain") << "Base texture comps != input texture comps" << LL_ENDL;
return FALSE;
}
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 0d3f65502a..e10ba77e16 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -658,6 +658,8 @@ void LLVivoxVoiceClient::voiceControlCoro()
mIsCoroutineActive = true;
LLCoros::set_consuming(true);
+ U32 retry = 0;
+
while (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
{
LL_DEBUGS("Voice") << "Suspending voiceControlCoro() momentarily for teleport. Tuning: " << mTuningMode << ". Relog: " << mRelogRequested << LL_ENDL;
@@ -666,7 +668,8 @@ void LLVivoxVoiceClient::voiceControlCoro()
do
{
- if (startAndConnectSession())
+ bool success = startAndConnectSession();
+ if (success)
{
if (mTuningMode)
{
@@ -677,6 +680,7 @@ void LLVivoxVoiceClient::voiceControlCoro()
LL_DEBUGS("Voice") << "lost channel RelogRequested=" << mRelogRequested << LL_ENDL;
endAndDisconnectSession();
+ retry = 0;
}
// if we hit this and mRelogRequested is true, that indicates
@@ -689,7 +693,19 @@ void LLVivoxVoiceClient::voiceControlCoro()
<< LL_ENDL;
if (mRelogRequested)
{
- LL_INFOS("Voice") << "will attempt to reconnect to voice" << LL_ENDL;
+ if (!success)
+ {
+ // We failed to connect, give it a bit time before retrying.
+ retry++;
+ F32 delay = llmin(5.f * (F32)retry, 60.f);
+ llcoro::suspendUntilTimeout(delay);
+ LL_INFOS("Voice") << "Voice failed to establish session after " << retry << " tries. Will attempt to reconnect." << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("Voice") << "will attempt to reconnect to voice" << LL_ENDL;
+ }
+
while (isGatewayRunning() || gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
{
LL_INFOS("Voice") << "waiting for SLVoice to exit" << LL_ENDL;
@@ -770,12 +786,16 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
{
#ifndef VIVOXDAEMON_REMOTEHOST
// Launch the voice daemon
- std::string exe_path = gDirUtilp->getAppRODataDir();
#if LL_WINDOWS
+ // On windows use exe (not work or RO) directory
+ std::string exe_path = gDirUtilp->getExecutableDir();
gDirUtilp->append(exe_path, "SLVoice.exe");
#elif LL_DARWIN
+ // On MAC use resource directory
+ std::string exe_path = gDirUtilp->getAppRODataDir();
gDirUtilp->append(exe_path, "SLVoice");
#else
+ std::string exe_path = gDirUtilp->getExecutableDir();
gDirUtilp->append(exe_path, "SLVoice");
#endif
// See if the vivox executable exists
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index a72244929e..bd73c234a6 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4062,7 +4062,6 @@ void LLPipeline::postSort(LLCamera& camera)
void render_hud_elements()
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
gPipeline.disableLights();
LLGLDisable fog(GL_FOG);
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 08130992e8..40f1d8b88f 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -133,7 +133,6 @@ with the same filename but different name
<texture name="Command_Chat_Icon" file_name="toolbar_icons/chat.png" preload="true" />
<texture name="Command_Compass_Icon" file_name="toolbar_icons/land.png" preload="true" />
<texture name="Command_Destinations_Icon" file_name="toolbar_icons/destinations.png" preload="true" />
- <texture name="Command_Facebook_Icon" file_name="toolbar_icons/facebook.png" preload="true" />
<texture name="Command_Flickr_Icon" file_name="toolbar_icons/flickr.png" preload="true" />
<texture name="Command_Gestures_Icon" file_name="toolbar_icons/gestures.png" preload="true" />
<texture name="Command_Grid_Status_Icon" file_name="toolbar_icons/grid_status.png" preload="true" />
@@ -205,11 +204,10 @@ with the same filename but different name
<texture name="ExternalBrowser_Off" file_name="icons/ExternalBrowser_Off.png" preload="false" />
<texture name="Edit_Wrench" file_name="icons/Edit_Wrench.png" preload="false" />
- <texture name="Facebook_Icon" file_name="icons/Facebook.png" preload="false" />
+ <texture name="Presets_Icon" file_name="icons/Presets_Icon.png" preload="true" />
<texture name="Presets_Icon_Graphic" file_name="icons/Presets_Icon_Graphic.png" preload="true" />
-
- <texture name="Favorite_Star_Active" file_name="navbar/Favorite_Star_Active.png" preload="false" />
+ <texture name="Favorite_Star_Active" file_name="navbar/Favorite_Star_Active.png" preload="false" />
<texture name="Favorite_Star_Off" file_name="navbar/Favorite_Star_Off.png" preload="false" />
<texture name="Favorite_Star_Press" file_name="navbar/Favorite_Star_Press.png" preload="false" />
<texture name="Favorite_Star_Over" file_name="navbar/Favorite_Star_Over.png" preload="false" />
@@ -593,9 +591,7 @@ with the same filename but different name
<texture name="Snapshot_Email" file_name="snapshot_email.png" preload="false" />
<texture name="Snapshot_Inventory" file_name="toolbar_icons/inventory.png" preload="false" />
<texture name="Snapshot_Profile" file_name="toolbar_icons/profile.png" preload="false" />
- <texture name="Snapshot_Facebook" file_name="toolbar_icons/facebook.png" preload="false" />
-
- <texture name="startup_logo" file_name="windows/startup_logo.png" preload="true" />
+ <texture name="startup_logo" file_name="windows/startup_logo.png" preload="true" />
<texture name="login_sl_logo" file_name="windows/login_sl_logo.png" preload="true" />
<texture name="login_sl_logo_small" file_name="windows/login_sl_logo_small.png" preload="true" />
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 1e18ab20e8..2bff6d3e2f 100644
--- a/indra/newview/skins/default/xui/de/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/de/floater_about_land.xml
@@ -21,7 +21,7 @@
<floater.string name="Remaining">
Restzeit
</floater.string>
- <tab_container name="landtab" tab_min_width="40" width="489">
+ <tab_container name="landtab" tab_min_width="40">
<panel label="ALLGEMEIN" name="land_general_panel">
<panel.string name="new users only">
Nur neue Benutzer
@@ -361,8 +361,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>
@@ -433,7 +433,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/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index d04e738b22..9f853fd960 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -163,6 +163,7 @@
layout="topleft"
left_pad="2"
name="Description"
+ spellcheck="true"
top_delta="0"
width="365"
word_wrap="true" />
@@ -1268,6 +1269,7 @@ Only large parcels can be listed in search.
layout="topleft"
left_pad="2"
name="edit objects check"
+ tool_tip="If checked, Residents can create and rez objects on your land."
width="130" />
<check_box
height="16"
@@ -1275,6 +1277,7 @@ Only large parcels can be listed in search.
layout="topleft"
left_pad="2"
name="edit group objects check"
+ tool_tip="If checked, parcel group members can create and rez objects on your land."
width="70" />
<text
type="string"
@@ -1293,6 +1296,7 @@ Only large parcels can be listed in search.
layout="topleft"
left_pad="2"
name="all object entry check"
+ tool_tip="If checked, Residents can move existing objects from other parcels onto this parcel."
top_delta="0"
width="130" />
<check_box
@@ -1301,6 +1305,7 @@ Only large parcels can be listed in search.
layout="topleft"
left_pad="2"
name="group object entry check"
+ tool_tip="If checked, parcel group members can move existing objects from other parcels onto this parcel."
top_delta="0"
width="70" />
<text
@@ -1320,6 +1325,7 @@ Only large parcels can be listed in search.
layout="topleft"
left_pad="2"
name="check other scripts"
+ tool_tip="If checked, Residents can run scripts on your parcel, including attachments."
top_delta="0"
width="130" />
<check_box
@@ -1328,6 +1334,7 @@ Only large parcels can be listed in search.
layout="topleft"
left_pad="2"
name="check group scripts"
+ tool_tip="If checked, parcel group members can run scripts on your parcel, including attachments."
top_delta="0"
width="70" />
<panel
@@ -1466,11 +1473,12 @@ Only large parcels can be listed in search.
length="1"
follows="left|top"
text_color="LtGray"
+ text_readonly_color="LabelDisabledColor"
height="32"
layout="topleft"
left="274"
top="150"
- name="allow_label5"
+ name="allow_see_label"
width="205"
word_wrap="true">
Avatars on other parcels can see and chat with avatars on this parcel
@@ -1908,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/floater_ban_duration.xml b/indra/newview/skins/default/xui/en/floater_ban_duration.xml
index 5562f28877..6c537cc08d 100644
--- a/indra/newview/skins/default/xui/en/floater_ban_duration.xml
+++ b/indra/newview/skins/default/xui/en/floater_ban_duration.xml
@@ -28,12 +28,12 @@
draw_border="false"
enabled="true"
follows="left|top"
- height="40"
+ height="47"
left="20"
mouse_opaque="true"
name="ban_duration_radio"
tab_stop="true"
- width="200">
+ width="150">
<radio_item
type="string"
follows="left|top"
@@ -75,7 +75,7 @@
left_delta="70"
name="hours_textbox"
top_delta="5"
- width="75">
+ width="70">
hours.
</text>
diff --git a/indra/newview/skins/default/xui/en/floater_experienceprofile.xml b/indra/newview/skins/default/xui/en/floater_experienceprofile.xml
index 2dfba1ac44..f275fec066 100644
--- a/indra/newview/skins/default/xui/en/floater_experienceprofile.xml
+++ b/indra/newview/skins/default/xui/en/floater_experienceprofile.xml
@@ -493,6 +493,7 @@
layout="topleft"
left="11"
name="edit_experience_description"
+ spellcheck="true"
max_length="2048"
text_color="black"
right="-11"
diff --git a/indra/newview/skins/default/xui/en/floater_facebook.xml b/indra/newview/skins/default/xui/en/floater_facebook.xml
deleted file mode 100644
index b34d70516a..0000000000
--- a/indra/newview/skins/default/xui/en/floater_facebook.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<floater
- positioning="cascading"
- can_close="true"
- help_topic="floater_facebook"
- layout="topleft"
- name="floater_facebook"
- save_rect="true"
- single_instance="true"
- reuse_instance="true"
- title="POST TO FACEBOOK"
- min_height="462"
- min_width="304"
- height="462"
- width="272">
- <tab_container
- name="tabs"
- tab_group="1"
- tab_min_width="64"
- tab_height="21"
- tab_position="top"
- top="7"
- height="437"
- follows="all"
- halign="center">
- <panel
- filename="panel_facebook_status.xml"
- class="llfacebookstatuspanel"
- follows="all"
- label="STATUS"
- name="panel_facebook_status"/>
- <panel
- filename="panel_facebook_photo.xml"
- class="llfacebookphotopanel"
- follows="all"
- label="PHOTO"
- name="panel_facebook_photo"/>
- <panel
- filename="panel_facebook_place.xml"
- class="llfacebookcheckinpanel"
- follows="all"
- label="CHECK IN"
- name="panel_facebook_place"/>
- <panel
- filename="panel_facebook_friends.xml"
- class="llfacebookfriendspanel"
- follows="all"
- label="FRIENDS"
- name="panel_facebook_friends"/>
- <!--<panel
- filename="panel_facebook_account.xml"
- class="llfacebookaccountpanel"
- follows="all"
- label="ACCOUNT"
- name="panel_facebook_account"/>-->
- </tab_container>
- <text
- name="connection_error_text"
- type="string"
- follows="left|bottom|right"
- bottom="-5"
- left="10"
- width="250"
- height="20"
- wrap="true"
- halign="left"
- valign="center"
- text_color="DrYellow"
- font="SansSerif">
- Error
- </text>
- <loading_indicator
- follows="left|bottom"
- height="24"
- width="24"
- name="connection_loading_indicator"
- top_delta="-2"
- left="10"
- visible="true"/>
- <text
- name="connection_loading_text"
- type="string"
- follows="left|bottom|right"
- top_delta="2"
- left_pad="5"
- width="250"
- height="20"
- wrap="true"
- halign="left"
- valign="center"
- text_color="EmphasisColor"
- font="SansSerif">
- Loading...
- </text>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_fast_timers.xml b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
index fa7147d9ca..645003cc14 100644
--- a/indra/newview/skins/default/xui/en/floater_fast_timers.xml
+++ b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
@@ -60,10 +60,21 @@
min_width="100">
<panel top="0"
left="0"
- width="220"
+ width="204"
height="440"
name="legend"
follows="all"/>
+ <scroll_bar
+ top ="0"
+ right="-1"
+ height="440"
+ width="15"
+ follows="top|right|bottom"
+ name="scroll_vert"
+ orientation="vertical"
+ step_size="16"
+ doc_size="3000"
+ />
</layout_panel>
<layout_panel name="timers_panel"
auto_resize="true"
diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml
index 200e9b9537..9f051d9f8d 100644
--- a/indra/newview/skins/default/xui/en/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/en/floater_gesture.xml
@@ -119,6 +119,7 @@
follows="left|bottom"
height="23"
label="Edit"
+ tool_tip="Open window for editing selected gesture."
layout="topleft"
left="6"
name="edit_btn"
@@ -128,6 +129,7 @@
follows="left|bottom"
height="23"
label="Play"
+ tool_tip="Execute selected gesture in-world."
layout="topleft"
left_pad="6"
name="play_btn"
diff --git a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
index 1b4992b4ca..ca1d299553 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
@@ -2,7 +2,7 @@
<floater
legacy_header_height="18"
can_minimize="false"
- height="468"
+ height="448"
layout="topleft"
name="Inventory Finder"
help_topic="inventory_finder"
@@ -112,29 +112,12 @@
width="126" />
<icon
height="16"
- image_name="Inv_Mesh"
- layout="topleft"
- left="8"
- mouse_opaque="true"
- name="icon_mesh"
- top="142"
- width="16" />
- <check_box
- height="16"
- label="Meshes"
- layout="topleft"
- left_pad="2"
- name="check_mesh"
- top_delta="0"
- width="126" />
- <icon
- height="16"
image_name="Inv_Object"
layout="topleft"
left="8"
mouse_opaque="true"
name="icon_object"
- top="162"
+ top="142"
width="16" />
<check_box
height="16"
@@ -151,7 +134,7 @@
left="8"
mouse_opaque="true"
name="icon_script"
- top="182"
+ top="162"
width="16" />
<check_box
height="16"
@@ -168,7 +151,7 @@
left="8"
mouse_opaque="true"
name="icon_sound"
- top="202"
+ top="182"
width="16" />
<check_box
height="16"
@@ -185,7 +168,7 @@
left="8"
mouse_opaque="true"
name="icon_texture"
- top="222"
+ top="202"
width="16" />
<check_box
height="16"
@@ -202,7 +185,7 @@
left="8"
mouse_opaque="true"
name="icon_snapshot"
- top="242"
+ top="222"
width="16" />
<check_box
height="16"
@@ -220,7 +203,7 @@
layout="topleft"
left="8"
name="All"
- top="262"
+ top="242"
width="100" />
<button
height="20"
@@ -274,7 +257,7 @@
width="260"/>
<check_box
height="16"
- top="352"
+ top="332"
label="Since Logoff"
layout="topleft"
left_delta="0"
@@ -290,7 +273,7 @@
layout="topleft"
left_delta="0"
name="- OR -"
- top="370"
+ top="350"
width="144">
- OR -
</text>
@@ -298,7 +281,7 @@
height="16"
layout="topleft"
name="date_search_direction"
- top="388"
+ top="368"
left="8"
width="270">
<radio_item
@@ -368,6 +351,6 @@
layout="topleft"
name="Close"
right="-6"
- top="434"
+ top="414"
width="76" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml
index 93bfe53aae..659033efd4 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml
@@ -58,12 +58,12 @@
label_width="95"
layout="topleft"
left_delta="210"
- max_val="12000"
+ max_val="65535"
min_val="10"
name="web_proxy_port"
top_delta="0"
tool_tip="The port of the HTTP proxy you would like to use."
- width="145" />
+ width="150" />
<check_box
control_name="Socks5ProxyEnabled"
height="16"
@@ -111,11 +111,11 @@
label_width="95"
layout="topleft"
left_delta="210"
- max_val="12000"
+ max_val="65535"
min_val="10"
name="socks_proxy_port"
top_delta="0"
- width="145"
+ width="150"
tool_tip="The port of the SOCKS 5 proxy you would like to use."
commit_callback.function="Proxy.Change" />
<text
diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
index 2e1c8ce670..dcbdfa8794 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
@@ -6,7 +6,7 @@
height="361"
layout="topleft"
min_height="243"
- min_width="234"
+ min_width="330"
name="preview notecard"
help_topic="preview_notecard"
title="NOTECARD:"
@@ -77,6 +77,16 @@
word_wrap="true">
Loading...
</text_editor>
+ <button
+ follows="left|bottom"
+ height="22"
+ label="Edit..."
+ label_selected="Edit"
+ layout="topleft"
+ left="4"
+ name="Edit"
+ top="332"
+ width="100" />
<button
follows="right|bottom"
height="22"
diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
index 8fa5b49573..d07e3cb31b 100644
--- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
@@ -246,7 +246,7 @@
name="Land__Encroachment__Objects_textures"
value="63" />
<combo_box.item
- label="Gaming Policy Violation"
+ label="Skill Gaming Policy Violation"
name="Wagering_gambling"
value="67" />
</combo_box>
diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml
index e50747cb5f..832c2ee7da 100644
--- a/indra/newview/skins/default/xui/en/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml
@@ -24,10 +24,6 @@
Sending Email
</string>
<string
- name="facebook_progress_str">
- Posting to Facebook
- </string>
- <string
name="profile_progress_str">
Posting
</string>
@@ -40,10 +36,6 @@
Saving to Computer
</string>
<string
- name="facebook_succeeded_str">
- Image uploaded
- </string>
- <string
name="profile_succeeded_str">
Image uploaded
</string>
@@ -60,10 +52,6 @@
Saved to Computer!
</string>
<string
- name="facebook_failed_str">
- Failed to upload image to your Facebook timeline.
- </string>
- <string
name="profile_failed_str">
Failed to upload image to your Profile Feed.
</string>
diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml
index 8b1d50e58f..2d5263b78f 100644
--- a/indra/newview/skins/default/xui/en/fonts.xml
+++ b/indra/newview/skins/default/xui/en/fonts.xml
@@ -10,6 +10,8 @@
<file>simhei.ttf</file>
<file>ArialUni.ttf</file>
<file>msyh.ttc</file>
+ <file load_collection="true">Cambria.ttc</file>
+ <file>malgun.ttf</file>
</os>
<os name="Mac">
<file>ヒラギノ角ゴシック W3.ttc</file>
@@ -21,6 +23,7 @@
<file>AppleSDGothicNeo-Regular.otf</file>
<file>华文细黑.ttf</file>
<file>PingFang.ttc</file>
+ <file>STIXGeneral.otf</file>
</os>
</font>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index f2ee9c6447..7bb7b5d62c 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -307,13 +307,6 @@
</menu_item_check>
<menu_item_separator/>
<menu_item_call
- label="Facebook..."
- name="Facebook">
- <menu_item_call.on_click
- function="Floater.Toggle"
- parameter="facebook"/>
- </menu_item_call>
- <menu_item_call
label="Twitter..."
name="Twitter">
<menu_item_call.on_click
@@ -1051,8 +1044,7 @@
shortcut="control|D">
<menu_item_call.on_click
function="Object.Duplicate" />
- <menu_item_call.on_enable
- function="Object.EnableDuplicate" />
+
</menu_item_call>
</menu>
<menu
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index b7cd6517ea..053c041849 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6705,13 +6705,6 @@ Please select at least one type of content to search (General, Moderate, or Adul
[MESSAGE]
</notification>
- <notification
- icon="notify.tga"
- name="FacebookConnect"
- type="notifytip">
-[MESSAGE]
- </notification>
-
<notification
icon="notify.tga"
name="FlickrConnect"
@@ -8639,6 +8632,7 @@ Please check your network and firewall setup.
icon="alertmodal.tga"
name="NoVoiceConnect"
type="alertmodal">
+ <unique/>
We are unable to connect to the voice server:
[HOSTID]
diff --git a/indra/newview/skins/default/xui/en/panel_facebook_friends.xml b/indra/newview/skins/default/xui/en/panel_facebook_friends.xml
deleted file mode 100644
index 97994fb08b..0000000000
--- a/indra/newview/skins/default/xui/en/panel_facebook_friends.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<panel
- height="400"
- width="272"
- layout="topleft"
- follows="all"
- name="panel_facebook_friends">
- <string
- name="facebook_friends_empty"
- value="You currently do not have any Facebook friends who are also Second Life residents. Ask your Facebook friends to join Second Life today!" />
- <string
- name="facebook_friends_no_connected"
- value="You're currently not connected to Facebook. Please go to the Status tab to connect and enable this feature." />
- <accordion
- background_visible="false"
- bg_alpha_color="DkGray2"
- bg_opaque_color="DkGray2"
- follows="all"
- height="383"
- layout="topleft"
- left="10"
- name="friends_accordion"
- right="-10"
- top_pad="2">
- <accordion_tab
- layout="topleft"
- height="173"
- name="tab_second_life_friends"
- title="SL friends">
- <avatar_list
- ignore_online_status="true"
- allow_select="true"
- follows="all"
- height="173"
- layout="topleft"
- left="0"
- name="second_life_friends"
- show_permissions_granted="true"
- top="0"
- width="272" />
- </accordion_tab>
- <accordion_tab
- layout="topleft"
- height="173"
- name="tab_suggested_friends"
- title="Add these people as SL friends">
- <avatar_list
- ignore_online_status="true"
- allow_select="true"
- follows="all"
- height="173"
- layout="topleft"
- left="0"
- name="suggested_friends"
- show_permissions_granted="true"
- top="0"
- width="272" />
- </accordion_tab>
- </accordion>
- <text
- layout="topleft"
- word_wrap="true"
- height="64"
- width="250"
- follows="top|left|right"
- font="SansSerif"
- left="10"
- right="-10"
- name="facebook_friends_status"
- top="5"
- type="string">
- Not connected to Facebook.
- </text>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_facebook_photo.xml b/indra/newview/skins/default/xui/en/panel_facebook_photo.xml
deleted file mode 100644
index 22e6598352..0000000000
--- a/indra/newview/skins/default/xui/en/panel_facebook_photo.xml
+++ /dev/null
@@ -1,168 +0,0 @@
- <panel
- height="400"
- width="272"
- layout="topleft"
- follows="all"
- name="panel_facebook_photo">
- <combo_box
- control_name="FacebookPhotoResolution"
- follows="left|top"
- layout="topleft"
- top="7"
- left="10"
- name="resolution_combobox"
- tool_tip="Image resolution"
- height="21"
- width="124">
- <combo_box.item
- label="Current Window"
- name="CurrentWindow"
- value="[i0,i0]" />
- <combo_box.item
- label="640x480"
- name="640x480"
- value="[i640,i480]" />
- <combo_box.item
- label="800x600"
- name="800x600"
- value="[i800,i600]" />
- <combo_box.item
- label="1024x768"
- name="1024x768"
- value="[i1024,i768]" />
- <combo_box.item
- label="1200x630"
- name="1200x630"
- value="[i1200,i630]" />
- </combo_box>
- <combo_box
- control_name="FacebookPhotoFilters"
- follows="left|top"
- layout="topleft"
- name="filters_combobox"
- tool_tip="Image filters"
- top="7"
- left_pad="4"
- height="21"
- width="124">
- <combo_box.item
- label="No Filter"
- name="NoFilter"
- value="NoFilter" />
- </combo_box>
- <panel
- height="150"
- width="252"
- visible="true"
- layout="topleft"
- name="thumbnail_placeholder"
- top_pad="5"
- follows="left|top|rith"
- right="-10"
- left="10">
- </panel>
- <text
- follows="left|top"
- layout="topleft"
- font="SansSerif"
- text_color="EmphasisColor"
- height="14"
- top_pad="2"
- left="10"
- length="1"
- halign="center"
- name="working_lbl"
- translate="false"
- type="string"
- visible="true"
- width="251">
- Refreshing...
- </text>
- <view_border
- bevel_style="in"
- follows="left|top"
- layout="topleft"
- height="1"
- left="10"
- name="refresh_border"
- width="250"
- top_pad="0"/>
- <button
- follows="left|top"
- layout="topleft"
- height="23"
- label="Refresh"
- left="10"
- top_pad="5"
- name="new_snapshot_btn"
- tool_tip="Click to refresh"
- visible="true"
- width="100" >
- <button.commit_callback
- function="SocialSharing.RefreshPhoto" />
- </button>
- <button
- follows="right|top"
- layout="topleft"
- height="23"
- label="Preview"
- right="-10"
- top_delta="0"
- name="big_preview_btn"
- tool_tip="Click to toggle preview"
- is_toggle="true"
- visible="true"
- width="100" >
- <button.commit_callback
- function="SocialSharing.BigPreview" />
- </button>
- <text
- length="1"
- follows="top|left|right"
- layout="topleft"
- font="SansSerif"
- height="16"
- left="10"
- name="caption_label"
- top_pad="20"
- type="string">
- Comment (optional):
- </text>
- <text_editor
- follows="left|top|right|bottom"
- layout="topleft"
- height="87"
- width="250"
- left="10"
- right="-10"
- length="1"
- max_length="700"
- name="photo_caption"
- type="string"
- word_wrap="true">
- </text_editor>
- <button
- follows="left|top"
- layout="topleft"
- top_pad="22"
- left="10"
- height="23"
- label="Post"
- name="post_photo_btn"
- width="100">
- <button.commit_callback
- function="SocialSharing.SendPhoto" />
- </button>
- <button
- follows="right|top"
- layout="topleft"
- height="23"
- label="Cancel"
- name="cancel_photo_btn"
- right="-10"
- top_delta="0"
- width="100">
- <button.commit_callback
- function="SocialSharing.Cancel" />
- </button>
- </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_facebook_place.xml b/indra/newview/skins/default/xui/en/panel_facebook_place.xml
deleted file mode 100644
index f87b008c4e..0000000000
--- a/indra/newview/skins/default/xui/en/panel_facebook_place.xml
+++ /dev/null
@@ -1,113 +0,0 @@
- <panel
- height="400"
- width="272"
- layout="topleft"
- follows="all"
- name="panel_facebook_place">
- <text
- length="1"
- follows="top|left|right"
- layout="topleft"
- font="SansSerif"
- height="16"
- left="10"
- name="place_caption_label"
- top="5"
- type="string">
- Say something about where you are:
- </text>
- <text_editor
- follows="top|left|right"
- layout="topleft"
- height="70"
- width="250"
- left="10"
- right="-10"
- length="1"
- max_length="700"
- name="place_caption"
- type="string"
- word_wrap="true">
- </text_editor>
- <check_box
- follows="left|top"
- layout="topleft"
- initial_value="false"
- height="16"
- top_pad="8"
- width="8"
- label="Include overhead view of location"
- name="add_place_view_cb"
- left="10"/>
- <panel
- follows="left|top"
- layout="topleft"
- height="243"
- width="250"
- background_visible="true"
- bg_opaque_color="Black"
- bg_alpha_color="Black"
- top_pad="8"
- left="10"
- right="-12"
- visible="true"
- name="map_border">
- </panel>
- <icon
- follows="left|top"
- layout="topleft"
- height="243"
- width="250"
- image_name="Map_Placeholder_Icon"
- top_delta="0"
- right="-12"
- left="10"
- visible="true"
- name="map_placeholder">
- </icon>
- <icon
- follows="left|top"
- layout="topleft"
- height="243"
- width="250"
- image_name="Map_Placeholder_Icon"
- top_delta="0"
- left="10"
- right="-12"
- visible="true"
- name="map_default">
- </icon>
- <loading_indicator
- follows="left|top"
- layout="topleft"
- height="24"
- width="24"
- name="map_loading_indicator"
- top_delta="116"
- left="126"
- visible="false"/>
- <button
- follows="left|bottom"
- layout="topleft"
- top_pad="95"
- left="10"
- height="23"
- label="Post"
- name="post_place_btn"
- width="100">
- <button.commit_callback
- function="SocialSharing.SendCheckin" />
- </button>
- <button
- follows="right|bottom"
- layout="topleft"
- height="23"
- label="Cancel"
- name="cancel_place_btn"
- right="-10"
- top_delta="0"
- width="100">
- <button.commit_callback
- function="SocialSharing.Cancel" />
- </button>
- </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_facebook_status.xml b/indra/newview/skins/default/xui/en/panel_facebook_status.xml
deleted file mode 100644
index fe0f3c9279..0000000000
--- a/indra/newview/skins/default/xui/en/panel_facebook_status.xml
+++ /dev/null
@@ -1,130 +0,0 @@
- <panel
- height="400"
- width="272"
- follows="all"
- layout="topleft"
- name="panel_facebook_status">
- <string
- name="facebook_connected"
- value="You are connected to Facebook as:" />
- <string
- name="facebook_disconnected"
- value="Not connected to Facebook" />
- <text
- layout="topleft"
- length="1"
- follows="top|left"
- font="SansSerif"
- height="16"
- left="10"
- name="account_caption_label"
- top="5"
- type="string">
- Not connected to Facebook.
- </text>
- <text
- layout="topleft"
- top_pad="2"
- length="1"
- follows="top|left"
- font="SansSerif"
- height="16"
- left="10"
- name="account_name_label"
- parse_urls="true"
- type="string"/>
- <panel
- layout="topleft"
- follows="left|top"
- name="panel_buttons"
- height="60"
- left="0">
- <button
- layout="topleft"
- follows="left|top"
- top_pad="9"
- left="10"
- visible="true"
- height="23"
- label="Connect..."
- name="connect_btn"
- width="251">
- <commit_callback function="SocialSharing.Connect"/>
- </button>
-
- <button
- layout="topleft"
- follows="left|top|right"
- top_delta="0"
- left="10"
- right="-10"
- height="23"
- label="Disconnect"
- name="disconnect_btn"
- width="210"
- visible="false">
- <commit_callback function="SocialSharing.Disconnect"/>
- </button>
- <text
- layout="topleft"
- length="1"
- follows="top|left|right"
- left="10"
- right="-10"
- height="16"
- name="account_learn_more_label"
- top_pad="5"
- type="string">
- [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Learn about posting to Facebook]
- </text>
- </panel>
-
- <text
- length="1"
- layout="topleft"
- follows="top|left|right"
- font="SansSerif"
- height="16"
- left="10"
- name="status_caption_label"
- top_pad="5"
- type="string">
- What's on your mind?
- </text>
- <text_editor
- follows="left|top|right"
- layout="topleft"
- height="150"
- width="252"
- left="10"
- length="1"
- max_length="700"
- name="status_message"
- type="string"
- word_wrap="true">
- </text_editor>
- <button
- follows="left|top"
- layout="topleft"
- top_pad="6"
- left="10"
- height="23"
- label="Post"
- name="post_status_btn"
- width="100">
- <button.commit_callback
- function="SocialSharing.SendStatus" />
- </button>
- <button
- follows="right|top"
- layout="topleft"
- height="23"
- label="Cancel"
- name="cancel_status_btn"
- right="-10"
- top_delta="0"
- width="100">
- <button.commit_callback
- function="SocialSharing.Cancel" />
- </button>
- </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
index 6074ab9ef6..7fb2291423 100644
--- a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
+++ b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
@@ -158,6 +158,7 @@
length="1"
max_length="700"
name="photo_description"
+ spellcheck="true"
type="string"
word_wrap="true">
</text_editor>
diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml
index 26f54bacbc..e34335a2af 100644
--- a/indra/newview/skins/default/xui/en/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
@@ -214,7 +214,7 @@ Hover your mouse over the options for more help.
layout="topleft"
left="10"
name="group_mature_check"
- tool_tip="Sets whether your group contains information rated as Moderate"
+ tool_tip="Maturity ratings designate the type of content and behavior allowed in a group"
top_pad="4"
width="190">
<combo_item name="select_mature" value="Select">
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_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
index fd6e96b9a7..13986c4030 100644
--- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
@@ -277,6 +277,7 @@
max_length="127"
name="notes_editor"
read_only="true"
+ spellcheck="true"
text_readonly_color="white"
text_type="ascii_with_newline"
top_pad="5"
diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml
index 213f9a6b0c..726e713595 100644
--- a/indra/newview/skins/default/xui/en/panel_login_first.xml
+++ b/indra/newview/skins/default/xui/en/panel_login_first.xml
@@ -111,7 +111,6 @@
combo_editor.font="SansSerifLarge"
max_chars="128"
top="0"
- commit_on_focus_lost="false"
combo_editor.prevalidate_callback="ascii"
tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine"
name="username_combo"
@@ -141,7 +140,7 @@
follows="left|top"
image_unselected="PushButton_Login"
image_pressed="PushButton_Login_Pressed"
- image_hover="PushButton_Login_Over"
+ image_hover_unselected="PushButton_Login_Over"
label="Log In"
label_color="White"
font="SansSerifLarge"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 8fc0f6f642..a47121ae99 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -367,24 +367,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
show_permissions_granted="true"
top="0"
width="307" />
- </accordion_tab>
- <accordion_tab
- layout="topleft"
- height="173"
- name="tab_suggested_friends"
- title="People you may want to friend">
- <avatar_list
- ignore_online_status="true"
- allow_select="true"
- follows="all"
- height="173"
- layout="topleft"
- left="0"
- name="suggested_friends"
- show_permissions_granted="true"
- top="0"
- width="307" />
- </accordion_tab>
+ </accordion_tab>
</accordion>
<text
follows="all"
diff --git a/indra/newview/skins/default/xui/en/panel_postcard_message.xml b/indra/newview/skins/default/xui/en/panel_postcard_message.xml
index 331a08b4bb..63c7259878 100644
--- a/indra/newview/skins/default/xui/en/panel_postcard_message.xml
+++ b/indra/newview/skins/default/xui/en/panel_postcard_message.xml
@@ -80,6 +80,7 @@
left="5"
max_length="700"
name="msg_form"
+ spellcheck="true"
right="-4"
top_pad="5"
word_wrap="true">
diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
index 5d060c0a0d..8243c2715d 100644
--- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
@@ -94,6 +94,7 @@
layout="topleft"
left_delta="0"
name="texture_detail_0"
+ default_image_id="0bc58228-74a0-7e83-89bc-5c23464bcec5"
top_delta="20"
width="100" />
<texture_picker
@@ -102,6 +103,7 @@
layout="topleft"
left_pad="10"
name="texture_detail_1"
+ default_image_id="63338ede-0037-c4fd-855b-015d77112fc8"
top_delta="0"
width="100" />
<texture_picker
@@ -110,6 +112,7 @@
layout="topleft"
left_pad="10"
name="texture_detail_2"
+ default_image_id="303cd381-8560-7579-23f1-f0a880799740"
top_delta="0"
width="100" />
<texture_picker
@@ -118,6 +121,7 @@
layout="topleft"
left_pad="10"
name="texture_detail_3"
+ default_image_id="53a2f406-4895-1d13-d541-d2e3b86bc19c"
top_delta="0"
width="100" />
<text
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/panel_snapshot_options.xml b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
index 305cce1cbe..981b9ab881 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
@@ -61,23 +61,6 @@
font="SansSerif"
halign="left"
height="22"
- image_overlay="Snapshot_Facebook"
- image_overlay_alignment="left"
- image_top_pad="0"
- imgoverlay_label_space="10"
- label="Share to Facebook"
- layout="topleft"
- left_delta="0"
- name="send_to_facebook_btn"
- top_pad="5">
- <button.commit_callback
- function="Snapshot.SendToFacebook"/>
- </button>
- <button
- follows="left|top"
- font="SansSerif"
- halign="left"
- height="22"
image_overlay="Command_Twitter_Icon"
image_overlay_alignment="left"
image_top_pad="0"
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
index d86cb92981..2fdbee49f0 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
@@ -126,6 +126,7 @@
length="1"
max_length="700"
name="caption"
+ spellcheck="true"
width="200"
top_pad="2"
type="string"
diff --git a/indra/newview/skins/default/xui/en/panel_twitter_photo.xml b/indra/newview/skins/default/xui/en/panel_twitter_photo.xml
index 9a460ceead..8774d09a03 100644
--- a/indra/newview/skins/default/xui/en/panel_twitter_photo.xml
+++ b/indra/newview/skins/default/xui/en/panel_twitter_photo.xml
@@ -39,6 +39,7 @@
length="1"
max_length="140"
name="photo_status"
+ spellcheck="true"
type="string"
word_wrap="true">
</text_editor>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 148effb01d..c386cb9457 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -58,6 +58,9 @@ Advanced Lighting Model: [GPU_SHADERS]
Texture memory: [TEXTURE_MEMORY]MB
VFS (cache) creation time: [VFS_TIME]
</string>
+ <string name="AboutOSXHiDPI">
+HiDPI display mode: [HIDPI]
+ </string>
<string name="AboutLibs">
J2C Decoder Version: [J2C_VERSION]
Audio Driver Version: [AUDIO_DRIVER_VERSION]
@@ -199,13 +202,7 @@ Please try logging in again in a minute.</string>
<string name="SentToInvalidRegion">You were sent to an invalid region.</string>
<string name="TestingDisconnect">Testing viewer disconnect</string>
- <!-- SLShare: Facebook, Flickr, and Twitter -->
- <string name="SocialFacebookConnecting">Connecting to Facebook...</string>
- <string name="SocialFacebookPosting">Posting...</string>
- <string name="SocialFacebookDisconnecting">Disconnecting from Facebook...</string>
- <string name="SocialFacebookErrorConnecting">Problem connecting to Facebook</string>
- <string name="SocialFacebookErrorPosting">Problem posting to Facebook</string>
- <string name="SocialFacebookErrorDisconnecting">Problem disconnecting from Facebook</string>
+ <!-- SLShare: Flickr and Twitter -->
<string name="SocialFlickrConnecting">Connecting to Flickr...</string>
<string name="SocialFlickrPosting">Posting...</string>
<string name="SocialFlickrDisconnecting">Disconnecting from Flickr...</string>
@@ -2302,6 +2299,9 @@ For AI Character: Get the closest navigable point to the point provided.
<string name="MarketplaceURL_Dashboard">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard</string>
<string name="MarketplaceURL_Imports">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports</string>
<string name="MarketplaceURL_LearnMore">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more</string>
+ <string name="InventoryPlayAnimationTooltip">Open window with Play options.</string>
+ <string name="InventoryPlayGestureTooltip">Execute selected gesture in-world.</string>
+ <string name="InventoryPlaySoundTooltip">Open window with Play options.</string>
<string name="InventoryOutboxNotMerchantTitle">Anyone can sell items on the Marketplace.</string>
<string name="InventoryOutboxNotMerchantTooltip"></string>
<string name="InventoryOutboxNotMerchant">
@@ -3653,9 +3653,6 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
Drag items from inventory here
</string>
- <string name="facebook_post_success">
- You posted to Facebook.
- </string>
<string name="flickr_post_success">
You posted to Flickr.
</string>
@@ -3943,7 +3940,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>
@@ -4088,7 +4085,6 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Conversations_Label">Conversations</string>
<string name="Command_Compass_Label">Compass</string>
<string name="Command_Destinations_Label">Destinations</string>
- <string name="Command_Facebook_Label">Facebook</string>
<string name="Command_Flickr_Label">Flickr</string>
<string name="Command_Gestures_Label">Gestures</string>
<string name="Command_Grid_Status_Label">Grid status</string>
@@ -4121,7 +4117,6 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Conversations_Tooltip">Converse with everyone</string>
<string name="Command_Compass_Tooltip">Compass</string>
<string name="Command_Destinations_Tooltip">Destinations of interest</string>
- <string name="Command_Facebook_Tooltip">Post to Facebook</string>
<string name="Command_Flickr_Tooltip">Upload to Flickr</string>
<string name="Command_Gestures_Tooltip">Gestures for your avatar</string>
<string name="Command_Grid_Status_Tooltip">Show current Grid status</string>
diff --git a/indra/newview/skins/default/xui/en/widgets/person_view.xml b/indra/newview/skins/default/xui/en/widgets/person_view.xml
index 46c1b7ff75..bfe6941a8a 100644
--- a/indra/newview/skins/default/xui/en/widgets/person_view.xml
+++ b/indra/newview/skins/default/xui/en/widgets/person_view.xml
@@ -13,16 +13,6 @@
text_pad_right="4"
arrow_size="10"
max_folder_item_overlap="2">
- <facebook_icon
- follows="left"
- height="14"
- image_name="Facebook_Icon"
- left="5"
- bottom="6"
- name="facebook_icon"
- tool_tip="Facebook User"
- visible="false"
- width="14" />
<avatar_icon
follows="left"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index 3ac2cfb69b..4239c949fd 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -2987,7 +2987,7 @@ Si vous restez dans cette région, vous serez déconnecté(e).
Si vous restez dans cette région, vous serez déconnecté(e).
</notification>
<notification name="LoadWebPage">
- Charger la page Web [URL] ?
+Charger la page Web [URL] ?
[MESSAGE]