Merge branch 'main' into DRTVWR-539
# Conflicts: # indra/integration_tests/llui_libtest/CMakeLists.txt # indra/newview/llfloateravatarrendersettings.cppmaster
commit
41d24952ff
|
|
@ -2701,9 +2701,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>2e8d817e7837dd6f4284b13fa3f5c15e</string>
|
||||
<string>9e1b5515ab59b4e9cfeef6626d65d03d</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104765/917714/viewer_manager-3.0.575083-darwin64-575083.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/108609/945996/viewer_manager-3.0.577252-darwin64-577252.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -2713,9 +2713,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>3efa80faaf537e39a77218cd6efa9409</string>
|
||||
<string>a3c599595ecc8fb987a5499fca42520a</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104766/917721/viewer_manager-3.0.575083-windows-575083.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/108610/946003/viewer_manager-3.0.577252-windows-577252.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -2726,7 +2726,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>source_type</key>
|
||||
<string>hg</string>
|
||||
<key>version</key>
|
||||
<string>3.0.575083</string>
|
||||
<string>3.0.577252</string>
|
||||
</map>
|
||||
<key>vlc-bin</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -272,6 +272,14 @@ public:
|
|||
boost::bind(&ReadPipeImpl::tick, this, _1));
|
||||
}
|
||||
|
||||
~ReadPipeImpl()
|
||||
{
|
||||
if (mConnection.connected())
|
||||
{
|
||||
mConnection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
// Much of the implementation is simply connecting the abstract virtual
|
||||
// methods with implementation data concealed from the base class.
|
||||
virtual std::istream& get_istream() { return mStream; }
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ from io import StringIO
|
|||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
|
||||
|
||||
from llbase.fastest_elementtree import parse as xml_parse
|
||||
from llbase import llsd
|
||||
|
||||
# we're in llcorehttp/tests ; testrunner.py is found in llmessage/tests
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@
|
|||
#include "llassettype.h"
|
||||
#include "lldir.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <chrono>
|
||||
|
||||
#include "lldiskcache.h"
|
||||
|
|
@ -100,19 +99,20 @@ void LLDiskCache::purge()
|
|||
#endif
|
||||
if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
|
||||
{
|
||||
for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
|
||||
boost::filesystem::directory_iterator iter(cache_path, ec);
|
||||
while (iter != boost::filesystem::directory_iterator() && !ec.failed())
|
||||
{
|
||||
if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
|
||||
if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
|
||||
{
|
||||
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
if ((*iter).path().string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
{
|
||||
uintmax_t file_size = boost::filesystem::file_size(entry, ec);
|
||||
uintmax_t file_size = boost::filesystem::file_size(*iter, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const std::string file_path = entry.path().string();
|
||||
const std::time_t file_time = boost::filesystem::last_write_time(entry, ec);
|
||||
const std::string file_path = (*iter).path().string();
|
||||
const std::time_t file_time = boost::filesystem::last_write_time(*iter, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
continue;
|
||||
|
|
@ -121,6 +121,7 @@ void LLDiskCache::purge()
|
|||
file_info.push_back(file_info_t(file_time, { file_size, file_path }));
|
||||
}
|
||||
}
|
||||
iter.increment(ec);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -348,19 +349,21 @@ void LLDiskCache::clearCache()
|
|||
#endif
|
||||
if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
|
||||
{
|
||||
for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
|
||||
boost::filesystem::directory_iterator iter(cache_path, ec);
|
||||
while (iter != boost::filesystem::directory_iterator() && !ec.failed())
|
||||
{
|
||||
if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
|
||||
if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
|
||||
{
|
||||
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
if ((*iter).path().string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
{
|
||||
boost::filesystem::remove(entry, ec);
|
||||
boost::filesystem::remove(*iter, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL;
|
||||
LL_WARNS() << "Failed to delete cache file " << *iter << ": " << ec.message() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
iter.increment(ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -379,20 +382,22 @@ void LLDiskCache::removeOldVFSFiles()
|
|||
#endif
|
||||
if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
|
||||
{
|
||||
for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
|
||||
boost::filesystem::directory_iterator iter(cache_path, ec);
|
||||
while (iter != boost::filesystem::directory_iterator() && !ec.failed())
|
||||
{
|
||||
if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
|
||||
if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
|
||||
{
|
||||
if ((entry.path().string().find(CACHE_FORMAT) != std::string::npos) ||
|
||||
(entry.path().string().find(DB_FORMAT) != std::string::npos))
|
||||
if (((*iter).path().string().find(CACHE_FORMAT) != std::string::npos) ||
|
||||
((*iter).path().string().find(DB_FORMAT) != std::string::npos))
|
||||
{
|
||||
boost::filesystem::remove(entry, ec);
|
||||
boost::filesystem::remove(*iter, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL;
|
||||
LL_WARNS() << "Failed to delete cache file " << *iter << ": " << ec.message() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
iter.increment(ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -418,19 +423,21 @@ uintmax_t LLDiskCache::dirFileSize(const std::string dir)
|
|||
#endif
|
||||
if (boost::filesystem::is_directory(dir_path, ec) && !ec.failed())
|
||||
{
|
||||
for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(dir_path, ec), {}))
|
||||
boost::filesystem::directory_iterator iter(dir_path, ec);
|
||||
while (iter != boost::filesystem::directory_iterator() && !ec.failed())
|
||||
{
|
||||
if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
|
||||
if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
|
||||
{
|
||||
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
if ((*iter).path().string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
{
|
||||
uintmax_t file_size = boost::filesystem::file_size(entry, ec);
|
||||
uintmax_t file_size = boost::filesystem::file_size(*iter, ec);
|
||||
if (!ec.failed())
|
||||
{
|
||||
total_file_size += file_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
iter.increment(ec);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ const U64 REGION_FLAGS_ALLOW_VOICE = (1 << 28);
|
|||
const U64 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29);
|
||||
const U64 REGION_FLAGS_DENY_AGEUNVERIFIED = (1 << 30);
|
||||
|
||||
const U64 REGION_FLAGS_DENY_BOTS = (1 << 31);
|
||||
|
||||
const U64 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK |
|
||||
REGION_FLAGS_ALLOW_SET_HOME |
|
||||
REGION_FLAGS_ALLOW_PARCEL_CHANGES |
|
||||
|
|
|
|||
|
|
@ -162,6 +162,11 @@ LLPluginProcessParent::~LLPluginProcessParent()
|
|||
{ // If we are quitting, the network sockets will already have been destroyed.
|
||||
killSockets();
|
||||
}
|
||||
|
||||
if (mPolling.connected())
|
||||
{
|
||||
mPolling.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
|
|
|
|||
|
|
@ -759,11 +759,13 @@ void LLFloater::closeFloater(bool app_quitting)
|
|||
}
|
||||
|
||||
// now close dependent floater
|
||||
for(handle_set_iter_t dependent_it = mDependents.begin();
|
||||
dependent_it != mDependents.end(); )
|
||||
while(mDependents.size() > 0)
|
||||
{
|
||||
handle_set_iter_t dependent_it = mDependents.begin();
|
||||
LLFloater* floaterp = dependent_it->get();
|
||||
dependent_it = mDependents.erase(dependent_it);
|
||||
// normally removeDependentFloater will do this, but in
|
||||
// case floaterp is somehow invalid or orphaned, erase now
|
||||
mDependents.erase(dependent_it);
|
||||
if (floaterp)
|
||||
{
|
||||
floaterp->mDependeeHandle = LLHandle<LLFloater>();
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ bool LLUrlEntryBase::isWikiLinkCorrect(const std::string &labeled_url) const
|
|||
{
|
||||
return (chr == L'\u02D0') // "Modifier Letter Colon"
|
||||
|| (chr == L'\uFF1A') // "Fullwidth Colon"
|
||||
|| (chr == L'\u2236') // "Ratio"
|
||||
|| (chr == L'\uFE55'); // "Small Colon"
|
||||
},
|
||||
L'\u003A'); // Colon
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
|
|||
for (it = mUrlEntry.begin(); it != mUrlEntry.end(); ++it)
|
||||
{
|
||||
//Skip for url entry icon if content is not trusted
|
||||
if(!is_content_trusted && (mUrlEntryIcon == *it))
|
||||
if((mUrlEntryIcon == *it) && ((text.find("Hand") != std::string::npos) || !is_content_trusted))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -215,6 +215,7 @@ NSWindowRef createNSWindow(int x, int y, int width, int height)
|
|||
styleMask:NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTexturedBackgroundWindowMask backing:NSBackingStoreBuffered defer:NO];
|
||||
[window makeKeyAndOrderFront:nil];
|
||||
[window setAcceptsMouseMovedEvents:TRUE];
|
||||
[window setRestorable:FALSE]; // Viewer manages state from own settings
|
||||
return window;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3905,42 +3905,48 @@ void LLWindowWin32::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
|
|||
|
||||
sLanguageTextInputAllowed = b;
|
||||
|
||||
if ( sLanguageTextInputAllowed )
|
||||
{
|
||||
// Allowing: Restore the previous IME status, so that the user has a feeling that the previous
|
||||
// text input continues naturally. Be careful, however, the IME status is meaningful only during the user keeps
|
||||
// using same Input Locale (aka Keyboard Layout).
|
||||
if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale)
|
||||
{
|
||||
HIMC himc = LLWinImm::getContext(mWindowHandle);
|
||||
LLWinImm::setOpenStatus(himc, TRUE);
|
||||
LLWinImm::setConversionStatus(himc, sWinIMEConversionMode, sWinIMESentenceMode);
|
||||
LLWinImm::releaseContext(mWindowHandle, himc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disallowing: Turn off the IME so that succeeding key events bypass IME and come to us directly.
|
||||
// However, do it after saving the current IME status. We need to restore the status when
|
||||
// allowing language text input again.
|
||||
sWinInputLocale = GetKeyboardLayout(0);
|
||||
sWinIMEOpened = LLWinImm::isIME(sWinInputLocale);
|
||||
if (sWinIMEOpened)
|
||||
{
|
||||
HIMC himc = LLWinImm::getContext(mWindowHandle);
|
||||
sWinIMEOpened = LLWinImm::getOpenStatus(himc);
|
||||
if (sWinIMEOpened)
|
||||
{
|
||||
LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode);
|
||||
if (sLanguageTextInputAllowed)
|
||||
{
|
||||
mWindowThread->post([=]()
|
||||
{
|
||||
// Allowing: Restore the previous IME status, so that the user has a feeling that the previous
|
||||
// text input continues naturally. Be careful, however, the IME status is meaningful only during the user keeps
|
||||
// using same Input Locale (aka Keyboard Layout).
|
||||
if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale)
|
||||
{
|
||||
HIMC himc = LLWinImm::getContext(mWindowHandle);
|
||||
LLWinImm::setOpenStatus(himc, TRUE);
|
||||
LLWinImm::setConversionStatus(himc, sWinIMEConversionMode, sWinIMESentenceMode);
|
||||
LLWinImm::releaseContext(mWindowHandle, himc);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
mWindowThread->post([=]()
|
||||
{
|
||||
// Disallowing: Turn off the IME so that succeeding key events bypass IME and come to us directly.
|
||||
// However, do it after saving the current IME status. We need to restore the status when
|
||||
// allowing language text input again.
|
||||
sWinInputLocale = GetKeyboardLayout(0);
|
||||
sWinIMEOpened = LLWinImm::isIME(sWinInputLocale);
|
||||
if (sWinIMEOpened)
|
||||
{
|
||||
HIMC himc = LLWinImm::getContext(mWindowHandle);
|
||||
sWinIMEOpened = LLWinImm::getOpenStatus(himc);
|
||||
if (sWinIMEOpened)
|
||||
{
|
||||
LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode);
|
||||
|
||||
// We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's
|
||||
// keyboard hooking, because Some IME reacts only on the former and some other on the latter...
|
||||
LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode);
|
||||
LLWinImm::setOpenStatus(himc, FALSE);
|
||||
}
|
||||
LLWinImm::releaseContext(mWindowHandle, himc);
|
||||
}
|
||||
}
|
||||
// We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's
|
||||
// keyboard hooking, because Some IME reacts only on the former and some other on the latter...
|
||||
LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode);
|
||||
LLWinImm::setOpenStatus(himc, FALSE);
|
||||
}
|
||||
LLWinImm::releaseContext(mWindowHandle, himc);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void LLWindowWin32::fillCandidateForm(const LLCoordGL& caret, const LLRect& bounds,
|
||||
|
|
@ -4137,6 +4143,10 @@ void LLWindowWin32::handleStartCompositionMessage()
|
|||
|
||||
void LLWindowWin32::handleCompositionMessage(const U32 indexes)
|
||||
{
|
||||
if (!mPreeditor)
|
||||
{
|
||||
return;
|
||||
}
|
||||
BOOL needs_update = FALSE;
|
||||
LLWString result_string;
|
||||
LLWString preedit_string;
|
||||
|
|
@ -4435,7 +4445,7 @@ BOOL LLWindowWin32::handleImeRequests(WPARAM request, LPARAM param, LRESULT *res
|
|||
LLWString context = find_context(wtext, preedit, preedit_length, &context_offset);
|
||||
preedit -= context_offset;
|
||||
preedit_length = llmin(preedit_length, (S32)context.length() - preedit);
|
||||
if (preedit_length && preedit >= 0)
|
||||
if (preedit_length > 0 && preedit >= 0)
|
||||
{
|
||||
// IMR_DOCUMENTFEED may be called when we have an active preedit.
|
||||
// We should pass the context string *excluding* the preedit string.
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
6.6.10
|
||||
6.6.11
|
||||
|
|
|
|||
|
|
@ -220,6 +220,17 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FetchGroupChatHistory</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Fetch recent messages from group chat servers when a group window opens</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>VoiceCallsFriendsOnly</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -133,7 +133,6 @@ LLAgentCamera::LLAgentCamera() :
|
|||
mCameraFOVZoomFactor(0.f),
|
||||
mCameraCurrentFOVZoomFactor(0.f),
|
||||
mCameraFocusOffset(),
|
||||
mCameraFOVDefault(DEFAULT_FIELD_OF_VIEW),
|
||||
|
||||
mCameraCollidePlane(),
|
||||
|
||||
|
|
@ -155,7 +154,6 @@ LLAgentCamera::LLAgentCamera() :
|
|||
mFocusObject(NULL),
|
||||
mFocusObjectDist(0.f),
|
||||
mFocusObjectOffset(),
|
||||
mFocusDotRadius( 0.1f ), // meters
|
||||
mTrackFocusObject(TRUE),
|
||||
|
||||
mAtKey(0), // Either 1, 0, or -1... indicates that movement-key is pressed
|
||||
|
|
@ -2361,6 +2359,11 @@ void LLAgentCamera::changeCameraToCustomizeAvatar()
|
|||
gAgent.standUp(); // force stand up
|
||||
gViewerWindow->getWindow()->resetBusyCount();
|
||||
|
||||
if (LLSelectMgr::getInstance()->getSelection()->isAttachment())
|
||||
{
|
||||
LLSelectMgr::getInstance()->deselectAll();
|
||||
}
|
||||
|
||||
if (gFaceEditToolset)
|
||||
{
|
||||
LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset);
|
||||
|
|
|
|||
|
|
@ -152,7 +152,6 @@ private:
|
|||
F32 mTargetCameraDistance; // Target camera offset from avatar
|
||||
F32 mCameraFOVZoomFactor; // Amount of fov zoom applied to camera when zeroing in on an object
|
||||
F32 mCameraCurrentFOVZoomFactor; // Interpolated fov zoom
|
||||
F32 mCameraFOVDefault; // Default field of view that is basis for FOV zoom effect
|
||||
LLVector4 mCameraCollidePlane; // Colliding plane for camera
|
||||
F32 mCameraZoomFraction; // Mousewheel driven fraction of zoom
|
||||
LLVector3 mCameraPositionAgent; // Camera position in agent coordinates
|
||||
|
|
@ -167,7 +166,6 @@ private:
|
|||
// Follow
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void setUsingFollowCam(bool using_follow_cam);
|
||||
bool isfollowCamLocked();
|
||||
private:
|
||||
LLFollowCam mFollowCam; // Ventrella
|
||||
|
|
@ -233,7 +231,6 @@ private:
|
|||
LLPointer<LLViewerObject> mFocusObject;
|
||||
F32 mFocusObjectDist;
|
||||
LLVector3 mFocusObjectOffset;
|
||||
F32 mFocusDotRadius; // Meters
|
||||
BOOL mTrackFocusObject;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -53,7 +53,16 @@ void LLAgentUI::buildSLURL(LLSLURL& slurl, const bool escaped /*= true*/)
|
|||
LLViewerRegion *regionp = gAgent.getRegion();
|
||||
if (regionp)
|
||||
{
|
||||
return_slurl = LLSLURL(regionp->getName(), gAgent.getPositionGlobal());
|
||||
// Make sure coordinates are within current region
|
||||
LLVector3d global_pos = gAgent.getPositionGlobal();
|
||||
LLVector3d region_origin = regionp->getOriginGlobal();
|
||||
// -1 otherwise slurl will fmod 256 to 0.
|
||||
// And valid slurl range is supposed to be 0..255
|
||||
F64 max_val = REGION_WIDTH_METERS - 1;
|
||||
global_pos.mdV[VX] = llclamp(global_pos[VX], region_origin[VX], region_origin[VX] + max_val);
|
||||
global_pos.mdV[VY] = llclamp(global_pos[VY], region_origin[VY], region_origin[VY] + max_val);
|
||||
|
||||
return_slurl = LLSLURL(regionp->getName(), global_pos);
|
||||
}
|
||||
slurl = return_slurl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5483,7 +5483,8 @@ void LLAppViewer::disconnectViewer()
|
|||
{
|
||||
gInventory.cache(gInventory.getRootFolderID(), gAgent.getID());
|
||||
if (gInventory.getLibraryRootFolderID().notNull()
|
||||
&& gInventory.getLibraryOwnerID().notNull())
|
||||
&& gInventory.getLibraryOwnerID().notNull()
|
||||
&& !mSecondInstance) // agent is unique, library isn't
|
||||
{
|
||||
gInventory.cache(
|
||||
gInventory.getLibraryRootFolderID(),
|
||||
|
|
|
|||
|
|
@ -79,7 +79,9 @@ static S32 cube_channel = -1;
|
|||
static S32 diffuse_channel = -1;
|
||||
static S32 bump_channel = -1;
|
||||
|
||||
#define LL_BUMPLIST_MULTITHREADED 0 // TODO -- figure out why this doesn't work
|
||||
// Enabled after changing LLViewerTexture::mNeedsCreateTexture to an
|
||||
// LLAtomicBool; this should work just fine, now. HB
|
||||
#define LL_BUMPLIST_MULTITHREADED 1
|
||||
|
||||
|
||||
// static
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ bool LLEstateInfoModel::getDenyAgeUnverified() const { return getFlag(REGION_FL
|
|||
bool LLEstateInfoModel::getAllowVoiceChat() const { return getFlag(REGION_FLAGS_ALLOW_VOICE); }
|
||||
bool LLEstateInfoModel::getAllowAccessOverride() const { return getFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE); }
|
||||
bool LLEstateInfoModel::getAllowEnvironmentOverride() const { return getFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE); }
|
||||
bool LLEstateInfoModel::getDenyScriptedAgents() const { return getFlag(REGION_FLAGS_DENY_BOTS); }
|
||||
|
||||
void LLEstateInfoModel::setUseFixedSun(bool val) { setFlag(REGION_FLAGS_SUN_FIXED, val); }
|
||||
void LLEstateInfoModel::setIsExternallyVisible(bool val) { setFlag(REGION_FLAGS_EXTERNALLY_VISIBLE, val); }
|
||||
|
|
@ -83,6 +84,7 @@ void LLEstateInfoModel::setDenyAgeUnverified(bool val) { setFlag(REGION_FLAGS_D
|
|||
void LLEstateInfoModel::setAllowVoiceChat(bool val) { setFlag(REGION_FLAGS_ALLOW_VOICE, val); }
|
||||
void LLEstateInfoModel::setAllowAccessOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE, val); }
|
||||
void LLEstateInfoModel::setAllowEnvironmentOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE, val); }
|
||||
void LLEstateInfoModel::setDenyScriptedAgents(bool val) { setFlag(REGION_FLAGS_DENY_BOTS, val); }
|
||||
|
||||
void LLEstateInfoModel::update(const strings_t& strings)
|
||||
{
|
||||
|
|
@ -148,6 +150,7 @@ void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url)
|
|||
body["allow_direct_teleport"] = getAllowDirectTeleport();
|
||||
body["deny_anonymous"] = getDenyAnonymous();
|
||||
body["deny_age_unverified"] = getDenyAgeUnverified();
|
||||
body["block_bots"] = getDenyScriptedAgents();
|
||||
body["allow_voice_chat"] = getAllowVoiceChat();
|
||||
body["override_public_access"] = getAllowAccessOverride();
|
||||
|
||||
|
|
@ -222,6 +225,7 @@ std::string LLEstateInfoModel::getInfoDump()
|
|||
dump["allow_direct_teleport"] = getAllowDirectTeleport();
|
||||
dump["deny_anonymous" ] = getDenyAnonymous();
|
||||
dump["deny_age_unverified" ] = getDenyAgeUnverified();
|
||||
dump["block_bots" ] = getDenyScriptedAgents();
|
||||
dump["allow_voice_chat" ] = getAllowVoiceChat();
|
||||
dump["override_public_access"] = getAllowAccessOverride();
|
||||
dump["override_environment"] = getAllowEnvironmentOverride();
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ public:
|
|||
bool getAllowVoiceChat() const;
|
||||
bool getAllowAccessOverride() const;
|
||||
bool getAllowEnvironmentOverride() const;
|
||||
bool getDenyScriptedAgents() const;
|
||||
|
||||
const std::string& getName() const { return mName; }
|
||||
const LLUUID& getOwnerID() const { return mOwnerID; }
|
||||
|
|
@ -72,6 +73,7 @@ public:
|
|||
void setAllowVoiceChat(bool val);
|
||||
void setAllowAccessOverride(bool val);
|
||||
void setAllowEnvironmentOverride(bool val);
|
||||
void setDenyScriptedAgents(bool val);
|
||||
|
||||
void setSunHour(F32 sun_hour) { mSunHour = sun_hour; }
|
||||
|
||||
|
|
|
|||
|
|
@ -428,13 +428,18 @@ void LLFloaterAvatarPicker::findCoro(std::string url, LLUUID queryID, std::strin
|
|||
|
||||
if (status || (status == LLCore::HttpStatus(HTTP_BAD_REQUEST)))
|
||||
{
|
||||
LLFloaterAvatarPicker* floater =
|
||||
LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker", name);
|
||||
if (floater)
|
||||
{
|
||||
result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
|
||||
floater->processResponse(queryID, result);
|
||||
}
|
||||
result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
|
||||
}
|
||||
else
|
||||
{
|
||||
result["failure_reason"] = status.toString();
|
||||
}
|
||||
|
||||
LLFloaterAvatarPicker* floater =
|
||||
LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker", name);
|
||||
if (floater)
|
||||
{
|
||||
floater->processResponse(queryID, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -672,59 +677,67 @@ void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD&
|
|||
{
|
||||
LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("SearchResults");
|
||||
|
||||
LLSD agents = content["agents"];
|
||||
// clear "Searching" label on first results
|
||||
search_results->deleteAllItems();
|
||||
|
||||
// clear "Searching" label on first results
|
||||
search_results->deleteAllItems();
|
||||
if (content.has("failure_reason"))
|
||||
{
|
||||
getChild<LLScrollListCtrl>("SearchResults")->setCommentText(content["failure_reason"].asString());
|
||||
getChildView("ok_btn")->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSD agents = content["agents"];
|
||||
|
||||
LLSD item;
|
||||
LLSD::array_const_iterator it = agents.beginArray();
|
||||
for ( ; it != agents.endArray(); ++it)
|
||||
{
|
||||
const LLSD& row = *it;
|
||||
if (row["id"].asUUID() != gAgent.getID() || !mExcludeAgentFromSearchResults)
|
||||
{
|
||||
item["id"] = row["id"];
|
||||
LLSD& columns = item["columns"];
|
||||
columns[0]["column"] = "name";
|
||||
columns[0]["value"] = row["display_name"];
|
||||
columns[1]["column"] = "username";
|
||||
columns[1]["value"] = row["username"];
|
||||
search_results->addElement(item);
|
||||
LLSD item;
|
||||
LLSD::array_const_iterator it = agents.beginArray();
|
||||
for (; it != agents.endArray(); ++it)
|
||||
{
|
||||
const LLSD& row = *it;
|
||||
if (row["id"].asUUID() != gAgent.getID() || !mExcludeAgentFromSearchResults)
|
||||
{
|
||||
item["id"] = row["id"];
|
||||
LLSD& columns = item["columns"];
|
||||
columns[0]["column"] = "name";
|
||||
columns[0]["value"] = row["display_name"];
|
||||
columns[1]["column"] = "username";
|
||||
columns[1]["value"] = row["username"];
|
||||
search_results->addElement(item);
|
||||
|
||||
// add the avatar name to our list
|
||||
LLAvatarName avatar_name;
|
||||
avatar_name.fromLLSD(row);
|
||||
sAvatarNameMap[row["id"].asUUID()] = avatar_name;
|
||||
}
|
||||
}
|
||||
// add the avatar name to our list
|
||||
LLAvatarName avatar_name;
|
||||
avatar_name.fromLLSD(row);
|
||||
sAvatarNameMap[row["id"].asUUID()] = avatar_name;
|
||||
}
|
||||
}
|
||||
|
||||
if (search_results->isEmpty())
|
||||
{
|
||||
std::string name = "'" + getChild<LLUICtrl>("Edit")->getValue().asString() + "'";
|
||||
LLSD item;
|
||||
item["id"] = LLUUID::null;
|
||||
item["columns"][0]["column"] = "name";
|
||||
item["columns"][0]["value"] = name;
|
||||
item["columns"][1]["column"] = "username";
|
||||
item["columns"][1]["value"] = getString("not_found_text");
|
||||
search_results->addElement(item);
|
||||
search_results->setEnabled(false);
|
||||
getChildView("ok_btn")->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
getChildView("ok_btn")->setEnabled(true);
|
||||
search_results->setEnabled(true);
|
||||
search_results->sortByColumnIndex(1, TRUE);
|
||||
std::string text = getChild<LLUICtrl>("Edit")->getValue().asString();
|
||||
if (!search_results->selectItemByLabel(text, TRUE, 1))
|
||||
{
|
||||
search_results->selectFirstItem();
|
||||
}
|
||||
onList();
|
||||
search_results->setFocus(TRUE);
|
||||
}
|
||||
if (search_results->isEmpty())
|
||||
{
|
||||
std::string name = "'" + getChild<LLUICtrl>("Edit")->getValue().asString() + "'";
|
||||
LLSD item;
|
||||
item["id"] = LLUUID::null;
|
||||
item["columns"][0]["column"] = "name";
|
||||
item["columns"][0]["value"] = name;
|
||||
item["columns"][1]["column"] = "username";
|
||||
item["columns"][1]["value"] = getString("not_found_text");
|
||||
search_results->addElement(item);
|
||||
search_results->setEnabled(false);
|
||||
getChildView("ok_btn")->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
getChildView("ok_btn")->setEnabled(true);
|
||||
search_results->setEnabled(true);
|
||||
search_results->sortByColumnIndex(1, TRUE);
|
||||
std::string text = getChild<LLUICtrl>("Edit")->getValue().asString();
|
||||
if (!search_results->selectItemByLabel(text, TRUE, 1))
|
||||
{
|
||||
search_results->selectFirstItem();
|
||||
}
|
||||
onList();
|
||||
search_results->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ public:
|
|||
virtual ~LLFloaterDisplayName() { }
|
||||
/*virtual*/ BOOL postBuild();
|
||||
void onSave();
|
||||
void onReset();
|
||||
void onCancel();
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
|
||||
|
|
@ -101,6 +102,7 @@ void LLFloaterDisplayName::onOpen(const LLSD& key)
|
|||
|
||||
BOOL LLFloaterDisplayName::postBuild()
|
||||
{
|
||||
getChild<LLUICtrl>("reset_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onReset, this));
|
||||
getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onCancel, this));
|
||||
getChild<LLUICtrl>("save_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onSave, this));
|
||||
|
||||
|
|
@ -156,6 +158,20 @@ void LLFloaterDisplayName::onCancel()
|
|||
setVisible(false);
|
||||
}
|
||||
|
||||
void LLFloaterDisplayName::onReset()
|
||||
{
|
||||
LLAvatarName av_name;
|
||||
if (!LLAvatarNameCache::get(gAgent.getID(), &av_name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
getChild<LLUICtrl>("display_name_editor")->setValue(av_name.getCompleteName());
|
||||
|
||||
getChild<LLUICtrl>("display_name_confirm")->clear();
|
||||
getChild<LLUICtrl>("display_name_confirm")->setFocus(TRUE);
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterDisplayName::onSave()
|
||||
{
|
||||
std::string display_name_utf8 = getChild<LLUICtrl>("display_name_editor")->getValue().asString();
|
||||
|
|
|
|||
|
|
@ -1880,6 +1880,7 @@ BOOL LLPanelEstateInfo::postBuild()
|
|||
initCtrl("allow_direct_teleport");
|
||||
initCtrl("limit_payment");
|
||||
initCtrl("limit_age_verified");
|
||||
initCtrl("limit_bots");
|
||||
initCtrl("voice_chat_check");
|
||||
initCtrl("parcel_access_override");
|
||||
|
||||
|
|
@ -1903,12 +1904,14 @@ void LLPanelEstateInfo::refresh()
|
|||
getChildView("Only Allow")->setEnabled(public_access);
|
||||
getChildView("limit_payment")->setEnabled(public_access);
|
||||
getChildView("limit_age_verified")->setEnabled(public_access);
|
||||
getChildView("limit_bots")->setEnabled(public_access);
|
||||
|
||||
// if this is set to false, then the limit fields are meaningless and should be turned off
|
||||
if (public_access == false)
|
||||
{
|
||||
getChild<LLUICtrl>("limit_payment")->setValue(false);
|
||||
getChild<LLUICtrl>("limit_age_verified")->setValue(false);
|
||||
getChild<LLUICtrl>("limit_bots")->setValue(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1925,6 +1928,7 @@ void LLPanelEstateInfo::refreshFromEstate()
|
|||
getChild<LLUICtrl>("limit_payment")->setValue(estate_info.getDenyAnonymous());
|
||||
getChild<LLUICtrl>("limit_age_verified")->setValue(estate_info.getDenyAgeUnverified());
|
||||
getChild<LLUICtrl>("parcel_access_override")->setValue(estate_info.getAllowAccessOverride());
|
||||
getChild<LLUICtrl>("limit_bots")->setValue(estate_info.getDenyScriptedAgents());
|
||||
|
||||
// Ensure appriopriate state of the management UI
|
||||
updateControls(gAgent.getRegion());
|
||||
|
|
@ -1968,6 +1972,7 @@ bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, con
|
|||
estate_info.setDenyAgeUnverified(getChild<LLUICtrl>("limit_age_verified")->getValue().asBoolean());
|
||||
estate_info.setAllowVoiceChat(getChild<LLUICtrl>("voice_chat_check")->getValue().asBoolean());
|
||||
estate_info.setAllowAccessOverride(getChild<LLUICtrl>("parcel_access_override")->getValue().asBoolean());
|
||||
estate_info.setDenyScriptedAgents(getChild<LLUICtrl>("limit_bots")->getValue().asBoolean());
|
||||
// JIGGLYPUFF
|
||||
//estate_info.setAllowAccessOverride(getChild<LLUICtrl>("")->getValue().asBoolean());
|
||||
// send the update to sim
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ const F32 HORIZONTAL_PADDING = 16.f;
|
|||
const F32 VERTICAL_PADDING = 12.f;
|
||||
const F32 LINE_PADDING = 3.f; // aka "leading"
|
||||
const F32 BUFFER_SIZE = 2.f;
|
||||
const F32 HUD_TEXT_MAX_WIDTH = 190.f;
|
||||
const S32 NUM_OVERLAP_ITERATIONS = 10;
|
||||
const F32 POSITION_DAMPING_TC = 0.2f;
|
||||
const F32 MAX_STABLE_CAMERA_VELOCITY = 0.1f;
|
||||
|
|
@ -67,6 +66,8 @@ const F32 LOD_2_SCREEN_COVERAGE = 0.40f;
|
|||
std::set<LLPointer<LLHUDNameTag> > LLHUDNameTag::sTextObjects;
|
||||
std::vector<LLPointer<LLHUDNameTag> > LLHUDNameTag::sVisibleTextObjects;
|
||||
BOOL LLHUDNameTag::sDisplayText = TRUE ;
|
||||
const F32 LLHUDNameTag::NAMETAG_MAX_WIDTH = 298.f;
|
||||
const F32 LLHUDNameTag::HUD_TEXT_MAX_WIDTH = 190.f;
|
||||
|
||||
bool llhudnametag_further_away::operator()(const LLPointer<LLHUDNameTag>& lhs, const LLPointer<LLHUDNameTag>& rhs) const
|
||||
{
|
||||
|
|
@ -414,7 +415,8 @@ void LLHUDNameTag::addLine(const std::string &text_utf8,
|
|||
const LLColor4& color,
|
||||
const LLFontGL::StyleFlags style,
|
||||
const LLFontGL* font,
|
||||
const bool use_ellipses)
|
||||
const bool use_ellipses,
|
||||
F32 max_pixels)
|
||||
{
|
||||
LLWString wline = utf8str_to_wstring(text_utf8);
|
||||
if (!wline.empty())
|
||||
|
|
@ -431,7 +433,7 @@ void LLHUDNameTag::addLine(const std::string &text_utf8,
|
|||
tokenizer tokens(wline, sep);
|
||||
tokenizer::iterator iter = tokens.begin();
|
||||
|
||||
const F32 max_pixels = HUD_TEXT_MAX_WIDTH;
|
||||
max_pixels = llmin(max_pixels, NAMETAG_MAX_WIDTH);
|
||||
while (iter != tokens.end())
|
||||
{
|
||||
U32 line_length = 0;
|
||||
|
|
@ -488,7 +490,7 @@ void LLHUDNameTag::setLabel(const std::string &label_utf8)
|
|||
addLabel(label_utf8);
|
||||
}
|
||||
|
||||
void LLHUDNameTag::addLabel(const std::string& label_utf8)
|
||||
void LLHUDNameTag::addLabel(const std::string& label_utf8, F32 max_pixels)
|
||||
{
|
||||
LLWString wstr = utf8string_to_wstring(label_utf8);
|
||||
if (!wstr.empty())
|
||||
|
|
@ -502,13 +504,15 @@ void LLHUDNameTag::addLabel(const std::string& label_utf8)
|
|||
tokenizer tokens(wstr, sep);
|
||||
tokenizer::iterator iter = tokens.begin();
|
||||
|
||||
max_pixels = llmin(max_pixels, NAMETAG_MAX_WIDTH);
|
||||
|
||||
while (iter != tokens.end())
|
||||
{
|
||||
U32 line_length = 0;
|
||||
do
|
||||
{
|
||||
S32 segment_length = mFontp->maxDrawableChars(iter->substr(line_length).c_str(),
|
||||
HUD_TEXT_MAX_WIDTH, wstr.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE);
|
||||
max_pixels, wstr.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE);
|
||||
LLHUDTextSegment segment(iter->substr(line_length, segment_length), LLFontGL::NORMAL, mColor, mFontp);
|
||||
mLabelSegments.push_back(segment);
|
||||
line_length += segment_length;
|
||||
|
|
@ -695,7 +699,7 @@ void LLHUDNameTag::updateSize()
|
|||
const LLFontGL* fontp = iter->mFont;
|
||||
height += fontp->getLineHeight();
|
||||
height += LINE_PADDING;
|
||||
width = llmax(width, llmin(iter->getWidth(fontp), HUD_TEXT_MAX_WIDTH));
|
||||
width = llmax(width, llmin(iter->getWidth(fontp), NAMETAG_MAX_WIDTH));
|
||||
++iter;
|
||||
}
|
||||
|
||||
|
|
@ -709,7 +713,7 @@ void LLHUDNameTag::updateSize()
|
|||
while (iter != mLabelSegments.end())
|
||||
{
|
||||
height += mFontp->getLineHeight();
|
||||
width = llmax(width, llmin(iter->getWidth(mFontp), HUD_TEXT_MAX_WIDTH));
|
||||
width = llmax(width, llmin(iter->getWidth(mFontp), NAMETAG_MAX_WIDTH));
|
||||
++iter;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,9 @@ public:
|
|||
ALIGN_VERT_CENTER
|
||||
} EVertAlignment;
|
||||
|
||||
static const F32 NAMETAG_MAX_WIDTH; // 298px, made to fit 31 M's
|
||||
static const F32 HUD_TEXT_MAX_WIDTH; // 190px
|
||||
|
||||
public:
|
||||
// Set entire string, eliminating existing lines
|
||||
void setString(const std::string& text_utf8);
|
||||
|
|
@ -92,11 +95,17 @@ public:
|
|||
void clearString();
|
||||
|
||||
// Add text a line at a time, allowing custom formatting
|
||||
void addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL, const LLFontGL* font = NULL, const bool use_ellipses = false);
|
||||
void addLine(
|
||||
const std::string &text_utf8,
|
||||
const LLColor4& color,
|
||||
const LLFontGL::StyleFlags style = LLFontGL::NORMAL,
|
||||
const LLFontGL* font = NULL,
|
||||
const bool use_ellipses = false,
|
||||
F32 max_pixels = HUD_TEXT_MAX_WIDTH);
|
||||
|
||||
// For bubble chat, set the part above the chat text
|
||||
void setLabel(const std::string& label_utf8);
|
||||
void addLabel(const std::string& label_utf8);
|
||||
void addLabel(const std::string& label_utf8, F32 max_pixels = HUD_TEXT_MAX_WIDTH);
|
||||
|
||||
// Sets the default font for lines with no font specified
|
||||
void setFont(const LLFontGL* font);
|
||||
|
|
|
|||
|
|
@ -453,7 +453,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
|
|||
BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
|
||||
BOOL accept_im_from_only_friend = gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly");
|
||||
BOOL is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
|
||||
LLMuteList::getInstance()->isLinden(name);
|
||||
LLMuteList::isLinden(name);
|
||||
|
||||
chat.mMuted = is_muted;
|
||||
chat.mFromID = from_id;
|
||||
|
|
@ -521,7 +521,9 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
|
|||
dialog,
|
||||
parent_estate_id,
|
||||
region_id,
|
||||
position);
|
||||
position,
|
||||
false, // is_region_msg
|
||||
timestamp);
|
||||
|
||||
if (!gIMMgr->isDNDMessageSend(session_id))
|
||||
{
|
||||
|
|
@ -592,7 +594,8 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
|
|||
parent_estate_id,
|
||||
region_id,
|
||||
position,
|
||||
region_message);
|
||||
region_message,
|
||||
timestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1111,7 +1114,9 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
|
|||
IM_SESSION_INVITE,
|
||||
parent_estate_id,
|
||||
region_id,
|
||||
position);
|
||||
position,
|
||||
false, // is_region_msg
|
||||
timestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1131,12 +1136,14 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
|
|||
from_id,
|
||||
name,
|
||||
buffer,
|
||||
IM_OFFLINE == offline,
|
||||
ll_safe_string((char*)binary_bucket),
|
||||
(IM_OFFLINE == offline),
|
||||
ll_safe_string((char*)binary_bucket), // session name
|
||||
IM_SESSION_INVITE,
|
||||
parent_estate_id,
|
||||
region_id,
|
||||
position);
|
||||
position,
|
||||
false, // is_region_msg
|
||||
timestamp);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -42,6 +42,7 @@ class LLAvatarName;
|
|||
class LLFriendObserver;
|
||||
class LLCallDialogManager;
|
||||
class LLIMSpeakerMgr;
|
||||
|
||||
/**
|
||||
* Timeout Timer for outgoing Ad-Hoc/Group IM sessions which being initialized by the server
|
||||
*/
|
||||
|
|
@ -63,11 +64,14 @@ private:
|
|||
class LLIMModel : public LLSingleton<LLIMModel>
|
||||
{
|
||||
LLSINGLETON(LLIMModel);
|
||||
|
||||
public:
|
||||
|
||||
struct LLIMSession : public boost::signals2::trackable
|
||||
typedef std::list<LLSD> chat_message_list_t;
|
||||
|
||||
struct LLIMSession : public boost::signals2::trackable
|
||||
{
|
||||
typedef enum e_session_type
|
||||
typedef enum e_session_type
|
||||
{ // for now we have 4 predefined types for a session
|
||||
P2P_SESSION,
|
||||
GROUP_SESSION,
|
||||
|
|
@ -75,15 +79,23 @@ public:
|
|||
NONE_SESSION,
|
||||
} SType;
|
||||
|
||||
LLIMSession(const LLUUID& session_id, const std::string& name,
|
||||
LLIMSession(const LLUUID& session_id, const std::string& name,
|
||||
const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg);
|
||||
virtual ~LLIMSession();
|
||||
|
||||
void sessionInitReplyReceived(const LLUUID& new_session_id);
|
||||
void addMessagesFromHistory(const std::list<LLSD>& history);
|
||||
void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history = false, bool is_region_msg = false);
|
||||
void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction);
|
||||
|
||||
void addMessagesFromHistoryCache(const std::list<LLSD>& history); // From local file
|
||||
void addMessagesFromServerHistory(const LLSD& history, const std::string& target_from, const std::string& target_message, U32 timestamp); // From chat server
|
||||
void addMessage(const std::string& from,
|
||||
const LLUUID& from_id,
|
||||
const std::string& utf8_text,
|
||||
const std::string& time,
|
||||
const bool is_history,
|
||||
const bool is_region_msg,
|
||||
U32 timestamp);
|
||||
|
||||
void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction);
|
||||
|
||||
/** @deprecated */
|
||||
static void chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata);
|
||||
|
||||
|
|
@ -112,6 +124,10 @@ public:
|
|||
uuid_vec_t mInitialTargetIDs;
|
||||
std::string mHistoryFileName;
|
||||
|
||||
// Saved messages from the last minute of history read from the local group chat cache file
|
||||
std::string mLastHistoryCacheDateTime;
|
||||
chat_message_list_t mLastHistoryCacheMsgs;
|
||||
|
||||
// connection to voice channel state change signal
|
||||
boost::signals2::connection mVoiceChannelStateChangeConnection;
|
||||
|
||||
|
|
@ -121,7 +137,7 @@ public:
|
|||
// does include all incoming messages
|
||||
S32 mNumUnread;
|
||||
|
||||
std::list<LLSD> mMsgs;
|
||||
chat_message_list_t mMsgs;
|
||||
|
||||
LLVoiceChannel* mVoiceChannel;
|
||||
LLIMSpeakerMgr* mSpeakers;
|
||||
|
|
@ -208,29 +224,43 @@ public:
|
|||
* and also saved into a file if log2file is specified.
|
||||
* It sends new message signal for each added message.
|
||||
*/
|
||||
bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true, bool is_region_msg = false);
|
||||
void addMessage(const LLUUID& session_id,
|
||||
const std::string& from,
|
||||
const LLUUID& other_participant_id,
|
||||
const std::string& utf8_text,
|
||||
bool log2file = true,
|
||||
bool is_region_msg = false,
|
||||
U32 time_stamp = 0);
|
||||
|
||||
void processAddingMessage(const LLUUID& session_id,
|
||||
const std::string& from,
|
||||
const LLUUID& from_id,
|
||||
const std::string& utf8_text,
|
||||
bool log2file,
|
||||
bool is_region_msg,
|
||||
U32 time_stamp);
|
||||
|
||||
/**
|
||||
* Similar to addMessage(...) above but won't send a signal about a new message added
|
||||
*/
|
||||
LLIMModel::LLIMSession* addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id,
|
||||
const std::string& utf8_text, bool log2file = true, bool is_region_msg = false);
|
||||
LLIMModel::LLIMSession* addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id,
|
||||
const std::string& utf8_text, bool log2file = true, bool is_region_msg = false, U32 timestamp = 0);
|
||||
|
||||
/**
|
||||
* Add a system message to an IM Model
|
||||
*/
|
||||
bool proccessOnlineOfflineNotification(const LLUUID& session_id, const std::string& utf8_text);
|
||||
void proccessOnlineOfflineNotification(const LLUUID& session_id, const std::string& utf8_text);
|
||||
|
||||
/**
|
||||
* Get a session's name.
|
||||
* For a P2P chat - it's an avatar's name,
|
||||
* Get a session's name.
|
||||
* For a P2P chat - it's an avatar's name,
|
||||
* For a group chat - it's a group's name
|
||||
* For an incoming ad-hoc chat - is received from the server and is in a from of "<Avatar's name> Conference"
|
||||
* It is updated in LLIMModel::LLIMSession's constructor to localize the "Conference".
|
||||
*/
|
||||
const std::string getName(const LLUUID& session_id) const;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get number of unread messages in a session with session_id
|
||||
* Returns -1 if the session with session_id doesn't exist
|
||||
*/
|
||||
|
|
@ -282,7 +312,7 @@ public:
|
|||
bool logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
/**
|
||||
* Populate supplied std::list with messages starting from index specified by start_index without
|
||||
* emitting no unread messages signal.
|
||||
|
|
@ -292,7 +322,7 @@ private:
|
|||
/**
|
||||
* Add message to a list of message associated with session specified by session_id
|
||||
*/
|
||||
bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg = false);
|
||||
bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg, U32 timestamp);
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -334,7 +364,8 @@ public:
|
|||
U32 parent_estate_id = 0,
|
||||
const LLUUID& region_id = LLUUID::null,
|
||||
const LLVector3& position = LLVector3::zero,
|
||||
bool is_region_msg = false);
|
||||
bool is_region_msg = false,
|
||||
U32 timestamp = 0);
|
||||
|
||||
void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args);
|
||||
|
||||
|
|
|
|||
|
|
@ -529,7 +529,11 @@ BOOL get_is_item_worn(const LLUUID& id)
|
|||
const LLViewerInventoryItem* item = gInventory.getItem(id);
|
||||
if (!item)
|
||||
return FALSE;
|
||||
|
||||
|
||||
if (item->getIsLinkType() && !gInventory.getItem(item->getLinkedUUID()))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
// Consider the item as worn if it has links in COF.
|
||||
if (LLAppearanceMgr::instance().isLinkedInCOF(id))
|
||||
{
|
||||
|
|
@ -787,7 +791,7 @@ void show_item_original(const LLUUID& item_uuid)
|
|||
LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel();
|
||||
if (main_inventory)
|
||||
{
|
||||
main_inventory->resetFilters();
|
||||
main_inventory->resetAllItemsFilters();
|
||||
}
|
||||
reset_inventory_filter();
|
||||
|
||||
|
|
@ -795,6 +799,7 @@ void show_item_original(const LLUUID& item_uuid)
|
|||
{
|
||||
LLFloaterReg::toggleInstanceOrBringToFront("inventory");
|
||||
}
|
||||
sidepanel_inventory->showInventoryPanel();
|
||||
|
||||
const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
|
||||
if (gInventory.isObjectDescendentOf(gInventory.getLinkedItemID(item_uuid), inbox_id))
|
||||
|
|
@ -2650,7 +2655,12 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
|
|||
}
|
||||
else
|
||||
{
|
||||
std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids));
|
||||
for (std::set<LLFolderViewItem*>::iterator it = selected_items.begin(), end_it = selected_items.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
ids.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
// Check for actions that get handled in bulk
|
||||
|
|
@ -2711,7 +2721,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
|
|||
}
|
||||
else if ("ungroup_folder_items" == action)
|
||||
{
|
||||
if (selected_uuid_set.size() == 1)
|
||||
if (ids.size() == 1)
|
||||
{
|
||||
LLInventoryCategory* inv_cat = gInventory.getCategory(*ids.begin());
|
||||
if (!inv_cat || LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()))
|
||||
|
|
|
|||
|
|
@ -1636,6 +1636,9 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo
|
|||
LL_WARNS(LOG_INV) << "Deleting non-existent object [ id: " << id << " ] " << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
//collect the links before removing the item from mItemMap
|
||||
LLInventoryModel::item_array_t links = collectLinksTo(id);
|
||||
|
||||
LL_DEBUGS(LOG_INV) << "Deleting inventory object " << id << LL_ENDL;
|
||||
mLastItem = NULL;
|
||||
|
|
@ -1693,7 +1696,7 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo
|
|||
// update is getting broken link info separately.
|
||||
if (fix_broken_links && !is_link_type)
|
||||
{
|
||||
updateLinkedObjectsFromPurge(id);
|
||||
rebuildLinkItems(links);
|
||||
}
|
||||
obj = nullptr; // delete obj
|
||||
if (do_notify_observers)
|
||||
|
|
@ -1702,26 +1705,25 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo
|
|||
}
|
||||
}
|
||||
|
||||
void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id)
|
||||
void LLInventoryModel::rebuildLinkItems(LLInventoryModel::item_array_t& items)
|
||||
{
|
||||
LLInventoryModel::item_array_t item_array = collectLinksTo(baseobj_id);
|
||||
|
||||
// REBUILD is expensive, so clear the current change list first else
|
||||
// everything else on the changelist will also get rebuilt.
|
||||
if (item_array.size() > 0)
|
||||
{
|
||||
notifyObservers();
|
||||
for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
|
||||
iter != item_array.end();
|
||||
iter++)
|
||||
{
|
||||
const LLViewerInventoryItem *linked_item = (*iter);
|
||||
const LLUUID &item_id = linked_item->getUUID();
|
||||
if (item_id == baseobj_id) continue;
|
||||
addChangedMask(LLInventoryObserver::REBUILD, item_id);
|
||||
}
|
||||
notifyObservers();
|
||||
}
|
||||
// REBUILD is expensive, so clear the current change list first else
|
||||
// everything else on the changelist will also get rebuilt.
|
||||
if (items.size() > 0)
|
||||
{
|
||||
notifyObservers();
|
||||
for (LLInventoryModel::item_array_t::const_iterator iter = items.begin();
|
||||
iter != items.end();
|
||||
iter++)
|
||||
{
|
||||
const LLViewerInventoryItem *linked_item = (*iter);
|
||||
if (linked_item)
|
||||
{
|
||||
addChangedMask(LLInventoryObserver::REBUILD, linked_item->getUUID());
|
||||
}
|
||||
}
|
||||
notifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
// Add/remove an observer. If the observer is destroyed, be sure to
|
||||
|
|
@ -1951,18 +1953,20 @@ void LLInventoryModel::cache(
|
|||
items,
|
||||
INCLUDE_TRASH,
|
||||
can_cache);
|
||||
std::string inventory_filename = getInvCacheAddres(agent_id);
|
||||
saveToFile(inventory_filename, categories, items);
|
||||
std::string gzip_filename(inventory_filename);
|
||||
// Use temporary file to avoid potential conflicts with other
|
||||
// instances (even a 'read only' instance unzips into a file)
|
||||
std::string temp_file = gDirUtilp->getTempFilename();
|
||||
saveToFile(temp_file, categories, items);
|
||||
std::string gzip_filename = getInvCacheAddres(agent_id);
|
||||
gzip_filename.append(".gz");
|
||||
if(gzip_file(inventory_filename, gzip_filename))
|
||||
if(gzip_file(temp_file, gzip_filename))
|
||||
{
|
||||
LL_DEBUGS(LOG_INV) << "Successfully compressed " << inventory_filename << LL_ENDL;
|
||||
LLFile::remove(inventory_filename);
|
||||
LL_DEBUGS(LOG_INV) << "Successfully compressed " << temp_file << " to " << gzip_filename << LL_ENDL;
|
||||
LLFile::remove(temp_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS(LOG_INV) << "Unable to compress " << inventory_filename << LL_ENDL;
|
||||
LL_WARNS(LOG_INV) << "Unable to compress " << temp_file << " into " << gzip_filename << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3035,6 +3039,7 @@ bool LLInventoryModel::saveToFile(const std::string& filename,
|
|||
return false;
|
||||
}
|
||||
}
|
||||
fileXML.flush();
|
||||
|
||||
fileXML.close();
|
||||
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ public:
|
|||
void checkTrashOverflow();
|
||||
|
||||
protected:
|
||||
void updateLinkedObjectsFromPurge(const LLUUID& baseobj_id);
|
||||
void rebuildLinkItems(LLInventoryModel::item_array_t& items);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Reorder
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
|
|||
//If there are items in mFetchQueue, we want to check the time since the last bulkFetch was
|
||||
//sent. If it exceeds our retry time, go ahead and fire off another batch.
|
||||
LLViewerRegion * region(gAgent.getRegion());
|
||||
if (! region || gDisconnected)
|
||||
if (! region || gDisconnected || LLApp::isExiting())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1627,6 +1627,7 @@ void LLInventoryPanel::purgeSelectedItems()
|
|||
if (inventory_selected.empty()) return;
|
||||
LLSD args;
|
||||
S32 count = inventory_selected.size();
|
||||
std::vector<LLUUID> selected_items;
|
||||
for (std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin(), end_it = inventory_selected.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
|
|
@ -1636,27 +1637,23 @@ void LLInventoryPanel::purgeSelectedItems()
|
|||
LLInventoryModel::item_array_t items;
|
||||
gInventory.collectDescendents(item_id, cats, items, LLInventoryModel::INCLUDE_TRASH);
|
||||
count += items.size() + cats.size();
|
||||
selected_items.push_back(item_id);
|
||||
}
|
||||
args["COUNT"] = count;
|
||||
LLNotificationsUtil::add("PurgeSelectedItems", args, LLSD(), boost::bind(&LLInventoryPanel::callbackPurgeSelectedItems, this, _1, _2));
|
||||
LLNotificationsUtil::add("PurgeSelectedItems", args, LLSD(), boost::bind(callbackPurgeSelectedItems, _1, _2, selected_items));
|
||||
}
|
||||
|
||||
void LLInventoryPanel::callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response)
|
||||
// static
|
||||
void LLInventoryPanel::callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response, const std::vector<LLUUID> inventory_selected)
|
||||
{
|
||||
if (!mFolderRoot.get()) return;
|
||||
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (option == 0)
|
||||
{
|
||||
const std::set<LLFolderViewItem*> inventory_selected = mFolderRoot.get()->getSelectionList();
|
||||
if (inventory_selected.empty()) return;
|
||||
|
||||
std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin();
|
||||
const std::set<LLFolderViewItem*>::const_iterator it_end = inventory_selected.end();
|
||||
for (; it != it_end; ++it)
|
||||
for (auto it : inventory_selected)
|
||||
{
|
||||
LLUUID item_id = static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID();
|
||||
remove_inventory_object(item_id, NULL);
|
||||
remove_inventory_object(it, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ public:
|
|||
// Clean up stuff when the folder root gets deleted
|
||||
void clearFolderRoot();
|
||||
|
||||
void callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response);
|
||||
static void callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response, const std::vector<LLUUID> inventory_selected);
|
||||
|
||||
protected:
|
||||
void openStartFolderOrMyInventory(); // open the first level of inventory
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@
|
|||
const S32 LOG_RECALL_SIZE = 2048;
|
||||
|
||||
const std::string LL_IM_TIME("time");
|
||||
const std::string LL_IM_DATE_TIME("datetime");
|
||||
const std::string LL_IM_TEXT("message");
|
||||
const std::string LL_IM_FROM("from");
|
||||
const std::string LL_IM_FROM_ID("from_id");
|
||||
|
|
@ -133,14 +134,14 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
|
|||
messages.back()[LL_IM_TEXT] = im_text;
|
||||
}
|
||||
|
||||
std::string remove_utf8_bom(const char* buf)
|
||||
const char* remove_utf8_bom(const char* buf)
|
||||
{
|
||||
std::string res(buf);
|
||||
if (res[0] == (char)0xEF && res[1] == (char)0xBB && res[2] == (char)0xBF)
|
||||
{
|
||||
res.erase(0, 3);
|
||||
const char* start = buf;
|
||||
if (start[0] == (char)0xEF && start[1] == (char)0xBB && start[2] == (char)0xBF)
|
||||
{ // If string starts with the magic bytes, return pointer after it.
|
||||
start += 3;
|
||||
}
|
||||
return res;
|
||||
return start;
|
||||
}
|
||||
|
||||
class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner>
|
||||
|
|
@ -315,7 +316,7 @@ std::string LLLogChat::cleanFileName(std::string filename)
|
|||
return filename;
|
||||
}
|
||||
|
||||
std::string LLLogChat::timestamp(bool withdate)
|
||||
std::string LLLogChat::timestamp2LogString(U32 timestamp, bool withdate)
|
||||
{
|
||||
std::string timeStr;
|
||||
if (withdate)
|
||||
|
|
@ -333,7 +334,14 @@ std::string LLLogChat::timestamp(bool withdate)
|
|||
}
|
||||
|
||||
LLSD substitution;
|
||||
substitution["datetime"] = (S32)time_corrected();
|
||||
if (timestamp == 0)
|
||||
{
|
||||
substitution["datetime"] = (S32)time_corrected();
|
||||
}
|
||||
else
|
||||
{ // timestamp is correct utc already
|
||||
substitution["datetime"] = (S32)timestamp;
|
||||
}
|
||||
|
||||
LLStringUtil::format (timeStr, substitution);
|
||||
return timeStr;
|
||||
|
|
@ -355,7 +363,7 @@ void LLLogChat::saveHistory(const std::string& filename,
|
|||
llassert(tmp_filename.size());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
llofstream file(LLLogChat::makeLogFileName(filename).c_str(), std::ios_base::app);
|
||||
if (!file.is_open())
|
||||
{
|
||||
|
|
@ -366,7 +374,7 @@ void LLLogChat::saveHistory(const std::string& filename,
|
|||
LLSD item;
|
||||
|
||||
if (gSavedPerAccountSettings.getBOOL("LogTimestamp"))
|
||||
item["time"] = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate"));
|
||||
item["time"] = LLLogChat::timestamp2LogString(0, gSavedPerAccountSettings.getBOOL("LogTimestampDate"));
|
||||
|
||||
item["from_id"] = from_id;
|
||||
item["message"] = line;
|
||||
|
|
@ -374,7 +382,7 @@ void LLLogChat::saveHistory(const std::string& filename,
|
|||
//adding "Second Life:" for all system messages to make chat log history parsing more reliable
|
||||
if (from.empty() && from_id.isNull())
|
||||
{
|
||||
item["from"] = SYSTEM_FROM;
|
||||
item["from"] = SYSTEM_FROM;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -393,37 +401,60 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
|
|||
{
|
||||
if (file_name.empty())
|
||||
{
|
||||
LL_WARNS("LLLogChat::loadChatHistory") << "Session name is Empty!" << LL_ENDL;
|
||||
LL_WARNS("LLLogChat::loadChatHistory") << "Local history file name is empty!" << LL_ENDL;
|
||||
return ;
|
||||
}
|
||||
|
||||
bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false;
|
||||
|
||||
LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
|
||||
// Stat the file to find it and get the last history entry time
|
||||
llstat stat_data;
|
||||
|
||||
std::string log_file_name = LLLogChat::makeLogFileName(file_name);
|
||||
LL_DEBUGS("ChatHistory") << "First attempt to stat chat history file " << log_file_name << LL_ENDL;
|
||||
|
||||
S32 no_stat = LLFile::stat(log_file_name, &stat_data);
|
||||
|
||||
if (no_stat)
|
||||
{
|
||||
if (is_group)
|
||||
{
|
||||
std::string old_name(file_name);
|
||||
old_name.erase(old_name.size() - GROUP_CHAT_SUFFIX.size()); // trim off " (group)"
|
||||
log_file_name = LLLogChat::makeLogFileName(old_name);
|
||||
LL_DEBUGS("ChatHistory") << "Attempting to stat adjusted chat history file " << log_file_name << LL_ENDL;
|
||||
no_stat = LLFile::stat(log_file_name, &stat_data);
|
||||
if (!no_stat)
|
||||
{ // Found it without "(group)", copy to new naming style. We already have the mod time in stat_data
|
||||
log_file_name = LLLogChat::makeLogFileName(file_name);
|
||||
LL_DEBUGS("ChatHistory") << "Attempt to stat copied history file " << log_file_name << LL_ENDL;
|
||||
LLFile::copy(LLLogChat::makeLogFileName(old_name), log_file_name);
|
||||
}
|
||||
}
|
||||
if (no_stat)
|
||||
{
|
||||
log_file_name = LLLogChat::oldLogFileName(file_name);
|
||||
LL_DEBUGS("ChatHistory") << "Attempt to stat old history file name " << log_file_name << LL_ENDL;
|
||||
no_stat = LLFile::stat(log_file_name, &stat_data);
|
||||
if (no_stat)
|
||||
{
|
||||
LL_DEBUGS("ChatHistory") << "No previous conversation log file found for " << file_name << LL_ENDL;
|
||||
return; //No previous conversation with this name.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we got here, we managed to stat the file.
|
||||
// Open the file to read
|
||||
LLFILE* fptr = LLFile::fopen(log_file_name, "r"); /*Flawfinder: ignore*/
|
||||
if (!fptr)
|
||||
{
|
||||
if (is_group)
|
||||
{
|
||||
std::string old_name(file_name);
|
||||
old_name.erase(old_name.size() - GROUP_CHAT_SUFFIX.size());
|
||||
fptr = LLFile::fopen(LLLogChat::makeLogFileName(old_name), "r");
|
||||
if (fptr)
|
||||
{
|
||||
fclose(fptr);
|
||||
LLFile::copy(LLLogChat::makeLogFileName(old_name), LLLogChat::makeLogFileName(file_name));
|
||||
}
|
||||
fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");
|
||||
}
|
||||
if (!fptr)
|
||||
{
|
||||
fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
|
||||
if (!fptr)
|
||||
{
|
||||
return; //No previous conversation with this name.
|
||||
}
|
||||
}
|
||||
{ // Ok, this is strange but not really tragic in the big picture of things
|
||||
LL_WARNS("ChatHistory") << "Unable to read file " << log_file_name << " after stat was successful" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
S32 save_num_messages = messages.size();
|
||||
|
||||
char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/
|
||||
char *bptr;
|
||||
S32 len;
|
||||
|
|
@ -441,6 +472,7 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
|
|||
while (fgets(buffer, LOG_RECALL_SIZE, fptr) && !feof(fptr))
|
||||
{
|
||||
len = strlen(buffer) - 1; /*Flawfinder: ignore*/
|
||||
// backfill any end of line characters with nulls
|
||||
for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--) *bptr='\0';
|
||||
|
||||
if (firstline)
|
||||
|
|
@ -473,6 +505,10 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
|
|||
}
|
||||
}
|
||||
fclose(fptr);
|
||||
|
||||
LL_DEBUGS("ChatHistory") << "Read " << (messages.size() - save_num_messages)
|
||||
<< " messages of chat history from " << log_file_name
|
||||
<< " file mod time " << (F64)stat_data.st_mtime << LL_ENDL;
|
||||
}
|
||||
|
||||
bool LLLogChat::historyThreadsFinished(LLUUID session_id)
|
||||
|
|
@ -837,7 +873,8 @@ bool LLLogChat::isTranscriptFileFound(std::string fullname)
|
|||
{
|
||||
//matching a timestamp
|
||||
boost::match_results<std::string::const_iterator> matches;
|
||||
if (ll_regex_match(remove_utf8_bom(buffer), matches, TIMESTAMP))
|
||||
std::string line(remove_utf8_bom(buffer));
|
||||
if (ll_regex_match(line, matches, TIMESTAMP))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
|
@ -847,7 +884,7 @@ bool LLLogChat::isTranscriptFileFound(std::string fullname)
|
|||
return result;
|
||||
}
|
||||
|
||||
//*TODO mark object's names in a special way so that they will be distinguishable form avatar name
|
||||
//*TODO mark object's names in a special way so that they will be distinguishable form avatar name
|
||||
//which are more strict by its nature (only firstname and secondname)
|
||||
//Example, an object's name can be written like "Object <actual_object's_name>"
|
||||
void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
|
||||
|
|
@ -865,7 +902,7 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
|
|||
ostr << '[' << timestamp << ']' << TWO_SPACES;
|
||||
}
|
||||
|
||||
//*TODO mark object's names in a special way so that they will be distinguishable form avatar name
|
||||
//*TODO mark object's names in a special way so that they will be distinguishable from avatar name
|
||||
//which are more strict by its nature (only firstname and secondname)
|
||||
//Example, an object's name can be written like "Object <actual_object's_name>"
|
||||
if (im[LL_IM_FROM].isDefined())
|
||||
|
|
@ -928,7 +965,9 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
|
|||
timestamp.erase(0, 1);
|
||||
timestamp.erase(timestamp.length()-1, 1);
|
||||
|
||||
if (cut_off_todays_date)
|
||||
im[LL_IM_DATE_TIME] = timestamp; // Retain full date-time for merging chat histories
|
||||
|
||||
if (cut_off_todays_date)
|
||||
{
|
||||
LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp);
|
||||
}
|
||||
|
|
@ -936,9 +975,9 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
|
|||
im[LL_IM_TIME] = timestamp;
|
||||
}
|
||||
else
|
||||
{
|
||||
//timestamp is optional
|
||||
im[LL_IM_TIME] = "";
|
||||
{ //timestamp is optional
|
||||
im[LL_IM_DATE_TIME] = "";
|
||||
im[LL_IM_TIME] = "";
|
||||
}
|
||||
|
||||
bool has_stuff = matches[IDX_STUFF].matched;
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ public:
|
|||
LOG_END
|
||||
};
|
||||
|
||||
static std::string timestamp(bool withdate = false);
|
||||
static std::string timestamp2LogString(U32 timestamp, bool withdate);
|
||||
static std::string makeLogFileName(std::string(filename));
|
||||
static void renameLogFile(const std::string& old_filename, const std::string& new_filename);
|
||||
/**
|
||||
|
|
@ -201,6 +201,7 @@ extern const std::string GROUP_CHAT_SUFFIX;
|
|||
|
||||
// LLSD map lookup constants
|
||||
extern const std::string LL_IM_TIME; //("time");
|
||||
extern const std::string LL_IM_DATE_TIME; //("datetime");
|
||||
extern const std::string LL_IM_TEXT; //("message");
|
||||
extern const std::string LL_IM_FROM; //("from");
|
||||
extern const std::string LL_IM_FROM_ID; //("from_id");
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ void LLMuteList::cleanupSingleton()
|
|||
LLAvatarNameCache::getInstance()->setAccountNameChangedCallback(NULL);
|
||||
}
|
||||
|
||||
BOOL LLMuteList::isLinden(const std::string& name) const
|
||||
bool LLMuteList::isLinden(const std::string& name)
|
||||
{
|
||||
std::string username = boost::replace_all_copy(name, ".", " ");
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
|
|
@ -200,9 +200,9 @@ BOOL LLMuteList::isLinden(const std::string& name) const
|
|||
tokenizer tokens(username, sep);
|
||||
tokenizer::iterator token_iter = tokens.begin();
|
||||
|
||||
if (token_iter == tokens.end()) return FALSE;
|
||||
if (token_iter == tokens.end()) return false;
|
||||
token_iter++;
|
||||
if (token_iter == tokens.end()) return FALSE;
|
||||
if (token_iter == tokens.end()) return false;
|
||||
|
||||
std::string last_name = *token_iter;
|
||||
LLStringUtil::toLower(last_name);
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ public:
|
|||
// Alternate (convenience) form for places we don't need to pass the name, but do need flags
|
||||
BOOL isMuted(const LLUUID& id, U32 flags) const { return isMuted(id, LLStringUtil::null, flags); };
|
||||
|
||||
BOOL isLinden(const std::string& name) const;
|
||||
static bool isLinden(const std::string& name);
|
||||
|
||||
BOOL isLoaded() const { return mIsLoaded; }
|
||||
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ void LLHandlerUtil::addNotifPanelToIM(const LLNotificationPtr& notification)
|
|||
LLSD offer;
|
||||
offer["notification_id"] = notification->getID();
|
||||
offer["from"] = SYSTEM_FROM;
|
||||
offer["time"] = LLLogChat::timestamp(false);
|
||||
offer["time"] = LLLogChat::timestamp2LogString(0, false); // Use current time
|
||||
offer["index"] = (LLSD::Integer)session->mMsgs.size();
|
||||
session->mMsgs.push_front(offer);
|
||||
|
||||
|
|
|
|||
|
|
@ -1103,6 +1103,18 @@ void LLPanelLogin::onRememberPasswordCheck(void*)
|
|||
if (sInstance)
|
||||
{
|
||||
gSavedSettings.setBOOL("UpdateRememberPasswordSetting", TRUE);
|
||||
|
||||
LLPointer<LLCredential> cred;
|
||||
bool remember_user, remember_password;
|
||||
getFields(cred, remember_user, remember_password);
|
||||
|
||||
std::string grid(LLGridManager::getInstance()->getGridId());
|
||||
std::string user_id(cred->userID());
|
||||
if (!remember_password)
|
||||
{
|
||||
gSecAPIHandler->removeFromProtectedMap("mfa_hash", grid, user_id);
|
||||
gSecAPIHandler->syncProtectedMap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -410,6 +410,18 @@ void LLPanelMainInventory::resetFilters()
|
|||
setFilterTextFromFilter();
|
||||
}
|
||||
|
||||
void LLPanelMainInventory::resetAllItemsFilters()
|
||||
{
|
||||
LLFloaterInventoryFinder *finder = getFinder();
|
||||
getAllItemsPanel()->getFilter().resetDefault();
|
||||
if (finder)
|
||||
{
|
||||
finder->updateElementsFromFilter();
|
||||
}
|
||||
|
||||
setFilterTextFromFilter();
|
||||
}
|
||||
|
||||
void LLPanelMainInventory::setSortBy(const LLSD& userdata)
|
||||
{
|
||||
U32 sort_order_mask = getActivePanel()->getSortOrder();
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ public:
|
|||
void toggleFindOptions();
|
||||
|
||||
void resetFilters();
|
||||
void resetAllItemsFilters();
|
||||
|
||||
protected:
|
||||
//
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "llagent.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llviewermedia.h"
|
||||
#include "llvovolume.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llselectmgr.h"
|
||||
#include "llbutton.h"
|
||||
|
|
@ -452,10 +453,17 @@ bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace(bool only_if_current_
|
|||
{
|
||||
viewer_media_t media_impl =
|
||||
LLViewerMedia::getInstance()->getMediaImplFromTextureID(object->getTE(face)->getMediaData()->getMediaID());
|
||||
if(media_impl)
|
||||
{
|
||||
if (media_impl)
|
||||
{
|
||||
media_impl->setPriority(LLPluginClassMedia::PRIORITY_NORMAL);
|
||||
media_impl->navigateHome();
|
||||
|
||||
if (!only_if_current_is_empty)
|
||||
{
|
||||
LLSD media_data;
|
||||
media_data[LLMediaEntry::CURRENT_URL_KEY] = std::string();
|
||||
object->getTE(face)->mergeIntoMediaData(media_data);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -471,6 +479,23 @@ bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace(bool only_if_current_
|
|||
LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
|
||||
selected_objects->getSelectedTEValue( &functor_navigate_media, all_face_media_navigated );
|
||||
|
||||
if (all_face_media_navigated)
|
||||
{
|
||||
struct functor_sync_to_server : public LLSelectedObjectFunctor
|
||||
{
|
||||
virtual bool apply(LLViewerObject* object)
|
||||
{
|
||||
LLVOVolume *volume = dynamic_cast<LLVOVolume*>(object);
|
||||
if (volume)
|
||||
{
|
||||
volume->sendMediaDataUpdate();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} sendfunc;
|
||||
selected_objects->applyToObjects(&sendfunc);
|
||||
}
|
||||
|
||||
// Note: we don't update the 'current URL' field until the media data itself changes
|
||||
|
||||
return all_face_media_navigated;
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ LLToolCamera::LLToolCamera()
|
|||
mOutsideSlopX(FALSE),
|
||||
mOutsideSlopY(FALSE),
|
||||
mValidClickPoint(FALSE),
|
||||
mClickPickPending(false),
|
||||
mValidSelection(FALSE),
|
||||
mMouseSteering(FALSE),
|
||||
mMouseUpX(0),
|
||||
|
|
@ -127,6 +128,11 @@ BOOL LLToolCamera::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
|
||||
mValidClickPoint = FALSE;
|
||||
|
||||
// Sometimes Windows issues down and up events near simultaneously
|
||||
// without giving async pick a chance to trigged
|
||||
// Ex: mouse from numlock emulation
|
||||
mClickPickPending = true;
|
||||
|
||||
// If mouse capture gets ripped away, claim we moused up
|
||||
// at the point we moused down. JC
|
||||
mMouseUpX = x;
|
||||
|
|
@ -142,13 +148,15 @@ BOOL LLToolCamera::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
|
||||
void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
|
||||
{
|
||||
if (!LLToolCamera::getInstance()->hasMouseCapture())
|
||||
LLToolCamera* camera = LLToolCamera::getInstance();
|
||||
if (!camera->mClickPickPending)
|
||||
{
|
||||
return;
|
||||
}
|
||||
camera->mClickPickPending = false;
|
||||
|
||||
LLToolCamera::getInstance()->mMouseDownX = pick_info.mMousePt.mX;
|
||||
LLToolCamera::getInstance()->mMouseDownY = pick_info.mMousePt.mY;
|
||||
camera->mMouseDownX = pick_info.mMousePt.mX;
|
||||
camera->mMouseDownY = pick_info.mMousePt.mY;
|
||||
|
||||
gViewerWindow->moveCursorToCenter();
|
||||
|
||||
|
|
@ -158,7 +166,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
|
|||
// Check for hit the sky, or some other invalid point
|
||||
if (!hit_obj && pick_info.mPosGlobal.isExactlyZero())
|
||||
{
|
||||
LLToolCamera::getInstance()->mValidClickPoint = FALSE;
|
||||
camera->mValidClickPoint = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -168,7 +176,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
|
|||
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
|
||||
if (!selection->getObjectCount() || selection->getSelectType() != SELECT_TYPE_HUD)
|
||||
{
|
||||
LLToolCamera::getInstance()->mValidClickPoint = FALSE;
|
||||
camera->mValidClickPoint = FALSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -192,7 +200,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
|
|||
|
||||
if( !good_customize_avatar_hit )
|
||||
{
|
||||
LLToolCamera::getInstance()->mValidClickPoint = FALSE;
|
||||
camera->mValidClickPoint = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -237,7 +245,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
|
|||
|
||||
}
|
||||
|
||||
LLToolCamera::getInstance()->mValidClickPoint = TRUE;
|
||||
camera->mValidClickPoint = TRUE;
|
||||
|
||||
if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode() )
|
||||
{
|
||||
|
|
@ -284,32 +292,36 @@ BOOL LLToolCamera::handleMouseUp(S32 x, S32 y, MASK mask)
|
|||
|
||||
if (hasMouseCapture())
|
||||
{
|
||||
if (mValidClickPoint)
|
||||
{
|
||||
if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode() )
|
||||
{
|
||||
LLCoordGL mouse_pos;
|
||||
LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgentCamera.getFocusGlobal());
|
||||
BOOL success = LLViewerCamera::getInstance()->projectPosAgentToScreen(focus_pos, mouse_pos);
|
||||
if (success)
|
||||
{
|
||||
LLUI::getInstance()->setMousePositionScreen(mouse_pos.mX, mouse_pos.mY);
|
||||
}
|
||||
}
|
||||
else if (mMouseSteering)
|
||||
{
|
||||
LLUI::getInstance()->setMousePositionScreen(mMouseDownX, mMouseDownY);
|
||||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->moveCursorToCenter();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// not a valid zoomable object
|
||||
LLUI::getInstance()->setMousePositionScreen(mMouseDownX, mMouseDownY);
|
||||
}
|
||||
// Do not move camera if we haven't gotten a pick
|
||||
if (!mClickPickPending)
|
||||
{
|
||||
if (mValidClickPoint)
|
||||
{
|
||||
if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode())
|
||||
{
|
||||
LLCoordGL mouse_pos;
|
||||
LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgentCamera.getFocusGlobal());
|
||||
BOOL success = LLViewerCamera::getInstance()->projectPosAgentToScreen(focus_pos, mouse_pos);
|
||||
if (success)
|
||||
{
|
||||
LLUI::getInstance()->setMousePositionScreen(mouse_pos.mX, mouse_pos.mY);
|
||||
}
|
||||
}
|
||||
else if (mMouseSteering)
|
||||
{
|
||||
LLUI::getInstance()->setMousePositionScreen(mMouseDownX, mMouseDownY);
|
||||
}
|
||||
else
|
||||
{
|
||||
gViewerWindow->moveCursorToCenter();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// not a valid zoomable object
|
||||
LLUI::getInstance()->setMousePositionScreen(mMouseDownX, mMouseDownY);
|
||||
}
|
||||
}
|
||||
|
||||
// calls releaseMouse() internally
|
||||
setMouseCapture(FALSE);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ public:
|
|||
|
||||
virtual LLTool* getOverrideTool(MASK mask) { return NULL; }
|
||||
|
||||
void setClickPickPending() { mClickPickPending = true; }
|
||||
static void pickCallback(const LLPickInfo& pick_info);
|
||||
BOOL mouseSteerMode() { return mMouseSteering; }
|
||||
|
||||
|
|
@ -65,6 +66,7 @@ protected:
|
|||
BOOL mOutsideSlopX;
|
||||
BOOL mOutsideSlopY;
|
||||
BOOL mValidClickPoint;
|
||||
bool mClickPickPending;
|
||||
BOOL mValidSelection;
|
||||
BOOL mMouseSteering;
|
||||
S32 mMouseUpX; // needed for releaseMouse()
|
||||
|
|
|
|||
|
|
@ -443,6 +443,7 @@ BOOL LLToolPie::handleLeftClickPick()
|
|||
LLToolMgr::getInstance()->setTransientTool(LLToolCamera::getInstance());
|
||||
gViewerWindow->hideCursor();
|
||||
LLToolCamera::getInstance()->setMouseCapture(TRUE);
|
||||
LLToolCamera::getInstance()->setClickPickPending();
|
||||
LLToolCamera::getInstance()->pickCallback(mPick);
|
||||
gAgentCamera.setFocusOnAvatar(TRUE, TRUE);
|
||||
|
||||
|
|
|
|||
|
|
@ -546,6 +546,18 @@ void LLBingTranslationHandler::verifyKey(const std::string &key, LLTranslate::Ke
|
|||
}
|
||||
|
||||
//=========================================================================
|
||||
LLTranslate::LLTranslate():
|
||||
mCharsSeen(0),
|
||||
mCharsSent(0),
|
||||
mFailureCount(0),
|
||||
mSuccessCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
LLTranslate::~LLTranslate()
|
||||
{
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void LLTranslate::translateMessage(const std::string &from_lang, const std::string &to_lang,
|
||||
const std::string &mesg, TranslationSuccess_fn success, TranslationFailure_fn failure)
|
||||
|
|
@ -634,6 +646,43 @@ bool LLTranslate::isTranslationConfigured()
|
|||
return getPreferredHandler().isConfigured();
|
||||
}
|
||||
|
||||
void LLTranslate::logCharsSeen(size_t count)
|
||||
{
|
||||
mCharsSeen += count;
|
||||
}
|
||||
|
||||
void LLTranslate::logCharsSent(size_t count)
|
||||
{
|
||||
mCharsSent += count;
|
||||
}
|
||||
|
||||
void LLTranslate::logSuccess(S32 count)
|
||||
{
|
||||
mSuccessCount += count;
|
||||
}
|
||||
|
||||
void LLTranslate::logFailure(S32 count)
|
||||
{
|
||||
mFailureCount += count;
|
||||
}
|
||||
|
||||
LLSD LLTranslate::asLLSD() const
|
||||
{
|
||||
LLSD res;
|
||||
bool on = gSavedSettings.getBOOL("TranslateChat");
|
||||
res["on"] = on;
|
||||
res["chars_seen"] = (S32) mCharsSeen;
|
||||
if (on)
|
||||
{
|
||||
res["chars_sent"] = (S32) mCharsSent;
|
||||
res["success_count"] = mSuccessCount;
|
||||
res["failure_count"] = mFailureCount;
|
||||
res["language"] = getTranslateLanguage();
|
||||
res["service"] = gSavedSettings.getString("TranslationService");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// static
|
||||
LLTranslationAPIHandler& LLTranslate::getPreferredHandler()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
#include "llbufferstream.h"
|
||||
#include <boost/function.hpp>
|
||||
|
||||
#include "llsingleton.h"
|
||||
|
||||
namespace Json
|
||||
{
|
||||
class Value;
|
||||
|
|
@ -48,8 +50,10 @@ class LLTranslationAPIHandler;
|
|||
*
|
||||
* API keys for translation are taken from saved settings.
|
||||
*/
|
||||
class LLTranslate
|
||||
class LLTranslate: public LLSingleton<LLTranslate>
|
||||
{
|
||||
LLSINGLETON(LLTranslate);
|
||||
~LLTranslate();
|
||||
LOG_CLASS(LLTranslate);
|
||||
|
||||
public :
|
||||
|
|
@ -94,9 +98,19 @@ public :
|
|||
static std::string addNoTranslateTags(std::string mesg);
|
||||
static std::string removeNoTranslateTags(std::string mesg);
|
||||
|
||||
void logCharsSeen(size_t count);
|
||||
void logCharsSent(size_t count);
|
||||
void logSuccess(S32 count);
|
||||
void logFailure(S32 count);
|
||||
LLSD asLLSD() const;
|
||||
private:
|
||||
static LLTranslationAPIHandler& getPreferredHandler();
|
||||
static LLTranslationAPIHandler& getHandler(EService service);
|
||||
|
||||
size_t mCharsSeen;
|
||||
size_t mCharsSent;
|
||||
S32 mFailureCount;
|
||||
S32 mSuccessCount;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -704,7 +704,7 @@ LLUUID LLBufferedAssetUploadInfo::finishUpload(LLSD &result)
|
|||
LLScriptAssetUpload::LLScriptAssetUpload(LLUUID itemId, std::string buffer, invnUploadFinish_f finish):
|
||||
LLBufferedAssetUploadInfo(itemId, LLAssetType::AT_LSL_TEXT, buffer, finish),
|
||||
mExerienceId(),
|
||||
mTargetType(LSL2),
|
||||
mTargetType(MONO),
|
||||
mIsRunning(false)
|
||||
{
|
||||
}
|
||||
|
|
@ -725,7 +725,7 @@ LLSD LLScriptAssetUpload::generatePostBody()
|
|||
if (getTaskId().isNull())
|
||||
{
|
||||
body["item_id"] = getItemId();
|
||||
body["target"] = "lsl2";
|
||||
body["target"] = "mono";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1907,7 +1907,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
|
|||
log_message = LLTrans::getString("InvOfferDecline", log_message_args);
|
||||
}
|
||||
chat.mText = log_message;
|
||||
if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::getInstance()->isLinden(mFromName) ) // muting for SL-42269
|
||||
if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::isLinden(mFromName) ) // muting for SL-42269
|
||||
{
|
||||
chat.mMuted = TRUE;
|
||||
accept_to_trash = false; // will send decline message
|
||||
|
|
@ -2426,6 +2426,7 @@ void translateSuccess(LLChat chat, LLSD toastArgs, std::string originalMsg, std:
|
|||
chat.mText += " (" + LLTranslate::removeNoTranslateTags(translation) + ")";
|
||||
}
|
||||
|
||||
LLTranslate::instance().logSuccess(1);
|
||||
LLNotificationsUI::LLNotificationManager::instance().onChat(chat, toastArgs);
|
||||
}
|
||||
|
||||
|
|
@ -2435,6 +2436,7 @@ void translateFailure(LLChat chat, LLSD toastArgs, int status, const std::string
|
|||
LLStringUtil::replaceString(msg, "\n", " "); // we want one-line error messages
|
||||
chat.mText += " (" + msg + ")";
|
||||
|
||||
LLTranslate::instance().logFailure(1);
|
||||
LLNotificationsUI::LLNotificationManager::instance().onChat(chat, toastArgs);
|
||||
}
|
||||
|
||||
|
|
@ -2512,7 +2514,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
|
|||
LLMute::flagTextChat)
|
||||
|| LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagTextChat);
|
||||
is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
|
||||
LLMuteList::getInstance()->isLinden(from_name);
|
||||
LLMuteList::isLinden(from_name);
|
||||
|
||||
if (is_muted && (chat.mSourceType == CHAT_SOURCE_OBJECT))
|
||||
{
|
||||
|
|
@ -2669,6 +2671,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
|
|||
LLSD args;
|
||||
chat.mOwnerID = owner_id;
|
||||
|
||||
LLTranslate::instance().logCharsSeen(mesg.size());
|
||||
if (gSavedSettings.getBOOL("TranslateChat") && chat.mSourceType != CHAT_SOURCE_SYSTEM)
|
||||
{
|
||||
if (chat.mChatStyle == CHAT_STYLE_IRC)
|
||||
|
|
@ -2678,6 +2681,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
|
|||
const std::string from_lang = ""; // leave empty to trigger autodetect
|
||||
const std::string to_lang = LLTranslate::getTranslateLanguage();
|
||||
|
||||
LLTranslate::instance().logCharsSent(mesg.size());
|
||||
LLTranslate::translateMessage(from_lang, to_lang, mesg,
|
||||
boost::bind(&translateSuccess, chat, args, mesg, from_lang, _1, _2),
|
||||
boost::bind(&translateFailure, chat, args, _1, _2));
|
||||
|
|
@ -5819,8 +5823,12 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
|
|||
{
|
||||
count++;
|
||||
known_questions |= script_perm.permbit;
|
||||
// check whether permission question should cause special caution dialog
|
||||
caution |= (script_perm.caution);
|
||||
|
||||
if (!LLMuteList::isLinden(owner_name))
|
||||
{
|
||||
// check whether permission question should cause special caution dialog
|
||||
caution |= (script_perm.caution);
|
||||
}
|
||||
|
||||
if (("ScriptTakeMoney" == script_perm.question) && has_not_only_debit)
|
||||
continue;
|
||||
|
|
@ -6346,7 +6354,7 @@ bool teleport_request_callback(const LLSD& notification, const LLSD& response)
|
|||
LLAvatarName av_name;
|
||||
LLAvatarNameCache::get(from_id, &av_name);
|
||||
|
||||
if(LLMuteList::getInstance()->isMuted(from_id) && !LLMuteList::getInstance()->isLinden(av_name.getUserName()))
|
||||
if(LLMuteList::getInstance()->isMuted(from_id) && !LLMuteList::isLinden(av_name.getUserName()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -815,7 +815,10 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
|
|||
{
|
||||
virtual bool apply(LLViewerObject* objectp)
|
||||
{
|
||||
objectp->boostTexturePriority();
|
||||
if (objectp)
|
||||
{
|
||||
objectp->boostTexturePriority();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} func;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@
|
|||
#include "llvoicevivox.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "lluiusage.h"
|
||||
#include "lltranslate.h"
|
||||
|
||||
namespace LLStatViewer
|
||||
{
|
||||
|
|
@ -591,6 +592,7 @@ void send_viewer_stats(bool include_preferences)
|
|||
agent["meters_traveled"] = gAgent.getDistanceTraveled();
|
||||
agent["regions_visited"] = gAgent.getRegionsVisited();
|
||||
agent["mem_use"] = LLMemory::getCurrentRSS() / 1024.0;
|
||||
agent["translation"] = LLTranslate::instance().asLLSD();
|
||||
|
||||
LLSD &system = body["system"];
|
||||
|
||||
|
|
@ -600,6 +602,7 @@ void send_viewer_stats(bool include_preferences)
|
|||
system["cpu_sse"] = gSysCPU.getSSEVersions();
|
||||
system["address_size"] = ADDRESS_SIZE;
|
||||
system["os_bitness"] = LLOSInfo::instance().getOSBitness();
|
||||
system["hardware_concurrency"] = (LLSD::Integer) std::thread::hardware_concurrency();
|
||||
unsigned char MACAddress[MAC_ADDRESS_BYTES];
|
||||
LLUUID::getNodeID(MACAddress);
|
||||
std::string macAddressString = llformat("%02x-%02x-%02x-%02x-%02x-%02x",
|
||||
|
|
@ -622,6 +625,7 @@ void send_viewer_stats(bool include_preferences)
|
|||
|
||||
gGLManager.asLLSD(system["gl"]);
|
||||
|
||||
|
||||
S32 shader_level = 0;
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1118,7 +1118,7 @@ void LLViewerFetchedTexture::init(bool firstinit)
|
|||
mLoadedCallbackDesiredDiscardLevel = S8_MAX;
|
||||
mPauseLoadedCallBacks = FALSE;
|
||||
|
||||
mNeedsCreateTexture = FALSE;
|
||||
mNeedsCreateTexture = false;
|
||||
|
||||
mIsRawImageValid = FALSE;
|
||||
mRawDiscardLevel = INVALID_DISCARD_LEVEL;
|
||||
|
|
@ -1400,12 +1400,12 @@ void LLViewerFetchedTexture::addToCreateTexture()
|
|||
{
|
||||
//just update some variables, not to create a real GL texture.
|
||||
createGLTexture(mRawDiscardLevel, mRawImage, 0, FALSE);
|
||||
mNeedsCreateTexture = FALSE;
|
||||
mNeedsCreateTexture = false;
|
||||
destroyRawImage();
|
||||
}
|
||||
else if(!force_update && getDiscardLevel() > -1 && getDiscardLevel() <= mRawDiscardLevel)
|
||||
{
|
||||
mNeedsCreateTexture = FALSE;
|
||||
mNeedsCreateTexture = false;
|
||||
destroyRawImage();
|
||||
}
|
||||
else
|
||||
|
|
@ -1441,7 +1441,7 @@ void LLViewerFetchedTexture::addToCreateTexture()
|
|||
mRawDiscardLevel += i;
|
||||
if(mRawDiscardLevel >= getDiscardLevel() && getDiscardLevel() > 0)
|
||||
{
|
||||
mNeedsCreateTexture = FALSE;
|
||||
mNeedsCreateTexture = false;
|
||||
destroyRawImage();
|
||||
return;
|
||||
}
|
||||
|
|
@ -1473,7 +1473,7 @@ BOOL LLViewerFetchedTexture::preCreateTexture(S32 usename/*= 0*/)
|
|||
destroyRawImage();
|
||||
return FALSE;
|
||||
}
|
||||
mNeedsCreateTexture = FALSE;
|
||||
mNeedsCreateTexture = false;
|
||||
|
||||
if (mRawImage.isNull())
|
||||
{
|
||||
|
|
@ -1609,14 +1609,14 @@ void LLViewerFetchedTexture::postCreateTexture()
|
|||
destroyRawImage();
|
||||
}
|
||||
|
||||
mNeedsCreateTexture = FALSE;
|
||||
mNeedsCreateTexture = false;
|
||||
}
|
||||
|
||||
void LLViewerFetchedTexture::scheduleCreateTexture()
|
||||
{
|
||||
if (!mNeedsCreateTexture)
|
||||
{
|
||||
mNeedsCreateTexture = TRUE;
|
||||
mNeedsCreateTexture = true;
|
||||
if (preCreateTexture())
|
||||
{
|
||||
#if LL_IMAGEGL_THREAD_CHECK
|
||||
|
|
@ -1630,7 +1630,7 @@ void LLViewerFetchedTexture::scheduleCreateTexture()
|
|||
memcpy(data_copy, data, size);
|
||||
}
|
||||
#endif
|
||||
mNeedsCreateTexture = TRUE;
|
||||
mNeedsCreateTexture = true;
|
||||
auto mainq = LLImageGLThread::sEnabled ? mMainQueue.lock() : nullptr;
|
||||
if (mainq)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#ifndef LL_LLVIEWERTEXTURE_H
|
||||
#define LL_LLVIEWERTEXTURE_H
|
||||
|
||||
#include "llatomic.h"
|
||||
#include "llgltexture.h"
|
||||
#include "lltimer.h"
|
||||
#include "llframetimer.h"
|
||||
|
|
@ -528,7 +529,9 @@ protected:
|
|||
LLFrameTimer mStopFetchingTimer; // Time since mDecodePriority == 0.f.
|
||||
|
||||
BOOL mInImageList; // TRUE if image is in list (in which case don't reset priority!)
|
||||
BOOL mNeedsCreateTexture;
|
||||
// This needs to be atomic, since it is written both in the main thread
|
||||
// and in the GL image worker thread... HB
|
||||
LLAtomicBool mNeedsCreateTexture;
|
||||
|
||||
BOOL mForSculpt ; //a flag if the texture is used as sculpt data.
|
||||
BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally.
|
||||
|
|
|
|||
|
|
@ -3547,14 +3547,15 @@ void LLVOAvatar::idleUpdateNameTagText(bool new_name)
|
|||
|
||||
void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font, const bool use_ellipses)
|
||||
{
|
||||
// extra width (NAMETAG_MAX_WIDTH) is for names only, not for chat
|
||||
llassert(mNameText);
|
||||
if (mVisibleChat)
|
||||
{
|
||||
mNameText->addLabel(line);
|
||||
mNameText->addLabel(line, LLHUDNameTag::NAMETAG_MAX_WIDTH);
|
||||
}
|
||||
else
|
||||
{
|
||||
mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font, use_ellipses);
|
||||
mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font, use_ellipses, LLHUDNameTag::NAMETAG_MAX_WIDTH);
|
||||
}
|
||||
mNameIsSet |= !line.empty();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4525,7 +4525,7 @@ void LLVivoxVoiceClient::messageEvent(
|
|||
{
|
||||
bool is_do_not_disturb = gAgent.isDoNotDisturb();
|
||||
bool is_muted = LLMuteList::getInstance()->isMuted(session->mCallerID, session->mName, LLMute::flagTextChat);
|
||||
bool is_linden = LLMuteList::getInstance()->isLinden(session->mName);
|
||||
bool is_linden = LLMuteList::isLinden(session->mName);
|
||||
LLChat chat;
|
||||
|
||||
chat.mMuted = is_muted && !is_linden;
|
||||
|
|
|
|||
|
|
@ -1778,20 +1778,17 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
|
|||
void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
|
||||
light_set_t::iterator iter = gPipeline.mNearbyLights.begin();
|
||||
|
||||
while (iter != gPipeline.mNearbyLights.end())
|
||||
{
|
||||
if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar)
|
||||
{
|
||||
gPipeline.mLights.erase(iter->drawable);
|
||||
iter = gPipeline.mNearbyLights.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin();
|
||||
iter != gPipeline.mNearbyLights.end(); iter++)
|
||||
{
|
||||
const LLViewerObject *vobj = iter->drawable->getVObj();
|
||||
if (vobj && vobj->getAvatar()
|
||||
&& vobj->isAttachment() && vobj->getAvatar() == muted_avatar)
|
||||
{
|
||||
gPipeline.mLights.erase(iter->drawable);
|
||||
gPipeline.mNearbyLights.erase(iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U32 LLPipeline::addObject(LLViewerObject *vobj)
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
Klicken und ziehen, um Land auszuwählen
|
||||
</floater.string>
|
||||
<floater.string name="status_selectcount">
|
||||
[OBJ_COUNT] Objekte ausgewählt, Auswirkung auf Land [LAND_IMPACT]
|
||||
[OBJ_COUNT] Objekte ausgewählt, Auswirkung auf Land [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?]
|
||||
</floater.string>
|
||||
<floater.string name="status_remaining_capacity">
|
||||
Verbleibende Kapazität [LAND_CAPACITY].
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
max_length_chars="31"
|
||||
height="20"
|
||||
top_pad="5"
|
||||
left="50" />
|
||||
left_delta="0" />
|
||||
<text
|
||||
top_pad="15"
|
||||
left="25"
|
||||
|
|
@ -72,23 +72,33 @@
|
|||
max_length_chars="31"
|
||||
height="20"
|
||||
top_pad="5"
|
||||
left="50" />
|
||||
left_delta="0" />
|
||||
<button
|
||||
label="Reset"
|
||||
layout="topleft"
|
||||
font="SansSerif"
|
||||
width="120"
|
||||
height="23"
|
||||
top_pad="40"
|
||||
left_delta="0"
|
||||
name="reset_btn"
|
||||
tool_tip="Use Username as a Display Name" />
|
||||
<button
|
||||
height="23"
|
||||
label="Save"
|
||||
layout="topleft"
|
||||
font="SansSerif"
|
||||
left="35"
|
||||
left_pad="35"
|
||||
name="save_btn"
|
||||
tool_tip="Save your new Display Name"
|
||||
top_pad="40"
|
||||
top_delta="0"
|
||||
width="120" />
|
||||
<button
|
||||
height="23"
|
||||
label="Cancel"
|
||||
font="SansSerif"
|
||||
layout="topleft"
|
||||
left_pad="125"
|
||||
left_pad="5"
|
||||
name="cancel_btn"
|
||||
width="120" />
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -323,7 +323,6 @@
|
|||
follows="left|top"
|
||||
decimal_digits="0"
|
||||
increment="1"
|
||||
control_name="Edit Cost"
|
||||
name="Edit Cost"
|
||||
label="Price:"
|
||||
label_width="100"
|
||||
|
|
|
|||
|
|
@ -1140,7 +1140,6 @@ even though the user gets a free copy.
|
|||
decimal_digits="0"
|
||||
increment="1"
|
||||
left_pad="0"
|
||||
control_name="Edit Cost"
|
||||
name="Edit Cost"
|
||||
label="L$"
|
||||
label_width="15"
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@
|
|||
parameter="conversation_log" />
|
||||
</menu_item_check>
|
||||
<menu_item_separator layout="topleft" />
|
||||
<menu_item_check name="Translate_chat" label="Translate Nearby chat">
|
||||
<menu_item_check name="Translate_chat" label="Translate chat">
|
||||
<menu_item_check.on_click
|
||||
function="IMFloaterContainer.Action"
|
||||
parameter="Translating.Toggle" />
|
||||
|
|
|
|||
|
|
@ -92,10 +92,7 @@
|
|||
label="Reset"
|
||||
left_delta="233"
|
||||
name="current_url_reset_btn"
|
||||
width="110" >
|
||||
<button.commit_callback
|
||||
function="Media.ResetCurrentUrl"/>
|
||||
</button>
|
||||
width="110"/>
|
||||
<check_box
|
||||
bottom_delta="-25"
|
||||
enabled="true"
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@
|
|||
<view_border
|
||||
bevel_style="none"
|
||||
follows="top|left"
|
||||
height="185"
|
||||
height="205"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="5"
|
||||
|
|
@ -125,6 +125,16 @@
|
|||
tool_tip="Residents must have payment information on file to access this estate. See the [SUPPORT_SITE] for more information."
|
||||
top_pad="2"
|
||||
width="278" />
|
||||
<check_box
|
||||
follows="top|left"
|
||||
height="18"
|
||||
label="Must not be a scripted agent"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="limit_bots"
|
||||
tool_tip="Residents must not be a scripted agents (bots) to access this estate. See the [SUPPORT_SITE] for more information."
|
||||
top_pad="2"
|
||||
width="278" />
|
||||
<check_box
|
||||
height="18"
|
||||
label="Parcel owners can be more restrictive"
|
||||
|
|
|
|||
|
|
@ -450,7 +450,6 @@
|
|||
follows="left|top"
|
||||
decimal_digits="0"
|
||||
increment="1"
|
||||
control_name="Edit Cost"
|
||||
name="Edit Cost"
|
||||
label="Price: L$"
|
||||
label_width="75"
|
||||
|
|
@ -461,8 +460,72 @@
|
|||
max_val="999999999"
|
||||
top_pad="10"
|
||||
tool_tip="Object cost." />
|
||||
</panel>
|
||||
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="BaseMaskDebug"
|
||||
text_color="White"
|
||||
top_pad="30"
|
||||
width="130">
|
||||
B:
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="60"
|
||||
name="OwnerMaskDebug"
|
||||
text_color="White"
|
||||
top_delta="0"
|
||||
width="270">
|
||||
O:
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="60"
|
||||
name="GroupMaskDebug"
|
||||
text_color="White"
|
||||
top_delta="0"
|
||||
width="210">
|
||||
G:
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="60"
|
||||
name="EveryoneMaskDebug"
|
||||
text_color="White"
|
||||
top_delta="0"
|
||||
width="150">
|
||||
E:
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="60"
|
||||
name="NextMaskDebug"
|
||||
text_color="White"
|
||||
top_delta="0"
|
||||
width="90">
|
||||
N:
|
||||
</text>
|
||||
</panel>
|
||||
</scroll_container>
|
||||
<panel
|
||||
height="30"
|
||||
|
|
|
|||
|
|
@ -454,7 +454,6 @@
|
|||
increment="1"
|
||||
top_pad="10"
|
||||
left="120"
|
||||
control_name="Edit Cost"
|
||||
name="Edit Cost"
|
||||
label="Price: L$"
|
||||
label_width="73"
|
||||
|
|
|
|||
|
|
@ -126,8 +126,8 @@ http://secondlife.com/download
|
|||
|
||||
For more information, see our FAQ below:
|
||||
http://secondlife.com/viewer-access-faq</string>
|
||||
<string name="LoginFailed">Grid emergency login failure.
|
||||
If you feel this is an error, please contact support@secondlife.com.</string>
|
||||
<string name="LoginFailed">"Login process did not complete due to system issues. Try again in a few minutes.
|
||||
If you feel this is an error, contact Support at https://support.secondlife.com"</string>
|
||||
<string name="LoginIntermediateOptionalUpdateAvailable">Optional viewer update available: [VERSION]</string>
|
||||
<string name="LoginFailedRequiredUpdate">Required viewer update: [VERSION]</string>
|
||||
<string name="LoginFailedAlreadyLoggedIn">This agent is already logged in.
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
Pulsa y arrastra para seleccionar el terreno.
|
||||
</floater.string>
|
||||
<floater.string name="status_selectcount">
|
||||
[OBJ_COUNT] objetos seleccionados, impacto en el terreno [LAND_IMPACT]
|
||||
[OBJ_COUNT] objetos seleccionados, impacto en el terreno [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?]
|
||||
</floater.string>
|
||||
<floater.string name="status_remaining_capacity">
|
||||
Capacidad restante [LAND_CAPACITY].
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
Cliquez et faites glisser pour sélectionner le terrain.
|
||||
</floater.string>
|
||||
<floater.string name="status_selectcount">
|
||||
[OBJ_COUNT] objets sélectionnés, impact sur le terrain [LAND_IMPACT]
|
||||
[OBJ_COUNT] objets sélectionnés, impact sur le terrain [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?]
|
||||
</floater.string>
|
||||
<floater.string name="status_remaining_capacity">
|
||||
Capacité restante [LAND_CAPACITY].
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
Clicca e trascina per selezionare il terreno
|
||||
</floater.string>
|
||||
<floater.string name="status_selectcount">
|
||||
[OBJ_COUNT] oggetti selezionati, impatto terreno [LAND_IMPACT]
|
||||
[OBJ_COUNT] oggetti selezionati, impatto terreno [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?]
|
||||
</floater.string>
|
||||
<floater.string name="status_remaining_capacity">
|
||||
Capacità restante [LAND_CAPACITY].
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
土地をクリックし、ドラッグして選択
|
||||
</floater.string>
|
||||
<floater.string name="status_selectcount">
|
||||
選択されているオブジェクトは [OBJ_COUNT] 個、土地の負荷は [LAND_IMPACT]
|
||||
選択されているオブジェクトは [OBJ_COUNT] 個、土地の負荷は [LAND_IMPACT] [secondlife:///app/openfloater/object_weights 詳細]
|
||||
</floater.string>
|
||||
<floater.string name="status_remaining_capacity">
|
||||
残りの許容数 [LAND_CAPACITY]。
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
Kliknij i przeciągnij, aby zaznaczyć teren
|
||||
</floater.string>
|
||||
<floater.string name="status_selectcount">
|
||||
[OBJ_COUNT] zaznaczonych obiektów, wpływ na strefę: [LAND_IMPACT]
|
||||
[OBJ_COUNT] zaznaczonych obiektów, wpływ na strefę: [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?]
|
||||
</floater.string>
|
||||
<floater.string name="status_remaining_capacity">
|
||||
Pojemność pozostała: [LAND_CAPACITY].
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
Clicar e arrastar para selecionar a terra
|
||||
</floater.string>
|
||||
<floater.string name="status_selectcount">
|
||||
[OBJ_COUNT] objetos selecionados, impacto no terreno [LAND_IMPACT]
|
||||
[OBJ_COUNT] objetos selecionados, impacto no terreno [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?]
|
||||
</floater.string>
|
||||
<floater.string name="status_remaining_capacity">
|
||||
Capacidade restante [LAND_CAPACITY].
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
Щелкните и перетащите для выделения земли
|
||||
</floater.string>
|
||||
<floater.string name="status_selectcount">
|
||||
Выбрано объектов: [OBJ_COUNT], влияние на землю [LAND_IMPACT]
|
||||
Выбрано объектов: [OBJ_COUNT], влияние на землю [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?]
|
||||
</floater.string>
|
||||
<floater.string name="status_remaining_capacity">
|
||||
Остаток емкости [LAND_CAPACITY].
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
Araziyi seçmek için tıklayın ve sürükleyin
|
||||
</floater.string>
|
||||
<floater.string name="status_selectcount">
|
||||
[OBJ_COUNT] nesne seçili, [LAND_IMPACT] arazi etkisi
|
||||
[OBJ_COUNT] nesne seçili, [LAND_IMPACT] arazi etkisi [secondlife:///app/openfloater/object_weights Ek bilgi]
|
||||
</floater.string>
|
||||
<floater.string name="status_remaining_capacity">
|
||||
Kalan kapasite [LAND_CAPACITY].
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
按住並拖曳,可以選取土地
|
||||
</floater.string>
|
||||
<floater.string name="status_selectcount">
|
||||
選取了 [OBJ_COUNT] 個物件,土地衝擊量 [LAND_IMPACT]
|
||||
選取了 [OBJ_COUNT] 個物件,土地衝擊量 [LAND_IMPACT] [secondlife:///app/openfloater/object_weights 詳情]
|
||||
</floater.string>
|
||||
<floater.string name="status_remaining_capacity">
|
||||
剩餘容納量 [LAND_CAPACITY]。
|
||||
|
|
|
|||
Loading…
Reference in New Issue