Merge of viewer 2

master
Palmer Truelson 2009-11-25 09:42:58 -08:00
commit bb614fa887
682 changed files with 47773 additions and 41426 deletions

View File

@ -14,6 +14,7 @@ LICENSES
indra/.distcc
indra/build-darwin-*
indra/build-vc[0-9]*
indra/CMakeFiles
indra/lib/mono/1.0/*.dll
indra/lib/mono/indra/*.dll
indra/lib/mono/indra/*.exe
@ -32,6 +33,7 @@ indra/newview/mozilla-universal-darwin.tgz
indra/newview/res-sdl
indra/newview/vivox-runtime
indra/server-linux-*
indra/temp
indra/test/linden_file.dat
indra/test_apps/llmediatest/dependencies/i686-win32
indra/test_apps/terrain_mule/*.dll
@ -54,3 +56,8 @@ glob:*.cpp.orig
glob:*.cpp.bak
glob:*.h.bak
glob:*.h.orig
glob:indra/newview/typed_locations.txt
glob:indra/newview/teleport_history.txt
glob:indra/newview/search_history.txt
glob:indra/newview/filters.xml
glob:indra/newview/avatar_icons_cache.txt

View File

@ -209,7 +209,7 @@ elseif(LINUX)
libapr-1.so.0
libaprutil-1.so.0
libatk-1.0.so
libcrypto.so
libcrypto.so.0.9.7
libdb-4.2.so
libexpat.so
libgmock_main.so

View File

@ -23,12 +23,11 @@ else (STANDALONE)
endif (STANDALONE)
if (GOOGLE_PERFTOOLS_FOUND)
set(USE_GOOGLE_PERFTOOLS ON CACHE BOOL "Build with Google PerfTools support.")
# XXX Disable temporarily, until we have compilation issues on 64-bit
# Etch sorted.
set(USE_GOOGLE_PERFTOOLS OFF CACHE BOOL "Build with Google PerfTools support.")
endif (GOOGLE_PERFTOOLS_FOUND)
# XXX Disable temporarily, until we have compilation issues on 64-bit
# Etch sorted.
set(USE_GOOGLE_PERFTOOLS OFF)
if (WINDOWS)
# *TODO -reenable this once we get server usage sorted out
#set(USE_GOOGLE_PERFTOOLS ON)

View File

@ -9,6 +9,7 @@ include(Linking)
include(Boost)
include(Pth)
include(LLSharedLibs)
include(GooglePerfTools)
include(Copy3rdPartyLibs)
include_directories(
@ -259,6 +260,7 @@ target_link_libraries(
${BOOST_PROGRAM_OPTIONS_LIBRARY}
${BOOST_REGEX_LIBRARY}
${PTH_LIBRARIES}
${GOOGLE_PERFTOOLS_LIBRARIES}
)
add_dependencies(llcommon stage_third_party_libs)

View File

@ -84,6 +84,7 @@ public:
mAudible(CHAT_AUDIBLE_FULLY),
mMuted(FALSE),
mTime(0.0),
mTimeStr(),
mPosAgent(),
mURL(),
mChatStyle(CHAT_STYLE_NORMAL)
@ -97,6 +98,7 @@ public:
EChatAudible mAudible;
BOOL mMuted; // pass muted chat to maintain list of chatters
F64 mTime; // viewer only, seconds from viewer start
std::string mTimeStr;
LLVector3 mPosAgent;
std::string mURL;
EChatStyle mChatStyle;

View File

@ -33,7 +33,7 @@
#ifndef LL_LLCLICKACTION_H
#define LL_LLCLICKACTION_H
// DO NOT CHANGE THE SEQUENCE OF THIS LIST!!
const U8 CLICK_ACTION_NONE = 0;
const U8 CLICK_ACTION_TOUCH = 0;
const U8 CLICK_ACTION_SIT = 1;
@ -42,5 +42,6 @@ const U8 CLICK_ACTION_PAY = 3;
const U8 CLICK_ACTION_OPEN = 4;
const U8 CLICK_ACTION_PLAY = 5;
const U8 CLICK_ACTION_OPEN_MEDIA = 6;
const U8 CLICK_ACTION_ZOOM = 7;
// DO NOT CHANGE THE SEQUENCE OF THIS LIST!!
#endif

View File

@ -76,6 +76,75 @@ extern int errno;
static const S32 CPUINFO_BUFFER_SIZE = 16383;
LLCPUInfo gSysCPU;
#if LL_WINDOWS
#ifndef DLLVERSIONINFO
typedef struct _DllVersionInfo
{
DWORD cbSize;
DWORD dwMajorVersion;
DWORD dwMinorVersion;
DWORD dwBuildNumber;
DWORD dwPlatformID;
}DLLVERSIONINFO;
#endif
#ifndef DLLGETVERSIONPROC
typedef int (FAR WINAPI *DLLGETVERSIONPROC) (DLLVERSIONINFO *);
#endif
bool get_shell32_dll_version(DWORD& major, DWORD& minor, DWORD& build_number)
{
bool result = false;
const U32 BUFF_SIZE = 32767;
WCHAR tempBuf[BUFF_SIZE];
if(GetSystemDirectory((LPWSTR)&tempBuf, BUFF_SIZE))
{
std::basic_string<WCHAR> shell32_path(tempBuf);
// Shell32.dll contains the DLLGetVersion function.
// according to msdn its not part of the API
// so you have to go in and get it.
// http://msdn.microsoft.com/en-us/library/bb776404(VS.85).aspx
shell32_path += TEXT("\\shell32.dll");
HMODULE hDllInst = LoadLibrary(shell32_path.c_str()); //load the DLL
if(hDllInst)
{ // Could successfully load the DLL
DLLGETVERSIONPROC pDllGetVersion;
/*
You must get this function explicitly because earlier versions of the DLL
don't implement this function. That makes the lack of implementation of the
function a version marker in itself.
*/
pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hDllInst,
"DllGetVersion");
if(pDllGetVersion)
{
// DLL supports version retrieval function
DLLVERSIONINFO dvi;
ZeroMemory(&dvi, sizeof(dvi));
dvi.cbSize = sizeof(dvi);
HRESULT hr = (*pDllGetVersion)(&dvi);
if(SUCCEEDED(hr))
{ // Finally, the version is at our hands
major = dvi.dwMajorVersion;
minor = dvi.dwMinorVersion;
build_number = dvi.dwBuildNumber;
result = true;
}
}
FreeLibrary(hDllInst); // Release DLL
}
}
return result;
}
#endif // LL_WINDOWS
LLOSInfo::LLOSInfo() :
mMajorVer(0), mMinorVer(0), mBuild(0)
{
@ -98,6 +167,11 @@ LLOSInfo::LLOSInfo() :
mMinorVer = osvi.dwMinorVersion;
mBuild = osvi.dwBuildNumber;
DWORD shell32_major, shell32_minor, shell32_build;
bool got_shell32_version = get_shell32_dll_version(shell32_major,
shell32_minor,
shell32_build);
switch(osvi.dwPlatformId)
{
case VER_PLATFORM_WIN32_NT:
@ -122,8 +196,22 @@ LLOSInfo::LLOSInfo() :
else
mOSStringSimple = "Microsoft Windows Server 2003 ";
}
else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0)
else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion <= 1)
{
if(osvi.dwMinorVersion == 0)
{
mOSStringSimple = "Microsoft Windows Vista ";
}
else if(osvi.dwMinorVersion == 1)
{
mOSStringSimple = "Microsoft Windows 7 ";
}
if(osvi.wProductType != VER_NT_WORKSTATION)
{
mOSStringSimple += "Server ";
}
///get native system info if available..
typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); ///function pointer for loading GetNativeSystemInfo
SYSTEM_INFO si; //System Info object file contains architecture info
@ -141,31 +229,12 @@ LLOSInfo::LLOSInfo() :
//of windows than this code does (in case it is needed for the future)
if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 ) //check for 64 bit
{
if(osvi.wProductType == VER_NT_WORKSTATION)
mOSStringSimple = "Microsoft Windows Vista 64-bit ";
else
mOSStringSimple = "Microsoft Windows Vista Server 64-bit ";
mOSStringSimple += "64-bit ";
}
else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL )
{
if(osvi.wProductType == VER_NT_WORKSTATION)
mOSStringSimple = "Microsoft Windows Vista 32-bit ";
else
mOSStringSimple = "Microsoft Windows Vista Server 32-bit ";
mOSStringSimple += "32-bit ";
}
else // PROCESSOR_ARCHITECTURE_IA64 || PROCESSOR_ARCHITECTURE_UNKNOWN not checked
{
if(osvi.wProductType == VER_NT_WORKSTATION)
mOSStringSimple = "Microsoft Windows Vista ";
else
mOSStringSimple = "Microsoft Windows Vista Server ";
}
}
else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1)
{
if(osvi.wProductType == VER_NT_WORKSTATION)
mOSStringSimple = "Microsoft Windows 7 ";
else mOSStringSimple = "Microsoft Windows 7 Server ";
}
else // Use the registry on early versions of Windows NT.
{
@ -211,6 +280,7 @@ LLOSInfo::LLOSInfo() :
csdversion.c_str(),
(osvi.dwBuildNumber & 0xffff));
}
mOSString = mOSStringSimple + tmpstr;
}
break;
@ -240,6 +310,21 @@ LLOSInfo::LLOSInfo() :
mOSString = mOSStringSimple;
break;
}
std::string compatibility_mode;
if(got_shell32_version)
{
if(osvi.dwMajorVersion != shell32_major
|| osvi.dwMinorVersion != shell32_minor)
{
compatibility_mode = llformat(" compatibility mode. real ver: %d.%d (Build %d)",
shell32_major,
shell32_minor,
shell32_build);
}
}
mOSString += compatibility_mode;
#else
struct utsname un;
if(uname(&un) != -1)

View File

@ -291,8 +291,8 @@ LLMutex::LLMutex(apr_pool_t *poolp) :
LLMutex::~LLMutex()
{
#if _DEBUG
llassert(!isLocked()); // better not be locked!
#if MUTEX_DEBUG
llassert_always(!isLocked()); // better not be locked!
#endif
apr_thread_mutex_destroy(mAPRMutexp);
mAPRMutexp = NULL;
@ -306,10 +306,24 @@ LLMutex::~LLMutex()
void LLMutex::lock()
{
apr_thread_mutex_lock(mAPRMutexp);
#if MUTEX_DEBUG
// Have to have the lock before we can access the debug info
U32 id = LLThread::currentID();
if (mIsLocked[id] != FALSE)
llerrs << "Already locked in Thread: " << id << llendl;
mIsLocked[id] = TRUE;
#endif
}
void LLMutex::unlock()
{
#if MUTEX_DEBUG
// Access the debug info while we have the lock
U32 id = LLThread::currentID();
if (mIsLocked[id] != TRUE)
llerrs << "Not locked in Thread: " << id << llendl;
mIsLocked[id] = FALSE;
#endif
apr_thread_mutex_unlock(mAPRMutexp);
}

View File

@ -128,6 +128,8 @@ protected:
//============================================================================
#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
class LL_COMMON_API LLMutex
{
public:
@ -142,6 +144,9 @@ protected:
apr_thread_mutex_t *mAPRMutexp;
apr_pool_t *mAPRPoolp;
BOOL mIsLocalPool;
#if MUTEX_DEBUG
std::map<U32, BOOL> mIsLocked;
#endif
};
// Actually a condition/mutex pair (since each condition needs to be associated with a mutex).

View File

@ -35,7 +35,6 @@
#include <functional>
#include "llassetstorage.h"
#include "lldarray.h"
#include "llfoldertype.h"
#include "llinventorytype.h"
@ -45,7 +44,6 @@
#include "llsaleinfo.h"
#include "llsd.h"
#include "lluuid.h"
#include "llxmlnode.h"
// consts for Key field in the task inventory update message
extern const U8 TASK_INVENTORY_ITEM_KEY;
@ -357,7 +355,7 @@ protected:
typedef std::list<LLPointer<LLInventoryObject> > InventoryObjectList;
// These functions convert between structured data and an inventroy
// These functions convert between structured data and an inventory
// item, appropriate for serialization.
LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item);
//LLPointer<LLInventoryItem> ll_create_item_from_sd(const LLSD& sd_item);

View File

@ -189,6 +189,7 @@ typedef std::set<LLUUID> AskQueue;
typedef std::list<PendingReply*> ReplyQueue;
typedef std::map<LLUUID,U32> PendingQueue;
typedef std::map<LLUUID, LLCacheNameEntry*> Cache;
typedef std::map<std::string, LLUUID> ReverseCache;
class LLCacheName::Impl
{
@ -198,7 +199,9 @@ public:
Cache mCache;
// the map of UUIDs to names
ReverseCache mReverseCache;
// map of names to UUIDs
AskQueue mAskNameQueue;
AskQueue mAskGroupQueue;
// UUIDs to ask our upstream host about
@ -371,7 +374,9 @@ void LLCacheName::importFile(LLFILE* fp)
entry->mFirstName = firstname;
entry->mLastName = lastname;
impl.mCache[id] = entry;
std::string fullname = entry->mFirstName + " " + entry->mLastName;
impl.mReverseCache[fullname] = id;
count++;
}
@ -407,6 +412,8 @@ bool LLCacheName::importFile(std::istream& istr)
entry->mFirstName = agent[FIRST].asString();
entry->mLastName = agent[LAST].asString();
impl.mCache[id] = entry;
std::string fullname = entry->mFirstName + " " + entry->mLastName;
impl.mReverseCache[fullname] = id;
++count;
}
@ -428,6 +435,7 @@ bool LLCacheName::importFile(std::istream& istr)
entry->mCreateTime = ctime;
entry->mGroupName = group[NAME].asString();
impl.mCache[id] = entry;
impl.mReverseCache[entry->mGroupName] = id;
++count;
}
llinfos << "LLCacheName loaded " << count << " group names" << llendl;
@ -548,6 +556,27 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group)
return FALSE;
}
}
BOOL LLCacheName::getUUID(const std::string& first, const std::string& last, LLUUID& id)
{
std::string fullname = first + " " + last;
return getUUID(fullname, id);
}
BOOL LLCacheName::getUUID(const std::string& fullname, LLUUID& id)
{
ReverseCache::iterator iter = impl.mReverseCache.find(fullname);
if (iter != impl.mReverseCache.end())
{
id = iter->second;
return TRUE;
}
else
{
return FALSE;
}
}
// This is a little bit kludgy. LLCacheNameCallback is a slot instead of a function pointer.
// The reason it is a slot is so that the legacy get() function below can bind an old callback
// and pass it as a slot. The reason it isn't a boost::function is so that trackable behavior
@ -897,10 +926,13 @@ void LLCacheName::Impl::processUUIDReply(LLMessageSystem* msg, bool isGroup)
if (!isGroup)
{
mSignal(id, entry->mFirstName, entry->mLastName, FALSE);
std::string fullname = entry->mFirstName + " " + entry->mLastName;
mReverseCache[fullname] = id;
}
else
{
mSignal(id, entry->mGroupName, "", TRUE);
mReverseCache[entry->mGroupName] = id;
}
}
}

View File

@ -86,6 +86,10 @@ public:
BOOL getName(const LLUUID& id, std::string& first, std::string& last);
BOOL getFullName(const LLUUID& id, std::string& fullname);
// Reverse lookup of UUID from name
BOOL getUUID(const std::string& first, const std::string& last, LLUUID& id);
BOOL getUUID(const std::string& fullname, LLUUID& id);
// If available, this method copies the group name into the string
// provided. The caller must allocate at least
// DB_GROUP_NAME_BUF_SIZE characters. If not available, this

View File

@ -61,11 +61,8 @@ BOOL LLRenderTarget::sUseFBO = FALSE;
LLRenderTarget::LLRenderTarget() :
mResX(0),
mResY(0),
mViewportWidth(0),
mViewportHeight(0),
mTex(0),
mFBO(0),
mColorFmt(0),
mDepth(0),
mStencil(0),
mUseDepth(FALSE),
@ -89,31 +86,13 @@ void LLRenderTarget::setSampleBuffer(LLMultisampleBuffer* buffer)
void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo)
{
// only reallocate if something changed
if (mResX == resx
&& mResY == resy
&& mUseDepth == depth
&& mStencil == stencil
&& mUsage == usage
&& (mFBO != 0) == ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
&& mColorFmt == color_fmt)
{
// nothing to do
return;
}
stop_glerror();
mResX = resx;
mResY = resy;
// default viewport to entire texture
mViewportWidth = mResX;
mViewportHeight = mResY;
mStencil = stencil;
mUsage = usage;
mUseDepth = depth;
mFBO = 0;
mColorFmt = color_fmt;
release();
@ -333,7 +312,7 @@ void LLRenderTarget::bindTarget()
}
}
glViewport(0, 0, mViewportWidth, mViewportHeight);
glViewport(0, 0, mResX, mResY);
sBoundTarget = this;
}
@ -536,18 +515,12 @@ BOOL LLRenderTarget::isComplete() const
return (!mTex.empty() || mDepth) ? TRUE : FALSE;
}
void LLRenderTarget::setViewport(U32 width, U32 height)
{
mViewportWidth = llmin(width, mResX);
mViewportHeight = llmin(height, mResY);
}
void LLRenderTarget::getViewport(S32* viewport)
{
viewport[0] = 0;
viewport[1] = 0;
viewport[2] = mViewportWidth;
viewport[3] = mViewportHeight;
viewport[2] = mResX;
viewport[3] = mResY;
}
//==================================================
@ -608,7 +581,7 @@ void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref)
check_framebuffer_status();
glViewport(0, 0, mViewportWidth, mViewportHeight);
glViewport(0, 0, mResX, mResY);
sBoundTarget = this;
}
@ -620,30 +593,13 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo, U32 samples )
{
if (mResX == resx
&& mResY == resy
&& mUseDepth == depth
&& mStencil == stencil
&& mUsage == usage
&& (mFBO != 0) == ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
&& mColorFmt == color_fmt
&& mSamples == samples)
{
// nothing to do
return;
}
stop_glerror();
mResX = resx;
mResY = resy;
mViewportWidth = mResX;
mViewportHeight = mResY;
mUsage = usage;
mUseDepth = depth;
mStencil = stencil;
mFBO = 0;
mColorFmt = color_fmt;
releaseSampleBuffer();

View File

@ -107,9 +107,6 @@ public:
//uses scissor rect if in copy-to-texture mode
void clear(U32 mask = 0xFFFFFFFF);
// override default viewport to a smaller size
void setViewport(U32 width, U32 height);
//get applied viewport
void getViewport(S32* viewport);
@ -153,16 +150,12 @@ protected:
friend class LLMultisampleBuffer;
U32 mResX;
U32 mResY;
U32 mViewportWidth;
U32 mViewportHeight;
std::vector<U32> mTex;
U32 mFBO;
U32 mColorFmt;
U32 mDepth;
BOOL mStencil;
BOOL mUseDepth;
BOOL mRenderDepth;
LLTexUnit::eTextureType mUsage;
U32 mSamples;
LLMultisampleBuffer* mSampleBuffer;

View File

@ -147,7 +147,11 @@ LLButton::LLButton(const LLButton::Params& p)
mCommitOnReturn(p.commit_on_return),
mFadeWhenDisabled(FALSE),
mForcePressedState(false),
mLastDrawCharsCount(0)
mLastDrawCharsCount(0),
mMouseDownSignal(NULL),
mMouseUpSignal(NULL),
mHeldDownSignal(NULL)
{
static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
@ -215,13 +219,28 @@ LLButton::LLButton(const LLButton::Params& p)
}
if (p.click_callback.isProvided())
initCommitCallback(p.click_callback, mCommitSignal); // alias -> commit_callback
{
setCommitCallback(initCommitCallback(p.click_callback)); // alias -> commit_callback
}
if (p.mouse_down_callback.isProvided())
initCommitCallback(p.mouse_down_callback, mMouseDownSignal);
{
setMouseDownCallback(initCommitCallback(p.mouse_down_callback));
}
if (p.mouse_up_callback.isProvided())
initCommitCallback(p.mouse_up_callback, mMouseUpSignal);
{
setMouseUpCallback(initCommitCallback(p.mouse_up_callback));
}
if (p.mouse_held_callback.isProvided())
initCommitCallback(p.mouse_held_callback, mHeldDownSignal);
{
setHeldDownCallback(initCommitCallback(p.mouse_held_callback));
}
}
LLButton::~LLButton()
{
delete mMouseDownSignal;
delete mMouseUpSignal;
delete mHeldDownSignal;
}
// HACK: Committing a button is the same as instantly clicking it.
@ -232,9 +251,9 @@ void LLButton::onCommit()
// panel containing it. Therefore we need to call LLUICtrl::onCommit()
// LAST, otherwise this becomes deleted memory.
mMouseDownSignal(this, LLSD());
if (mMouseDownSignal) (*mMouseDownSignal)(this, LLSD());
mMouseUpSignal(this, LLSD());
if (mMouseUpSignal) (*mMouseUpSignal)(this, LLSD());
if (getSoundFlags() & MOUSE_DOWN)
{
@ -257,19 +276,23 @@ void LLButton::onCommit()
boost::signals2::connection LLButton::setClickedCallback( const commit_signal_t::slot_type& cb )
{
return mCommitSignal.connect(cb);
if (!mCommitSignal) mCommitSignal = new commit_signal_t();
return mCommitSignal->connect(cb);
}
boost::signals2::connection LLButton::setMouseDownCallback( const commit_signal_t::slot_type& cb )
{
return mMouseDownSignal.connect(cb);
if (!mMouseDownSignal) mMouseDownSignal = new commit_signal_t();
return mMouseDownSignal->connect(cb);
}
boost::signals2::connection LLButton::setMouseUpCallback( const commit_signal_t::slot_type& cb )
{
return mMouseUpSignal.connect(cb);
if (!mMouseUpSignal) mMouseUpSignal = new commit_signal_t();
return mMouseUpSignal->connect(cb);
}
boost::signals2::connection LLButton::setHeldDownCallback( const commit_signal_t::slot_type& cb )
{
return mHeldDownSignal.connect(cb);
if (!mHeldDownSignal) mHeldDownSignal = new commit_signal_t();
return mHeldDownSignal->connect(cb);
}
@ -351,7 +374,7 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask)
*/
LLUICtrl::handleMouseDown(x, y, mask);
mMouseDownSignal(this, LLSD());
if(mMouseDownSignal) (*mMouseDownSignal)(this, LLSD());
mMouseDownTimer.start();
mMouseDownFrame = (S32) LLFrameTimer::getFrameCount();
@ -383,7 +406,7 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
LLUICtrl::handleMouseUp(x, y, mask);
// Regardless of where mouseup occurs, handle callback
mMouseUpSignal(this, LLSD());
if(mMouseUpSignal) (*mMouseUpSignal)(this, LLSD());
resetMouseDownTimer();
@ -493,7 +516,7 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
{
LLSD param;
param["count"] = mMouseHeldDownCount++;
mHeldDownSignal(this, param);
if (mHeldDownSignal) (*mHeldDownSignal)(this, param);
}
}

View File

@ -128,6 +128,8 @@ protected:
LLButton(const Params&);
public:
~LLButton();
// For backward compatability only
typedef boost::function<void(void*)> button_callback_t;
@ -251,9 +253,9 @@ private:
void resetMouseDownTimer();
private:
commit_signal_t mMouseDownSignal;
commit_signal_t mMouseUpSignal;
commit_signal_t mHeldDownSignal;
commit_signal_t* mMouseDownSignal;
commit_signal_t* mMouseUpSignal;
commit_signal_t* mHeldDownSignal;
const LLFontGL* mGLFont;

View File

@ -107,6 +107,7 @@ public:
std::string getLabel() const;
void setFont( const LLFontGL* font ) { mFont = font; }
const LLFontGL* getFont() { return mFont; }
virtual void setControlName(const std::string& control_name, LLView* context);

View File

@ -102,7 +102,6 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)
mMaxChars(p.max_chars),
mPrearrangeCallback(p.prearrange_callback()),
mTextEntryCallback(p.text_entry_callback()),
mSelectionCallback(p.selection_callback()),
mListPosition(p.list_position),
mLastSelectedIndex(-1)
{
@ -721,12 +720,6 @@ void LLComboBox::onItemSelected(const LLSD& data)
// commit does the reverse, asserting the value in the list
onCommit();
// call the callback if it exists
if(mSelectionCallback)
{
mSelectionCallback(this, data);
}
}
BOOL LLComboBox::handleToolTip(S32 x, S32 y, MASK mask)

View File

@ -82,8 +82,7 @@ public:
allow_new_values;
Optional<S32> max_chars;
Optional<commit_callback_t> prearrange_callback,
text_entry_callback,
selection_callback;
text_entry_callback;
Optional<EPreferredPosition, PreferredPositionValues> list_position;
@ -200,7 +199,6 @@ public:
void setPrearrangeCallback( commit_callback_t cb ) { mPrearrangeCallback = cb; }
void setTextEntryCallback( commit_callback_t cb ) { mTextEntryCallback = cb; }
void setSelectionCallback( commit_callback_t cb ) { mSelectionCallback = cb; }
void setButtonVisible(BOOL visible);

View File

@ -392,9 +392,4 @@ void LLConsole::addLine(const LLWString& wline, F32 size, const LLColor4 &color)
Paragraph paragraph(wline, color, mTimer.getElapsedTimeF32(), mFont, (F32)getRect().getWidth() );
mParagraphs.push_back ( paragraph );
#if LL_WINDOWS && LL_LCD_COMPILE
// add to LCD screen
AddNewDebugConsoleToLCD(wline);
#endif
}

View File

@ -136,21 +136,10 @@ void LLDockableFloater::setVisible(BOOL visible)
void LLDockableFloater::setMinimized(BOOL minimize)
{
if(minimize && isDocked())
if(minimize)
{
setVisible(FALSE);
}
if (minimize)
{
setCanDock(false);
}
else if (!minimize && mDockControl.get() != NULL && mDockControl.get()->isDockVisible())
{
setCanDock(true);
}
LLFloater::setMinimized(minimize);
}
LLView * LLDockableFloater::getDockWidget()

View File

@ -266,6 +266,11 @@ void LLDockControl::off()
mEnabled = false;
}
void LLDockControl::forceRecalculatePosition()
{
mRecalculateDocablePosition = true;
}
void LLDockControl::drawToungue()
{
if (mEnabled)

View File

@ -63,6 +63,7 @@ public:
public:
void on();
void off();
void forceRecalculatePosition();
void setDock(LLView* dockWidget);
LLView* getDock()
{

View File

@ -94,6 +94,9 @@ bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null*
item->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
item->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemRightMouseClick, this, new_pair, _4));
// Children don't accept the focus
item->setTabStop(false);
rearrangeItems();
notifyParentItemsRectChanged();
return true;
@ -282,6 +285,9 @@ void LLFlatListView::resetSelection(bool no_commit_on_deselection /*= false*/)
{
onCommit();
}
// Stretch selected items rect to ensure it won't be clipped
mSelectedItemsBorder->setRect(getSelectedItemsRect().stretch(-1));
}
void LLFlatListView::setNoItemsCommentText(const std::string& comment_text)
@ -381,8 +387,34 @@ LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)
//we don't need to stretch in vertical direction on reshaping by a parent
//no bottom following!
mItemsPanel->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_TOP);
LLViewBorder::Params params;
params.name("scroll border");
params.rect(getSelectedItemsRect());
params.visible(false);
params.bevel_style(LLViewBorder::BEVEL_IN);
mSelectedItemsBorder = LLUICtrlFactory::create<LLViewBorder> (params);
mItemsPanel->addChild( mSelectedItemsBorder );
};
// virtual
void LLFlatListView::draw()
{
// Highlight border if a child of this container has keyboard focus
if( mSelectedItemsBorder->getVisible() )
{
mSelectedItemsBorder->setKeyboardFocusHighlight( hasFocus() );
}
LLScrollContainer::draw();
}
// virtual
BOOL LLFlatListView::postBuild()
{
setTabStop(true);
return LLScrollContainer::postBuild();
}
void LLFlatListView::rearrangeItems()
{
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
@ -444,6 +476,9 @@ void LLFlatListView::rearrangeItems()
// move top for next item in list
item_new_top -= (rc.getHeight() + mItemPad);
}
// Stretch selected items rect to ensure it won't be clipped
mSelectedItemsBorder->setRect(getSelectedItemsRect().stretch(-1));
}
void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
@ -473,6 +508,64 @@ void LLFlatListView::onItemRightMouseClick(item_pair_t* item_pair, MASK mask)
onItemMouseClick(item_pair, mask);
}
BOOL LLFlatListView::handleKeyHere(KEY key, MASK mask)
{
BOOL reset_selection = (mask != MASK_SHIFT);
BOOL handled = FALSE;
switch (key)
{
case KEY_RETURN:
{
if (mSelectedItemPairs.size() && mask == MASK_NONE)
{
mOnReturnSignal(this, getValue());
handled = TRUE;
}
break;
}
case KEY_UP:
{
if ( !selectNextItemPair(true, reset_selection) && reset_selection)
{
// If case we are in accordion tab notify parent to go to the previous accordion
notifyParent(LLSD().insert("action","select_prev"));
}
break;
}
case KEY_DOWN:
{
if ( !selectNextItemPair(false, reset_selection) && reset_selection)
{
// If case we are in accordion tab notify parent to go to the next accordion
notifyParent(LLSD().insert("action","select_next"));
}
break;
}
case 'A':
{
if(MASK_CONTROL & mask)
{
selectAll();
handled = TRUE;
}
break;
}
default:
break;
}
if ( key == KEY_UP || key == KEY_DOWN )
{
LLRect selcted_rect = getLastSelectedItemRect().stretch(1);
LLRect visible_rect = getVisibleContentRect();
if ( !visible_rect.contains (selcted_rect) )
scrollToShowRect(selcted_rect);
handled = TRUE;
}
return handled ? handled : LLScrollContainer::handleKeyHere(key, mask);
}
LLFlatListView::item_pair_t* LLFlatListView::getItemPair(LLPanel* item) const
{
llassert(item);
@ -552,6 +645,143 @@ bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select)
onCommit();
}
setFocus(TRUE);
// Stretch selected items rect to ensure it won't be clipped
mSelectedItemsBorder->setRect(getSelectedItemsRect().stretch(-1));
return true;
}
LLRect LLFlatListView::getLastSelectedItemRect()
{
if (!mSelectedItemPairs.size())
{
return LLRect::null;
}
return mSelectedItemPairs.back()->first->getRect();
}
LLRect LLFlatListView::getSelectedItemsRect()
{
if (!mSelectedItemPairs.size())
{
return LLRect::null;
}
LLRect rc = getLastSelectedItemRect();
for ( pairs_const_iterator_t
it = mSelectedItemPairs.begin(),
it_end = mSelectedItemPairs.end();
it != it_end; ++it )
{
rc.unionWith((*it)->first->getRect());
}
return rc;
}
// virtual
bool LLFlatListView::selectNextItemPair(bool is_up_direction, bool reset_selection)
{
// No items - no actions!
if ( !mItemPairs.size() )
return false;
item_pair_t* cur_sel_pair = NULL;
item_pair_t* to_sel_pair = NULL;
if ( mSelectedItemPairs.size() )
{
// Take the last selected pair
cur_sel_pair = mSelectedItemPairs.back();
}
else
{
// If there weren't selected items then choose the first one bases on given direction
cur_sel_pair = (is_up_direction) ? mItemPairs.back() : mItemPairs.front();
// Force selection to first item
to_sel_pair = cur_sel_pair;
}
// Bases on given direction choose next item to select
if ( is_up_direction )
{
// Find current selected item position in mItemPairs list
pairs_list_t::reverse_iterator sel_it = std::find(mItemPairs.rbegin(), mItemPairs.rend(), cur_sel_pair);
for (;++sel_it != mItemPairs.rend();)
{
// skip invisible items
if ( (*sel_it)->first->getVisible() )
{
to_sel_pair = *sel_it;
break;
}
}
}
else
{
// Find current selected item position in mItemPairs list
pairs_list_t::iterator sel_it = std::find(mItemPairs.begin(), mItemPairs.end(), cur_sel_pair);
for (;++sel_it != mItemPairs.end();)
{
// skip invisible items
if ( (*sel_it)->first->getVisible() )
{
to_sel_pair = *sel_it;
break;
}
}
}
if ( to_sel_pair )
{
bool select = true;
if ( reset_selection )
{
// Reset current selection if we were asked about it
resetSelection();
}
else
{
// If item already selected and no reset request than we should deselect last selected item.
select = (mSelectedItemPairs.end() == std::find(mSelectedItemPairs.begin(), mSelectedItemPairs.end(), to_sel_pair));
}
// Select/Deselect next item
selectItemPair(select ? to_sel_pair : cur_sel_pair, select);
return true;
}
return false;
}
bool LLFlatListView::selectAll()
{
if (!mAllowSelection)
return false;
mSelectedItemPairs.clear();
for (pairs_const_iterator_t it= mItemPairs.begin(); it != mItemPairs.end(); ++it)
{
item_pair_t* item_pair = *it;
mSelectedItemPairs.push_back(item_pair);
//a way of notifying panel of selection state changes
LLPanel* item = item_pair->first;
item->setValue(SELECTED_EVENT);
}
if (mCommitOnSelectionChange)
{
onCommit();
}
// Stretch selected items rect to ensure it won't be clipped
mSelectedItemsBorder->setRect(getSelectedItemsRect().stretch(-1));
return true;
}
@ -670,4 +900,15 @@ void LLFlatListView::getValues(std::vector<LLSD>& values) const
}
}
// virtual
void LLFlatListView::onFocusReceived()
{
mSelectedItemsBorder->setVisible(TRUE);
}
// virtual
void LLFlatListView::onFocusLost()
{
mSelectedItemsBorder->setVisible(FALSE);
}
//EOF

View File

@ -50,7 +50,7 @@ class LLTextBox;
* is ignored. The option "keep_one_selected" forces at least one item to be selected at any time (only for mouse events on items)
* since any item of the list was selected.
*
* Examples of using this control are presented in Picks panel (Me Profile and Profile View), where this control is used to
* Examples of using this control are presented in Picks panel (My Profile and Profile View), where this control is used to
* manage the list of pick items.
*
* ASSUMPTIONS AND STUFF
@ -113,6 +113,10 @@ public:
virtual ~LLFlatListView() { clear(); };
/**
* Connects callback to signal called when Return key is pressed.
*/
boost::signals2::connection setReturnCallback( const commit_signal_t::slot_type& cb ) { return mOnReturnSignal.connect(cb); }
/** Overridden LLPanel's reshape, height is ignored, the list sets its height to accommodate all items */
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
@ -318,6 +322,10 @@ protected:
virtual bool selectItemPair(item_pair_t* item_pair, bool select);
virtual bool selectNextItemPair(bool is_up_direction, bool reset_selection);
virtual bool selectAll();
virtual bool isSelected(item_pair_t* item_pair) const;
virtual bool removeItemPair(item_pair_t* item_pair);
@ -331,6 +339,19 @@ protected:
*/
void notifyParentItemsRectChanged();
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL postBuild();
virtual void onFocusReceived();
virtual void onFocusLost();
virtual void draw();
LLRect getLastSelectedItemRect();
LLRect getSelectedItemsRect();
private:
@ -381,6 +402,10 @@ private:
LLRect mPrevNotifyParentRect;
LLTextBox* mNoItemsCommentTextbox;
LLViewBorder* mSelectedItemsBorder;
commit_signal_t mOnReturnSignal;
};
#endif

View File

@ -2526,8 +2526,12 @@ void LLFloaterView::pushVisibleAll(BOOL visible, const skip_list_t& skip_list)
void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)
{
for (child_list_const_iter_t child_iter = getChildList()->begin();
child_iter != getChildList()->end(); ++child_iter)
// make a copy of the list since some floaters change their
// order in the childList when changing visibility.
child_list_t child_list_copy = *getChildList();
for (child_list_const_iter_t child_iter = child_list_copy.begin();
child_iter != child_list_copy.end(); ++child_iter)
{
LLView *view = *child_iter;
if (skip_list.find(view) == skip_list.end())
@ -2638,10 +2642,14 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
// open callback
if (p.open_callback.isProvided())
initCommitCallback(p.open_callback, mOpenSignal);
{
mOpenSignal.connect(initCommitCallback(p.open_callback));
}
// close callback
if (p.close_callback.isProvided())
initCommitCallback(p.close_callback, mCloseSignal);
{
mCloseSignal.connect(initCommitCallback(p.close_callback));
}
}
LLFastTimer::DeclareTimer POST_BUILD("Floater Post Build");

View File

@ -195,6 +195,7 @@ public:
/// The static isShown() can accept a NULL pointer (which of course
/// returns false). When non-NULL, it calls the non-static isShown().
static bool isShown(const LLFloater* floater);
BOOL isFirstLook() { return mFirstLook; } // EXT-2653: This function is necessary to prevent overlapping for secondary showed toasts
BOOL isFrontmost();
BOOL isDependent() { return !mDependeeHandle.isDead(); }
void setCanMinimize(BOOL can_minimize);

View File

@ -41,6 +41,10 @@ const F32 FOCUS_FADE_TIME = 0.3f;
// NOTE: the LLFocusableElement implementation has been moved here from lluictrl.cpp.
LLFocusableElement::LLFocusableElement()
: mFocusLostCallback(NULL),
mFocusReceivedCallback(NULL),
mFocusChangedCallback(NULL),
mTopLostCallback(NULL)
{
}
@ -59,23 +63,27 @@ BOOL LLFocusableElement::handleUnicodeChar(llwchar uni_char, BOOL called_from_pa
// virtual
LLFocusableElement::~LLFocusableElement()
{
delete mFocusLostCallback;
delete mFocusReceivedCallback;
delete mFocusChangedCallback;
delete mTopLostCallback;
}
void LLFocusableElement::onFocusReceived()
{
mFocusReceivedCallback(this);
mFocusChangedCallback(this);
if (mFocusReceivedCallback) (*mFocusReceivedCallback)(this);
if (mFocusChangedCallback) (*mFocusChangedCallback)(this);
}
void LLFocusableElement::onFocusLost()
{
mFocusLostCallback(this);
mFocusChangedCallback(this);
if (mFocusLostCallback) (*mFocusLostCallback)(this);
if (mFocusChangedCallback) (*mFocusChangedCallback)(this);
}
void LLFocusableElement::onTopLost()
{
mTopLostCallback(this);
if (mTopLostCallback) (*mTopLostCallback)(this);
}
BOOL LLFocusableElement::hasFocus() const
@ -87,6 +95,31 @@ void LLFocusableElement::setFocus(BOOL b)
{
}
boost::signals2::connection LLFocusableElement::setFocusLostCallback( const focus_signal_t::slot_type& cb)
{
if (!mFocusLostCallback) mFocusLostCallback = new focus_signal_t();
return mFocusLostCallback->connect(cb);
}
boost::signals2::connection LLFocusableElement::setFocusReceivedCallback(const focus_signal_t::slot_type& cb)
{
if (!mFocusReceivedCallback) mFocusReceivedCallback = new focus_signal_t();
return mFocusReceivedCallback->connect(cb);
}
boost::signals2::connection LLFocusableElement::setFocusChangedCallback(const focus_signal_t::slot_type& cb)
{
if (!mFocusChangedCallback) mFocusChangedCallback = new focus_signal_t();
return mFocusChangedCallback->connect(cb);
}
boost::signals2::connection LLFocusableElement::setTopLostCallback(const focus_signal_t::slot_type& cb)
{
if (!mTopLostCallback) mTopLostCallback = new focus_signal_t();
return mTopLostCallback->connect(cb);
}
LLFocusMgr gFocusMgr;

View File

@ -56,10 +56,10 @@ public:
typedef boost::signals2::signal<void(LLFocusableElement*)> focus_signal_t;
boost::signals2::connection setFocusLostCallback( const focus_signal_t::slot_type& cb) { return mFocusLostCallback.connect(cb);}
boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb) { return mFocusReceivedCallback.connect(cb);}
boost::signals2::connection setFocusChangedCallback(const focus_signal_t::slot_type& cb) { return mFocusChangedCallback.connect(cb);}
void setTopLostCallback(const focus_signal_t::slot_type& cb) { mTopLostCallback.connect(cb);}
boost::signals2::connection setFocusLostCallback( const focus_signal_t::slot_type& cb);
boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb);
boost::signals2::connection setFocusChangedCallback(const focus_signal_t::slot_type& cb);
boost::signals2::connection setTopLostCallback(const focus_signal_t::slot_type& cb);
// These were brought up the hierarchy from LLView so that we don't have to use dynamic_cast when dealing with keyboard focus.
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
@ -69,10 +69,10 @@ protected:
virtual void onFocusReceived();
virtual void onFocusLost();
virtual void onTopLost(); // called when registered as top ctrl and user clicks elsewhere
focus_signal_t mFocusLostCallback;
focus_signal_t mFocusReceivedCallback;
focus_signal_t mFocusChangedCallback;
focus_signal_t mTopLostCallback;
focus_signal_t* mFocusLostCallback;
focus_signal_t* mFocusReceivedCallback;
focus_signal_t* mFocusChangedCallback;
focus_signal_t* mTopLostCallback;
};

View File

@ -413,6 +413,19 @@ void LLLayoutStack::updatePanelAutoResize(const std::string& panel_name, BOOL au
}
}
bool LLLayoutStack::getPanelMinSize(const std::string& panel_name, S32* min_widthp, S32* min_heightp)
{
LayoutPanel* panel = findEmbeddedPanelByName(panel_name);
if (panel)
{
if (min_widthp) *min_widthp = panel->mMinWidth;
if (min_heightp) *min_heightp = panel->mMinHeight;
}
return NULL != panel;
}
static LLFastTimer::DeclareTimer FTM_UPDATE_LAYOUT("Update LayoutStacks");
void LLLayoutStack::updateLayout(BOOL force_resize)
{

View File

@ -82,6 +82,14 @@ public:
void updatePanelAutoResize(const std::string& panel_name, BOOL auto_resize);
/**
* Gets minimal width and/or height of the specified by name panel.
*
* If it is necessary to get only the one dimension pass NULL for another one.
* @returns true if specified by panel_name internal panel exists, false otherwise.
*/
bool getPanelMinSize(const std::string& panel_name, S32* min_widthp, S32* min_heightp);
void updateLayout(BOOL force_resize = FALSE);
static void updateClass();

View File

@ -84,8 +84,8 @@ void LLLineEditor::PrevalidateNamedFuncs::declareValues()
declare("non_negative_s32", LLLineEditor::prevalidateNonNegativeS32);
declare("alpha_num", LLLineEditor::prevalidateAlphaNum);
declare("alpha_num_space", LLLineEditor::prevalidateAlphaNumSpace);
declare("printable_not_pipe", LLLineEditor::prevalidatePrintableNotPipe);
declare("printable_no_space", LLLineEditor::prevalidatePrintableNoSpace);
declare("ascii_printable_no_pipe", LLLineEditor::prevalidateASCIIPrintableNoPipe);
declare("ascii_printable_no_space", LLLineEditor::prevalidateASCIIPrintableNoSpace);
}
LLLineEditor::Params::Params()
@ -323,6 +323,19 @@ void LLLineEditor::setMaxTextLength(S32 max_text_length)
mMaxLengthBytes = max_len;
}
void LLLineEditor::getTextPadding(S32 *left, S32 *right)
{
*left = mTextPadLeft;
*right = mTextPadRight;
}
void LLLineEditor::setTextPadding(S32 left, S32 right)
{
mTextPadLeft = left;
mTextPadRight = right;
updateTextPadding();
}
void LLLineEditor::updateTextPadding()
{
static LLUICachedControl<S32> line_editor_hpad ("UILineEditorHPad", 0);
@ -626,7 +639,8 @@ BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
// delay cursor flashing
mKeystrokeTimer.reset();
mMouseDownSignal(this,x,y,mask);
if (mMouseDownSignal)
(*mMouseDownSignal)(this,x,y,mask);
return TRUE;
}
@ -742,7 +756,8 @@ BOOL LLLineEditor::handleMouseUp(S32 x, S32 y, MASK mask)
}
// We won't call LLUICtrl::handleMouseUp to avoid double calls of childrenHandleMouseUp().Just invoke the signal manually.
mMouseUpSignal(this,x,y, mask);
if (mMouseUpSignal)
(*mMouseUpSignal)(this,x,y, mask);
return handled;
}
@ -2186,20 +2201,28 @@ BOOL LLLineEditor::prevalidateAlphaNumSpace(const LLWString &str)
return rv;
}
// Used for most names of things stored on the server, due to old file-formats
// that used the pipe (|) for multiline text storage. Examples include
// inventory item names, parcel names, object names, etc.
// static
BOOL LLLineEditor::prevalidatePrintableNotPipe(const LLWString &str)
BOOL LLLineEditor::prevalidateASCIIPrintableNoPipe(const LLWString &str)
{
BOOL rv = TRUE;
S32 len = str.length();
if(len == 0) return rv;
while(len--)
{
if('|' == str[len])
llwchar wc = str[len];
if (wc < 0x20
|| wc > 0x7f
|| wc == '|')
{
rv = FALSE;
break;
}
if(!((' ' == str[len]) || LLStringOps::isAlnum((char)str[len]) || LLStringOps::isPunct((char)str[len])))
if(!(wc == ' '
|| LLStringOps::isAlnum((char)wc)
|| LLStringOps::isPunct((char)wc) ) )
{
rv = FALSE;
break;
@ -2209,15 +2232,19 @@ BOOL LLLineEditor::prevalidatePrintableNotPipe(const LLWString &str)
}
// Used for avatar names
// static
BOOL LLLineEditor::prevalidatePrintableNoSpace(const LLWString &str)
BOOL LLLineEditor::prevalidateASCIIPrintableNoSpace(const LLWString &str)
{
BOOL rv = TRUE;
S32 len = str.length();
if(len == 0) return rv;
while(len--)
{
if(LLStringOps::isSpace(str[len]))
llwchar wc = str[len];
if (wc < 0x20
|| wc > 0x7f
|| LLStringOps::isSpace(wc))
{
rv = FALSE;
break;
@ -2232,6 +2259,7 @@ BOOL LLLineEditor::prevalidatePrintableNoSpace(const LLWString &str)
return rv;
}
// static
BOOL LLLineEditor::prevalidateASCII(const LLWString &str)
{

View File

@ -226,6 +226,9 @@ public:
void setKeystrokeCallback(callback_t callback, void* user_data);
void setMaxTextLength(S32 max_text_length);
// Manipulate left and right padding for text
void getTextPadding(S32 *left, S32 *right);
void setTextPadding(S32 left, S32 right);
// Prevalidation controls which keystrokes can affect the editor
void setPrevalidate( LLLinePrevalidateFunc func );
@ -235,8 +238,8 @@ public:
static BOOL prevalidateNonNegativeS32(const LLWString &str);
static BOOL prevalidateAlphaNum(const LLWString &str );
static BOOL prevalidateAlphaNumSpace(const LLWString &str );
static BOOL prevalidatePrintableNotPipe(const LLWString &str);
static BOOL prevalidatePrintableNoSpace(const LLWString &str);
static BOOL prevalidateASCIIPrintableNoPipe(const LLWString &str);
static BOOL prevalidateASCIIPrintableNoSpace(const LLWString &str);
static BOOL prevalidateASCII(const LLWString &str);
static BOOL postvalidateFloat(const std::string &str);

View File

@ -760,21 +760,25 @@ void LLMenuItemCallGL::initFromParams(const Params& p)
{
if (p.on_visible.isProvided())
{
initVisibleCallback(p.on_visible, mVisibleSignal);
mVisibleSignal.connect(initVisibleCallback(p.on_visible));
}
if (p.on_enable.isProvided())
{
initEnableCallback(p.on_enable, mEnableSignal);
setEnableCallback(initEnableCallback(p.on_enable));
// Set the enabled control variable (for backwards compatability)
if (p.on_enable.control_name.isProvided() && !p.on_enable.control_name().empty())
{
LLControlVariable* control = findControl(p.on_enable.control_name());
if (control)
{
setEnabledControlVariable(control);
}
}
}
if (p.on_click.isProvided())
initCommitCallback(p.on_click, mCommitSignal);
{
setCommitCallback(initCommitCallback(p.on_click));
}
LLUICtrl::initFromParams(p);
}
@ -795,7 +799,10 @@ void LLMenuItemCallGL::updateEnabled( void )
if (mEnabledControlVariable)
{
if (!enabled)
mEnabledControlVariable->set(false); // callback overrides control variable; this will call setEnabled()
{
// callback overrides control variable; this will call setEnabled()
mEnabledControlVariable->set(false);
}
}
else
{
@ -854,7 +861,7 @@ void LLMenuItemCheckGL::initFromParams(const Params& p)
{
if (p.on_check.isProvided())
{
initEnableCallback(p.on_check, mCheckSignal);
setCheckCallback(initEnableCallback(p.on_check));
// Set the control name (for backwards compatability)
if (p.on_check.control_name.isProvided() && !p.on_check.control_name().empty())
{

View File

@ -84,17 +84,30 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
mThumbCenterSelectedColor(p.thumb_center_selected_color()),
mDisabledThumbColor(p.thumb_disabled_color()),
mTriangleColor(p.triangle_color()),
mThumbWidth(p.thumb_width)
mThumbWidth(p.thumb_width),
mMouseDownSignal(NULL),
mMouseUpSignal(NULL)
{
mValue.emptyMap();
mCurSlider = LLStringUtil::null;
if (p.mouse_down_callback.isProvided())
initCommitCallback(p.mouse_down_callback, mMouseDownSignal);
{
setMouseDownCallback(initCommitCallback(p.mouse_down_callback));
}
if (p.mouse_up_callback.isProvided())
initCommitCallback(p.mouse_up_callback, mMouseUpSignal);
{
setMouseUpCallback(initCommitCallback(p.mouse_up_callback));
}
}
LLMultiSlider::~LLMultiSlider()
{
delete mMouseDownSignal;
delete mMouseUpSignal;
}
void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from_event)
{
// exit if not there
@ -325,7 +338,8 @@ BOOL LLMultiSlider::handleMouseUp(S32 x, S32 y, MASK mask)
{
gFocusMgr.setMouseCapture( NULL );
mMouseUpSignal( this, LLSD() );
if (mMouseUpSignal)
(*mMouseUpSignal)( this, LLSD() );
handled = TRUE;
make_ui_sound("UISndClickRelease");
@ -345,7 +359,8 @@ BOOL LLMultiSlider::handleMouseDown(S32 x, S32 y, MASK mask)
{
setFocus(TRUE);
}
mMouseDownSignal( this, LLSD() );
if (mMouseDownSignal)
(*mMouseDownSignal)( this, LLSD() );
if (MASK_CONTROL & mask) // if CTRL is modifying
{
@ -557,3 +572,15 @@ void LLMultiSlider::draw()
LLF32UICtrl::draw();
}
boost::signals2::connection LLMultiSlider::setMouseDownCallback( const commit_signal_t::slot_type& cb )
{
if (!mMouseDownSignal) mMouseDownSignal = new commit_signal_t();
return mMouseDownSignal->connect(cb);
}
boost::signals2::connection LLMultiSlider::setMouseUpCallback( const commit_signal_t::slot_type& cb )
{
if (!mMouseUpSignal) mMouseUpSignal = new commit_signal_t();
return mMouseUpSignal->connect(cb);
}

View File

@ -67,6 +67,7 @@ protected:
LLMultiSlider(const Params&);
friend class LLUICtrlFactory;
public:
virtual ~LLMultiSlider();
void setSliderValue(const std::string& name, F32 value, BOOL from_event = FALSE);
F32 getSliderValue(const std::string& name) const;
@ -78,8 +79,8 @@ public:
/*virtual*/ void setValue(const LLSD& value);
/*virtual*/ LLSD getValue() const { return mValue; }
boost::signals2::connection setMouseDownCallback( const commit_signal_t::slot_type& cb ) { return mMouseDownSignal.connect(cb); }
boost::signals2::connection setMouseUpCallback( const commit_signal_t::slot_type& cb ) { return mMouseUpSignal.connect(cb); }
boost::signals2::connection setMouseDownCallback( const commit_signal_t::slot_type& cb );
boost::signals2::connection setMouseUpCallback( const commit_signal_t::slot_type& cb );
bool findUnusedValue(F32& initVal);
const std::string& addSlider();
@ -116,8 +117,8 @@ protected:
LLUIColor mDisabledThumbColor;
LLUIColor mTriangleColor;
commit_signal_t mMouseDownSignal;
commit_signal_t mMouseUpSignal;
commit_signal_t* mMouseDownSignal;
commit_signal_t* mMouseUpSignal;
};
#endif // LL_MULTI_SLIDER_H

View File

@ -344,7 +344,7 @@ void LLMultiSliderCtrl::onEditorCommit( LLUICtrl* ctrl, const LLSD& userdata)
if( self->mMultiSlider->getMinValue() <= val && val <= self->mMultiSlider->getMaxValue() )
{
self->setCurSliderValue( val ); // set the value temporarily so that the callback can retrieve it.
if( self->mValidateSignal( self, val ) )
if( !self->mValidateSignal || (*(self->mValidateSignal))( self, val ) )
{
success = TRUE;
}
@ -378,7 +378,7 @@ void LLMultiSliderCtrl::onSliderCommit(LLUICtrl* ctrl, const LLSD& userdata)
F32 new_val = self->mMultiSlider->getCurSliderValue();
self->mCurValue = new_val; // set the value temporarily so that the callback can retrieve it.
if( self->mValidateSignal( self, new_val ) )
if( !self->mValidateSignal || (*(self->mValidateSignal))( self, new_val ) )
{
success = TRUE;
}

View File

@ -106,7 +106,8 @@ LLPanel::LLPanel(const LLPanel::Params& p)
mHelpTopic(p.help_topic),
mCommitCallbackRegistrar(false),
mEnableCallbackRegistrar(false),
mXMLFilename(p.filename)
mXMLFilename(p.filename),
mVisibleSignal(NULL)
// *NOTE: Be sure to also change LLPanel::initFromParams(). We have too
// many classes derived from LLPanel to retrofit them all to pass in params.
{
@ -118,6 +119,11 @@ LLPanel::LLPanel(const LLPanel::Params& p)
mPanelHandle.bind(this);
}
LLPanel::~LLPanel()
{
delete mVisibleSignal;
}
// virtual
BOOL LLPanel::isPanel() const
{
@ -332,7 +338,8 @@ BOOL LLPanel::handleKeyHere( KEY key, MASK mask )
void LLPanel::handleVisibilityChange ( BOOL new_visibility )
{
LLUICtrl::handleVisibilityChange ( new_visibility );
mVisibleSignal(this, LLSD(new_visibility) ); // Pass BOOL as LLSD
if (mVisibleSignal)
(*mVisibleSignal)(this, LLSD(new_visibility) ); // Pass BOOL as LLSD
}
void LLPanel::setFocus(BOOL b)
@ -424,7 +431,9 @@ void LLPanel::initFromParams(const LLPanel::Params& p)
// visible callback
if (p.visible_callback.isProvided())
initCommitCallback(p.visible_callback, mVisibleSignal);
{
setVisibleCallback(initCommitCallback(p.visible_callback));
}
for (LLInitParam::ParamIterator<LocalizedString>::const_iterator it = p.strings().begin();
it != p.strings().end();
@ -907,3 +916,13 @@ void LLPanel::childSetControlName(const std::string& id, const std::string& cont
view->setControlName(control_name, NULL);
}
}
boost::signals2::connection LLPanel::setVisibleCallback( const commit_signal_t::slot_type& cb )
{
if (!mVisibleSignal)
{
mVisibleSignal = new commit_signal_t();
}
return mVisibleSignal->connect(cb);
}

View File

@ -109,7 +109,7 @@ protected:
public:
// LLPanel(const std::string& name, const LLRect& rect = LLRect(), BOOL bordered = TRUE);
/*virtual*/ ~LLPanel() {}
/*virtual*/ ~LLPanel();
// LLView interface
/*virtual*/ BOOL isPanel() const;
@ -241,6 +241,8 @@ public:
void setXMLFilename(std::string filename) { mXMLFilename = filename; };
std::string getXMLFilename() { return mXMLFilename; };
boost::signals2::connection setVisibleCallback( const commit_signal_t::slot_type& cb );
protected:
// Override to set not found list
LLButton* getDefaultButton() { return mDefaultBtn; }
@ -249,7 +251,7 @@ protected:
EnableCallbackRegistry::ScopedRegistrar mEnableCallbackRegistrar;
VisibleCallbackRegistry::ScopedRegistrar mVisibleCallbackRegistrar;
commit_signal_t mVisibleSignal; // Called when visibility changes, passes new visibility as LLSD()
commit_signal_t* mVisibleSignal; // Called when visibility changes, passes new visibility as LLSD()
std::string mHelpTopic; // the name of this panel's help topic to display in the Help Viewer

View File

@ -143,6 +143,12 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
if( valid_rect.localPointInRect( screen_x, screen_y ) && mResizingView )
{
// undock floater when user resize it
if (((LLFloater*)getParent())->isDocked())
{
((LLFloater*)getParent())->setDocked(false, false);
}
// Resize the parent
LLRect orig_rect = mResizingView->getRect();
LLRect scaled_rect = orig_rect;

View File

@ -135,6 +135,12 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
LLView* resizing_view = getParent();
if( resizing_view )
{
// undock floater when user resize it
if (((LLFloater*)getParent())->isDocked())
{
((LLFloater*)getParent())->setDocked(false, false);
}
// Resize the parent
LLRect orig_rect = resizing_view->getRect();
LLRect scaled_rect = orig_rect;

View File

@ -77,7 +77,9 @@ LLSlider::LLSlider(const LLSlider::Params& p)
mTrackImageHorizontal(p.track_image_horizontal),
mTrackImageVertical(p.track_image_vertical),
mTrackHighlightHorizontalImage(p.track_highlight_horizontal_image),
mTrackHighlightVerticalImage(p.track_highlight_vertical_image)
mTrackHighlightVerticalImage(p.track_highlight_vertical_image),
mMouseDownSignal(NULL),
mMouseUpSignal(NULL)
{
mViewModel->setValue(p.initial_value);
updateThumbRect();
@ -86,9 +88,19 @@ LLSlider::LLSlider(const LLSlider::Params& p)
setValue(getValueF32());
if (p.mouse_down_callback.isProvided())
initCommitCallback(p.mouse_down_callback, mMouseDownSignal);
{
setMouseDownCallback(initCommitCallback(p.mouse_down_callback));
}
if (p.mouse_up_callback.isProvided())
initCommitCallback(p.mouse_up_callback, mMouseUpSignal);
{
setMouseUpCallback(initCommitCallback(p.mouse_up_callback));
}
}
LLSlider::~LLSlider()
{
delete mMouseDownSignal;
delete mMouseUpSignal;
}
void LLSlider::setValue(F32 value, BOOL from_event)
@ -202,7 +214,8 @@ BOOL LLSlider::handleMouseUp(S32 x, S32 y, MASK mask)
{
gFocusMgr.setMouseCapture( NULL );
mMouseUpSignal( this, getValueF32() );
if (mMouseUpSignal)
(*mMouseUpSignal)( this, getValueF32() );
handled = TRUE;
make_ui_sound("UISndClickRelease");
@ -222,7 +235,8 @@ BOOL LLSlider::handleMouseDown(S32 x, S32 y, MASK mask)
{
setFocus(TRUE);
}
mMouseDownSignal( this, getValueF32() );
if (mMouseDownSignal)
(*mMouseDownSignal)( this, getValueF32() );
if (MASK_CONTROL & mask) // if CTRL is modifying
{
@ -364,3 +378,15 @@ void LLSlider::draw()
LLUICtrl::draw();
}
boost::signals2::connection LLSlider::setMouseDownCallback( const commit_signal_t::slot_type& cb )
{
if (!mMouseDownSignal) mMouseDownSignal = new commit_signal_t();
return mMouseDownSignal->connect(cb);
}
boost::signals2::connection LLSlider::setMouseUpCallback( const commit_signal_t::slot_type& cb )
{
if (!mMouseUpSignal) mMouseUpSignal = new commit_signal_t();
return mMouseUpSignal->connect(cb);
}

View File

@ -67,6 +67,7 @@ protected:
LLSlider(const Params&);
friend class LLUICtrlFactory;
public:
virtual ~LLSlider();
void setValue( F32 value, BOOL from_event = FALSE );
// overrides for LLF32UICtrl methods
virtual void setValue(const LLSD& value ) { setValue((F32)value.asReal(), TRUE); }
@ -76,8 +77,8 @@ public:
virtual void setMinValue(F32 min_value) { LLF32UICtrl::setMinValue(min_value); updateThumbRect(); }
virtual void setMaxValue(F32 max_value) { LLF32UICtrl::setMaxValue(max_value); updateThumbRect(); }
boost::signals2::connection setMouseDownCallback( const commit_signal_t::slot_type& cb ) { return mMouseDownSignal.connect(cb); }
boost::signals2::connection setMouseUpCallback( const commit_signal_t::slot_type& cb ) { return mMouseUpSignal.connect(cb); }
boost::signals2::connection setMouseDownCallback( const commit_signal_t::slot_type& cb );
boost::signals2::connection setMouseUpCallback( const commit_signal_t::slot_type& cb );
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
@ -109,8 +110,8 @@ private:
LLUIColor mThumbOutlineColor;
LLUIColor mThumbCenterColor;
commit_signal_t mMouseDownSignal;
commit_signal_t mMouseUpSignal;
commit_signal_t* mMouseDownSignal;
commit_signal_t* mMouseUpSignal;
};
#endif // LL_LLSLIDER_H

View File

@ -122,7 +122,8 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
slider_p.min_value.setIfNotProvided(p.min_value);
slider_p.max_value.setIfNotProvided(p.max_value);
slider_p.increment.setIfNotProvided(p.increment);
slider_p.orientation.setIfNotProvided(p.orientation);
slider_p.commit_callback.function(&LLSliderCtrl::onSliderCommit);
slider_p.control_name(p.control_name);
slider_p.mouse_down_callback( p.mouse_down_callback );
@ -260,7 +261,7 @@ void LLSliderCtrl::onEditorCommit( LLUICtrl* ctrl, const LLSD& userdata )
if( self->mSlider->getMinValue() <= val && val <= self->mSlider->getMaxValue() )
{
self->setValue( val ); // set the value temporarily so that the callback can retrieve it.
if( self->mValidateSignal( self, val ) )
if( !self->mValidateSignal || (*(self->mValidateSignal))( self, val ) )
{
success = TRUE;
}
@ -294,7 +295,7 @@ void LLSliderCtrl::onSliderCommit( LLUICtrl* ctrl, const LLSD& userdata )
F32 new_val = self->mSlider->getValueF32();
self->mValue = new_val; // set the value temporarily so that the callback can retrieve it.
if( self->mValidateSignal( self, new_val ) )
if( !self->mValidateSignal || (*(self->mValidateSignal))( self, new_val ) )
{
success = TRUE;
}

View File

@ -46,6 +46,7 @@ class LLSliderCtrl : public LLF32UICtrl
public:
struct Params : public LLInitParam::Block<Params, LLF32UICtrl::Params>
{
Optional<std::string> orientation;
Optional<S32> label_width;
Optional<S32> text_width;
Optional<bool> show_text;
@ -78,7 +79,8 @@ public:
value_text("value_text"),
slider_label("slider_label"),
mouse_down_callback("mouse_down_callback"),
mouse_up_callback("mouse_up_callback")
mouse_up_callback("mouse_up_callback"),
orientation("orientation", std::string ("horizontal"))
{}
};
protected:

View File

@ -190,7 +190,7 @@ void LLSpinCtrl::onUpBtn( const LLSD& data )
F32 saved_val = (F32)getValue().asReal();
setValue(val);
if( !mValidateSignal( this, val ) )
if( mValidateSignal && !(*mValidateSignal)( this, val ) )
{
setValue( saved_val );
reportInvalidData();
@ -224,7 +224,7 @@ void LLSpinCtrl::onDownBtn( const LLSD& data )
F32 saved_val = (F32)getValue().asReal();
setValue(val);
if( !mValidateSignal( this, val ) )
if( mValidateSignal && !(*mValidateSignal)( this, val ) )
{
setValue( saved_val );
reportInvalidData();
@ -316,7 +316,7 @@ void LLSpinCtrl::onEditorCommit( const LLSD& data )
F32 saved_val = getValueF32();
setValue(val);
if( mValidateSignal( this, val ) )
if( !mValidateSignal || (*mValidateSignal)( this, val ) )
{
success = TRUE;
onCommit();

View File

@ -391,7 +391,7 @@ void LLTabContainer::draw()
mNextArrowBtn->setFlashing( TRUE );
}
}
}
}
idx++;
}
@ -1339,12 +1339,12 @@ BOOL LLTabContainer::selectTab(S32 which)
cbdata = selected_tuple->mTabPanel->getName();
BOOL res = FALSE;
if( mValidateSignal( this, cbdata ) )
if( !mValidateSignal || (*mValidateSignal)( this, cbdata ) )
{
res = setTab(which);
if (res)
if (res && mCommitSignal)
{
mCommitSignal(this, cbdata);
(*mCommitSignal)(this, cbdata);
}
}

View File

@ -60,6 +60,11 @@ LLTextBase::line_info::line_info(S32 index_start, S32 index_end, LLRect rect, S3
bool LLTextBase::compare_segment_end::operator()(const LLTextSegmentPtr& a, const LLTextSegmentPtr& b) const
{
// sort empty spans (e.g. 11-11) after previous non-empty spans (e.g. 5-11)
if (a->getEnd() == b->getEnd())
{
return a->getStart() < b->getStart();
}
return a->getEnd() < b->getEnd();
}
@ -1505,6 +1510,7 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
LLStyle::Params link_params = style_params;
link_params.color = match.getColor();
link_params.readonly_color = match.getColor();
// apply font name from requested style_params
std::string font_name = LLFontGL::nameFromFont(style_params.font());
std::string font_size = LLFontGL::sizeFromFont(style_params.font());
@ -2059,16 +2065,16 @@ void LLTextBase::updateRects()
mContentsRect.unionWith(line_iter->mRect);
}
mContentsRect.mLeft = 0;
S32 delta_pos_x = -mContentsRect.mLeft;
mContentsRect.mTop += mVPad;
S32 delta_pos = -mContentsRect.mBottom;
// move line segments to fit new document rect
for (line_list_t::iterator it = mLineInfoList.begin(); it != mLineInfoList.end(); ++it)
{
it->mRect.translate(0, delta_pos);
it->mRect.translate(delta_pos_x, delta_pos);
}
mContentsRect.translate(0, delta_pos);
mContentsRect.translate(delta_pos_x, delta_pos);
}
// update document container dimensions according to text contents
@ -2380,6 +2386,14 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
// if last character is a newline, then return true, forcing line break
llwchar last_char = text[mStart + first_char + num_chars - 1];
LLUIImagePtr image = mStyle->getImage();
if( image.notNull())
{
width += image->getWidth();
height = llmax(height, image->getHeight());
}
return num_chars >= 1 && last_char == '\n';
}

View File

@ -750,8 +750,10 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask)
{
if( mIsSelecting )
{
mScroller->autoScroll(x, y);
if(mScroller)
{
mScroller->autoScroll(x, y);
}
S32 clamped_x = llclamp(x, mTextRect.mLeft, mTextRect.mRight);
S32 clamped_y = llclamp(y, mTextRect.mBottom, mTextRect.mTop);
setCursorAtLocalPos( clamped_x, clamped_y, true );
@ -799,7 +801,10 @@ BOOL LLTextEditor::handleMouseUp(S32 x, S32 y, MASK mask)
{
if( mIsSelecting )
{
mScroller->autoScroll(x, y);
if(mScroller)
{
mScroller->autoScroll(x, y);
}
S32 clamped_x = llclamp(x, mTextRect.mLeft, mTextRect.mRight);
S32 clamped_y = llclamp(y, mTextRect.mBottom, mTextRect.mTop);
setCursorAtLocalPos( clamped_x, clamped_y, true );
@ -1696,7 +1701,15 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
*/
if (mReadOnly)
{
handled = mScroller->handleKeyHere( key, mask );
if(mScroller)
{
handled = mScroller->handleKeyHere( key, mask );
}
else
{
handled = handleNavigationKey( key, mask );
}
}
else
{
@ -2135,9 +2148,8 @@ void LLTextEditor::drawPreeditMarker()
void LLTextEditor::drawLineNumbers()
{
LLGLSUIDefault gls_ui;
LLRect scrolled_view_rect = mScroller->getVisibleContentRect();
LLRect content_rect = mScroller->getContentWindowRect();
LLRect scrolled_view_rect = getVisibleDocumentRect();
LLRect content_rect = getTextRect();
LLLocalClipRect clip(content_rect);
S32 first_line = getFirstVisibleLine();
S32 num_lines = getLineCount();

View File

@ -78,7 +78,16 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)
mEnabledControlVariable(NULL),
mDisabledControlVariable(NULL),
mMakeVisibleControlVariable(NULL),
mMakeInvisibleControlVariable(NULL)
mMakeInvisibleControlVariable(NULL),
mCommitSignal(NULL),
mValidateSignal(NULL),
mMouseEnterSignal(NULL),
mMouseLeaveSignal(NULL),
mMouseDownSignal(NULL),
mMouseUpSignal(NULL),
mRightMouseDownSignal(NULL),
mRightMouseUpSignal(NULL),
mDoubleClickSignal(NULL)
{
mUICtrlHandle.bind(this);
}
@ -129,10 +138,14 @@ void LLUICtrl::initFromParams(const Params& p)
}
if (p.commit_callback.isProvided())
initCommitCallback(p.commit_callback, mCommitSignal);
{
setCommitCallback(initCommitCallback(p.commit_callback));
}
if (p.validate_callback.isProvided())
initEnableCallback(p.validate_callback, mValidateSignal);
{
setValidateCallback(initEnableCallback(p.validate_callback));
}
if (p.init_callback.isProvided())
{
@ -151,10 +164,14 @@ void LLUICtrl::initFromParams(const Params& p)
}
if(p.mouseenter_callback.isProvided())
initCommitCallback(p.mouseenter_callback, mMouseEnterSignal);
{
setMouseEnterCallback(initCommitCallback(p.mouseenter_callback));
}
if(p.mouseleave_callback.isProvided())
initCommitCallback(p.mouseleave_callback, mMouseLeaveSignal);
{
setMouseLeaveCallback(initCommitCallback(p.mouseleave_callback));
}
}
@ -167,16 +184,40 @@ LLUICtrl::~LLUICtrl()
llwarns << "UI Control holding top ctrl deleted: " << getName() << ". Top view removed." << llendl;
gFocusMgr.removeTopCtrlWithoutCallback( this );
}
delete mCommitSignal;
delete mValidateSignal;
delete mMouseEnterSignal;
delete mMouseLeaveSignal;
delete mMouseDownSignal;
delete mMouseUpSignal;
delete mRightMouseDownSignal;
delete mRightMouseUpSignal;
delete mDoubleClickSignal;
}
void LLUICtrl::initCommitCallback(const CommitCallbackParam& cb, commit_signal_t& sig)
void default_commit_handler(LLUICtrl* ctrl, const LLSD& param)
{}
bool default_enable_handler(LLUICtrl* ctrl, const LLSD& param)
{
return true;
}
bool default_visible_handler(LLUICtrl* ctrl, const LLSD& param)
{
return true;
}
LLUICtrl::commit_signal_t::slot_type LLUICtrl::initCommitCallback(const CommitCallbackParam& cb)
{
if (cb.function.isProvided())
{
if (cb.parameter.isProvided())
sig.connect(boost::bind(cb.function(), _1, cb.parameter));
return boost::bind(cb.function(), _1, cb.parameter);
else
sig.connect(cb.function());
return cb.function();
}
else
{
@ -185,26 +226,27 @@ void LLUICtrl::initCommitCallback(const CommitCallbackParam& cb, commit_signal_t
if (func)
{
if (cb.parameter.isProvided())
sig.connect(boost::bind((*func), _1, cb.parameter));
return boost::bind((*func), _1, cb.parameter);
else
sig.connect(*func);
return commit_signal_t::slot_type(*func);
}
else if (!function_name.empty())
{
llwarns << "No callback found for: '" << function_name << "' in control: " << getName() << llendl;
}
}
return default_commit_handler;
}
void LLUICtrl::initEnableCallback(const EnableCallbackParam& cb, enable_signal_t& sig)
LLUICtrl::enable_signal_t::slot_type LLUICtrl::initEnableCallback(const EnableCallbackParam& cb)
{
// Set the callback function
if (cb.function.isProvided())
{
if (cb.parameter.isProvided())
sig.connect(boost::bind(cb.function(), this, cb.parameter));
return boost::bind(cb.function(), this, cb.parameter);
else
sig.connect(cb.function());
return cb.function();
}
else
{
@ -212,22 +254,23 @@ void LLUICtrl::initEnableCallback(const EnableCallbackParam& cb, enable_signal_t
if (func)
{
if (cb.parameter.isProvided())
sig.connect(boost::bind((*func), this, cb.parameter));
return boost::bind((*func), this, cb.parameter);
else
sig.connect(*func);
return enable_signal_t::slot_type(*func);
}
}
return default_enable_handler;
}
void LLUICtrl::initVisibleCallback(const VisibleCallbackParam& cb, visible_signal_t& sig)
LLUICtrl::visible_signal_t::slot_type LLUICtrl::initVisibleCallback(const VisibleCallbackParam& cb)
{
// Set the callback function
if (cb.function.isProvided())
{
if (cb.parameter.isProvided())
sig.connect(boost::bind(cb.function(), this, cb.parameter));
return boost::bind(cb.function(), this, cb.parameter);
else
sig.connect(cb.function());
return cb.function();
}
else
{
@ -235,30 +278,40 @@ void LLUICtrl::initVisibleCallback(const VisibleCallbackParam& cb, visible_signa
if (func)
{
if (cb.parameter.isProvided())
sig.connect(boost::bind((*func), this, cb.parameter));
return boost::bind((*func), this, cb.parameter);
else
sig.connect(*func);
return visible_signal_t::slot_type(*func);
}
}
return default_visible_handler;
}
// virtual
void LLUICtrl::onMouseEnter(S32 x, S32 y, MASK mask)
{
mMouseEnterSignal(this, getValue());
if (mMouseEnterSignal)
{
(*mMouseEnterSignal)(this, getValue());
}
}
// virtual
void LLUICtrl::onMouseLeave(S32 x, S32 y, MASK mask)
{
mMouseLeaveSignal(this, getValue());
if(mMouseLeaveSignal)
{
(*mMouseLeaveSignal)(this, getValue());
}
}
//virtual
BOOL LLUICtrl::handleMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLView::handleMouseDown(x,y,mask);
mMouseDownSignal(this,x,y,mask);
if (mMouseDownSignal)
{
(*mMouseDownSignal)(this,x,y,mask);
}
return handled;
}
@ -266,7 +319,10 @@ BOOL LLUICtrl::handleMouseDown(S32 x, S32 y, MASK mask)
BOOL LLUICtrl::handleMouseUp(S32 x, S32 y, MASK mask)
{
BOOL handled = LLView::handleMouseUp(x,y,mask);
mMouseUpSignal(this,x,y,mask);
if (mMouseUpSignal)
{
(*mMouseUpSignal)(this,x,y,mask);
}
return handled;
}
@ -274,7 +330,10 @@ BOOL LLUICtrl::handleMouseUp(S32 x, S32 y, MASK mask)
BOOL LLUICtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLView::handleRightMouseDown(x,y,mask);
mRightMouseDownSignal(this,x,y,mask);
if (mRightMouseDownSignal)
{
(*mRightMouseDownSignal)(this,x,y,mask);
}
return handled;
}
@ -282,14 +341,20 @@ BOOL LLUICtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
BOOL LLUICtrl::handleRightMouseUp(S32 x, S32 y, MASK mask)
{
BOOL handled = LLView::handleRightMouseUp(x,y,mask);
mRightMouseUpSignal(this,x,y,mask);
if(mRightMouseUpSignal)
{
(*mRightMouseUpSignal)(this,x,y,mask);
}
return handled;
}
BOOL LLUICtrl::handleDoubleClick(S32 x, S32 y, MASK mask)
{
BOOL handled = LLView::handleDoubleClick(x, y, mask);
mDoubleClickSignal(this, x, y, mask);
if (mDoubleClickSignal)
{
(*mDoubleClickSignal)(this, x, y, mask);
}
return handled;
}
@ -302,7 +367,8 @@ BOOL LLUICtrl::canFocusChildren() const
void LLUICtrl::onCommit()
{
mCommitSignal(this, getValue());
if (mCommitSignal)
(*mCommitSignal)(this, getValue());
}
//virtual
@ -832,7 +898,8 @@ boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (L
}
boost::signals2::connection LLUICtrl::setValidateBeforeCommit( boost::function<bool (const LLSD& data)> cb )
{
return mValidateSignal.connect(boost::bind(cb, _2));
if (!mValidateSignal) mValidateSignal = new enable_signal_t();
return mValidateSignal->connect(boost::bind(cb, _2));
}
// virtual
@ -850,3 +917,57 @@ BOOL LLUICtrl::getTentative() const
// virtual
void LLUICtrl::setColor(const LLColor4& color)
{ }
boost::signals2::connection LLUICtrl::setCommitCallback( const commit_signal_t::slot_type& cb )
{
if (!mCommitSignal) mCommitSignal = new commit_signal_t();
return mCommitSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setValidateCallback( const enable_signal_t::slot_type& cb )
{
if (!mValidateSignal) mValidateSignal = new enable_signal_t();
return mValidateSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseEnterCallback( const commit_signal_t::slot_type& cb )
{
if (!mMouseEnterSignal) mMouseEnterSignal = new commit_signal_t();
return mMouseEnterSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseLeaveCallback( const commit_signal_t::slot_type& cb )
{
if (!mMouseLeaveSignal) mMouseLeaveSignal = new commit_signal_t();
return mMouseLeaveSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseDownCallback( const mouse_signal_t::slot_type& cb )
{
if (!mMouseDownSignal) mMouseDownSignal = new mouse_signal_t();
return mMouseDownSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseUpCallback( const mouse_signal_t::slot_type& cb )
{
if (!mMouseUpSignal) mMouseUpSignal = new mouse_signal_t();
return mMouseUpSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setRightMouseDownCallback( const mouse_signal_t::slot_type& cb )
{
if (!mRightMouseDownSignal) mRightMouseDownSignal = new mouse_signal_t();
return mRightMouseDownSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setRightMouseUpCallback( const mouse_signal_t::slot_type& cb )
{
if (!mRightMouseUpSignal) mRightMouseUpSignal = new mouse_signal_t();
return mRightMouseUpSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setDoubleClickCallback( const mouse_signal_t::slot_type& cb )
{
if (!mDoubleClickSignal) mDoubleClickSignal = new mouse_signal_t();
return mDoubleClickSignal->connect(cb);
}

View File

@ -162,9 +162,9 @@ protected:
LLUICtrl(const Params& p = getDefaultParams(),
const LLViewModelPtr& viewmodel=LLViewModelPtr(new LLViewModel));
void initCommitCallback(const CommitCallbackParam& cb, commit_signal_t& sig);
void initEnableCallback(const EnableCallbackParam& cb, enable_signal_t& sig);
void initVisibleCallback(const VisibleCallbackParam& cb, visible_signal_t& sig);
commit_signal_t::slot_type initCommitCallback(const CommitCallbackParam& cb);
enable_signal_t::slot_type initEnableCallback(const EnableCallbackParam& cb);
visible_signal_t::slot_type initVisibleCallback(const VisibleCallbackParam& cb);
// We need this virtual so we can override it with derived versions
virtual LLViewModel* getViewModel() const;
@ -254,18 +254,18 @@ public:
// topic then put in help_topic_out
bool findHelpTopic(std::string& help_topic_out);
boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ) { return mCommitSignal.connect(cb); }
boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb ) { return mValidateSignal.connect(cb); }
boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb );
boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb );
boost::signals2::connection setMouseEnterCallback( const commit_signal_t::slot_type& cb ) { return mMouseEnterSignal.connect(cb); }
boost::signals2::connection setMouseLeaveCallback( const commit_signal_t::slot_type& cb ) { return mMouseLeaveSignal.connect(cb); }
boost::signals2::connection setMouseEnterCallback( const commit_signal_t::slot_type& cb );
boost::signals2::connection setMouseLeaveCallback( const commit_signal_t::slot_type& cb );
boost::signals2::connection setMouseDownCallback( const mouse_signal_t::slot_type& cb ) { return mMouseDownSignal.connect(cb); }
boost::signals2::connection setMouseUpCallback( const mouse_signal_t::slot_type& cb ) { return mMouseUpSignal.connect(cb); }
boost::signals2::connection setRightMouseDownCallback( const mouse_signal_t::slot_type& cb ) { return mRightMouseDownSignal.connect(cb); }
boost::signals2::connection setRightMouseUpCallback( const mouse_signal_t::slot_type& cb ) { return mRightMouseUpSignal.connect(cb); }
boost::signals2::connection setMouseDownCallback( const mouse_signal_t::slot_type& cb );
boost::signals2::connection setMouseUpCallback( const mouse_signal_t::slot_type& cb );
boost::signals2::connection setRightMouseDownCallback( const mouse_signal_t::slot_type& cb );
boost::signals2::connection setRightMouseUpCallback( const mouse_signal_t::slot_type& cb );
boost::signals2::connection setDoubleClickCallback( const mouse_signal_t::slot_type& cb ) { return mDoubleClickSignal.connect(cb); }
boost::signals2::connection setDoubleClickCallback( const mouse_signal_t::slot_type& cb );
// *TODO: Deprecate; for backwards compatability only:
boost::signals2::connection setCommitCallback( boost::function<void (LLUICtrl*,void*)> cb, void* data);
@ -293,18 +293,18 @@ protected:
static bool controlListener(const LLSD& newvalue, LLHandle<LLUICtrl> handle, std::string type);
commit_signal_t mCommitSignal;
enable_signal_t mValidateSignal;
commit_signal_t* mCommitSignal;
enable_signal_t* mValidateSignal;
commit_signal_t mMouseEnterSignal;
commit_signal_t mMouseLeaveSignal;
commit_signal_t* mMouseEnterSignal;
commit_signal_t* mMouseLeaveSignal;
mouse_signal_t mMouseDownSignal;
mouse_signal_t mMouseUpSignal;
mouse_signal_t mRightMouseDownSignal;
mouse_signal_t mRightMouseUpSignal;
mouse_signal_t* mMouseDownSignal;
mouse_signal_t* mMouseUpSignal;
mouse_signal_t* mRightMouseDownSignal;
mouse_signal_t* mRightMouseUpSignal;
mouse_signal_t mDoubleClickSignal;
mouse_signal_t* mDoubleClickSignal;
LLViewModelPtr mViewModel;

View File

@ -34,6 +34,7 @@
#include "linden_common.h"
#include "llurlentry.h"
#include "lluri.h"
#include "llcachename.h"
#include "lltrans.h"
#include "lluicolortable.h"
@ -383,6 +384,38 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa
}
}
//
// LLUrlEntryInventory Describes a Second Life inventory Url, e.g.,
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select
//
LLUrlEntryInventory::LLUrlEntryInventory()
{
mPattern = boost::regex("secondlife:///app/inventory/[\\da-f-]+/\\w+",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_inventory.xml";
}
std::string LLUrlEntryInventory::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
{
return unescapeUrl(url);
// TODO: Figure out if we can somehow access the inventory from here to get the actual item name
/*
std::string inventory_id_string = getIDStringFromUrl(url);
if (inventory_id_string.empty())
{
// something went wrong, give raw url
return unescapeUrl(url);
}
LLUUID inventory_id(inventory_id_string);
LLInventoryItem* item = gInventory.getItem(inventory_id);
if(!item)
{
return unescapeUrl(url);
}
return item->getName(); */
}
///
/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about

View File

@ -173,6 +173,19 @@ private:
const std::string& last, BOOL is_group);
};
///
/// LLUrlEntryInventory Describes a Second Life inventory Url, e.g.,
/// secondlife:///app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select
///
class LLUrlEntryInventory : public LLUrlEntryBase
{
public:
LLUrlEntryInventory();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
private:
};
///
/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about

View File

@ -55,6 +55,7 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(new LLUrlEntryPlace());
registerUrl(new LLUrlEntrySL());
registerUrl(new LLUrlEntrySLLabel());
registerUrl(new LLUrlEntryInventory());
}
LLUrlRegistry::~LLUrlRegistry()

View File

@ -522,7 +522,6 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
if (mTSMDocument)
{
ActivateTSMDocument(mTSMDocument);
UseInputWindow(mTSMDocument, FALSE);
allowLanguageTextInput(NULL, FALSE);
}
}
@ -3317,6 +3316,8 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
return;
}
UseInputWindow(mTSMDocument, !b);
// Take care of old and new preeditors.
if (preeditor != mPreeditor || !b)
{

View File

@ -46,7 +46,7 @@ namespace LLInitParam
{
const U8* my_addr = reinterpret_cast<const U8*>(this);
const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
mEnclosingBlockOffset = (S16)(block_addr - my_addr);
mEnclosingBlockOffset = (U16)(my_addr - block_addr);
}
//

View File

@ -300,14 +300,14 @@ namespace LLInitParam
const U8* my_addr = reinterpret_cast<const U8*>(this);
// get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class
return *const_cast<BaseBlock*>(
reinterpret_cast<const BaseBlock*>(my_addr + (ptrdiff_t)mEnclosingBlockOffset));
reinterpret_cast<const BaseBlock*>(my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));
}
private:
friend class BaseBlock;
bool mIsProvided;
S16 mEnclosingBlockOffset;
U16 mEnclosingBlockOffset;
};
// various callbacks and constraints associated with an individual param

View File

@ -613,6 +613,7 @@ extern "C" { int yyerror(const char *fmt, ...); }
"CLICK_ACTION_OPEN" { count(); yylval.ival = CLICK_ACTION_OPEN; return(INTEGER_CONSTANT); }
"CLICK_ACTION_PLAY" { count(); yylval.ival = CLICK_ACTION_PLAY; return(INTEGER_CONSTANT); }
"CLICK_ACTION_OPEN_MEDIA" { count(); yylval.ival = CLICK_ACTION_OPEN_MEDIA; return(INTEGER_CONSTANT); }
"CLICK_ACTION_ZOOM" { count(); yylval.ival = CLICK_ACTION_ZOOM; return(INTEGER_CONSTANT); }
"TEXTURE_BLANK" { yylval.sval = new char[UUID_STR_LENGTH]; strcpy(yylval.sval, "5748decc-f629-461c-9a36-a35a221fe21f"); return(STRING_CONSTANT); }
"TEXTURE_DEFAULT" { yylval.sval = new char[UUID_STR_LENGTH]; strcpy(yylval.sval, "89556747-24cb-43ed-920b-47caed15465f"); return(STRING_CONSTANT); }

View File

@ -245,6 +245,7 @@ set(viewer_SOURCE_FILES
llhudtext.cpp
llhudview.cpp
llimfloater.cpp
llimfloatercontainer.cpp
llimhandler.cpp
llimpanel.cpp
llimview.cpp
@ -303,8 +304,6 @@ set(viewer_SOURCE_FILES
llnotify.cpp
lloutputmonitorctrl.cpp
lloverlaybar.cpp
llpanelappearance.cpp
llpanelappearancetab.cpp
llpanelavatar.cpp
llpanelavatarrow.cpp
llpanelavatartag.cpp
@ -328,14 +327,14 @@ set(viewer_SOURCE_FILES
llpanellandmedia.cpp
llpanellogin.cpp
llpanellookinfo.cpp
llpanellooks.cpp
llpanelmaininventory.cpp
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
llpanelmediasettingssecurity.cpp
llpanelmeprofile.cpp
llpanelme.cpp
llpanelobject.cpp
llpanelobjectinventory.cpp
llpaneloutfitsinventory.cpp
llpanelpeople.cpp
llpanelpeoplemenus.cpp
llpanelpermissions.cpp
@ -372,10 +371,12 @@ set(viewer_SOURCE_FILES
llremoteparcelrequest.cpp
llsavedsettingsglue.cpp
llscreenchannel.cpp
llscriptfloater.cpp
llscrollingpanelparam.cpp
llsearchcombobox.cpp
llsearchhistory.cpp
llselectmgr.cpp
llsidepanelappearance.cpp
llsidepanelinventory.cpp
llsidepanelinventorysubpanel.cpp
llsidepaneliteminfo.cpp
@ -746,6 +747,7 @@ set(viewer_HEADER_FILES
llhudtext.h
llhudview.h
llimfloater.h
llimfloatercontainer.h
llimpanel.h
llimview.h
llinspect.h
@ -800,8 +802,6 @@ set(viewer_HEADER_FILES
llnotify.h
lloutputmonitorctrl.h
lloverlaybar.h
llpanelappearance.h
llpanelappearancetab.h
llpanelavatar.h
llpanelavatarrow.h
llpanelavatartag.h
@ -825,14 +825,14 @@ set(viewer_HEADER_FILES
llpanellandmedia.h
llpanellogin.h
llpanellookinfo.h
llpanellooks.h
llpanelmaininventory.h
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
llpanelmediasettingssecurity.h
llpanelmeprofile.h
llpanelme.h
llpanelobject.h
llpanelobjectinventory.h
llpaneloutfitsinventory.h
llpanelpeople.h
llpanelpeoplemenus.h
llpanelpermissions.h
@ -871,10 +871,12 @@ set(viewer_HEADER_FILES
llrootview.h
llsavedsettingsglue.h
llscreenchannel.h
llscriptfloater.h
llscrollingpanelparam.h
llsearchcombobox.h
llsearchhistory.h
llselectmgr.h
llsidepanelappearance.h
llsidepanelinventory.h
llsidepanelinventorysubpanel.h
llsidepaneliteminfo.h
@ -1387,7 +1389,7 @@ if (WINDOWS)
# sets the 'working directory' for debugging from visual studio.
if (NOT UNATTENDED)
add_custom_command(
TARGET ${VIEWER_BINARY_NAME} PRE_BUILD
TARGET ${VIEWER_BINARY_NAME} POST_BUILD
COMMAND ${CMAKE_SOURCE_DIR}/tools/vstool/vstool.exe
ARGS
--solution

View File

@ -510,6 +510,7 @@ CLICK_ACTION_PAY Used with llSetClickAction to set pay as the default act
CLICK_ACTION_OPEN Used with llSetClickAction to set open as the default action when object is clicked
CLICK_ACTION_PLAY Used with llSetClickAction to set play as the default action when object is clicked
CLICK_ACTION_OPEN_MEDIA Used with llSetClickAction to set open-media as the default action when object is clicked
CLICK_ACTION_ZOOM Used with llSetClickAction to set zoom in as the default action when object is clicked
TOUCH_INVALID_TEXCOORD Value returned by llDetectedTouchUV() and llDetectedTouchST() when the touch position is not valid.
TOUCH_INVALID_VECTOR Value returned by llDetectedTouchPos(), llDetectedTouchNormal(), and llDetectedTouchBinormal() when the touch position is not valid.

View File

@ -3585,7 +3585,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>http://docs.lindenlab.com/help/helpfloater.php?topic=[TOPIC]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;os=[OS]&amp;language=[LANGUAGE]&amp;version_major=[VERSION_MAJOR]&amp;version_minor=[VERSION_MINOR]&amp;version_patch=[VERSION_PATCH]&amp;version_build=[VERSION_BUILD]</string>
<string>http://viewer-help.secondlife.com/[LANGUAGE]/[CHANNEL]/[VERSION]/[TOPIC]</string>
</map>
<key>HighResSnapshot</key>
<map>
@ -3620,7 +3620,7 @@
<key>Value</key>
<string />
</map>
<key>IMInChatConsole</key>
<key>IMInChat</key>
<map>
<key>Comment</key>
<string>Copy IM into chat console</string>
@ -3629,17 +3629,6 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>IMInChatHistory</key>
<map>
<key>Comment</key>
<string>Copy IM into chat history</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>IMShowTimestamps</key>
@ -5382,6 +5371,19 @@
<key>Value</key>
<real>1.0</real>
</map>
<key>PlainTextChatHistory</key>
<map>
<key>Comment</key>
<string>Enable/Disable plain text chat history style</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>PluginInstancesLow</key>
<map>
<key>Comment</key>
@ -7732,10 +7734,10 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>ShowCoordinatesOption</key>
<key>NavBarShowCoordinates</key>
<map>
<key>Comment</key>
<string>Show Coordinates in Location Input Field</string>
<string>Show coordinates in navigation bar</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@ -7743,6 +7745,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>NavBarShowParcelProperties</key>
<map>
<key>Comment</key>
<string>Show parcel property icons in navigation bar</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>ShowCrosshairs</key>
<map>
<key>Comment</key>
@ -9657,116 +9670,6 @@
<key>Value</key>
<string>00000000-0000-0000-0000-000000000000</string>
</map>
<key>UISndPieMenuAppear</key>
<map>
<key>Comment</key>
<string>Sound file for opening pie menu (uuid for sound asset)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>8eaed61f-92ff-6485-de83-4dcc938a478e</string>
</map>
<key>UISndPieMenuHide</key>
<map>
<key>Comment</key>
<string>Sound file for closing pie menu (uuid for sound asset)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>00000000-0000-0000-0000-000000000000</string>
</map>
<key>UISndPieMenuSliceHighlight0</key>
<map>
<key>Comment</key>
<string>Sound file for selecting pie menu item 0 (uuid for sound asset)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>d9f73cf8-17b4-6f7a-1565-7951226c305d</string>
</map>
<key>UISndPieMenuSliceHighlight1</key>
<map>
<key>Comment</key>
<string>Sound file for selecting pie menu item 1 (uuid for sound asset)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>f6ba9816-dcaf-f755-7b67-51b31b6233e5</string>
</map>
<key>UISndPieMenuSliceHighlight2</key>
<map>
<key>Comment</key>
<string>Sound file for selecting pie menu item 2 (uuid for sound asset)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>7aff2265-d05b-8b72-63c7-dbf96dc2f21f</string>
</map>
<key>UISndPieMenuSliceHighlight3</key>
<map>
<key>Comment</key>
<string>Sound file for selecting pie menu item 3 (uuid for sound asset)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>09b2184e-8601-44e2-afbb-ce37434b8ba1</string>
</map>
<key>UISndPieMenuSliceHighlight4</key>
<map>
<key>Comment</key>
<string>Sound file for selecting pie menu item 4 (uuid for sound asset)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>bbe4c7fc-7044-b05e-7b89-36924a67593c</string>
</map>
<key>UISndPieMenuSliceHighlight5</key>
<map>
<key>Comment</key>
<string>Sound file for selecting pie menu item 5 (uuid for sound asset)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>d166039b-b4f5-c2ec-4911-c85c727b016c</string>
</map>
<key>UISndPieMenuSliceHighlight6</key>
<map>
<key>Comment</key>
<string>Sound file for selecting pie menu item 6 (uuid for sound asset)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>242af82b-43c2-9a3b-e108-3b0c7e384981</string>
</map>
<key>UISndPieMenuSliceHighlight7</key>
<map>
<key>Comment</key>
<string>Sound file for selecting pie menu item 7 (uuid for sound asset)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>c1f334fb-a5be-8fe7-22b3-29631c21cf0b</string>
</map>
<key>UISndSnapshot</key>
<map>
<key>Comment</key>

View File

@ -22,17 +22,6 @@
<key>Value</key>
<string>|TOKEN COPY BusyModeResponse|</string>
</map>
<key>IMLogOptions</key>
<map>
<key>Comment</key>
<string>Log options for Instant Messages</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>2</integer>
</map>
<key>InstantMessageLogFolder</key>
<map>
<key>Comment</key>
@ -75,18 +64,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>LogChatIM</key>
<map>
<key>Comment</key>
<string>Log Incoming Instant Messages with Chat</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>LogTimestamp</key>
<map>
@ -97,7 +75,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
<integer>1</integer>
</map>
<key>LogInstantMessages</key>
<map>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
<linden_avatar
version="1.0" wearable_definition_version="24">
version="1.0" wearable_definition_version="22">
<!-- The wearable_definition_version is checked during asset upload. -->
<!-- If you increment it, check indra/lib/python/indra/assetutil.py. -->
<skeleton

View File

@ -1,6 +1,6 @@
The language files in this directory are Unicode (Little-Endian) format, also known as UTF-16 LE.
This is the format required for NSIS Unicode. See http://www.scratchpaper.com/ for details.
James Cook
September 2008
The language files in this directory are Unicode (Little-Endian) format, also known as UTF-16 LE.
This is the format required for NSIS Unicode. See http://www.scratchpaper.com/ for details.
James Cook
September 2008

View File

@ -31,84 +31,54 @@
*/
#include "llviewerprecompiledheaders.h"
#include "llagent.h"
#include "llagentwearables.h"
#include "pipeline.h"
#include "llagentlistener.h"
#include "llagentwearables.h"
#include "llagentui.h"
#include "llanimationstates.h"
#include "llbottomtray.h"
#include "llcallingcard.h"
#include "llchannelmanager.h"
#include "llconsole.h"
#include "lldrawable.h"
#include "llfirstuse.h"
#include "llfloaterreg.h"
#include "llspeakers.h"
#include "llfloatercamera.h"
#include "llfloatercustomize.h"
#include "llfloaterland.h"
#include "llfloatersnapshot.h"
#include "llfloaterreg.h"
#include "llfloatertools.h"
#include "llfloaterworldmap.h"
#include "llgroupactions.h"
#include "llfocusmgr.h"
#include "llgroupmgr.h"
#include "llhomelocationresponder.h"
#include "llimview.h"
#include "llhudmanager.h"
#include "lljoystickbutton.h"
#include "llmenugl.h"
#include "llmorphview.h"
#include "llmoveview.h"
#include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state
#include "llnearbychatbar.h"
#include "llparcel.h"
#include "llquantize.h"
#include "llrand.h"
#include "llregionhandle.h"
#include "llsdutil.h"
#include "llselectmgr.h"
#include "llsky.h"
#include "llslurl.h"
#include "llsmoothstep.h"
#include "llsidetray.h"
#include "llsky.h"
#include "llsmoothstep.h"
#include "llstatusbar.h"
#include "llteleportflags.h"
#include "llteleporthistory.h"
#include "lltexturestats.h"
#include "lltexturestats.h"
#include "lltool.h"
#include "lltoolcomp.h"
#include "lltoolmgr.h"
#include "lluictrlfactory.h"
#include "llurldispatcher.h"
#include "llviewercamera.h"
#include "lltrans.h"
#include "llviewercontrol.h"
#include "llviewerdisplay.h"
#include "llviewerjoystick.h"
#include "llviewermediafocus.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
#include "llviewerstats.h"
#include "llviewerwindow.h"
#include "llviewercontrol.h"
#include "llviewerjoystick.h"
#include "llvoavatarself.h"
#include "llwindow.h"
#include "llworld.h"
#include "llworldmap.h"
#include "pipeline.h"
#include "lltrans.h"
#include "llbottomtray.h"
#include "llnearbychatbar.h"
#include "stringize.h"
#include "llcapabilitylistener.h"
#include "llnavigationbar.h" //to show/hide navigation bar when changing mouse look state
#include "llagentui.h"
#include "llchannelmanager.h"
using namespace LLVOAvatarDefines;
extern LLMenuBarGL* gMenuBarView;
@ -764,6 +734,10 @@ BOOL LLAgent::canFly()
return parcel->getAllowFly();
}
BOOL LLAgent::getFlying() const
{
return mControlFlags & AGENT_CONTROL_FLY;
}
//-----------------------------------------------------------------------------
// setFlying()
@ -821,7 +795,7 @@ void LLAgent::setFlying(BOOL fly)
// static
void LLAgent::toggleFlying()
{
BOOL fly = !(gAgent.mControlFlags & AGENT_CONTROL_FLY);
BOOL fly = !gAgent.getFlying();
gAgent.setFlying( fly );
gAgent.resetView();
@ -2825,7 +2799,8 @@ void LLAgent::endAnimationUpdateUI()
LLBottomTray::getInstance()->setVisible(TRUE);
LLSideTray::getInstance()->setVisible(TRUE);
LLSideTray::getInstance()->getButtonsPanel()->setVisible(TRUE);
LLSideTray::getInstance()->updateSidetrayVisibility();
LLPanelStandStopFlying::getInstance()->setVisible(TRUE);
@ -2840,7 +2815,11 @@ void LLAgent::endAnimationUpdateUI()
LLFloaterReg::restoreVisibleInstances();
#else // Use this for now
LLFloaterView::skip_list_t skip_list;
skip_list.insert(LLFloaterReg::findInstance("mini_map"));
if (LLFloaterReg::findInstance("mini_map"))
{
skip_list.insert(LLFloaterReg::findInstance("mini_map"));
}
gFloaterView->popVisibleAll(skip_list);
#endif
mViewsPushed = FALSE;
@ -2919,7 +2898,8 @@ void LLAgent::endAnimationUpdateUI()
LLBottomTray::getInstance()->setVisible(FALSE);
LLSideTray::getInstance()->setVisible(FALSE);
LLSideTray::getInstance()->getButtonsPanel()->setVisible(FALSE);
LLSideTray::getInstance()->updateSidetrayVisibility();
LLPanelStandStopFlying::getInstance()->setVisible(FALSE);
@ -6356,7 +6336,7 @@ void LLAgent::sendAgentSetAppearance()
msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);
}
msg->nextBlockFast(_PREHASH_ObjectData);
mAvatarObject->packTEMessage( gMessageSystem );
mAvatarObject->sendAppearanceMessage( gMessageSystem );
}
else
{

View File

@ -36,14 +36,13 @@
#include "indra_constants.h"
#include "llevent.h" // LLObservable base class
#include "llagentaccess.h"
#include "llagentaccess.h"
#include "llagentconstants.h"
#include "llhudeffectpointat.h" // ELookAtType
#include "llhudeffectlookat.h" // EPointAtType
#include "llpointer.h"
#include "llagentdata.h" // gAgentID, gAgentSessionID
#include "llcharacter.h" // LLAnimPauseRequest
#include "llfollowcam.h" // Ventrella
#include "llagentdata.h" // gAgentID, gAgentSessionID
#include "llhudeffectlookat.h" // EPointAtType
#include "llhudeffectpointat.h" // ELookAtType
#include "llpointer.h"
#include "lluicolor.h"
#include "llvoavatardefines.h"
@ -311,7 +310,7 @@ private:
// Fly
//--------------------------------------------------------------------
public:
BOOL getFlying() const { return mControlFlags & AGENT_CONTROL_FLY; }
BOOL getFlying() const;
void setFlying(BOOL fly);
static void toggleFlying();
static bool enableFlying();

View File

@ -130,6 +130,7 @@ BOOL LLAgentUI::buildLocationString(std::string& str, ELocationFormat fmt,const
// create a default name and description for the landmark
std::string parcel_name = LLViewerParcelMgr::getInstance()->getAgentParcelName();
std::string region_name = region->getName();
std::string sim_access_string = region->getSimAccessString();
std::string buffer;
if( parcel_name.empty() )
{
@ -142,7 +143,13 @@ BOOL LLAgentUI::buildLocationString(std::string& str, ELocationFormat fmt,const
case LOCATION_FORMAT_NORMAL:
buffer = llformat("%s", region_name.c_str());
break;
case LOCATION_FORMAT_WITHOUT_SIM:
case LOCATION_FORMAT_NO_COORDS:
buffer = llformat("%s%s%s",
region_name.c_str(),
sim_access_string.empty() ? "" : " - ",
sim_access_string.c_str());
break;
case LOCATION_FORMAT_NO_MATURITY:
case LOCATION_FORMAT_FULL:
buffer = llformat("%s (%d, %d, %d)",
region_name.c_str(),
@ -161,14 +168,20 @@ BOOL LLAgentUI::buildLocationString(std::string& str, ELocationFormat fmt,const
case LOCATION_FORMAT_NORMAL:
buffer = llformat("%s, %s", parcel_name.c_str(), region_name.c_str());
break;
case LOCATION_FORMAT_WITHOUT_SIM:
case LOCATION_FORMAT_NO_MATURITY:
buffer = llformat("%s, %s (%d, %d, %d)",
parcel_name.c_str(),
region_name.c_str(),
pos_x, pos_y, pos_z);
break;
case LOCATION_FORMAT_NO_COORDS:
buffer = llformat("%s, %s%s%s",
parcel_name.c_str(),
region_name.c_str(),
sim_access_string.empty() ? "" : " - ",
sim_access_string.c_str());
break;
case LOCATION_FORMAT_FULL:
std::string sim_access_string = region->getSimAccessString();
buffer = llformat("%s, %s (%d, %d, %d)%s%s",
parcel_name.c_str(),
region_name.c_str(),

View File

@ -38,10 +38,11 @@ class LLAgentUI
public:
enum ELocationFormat
{
LOCATION_FORMAT_NORMAL,
LOCATION_FORMAT_LANDMARK,
LOCATION_FORMAT_WITHOUT_SIM,
LOCATION_FORMAT_FULL,
LOCATION_FORMAT_NORMAL, // Parcel
LOCATION_FORMAT_LANDMARK, // Parcel, Region
LOCATION_FORMAT_NO_MATURITY, // Parcel, Region (x, y, z)
LOCATION_FORMAT_NO_COORDS, // Parcel, Region - Maturity
LOCATION_FORMAT_FULL, // Parcel, Region (x, y, z) - Maturity
};
static void buildName(std::string& name);

View File

@ -62,7 +62,7 @@ class LLInitialWearablesFetch : public LLInventoryFetchDescendentsObserver
{
public:
LLInitialWearablesFetch() {}
~LLInitialWearablesFetch() {}
~LLInitialWearablesFetch();
virtual void done();
struct InitialWearableData
@ -84,7 +84,6 @@ public:
protected:
void processWearablesMessage();
void processContents();
static void onIdle(void *userdata);
};
class LLLibraryOutfitsFetch : public LLInventoryFetchDescendentsObserver
@ -654,11 +653,13 @@ LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index)
void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearable *wearable)
{
if (!getWearable(type,index))
LLWearable *old_wearable = getWearable(type,index);
if (!old_wearable)
{
pushWearable(type,wearable);
return;
}
wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter == mWearableDatas.end())
{
@ -673,7 +674,8 @@ void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearab
else
{
wearable_vec[index] = wearable;
mAvatarObject->wearableUpdated(wearable->getType());
old_wearable->setLabelUpdated();
wearableUpdated(wearable);
}
}
@ -688,12 +690,32 @@ U32 LLAgentWearables::pushWearable(const EWearableType type, LLWearable *wearabl
if (type < WT_COUNT || mWearableDatas[type].size() < MAX_WEARABLES_PER_TYPE)
{
mWearableDatas[type].push_back(wearable);
mAvatarObject->wearableUpdated(wearable->getType());
wearableUpdated(wearable);
return mWearableDatas[type].size()-1;
}
return MAX_WEARABLES_PER_TYPE;
}
void LLAgentWearables::wearableUpdated(LLWearable *wearable)
{
mAvatarObject->wearableUpdated(wearable->getType());
wearable->setLabelUpdated();
// Hack pt 2. If the wearable we just loaded has definition version 24,
// then force a re-save of this wearable after slamming the version number to 22.
// This number was incorrectly incremented for internal builds before release, and
// this fix will ensure that the affected wearables are re-saved with the right version number.
// the versions themselves are compatible. This code can be removed before release.
if( wearable->getDefinitionVersion() == 24 )
{
wearable->setDefinitionVersion(22);
U32 index = getWearableIndex(wearable);
llinfos << "forcing werable type " << wearable->getType() << " to version 22 from 24" << llendl;
saveWearable(wearable->getType(),index,TRUE);
}
}
void LLAgentWearables::popWearable(LLWearable *wearable)
{
if (wearable == NULL)
@ -718,6 +740,7 @@ void LLAgentWearables::popWearable(const EWearableType type, U32 index)
{
mWearableDatas[type].erase(mWearableDatas[type].begin() + index);
mAvatarObject->wearableUpdated(wearable->getType());
wearable->setLabelUpdated();
}
}
@ -1413,14 +1436,10 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem
for (S32 i=max_entry; i>=0; i--)
{
LLWearable* old_wearable = getWearable(type,i);
const LLUUID &item_id = getWearableItemID(type,i);
popWearable(type,i);
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
LLAppearanceManager::instance().removeItemLinks(item_id,false);
//queryWearableCache(); // moved below
if (old_wearable)
{
popWearable(old_wearable);
old_wearable->removeFromAvatar(TRUE);
}
}
@ -1429,16 +1448,11 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem
else
{
LLWearable* old_wearable = getWearable(type, index);
const LLUUID &item_id = getWearableItemID(type,index);
popWearable(type, index);
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
LLAppearanceManager::instance().removeItemLinks(item_id,false);
//queryWearableCache(); // moved below
if (old_wearable)
{
popWearable(old_wearable);
old_wearable->removeFromAvatar(TRUE);
}
}
@ -1500,7 +1514,6 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
continue;
}
gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
// Assumes existing wearables are not dirty.
if (old_wearable->isDirty())
{
@ -1509,9 +1522,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
}
}
setWearable(type,0,new_wearable);
if (new_wearable)
new_wearable->setItemID(new_item->getUUID());
setWearable(type,0,new_wearable);
}
std::vector<LLWearable*> wearables_being_removed;
@ -1534,7 +1547,6 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
gInventory.notifyObservers();
queryWearableCache();
std::vector<LLWearable*>::iterator wearable_iter;
@ -1557,6 +1569,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
// Start rendering & update the server
mWearablesLoaded = TRUE;
checkWearablesLoaded();
queryWearableCache();
updateServer();
lldebugs << "setWearableOutfit() end" << llendl;
@ -2159,6 +2172,10 @@ void LLLibraryOutfitsFetch::contentsDone(void)
// to avoid gInventory.notifyObservers recursion.
//--------------------------------------------------------------------
LLInitialWearablesFetch::~LLInitialWearablesFetch()
{
}
// virtual
void LLInitialWearablesFetch::done()
{
@ -2166,15 +2183,7 @@ void LLInitialWearablesFetch::done()
// gInventory.notifyObservers. The results will be handled in the next
// idle tick instead.
gInventory.removeObserver(this);
gIdleCallbacks.addFunction(onIdle, this);
}
// static
void LLInitialWearablesFetch::onIdle(void *data)
{
gIdleCallbacks.deleteFunction(onIdle, data);
LLInitialWearablesFetch *self = reinterpret_cast<LLInitialWearablesFetch*>(data);
self->processContents();
doOnIdle(boost::bind(&LLInitialWearablesFetch::processContents,this));
}
void LLInitialWearablesFetch::processContents()
@ -2194,17 +2203,50 @@ void LLInitialWearablesFetch::processContents()
else
{
processWearablesMessage();
// Create links for attachments that may have arrived before the COF existed.
LLAppearanceManager::instance().linkRegisteredAttachments();
}
delete this;
}
class LLFetchAndLinkObserver: public LLInventoryFetchObserver
{
public:
LLFetchAndLinkObserver(LLInventoryFetchObserver::item_ref_t& ids):
m_ids(ids),
LLInventoryFetchObserver(true)
{
}
~LLFetchAndLinkObserver()
{
}
virtual void done()
{
gInventory.removeObserver(this);
// Link to all fetched items in COF.
for (LLInventoryFetchObserver::item_ref_t::iterator it = m_ids.begin();
it != m_ids.end();
++it)
{
LLUUID id = *it;
LLViewerInventoryItem *item = gInventory.getItem(*it);
if (!item)
{
llwarns << "fetch failed!" << llendl;
continue;
}
link_inventory_item(gAgent.getID(), item->getLinkedUUID(), LLAppearanceManager::instance().getCOF(), item->getName(),
LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
}
}
private:
LLInventoryFetchObserver::item_ref_t m_ids;
};
void LLInitialWearablesFetch::processWearablesMessage()
{
if (!mAgentInitialWearables.empty()) // We have an empty current outfit folder, use the message data instead.
{
const LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
const LLUUID current_outfit_id = LLAppearanceManager::instance().getCOF();
LLInventoryFetchObserver::item_ref_t ids;
for (U8 i = 0; i < mAgentInitialWearables.size(); ++i)
{
// Populate the current outfit folder with links to the wearables passed in the message
@ -2213,9 +2255,7 @@ void LLInitialWearablesFetch::processWearablesMessage()
if (wearable_data->mAssetID.notNull())
{
#ifdef USE_CURRENT_OUTFIT_FOLDER
const std::string link_name = "WearableLink"; // Unimportant what this is named, it isn't exposed.
link_inventory_item(gAgent.getID(), wearable_data->mItemID, current_outfit_id, link_name,
LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
ids.push_back(wearable_data->mItemID);
#endif
// Fetch the wearables
LLWearableList::instance().getAsset(wearable_data->mAssetID,
@ -2229,6 +2269,42 @@ void LLInitialWearablesFetch::processWearablesMessage()
<< wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl;
}
}
// Add all current attachments to the requested items as well.
LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
if( avatar )
{
for (LLVOAvatar::attachment_map_t::const_iterator iter = avatar->mAttachmentPoints.begin();
iter != avatar->mAttachmentPoints.end(); ++iter)
{
LLViewerJointAttachment* attachment = iter->second;
if (!attachment) continue;
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
LLViewerObject* attached_object = (*attachment_iter);
if (!attached_object) continue;
const LLUUID& item_id = attached_object->getItemID();
if (item_id.isNull()) continue;
ids.push_back(item_id);
}
}
}
// Need to fetch the inventory items for ids, then create links to them after they arrive.
LLFetchAndLinkObserver *fetcher = new LLFetchAndLinkObserver(ids);
fetcher->fetchItems(ids);
// If no items to be fetched, done will never be triggered.
// TODO: Change LLInventoryFetchObserver::fetchItems to trigger done() on this condition.
if (fetcher->isEverythingComplete())
{
fetcher->done();
}
else
{
gInventory.addObserver(fetcher);
}
}
else
{

View File

@ -107,6 +107,7 @@ private:
// Low-level data structure setter - public access is via setWearableItem, etc.
void setWearable(const EWearableType type, U32 index, LLWearable *wearable);
U32 pushWearable(const EWearableType type, LLWearable *wearable);
void wearableUpdated(LLWearable *wearable);
void popWearable(LLWearable *wearable);
void popWearable(const EWearableType type, U32 index);

View File

@ -40,7 +40,7 @@
#include "llinventorybridge.h"
#include "llinventoryobserver.h"
#include "llnotifications.h"
#include "llpanelappearance.h"
#include "llsidepanelappearance.h"
#include "llsidetray.h"
#include "llvoavatar.h"
#include "llvoavatarself.h"
@ -96,7 +96,8 @@ public:
mAppend(append)
{}
~LLOutfitObserver() {}
virtual void done(); //public
virtual void done();
void doWearCategory();
protected:
LLUUID mCatID;
@ -105,6 +106,12 @@ protected:
};
void LLOutfitObserver::done()
{
gInventory.removeObserver(this);
doOnIdle(boost::bind(&LLOutfitObserver::doWearCategory,this));
}
void LLOutfitObserver::doWearCategory()
{
// We now have an outfit ready to be copied to agent inventory. Do
// it, and wear that outfit normally.
@ -175,6 +182,7 @@ void LLOutfitObserver::done()
// Wear the inventory category.
LLAppearanceManager::instance().wearInventoryCategoryOnAvatar(gInventory.getCategory(mCatID), mAppend);
}
delete this;
}
class LLOutfitFetch : public LLInventoryFetchDescendentsObserver
@ -222,7 +230,6 @@ void LLOutfitFetch::done()
// loop.
//dec_busy_count();
gInventory.removeObserver(this);
delete this;
// increment busy count and either tell the inventory to check &
// call done, or add this object to the inventory for observation.
@ -241,6 +248,7 @@ void LLOutfitFetch::done()
// will call done for us when everything is here.
gInventory.addObserver(outfit_observer);
}
delete this;
}
class LLUpdateAppearanceOnDestroy: public LLInventoryCallback
@ -355,6 +363,35 @@ LLUUID LLAppearanceManager::getCOF()
return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
}
const LLViewerInventoryItem* LLAppearanceManager::getCurrentOutfitLink()
{
const LLUUID& current_outfit_cat = getCOF();
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
// Can't search on FT_OUTFIT since links to categories return FT_CATEGORY for type since they don't
// return preferred type.
LLIsType is_category( LLAssetType::AT_CATEGORY );
gInventory.collectDescendentsIf(current_outfit_cat,
cat_array,
item_array,
false,
is_category,
false);
for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
iter != item_array.end();
iter++)
{
const LLViewerInventoryItem *item = (*iter);
const LLViewerInventoryCategory *cat = item->getLinkedCategory();
if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)
{
return item;
}
}
return NULL;
}
// Update appearance from outfit folder.
void LLAppearanceManager::changeOutfit(bool proceed, const LLUUID& category, bool append)
{
@ -457,7 +494,7 @@ void LLAppearanceManager::filterWearableItems(
// Create links to all listed items.
void LLAppearanceManager::linkAll(const LLUUID& category,
LLInventoryModel::item_array_t& items,
LLPointer<LLInventoryCallback> cb)
LLPointer<LLInventoryCallback> cb)
{
for (S32 i=0; i<items.count(); i++)
{
@ -522,6 +559,7 @@ void LLAppearanceManager::updateCOF(const LLUUID& category, bool append)
linkAll(cof, obj_items, link_waiter);
linkAll(cof, gest_items, link_waiter);
LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance *>(LLSideTray::getInstance()->getPanel("sidepanel_appearance"));
// Add link to outfit if category is an outfit.
LLViewerInventoryCategory* catp = gInventory.getCategory(category);
if (!append && catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
@ -530,13 +568,18 @@ void LLAppearanceManager::updateCOF(const LLUUID& category, bool append)
LLAssetType::AT_LINK_FOLDER, link_waiter);
// Update the current outfit name of the appearance sidepanel.
LLPanelAppearance* panel_appearance = dynamic_cast<LLPanelAppearance *>(LLSideTray::getInstance()->getPanel("panel_appearance"));
if (panel_appearance)
{
panel_appearance->refreshCurrentLookName(catp->getName());
panel_appearance->refreshCurrentOutfitName(catp->getName());
}
}
else
{
if (panel_appearance)
{
panel_appearance->refreshCurrentOutfitName("");
}
}
}
void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder, bool append)
@ -571,7 +614,6 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder,
if(wearables.count() > 0)
{
gAgentWearables.setWearableOutfit(items, wearables, !append);
gInventory.notifyObservers();
}
delete holder;
@ -811,15 +853,23 @@ bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventor
(a->getWearableType() == b->getWearableType()));
}
void LLAppearanceManager::addItemLink( LLInventoryItem* item, bool do_update )
void LLAppearanceManager::addCOFItemLink(const LLUUID &item_id, bool do_update )
{
LLViewerInventoryItem *vitem = dynamic_cast<LLViewerInventoryItem*>(item);
const LLInventoryItem *item = gInventory.getItem(item_id);
addCOFItemLink(item, do_update);
}
void LLAppearanceManager::addCOFItemLink(const LLInventoryItem *item, bool do_update )
{
const LLViewerInventoryItem *vitem = dynamic_cast<const LLViewerInventoryItem*>(item);
if (!vitem)
{
llwarns << "not an llviewerinventoryitem, failed" << llendl;
return;
}
gInventory.addChangedMask(LLInventoryObserver::LABEL, vitem->getLinkedUUID());
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
gInventory.collectDescendents(LLAppearanceManager::getCOF(),
@ -831,7 +881,7 @@ void LLAppearanceManager::addItemLink( LLInventoryItem* item, bool do_update )
{
// Are these links to the same object?
const LLViewerInventoryItem* inv_item = item_array.get(i).get();
if (inv_item->getLinkedUUID() == item->getLinkedUUID())
if (inv_item->getLinkedUUID() == vitem->getLinkedUUID())
{
linked_already = true;
}
@ -842,7 +892,6 @@ void LLAppearanceManager::addItemLink( LLInventoryItem* item, bool do_update )
{
gAgentWearables.removeWearable(inv_item->getWearableType(),true,0);
gInventory.purgeObject(inv_item->getUUID());
gInventory.notifyObservers();
}
}
if (linked_already)
@ -878,8 +927,10 @@ void LLAppearanceManager::addEnsembleLink( LLInventoryCategory* cat, bool do_upd
#endif
}
void LLAppearanceManager::removeItemLinks(const LLUUID& item_id, bool do_update)
void LLAppearanceManager::removeCOFItemLinks(const LLUUID& item_id, bool do_update)
{
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
gInventory.collectDescendents(LLAppearanceManager::getCOF(),
@ -891,7 +942,8 @@ void LLAppearanceManager::removeItemLinks(const LLUUID& item_id, bool do_update)
const LLInventoryItem* item = item_array.get(i).get();
if (item->getLinkedUUID() == item_id)
{
gInventory.purgeObject(item_array.get(i)->getUUID());
const LLUUID& item_id = item_array.get(i)->getUUID();
gInventory.purgeObject(item_id);
}
}
if (do_update)
@ -970,18 +1022,12 @@ void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)
void LLAppearanceManager::registerAttachment(const LLUUID& item_id)
{
mRegisteredAttachments.insert(item_id);
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
//dumpAttachmentSet(mRegisteredAttachments,"after register:");
if (mAttachmentInvLinkEnabled)
{
LLViewerInventoryItem *item = gInventory.getItem(item_id);
if (item)
{
//LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Adding attachment link:");
LLAppearanceManager::addItemLink(item,false); // Add COF link for item.
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
gInventory.notifyObservers();
}
LLAppearanceManager::addCOFItemLink(item_id, false); // Add COF link for item.
}
else
{
@ -992,15 +1038,14 @@ void LLAppearanceManager::registerAttachment(const LLUUID& item_id)
void LLAppearanceManager::unregisterAttachment(const LLUUID& item_id)
{
mRegisteredAttachments.erase(item_id);
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
//dumpAttachmentSet(mRegisteredAttachments,"after unregister:");
if (mAttachmentInvLinkEnabled)
{
//LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Removing attachment link:");
LLAppearanceManager::removeItemLinks(item_id, false);
// BAP - needs to change for label to track link.
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
gInventory.notifyObservers();
LLAppearanceManager::removeCOFItemLinks(item_id, false);
}
else
{
@ -1015,13 +1060,7 @@ void LLAppearanceManager::linkRegisteredAttachments()
++it)
{
LLUUID item_id = *it;
LLViewerInventoryItem *item = gInventory.getItem(item_id);
if (item)
{
addItemLink(item, false);
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
gInventory.notifyObservers();
}
addCOFItemLink(item_id, false);
}
mRegisteredAttachments.clear();
}

View File

@ -36,6 +36,7 @@
#include "llsingleton.h"
#include "llinventorymodel.h"
#include "llviewerinventory.h"
#include "llcallbacklist.h"
class LLWearable;
struct LLWearableHoldingPattern;
@ -53,12 +54,6 @@ public:
void wearOutfitByName(const std::string& name);
void changeOutfit(bool proceed, const LLUUID& category, bool append);
// Add COF link to individual item.
void addItemLink(LLInventoryItem* item, bool do_update = true);
// Add COF link to ensemble folder.
void addEnsembleLink(LLInventoryCategory* item, bool do_update = true);
// Copy all items in a category.
void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,
LLPointer<LLInventoryCallback> cb);
@ -66,8 +61,8 @@ public:
// Find the Current Outfit folder.
LLUUID getCOF();
// Remove COF entries
void removeItemLinks(const LLUUID& item_id, bool do_update = true);
// Finds the folder link to the currently worn outfit
const LLViewerInventoryItem *getCurrentOutfitLink();
void updateAgentWearables(LLWearableHoldingPattern* holder, bool append);
@ -81,6 +76,21 @@ public:
void setAttachmentInvLinkEnable(bool val);
void linkRegisteredAttachments();
// utility function for bulk linking.
void linkAll(const LLUUID& category,
LLInventoryModel::item_array_t& items,
LLPointer<LLInventoryCallback> cb);
// Add COF link to individual item.
void addCOFItemLink(const LLUUID& item_id, bool do_update = true);
void addCOFItemLink(const LLInventoryItem *item, bool do_update = true);
// Remove COF entries
void removeCOFItemLinks(const LLUUID& item_id, bool do_update = true);
// Add COF link to ensemble folder.
void addEnsembleLink(LLInventoryCategory* item, bool do_update = true);
protected:
LLAppearanceManager();
~LLAppearanceManager();
@ -88,9 +98,6 @@ protected:
private:
void filterWearableItems(LLInventoryModel::item_array_t& items, S32 max_per_type);
void linkAll(const LLUUID& category,
LLInventoryModel::item_array_t& items,
LLPointer<LLInventoryCallback> cb);
void getDescendentsOfAssetType(const LLUUID& category,
LLInventoryModel::item_array_t& items,
@ -111,4 +118,36 @@ private:
#define SUPPORT_ENSEMBLES 0
// Shim class and template function to allow arbitrary boost::bind
// expressions to be run as one-time idle callbacks.
template <typename T>
class OnIdleCallback
{
public:
OnIdleCallback(T callable):
mCallable(callable)
{
}
static void onIdle(void *data)
{
gIdleCallbacks.deleteFunction(onIdle, data);
OnIdleCallback<T>* self = reinterpret_cast<OnIdleCallback<T>*>(data);
self->call();
delete self;
}
void call()
{
mCallable();
}
private:
T mCallable;
};
template <typename T>
void doOnIdle(T callable)
{
OnIdleCallback<T>* cb_functor = new OnIdleCallback<T>(callable);
gIdleCallbacks.addFunction(&OnIdleCallback<T>::onIdle,cb_functor);
}
#endif

View File

@ -799,13 +799,6 @@ bool LLAppViewer::init()
// call all self-registered classes
LLInitClassList::instance().fireCallbacks();
#if LL_LCD_COMPILE
// start up an LCD window on a logitech keyboard, if there is one
HINSTANCE hInstance = GetModuleHandle(NULL);
gLcdScreen = new LLLCD(hInstance);
CreateLCDDebugWindows();
#endif
LLFolderViewItem::initClass(); // SJB: Needs to happen after initWindow(), not sure why but related to fonts
gGLManager.getGLInfo(gDebugInfo);
@ -985,7 +978,8 @@ bool LLAppViewer::mainLoop()
#endif
//memory leaking simulation
LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::getTypedInstance<LLFloaterMemLeak>("mem_leaking");
LLFloaterMemLeak* mem_leak_instance =
LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
if(mem_leak_instance)
{
mem_leak_instance->idle() ;
@ -1171,7 +1165,8 @@ bool LLAppViewer::mainLoop()
catch(std::bad_alloc)
{
//stop memory leaking simulation
LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::getTypedInstance<LLFloaterMemLeak>("mem_leaking");
LLFloaterMemLeak* mem_leak_instance =
LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
if(mem_leak_instance)
{
mem_leak_instance->stop() ;
@ -1199,7 +1194,8 @@ bool LLAppViewer::mainLoop()
llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ;
//stop memory leaking simulation
LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::getTypedInstance<LLFloaterMemLeak>("mem_leaking");
LLFloaterMemLeak* mem_leak_instance =
LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
if(mem_leak_instance)
{
mem_leak_instance->stop() ;
@ -1357,19 +1353,25 @@ bool LLAppViewer::cleanup()
llinfos << "Waiting for pending IO to finish: " << pending << llendflush;
ms_sleep(100);
}
llinfos << "Shutting down." << llendflush;
llinfos << "Shutting down Views" << llendflush;
// Destroy the UI
if( gViewerWindow)
gViewerWindow->shutdownViews();
llinfos << "Cleaning up Inevntory" << llendflush;
// Cleanup Inventory after the UI since it will delete any remaining observers
// (Deleted observers should have already removed themselves)
gInventory.cleanupInventory();
llinfos << "Cleaning up Selections" << llendflush;
// Clean up selection managers after UI is destroyed, as UI may be observing them.
// Clean up before GL is shut down because we might be holding on to objects with texture references
LLSelectMgr::cleanupGlobals();
llinfos << "Shutting down OpenGL" << llendflush;
// Shut down OpenGL
if( gViewerWindow)
@ -1383,11 +1385,18 @@ bool LLAppViewer::cleanup()
gViewerWindow = NULL;
llinfos << "ViewerWindow deleted" << llendflush;
}
llinfos << "Cleaning up Keyboard & Joystick" << llendflush;
// viewer UI relies on keyboard so keep it aound until viewer UI isa gone
delete gKeyboard;
gKeyboard = NULL;
// Turn off Space Navigator and similar devices
LLViewerJoystick::getInstance()->terminate();
llinfos << "Cleaning up Objects" << llendflush;
LLViewerObject::cleanupVOClasses();
LLWaterParamManager::cleanupClass();
@ -1410,6 +1419,8 @@ bool LLAppViewer::cleanup()
}
LLPrimitive::cleanupVolumeManager();
llinfos << "Additional Cleanup..." << llendflush;
LLViewerParcelMgr::cleanupGlobals();
// *Note: this is where gViewerStats used to be deleted.
@ -1429,9 +1440,11 @@ bool LLAppViewer::cleanup()
// Also after shutting down the messaging system since it has VFS dependencies
//
llinfos << "Cleaning up VFS" << llendflush;
LLVFile::cleanupClass();
llinfos << "VFS cleaned up" << llendflush;
llinfos << "Saving Data" << llendflush;
// Quitting with "Remember Password" turned off should always stomp your
// saved password, whether or not you successfully logged in. JC
if (!gSavedSettings.getBOOL("RememberPassword"))
@ -1473,13 +1486,16 @@ bool LLAppViewer::cleanup()
gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask);
}
// Turn off Space Navigator and similar devices
LLViewerJoystick::getInstance()->terminate();
removeMarkerFile(); // Any crashes from here on we'll just have to ignore
writeDebugInfo();
LLLocationHistory::getInstance()->save();
LLAvatarIconIDCache::getInstance()->save();
llinfos << "Shutting down Threads" << llendflush;
// Let threads finish
LLTimer idleTimer;
idleTimer.reset();
@ -1512,14 +1528,9 @@ bool LLAppViewer::cleanup()
sTextureFetch = NULL;
delete sImageDecodeThread;
sImageDecodeThread = NULL;
LLLocationHistory::getInstance()->save();
LLAvatarIconIDCache::getInstance()->save();
delete mFastTimerLogThread;
mFastTimerLogThread = NULL;
if (LLFastTimerView::sAnalyzePerformance)
{
llinfos << "Analyzing performance" << llendl;
@ -1541,6 +1552,8 @@ bool LLAppViewer::cleanup()
}
LLMetricPerformanceTester::cleanClass() ;
llinfos << "Cleaning up Media and Textures" << llendflush;
//Note:
//LLViewerMedia::cleanupClass() has to be put before gTextureList.shutdown()
//because some new image might be generated during cleaning up media. --bao
@ -1554,13 +1567,13 @@ bool LLAppViewer::cleanup()
LLVFSThread::cleanupClass();
LLLFSThread::cleanupClass();
llinfos << "VFS Thread finished" << llendflush;
#ifndef LL_RELEASE_FOR_DOWNLOAD
llinfos << "Auditing VFS" << llendl;
gVFS->audit();
#endif
llinfos << "Misc Cleanup" << llendflush;
// For safety, the LLVFS has to be deleted *after* LLVFSThread. This should be cleaned up.
// (LLVFS doesn't know about LLVFSThread so can't kill pending requests) -Steve
delete gStaticVFS;
@ -1574,12 +1587,11 @@ bool LLAppViewer::cleanup()
LLWatchdog::getInstance()->cleanup();
llinfos << "Shutting down message system" << llendflush;
end_messaging_system();
llinfos << "Message system deleted." << llendflush;
// *NOTE:Mani - The following call is not thread safe.
LLCurl::cleanupClass();
llinfos << "LLCurl cleaned up." << llendflush;
// If we're exiting to launch an URL, do that here so the screen
// is at the right resolution before we launch IE.
@ -1600,7 +1612,7 @@ bool LLAppViewer::cleanup()
ll_close_fail_log();
llinfos << "Goodbye" << llendflush;
llinfos << "Goodbye!" << llendflush;
// return 0;
return true;
@ -3534,6 +3546,7 @@ void LLAppViewer::idle()
gEventNotifier.update();
gIdleCallbacks.callFunctions();
gInventory.idleNotifyObservers();
}
if (gDisconnected)
@ -4185,7 +4198,7 @@ void LLAppViewer::loadEventHostModule(S32 listen_port)
if(dso_path == "")
{
llwarns << "QAModeEventHost requested but module \"" << dso_name << "\" not found!" << llendl;
llerrs << "QAModeEventHost requested but module \"" << dso_name << "\" not found!" << llendl;
return;
}
@ -4213,7 +4226,7 @@ void LLAppViewer::loadEventHostModule(S32 listen_port)
if(status != 0)
{
llwarns << "problem loading eventhost plugin, status: " << status << llendl;
llerrs << "problem loading eventhost plugin, status: " << status << llendl;
}
mPlugins.insert(eventhost_dso_handle);

View File

@ -189,6 +189,19 @@ void LLAvatarActions::startIM(const LLUUID& id)
make_ui_sound("UISndStartIM");
}
// static
void LLAvatarActions::endIM(const LLUUID& id)
{
if (id.isNull())
return;
LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, id);
if (session_id != LLUUID::null)
{
gIMMgr->leaveSession(session_id);
}
}
// static
void LLAvatarActions::startCall(const LLUUID& id)
{
@ -284,7 +297,7 @@ void LLAvatarActions::showProfile(const LLUUID& id)
//Show own profile
if(gAgent.getID() == id)
{
LLSideTray::getInstance()->showPanel("panel_me_profile", params);
LLSideTray::getInstance()->showPanel("panel_me", params);
}
//Show other user profile
else
@ -311,6 +324,27 @@ void LLAvatarActions::pay(const LLUUID& id)
}
}
//static
void LLAvatarActions::share(const LLUUID& id)
{
LLSD key;
LLSideTray::getInstance()->showPanel("sidepanel_inventory", key);
LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL,id);
if (!gIMMgr->hasSession(session_id))
{
startIM(id);
}
if (gIMMgr->hasSession(session_id))
{
// we should always get here, but check to verify anyways
LLIMModel::getInstance()->addMessage(session_id, SYSTEM_FROM, LLUUID::null, LLTrans::getString("share_alert"), false);
}
}
// static
void LLAvatarActions::toggleBlock(const LLUUID& id)
{
@ -334,9 +368,9 @@ void LLAvatarActions::inviteToGroup(const LLUUID& id)
LLFloaterGroupPicker* widget = LLFloaterReg::showTypedInstance<LLFloaterGroupPicker>("group_picker", LLSD(id));
if (widget)
{
widget->removeNoneOption();
widget->center();
widget->setPowersMask(GP_MEMBER_INVITE);
widget->removeNoneOption();
widget->setSelectGroupCallback(boost::bind(callback_invite_to_group, _1, id));
}
}

View File

@ -73,6 +73,11 @@ public:
*/
static void startIM(const LLUUID& id);
/**
* End instant messaging session.
*/
static void endIM(const LLUUID& id);
/**
* Start an avatar-to-avatar voice call with another user
*/
@ -98,6 +103,11 @@ public:
*/
static void pay(const LLUUID& id);
/**
* Share items with the avatar.
*/
static void share(const LLUUID& id);
/**
* Block/unblock the avatar.
*/

View File

@ -48,6 +48,7 @@
LLBottomTray::LLBottomTray(const LLSD&)
: mChicletPanel(NULL),
mSysWell(NULL),
mSpeakPanel(NULL),
mSpeakBtn(NULL),
mNearbyChatBar(NULL),
mToolbarStack(NULL)
@ -237,7 +238,7 @@ void LLBottomTray::setVisible(BOOL visible)
LLView* viewp = *child_it;
std::string name = viewp->getName();
if ("chat_bar" == name || "movement_panel" == name || "cam_panel" == name || "snapshot_panel" == name)
if ("chat_bar" == name || "movement_panel" == name || "cam_panel" == name || "snapshot_panel" == name || "gesture_panel" == name)
continue;
else
{
@ -304,6 +305,7 @@ BOOL LLBottomTray::postBuild()
mSnapshotPanel = getChild<LLPanel>("snapshot_panel");
setRightMouseDownCallback(boost::bind(&LLBottomTray::showBottomTrayContextMenu,this, _2, _3,_4));
mSpeakPanel = getChild<LLPanel>("speak_panel");
mSpeakBtn = getChild<LLSpeakButton>("talk");
// Speak button should be initially disabled because
@ -317,6 +319,11 @@ BOOL LLBottomTray::postBuild()
// Registering Chat Bar to receive Voice client status change notifications.
gVoiceClient->addObserver(this);
mObjectDefaultWidthMap[RS_BUTTON_GESTURES] = mGesturePanel->getRect().getWidth();
mObjectDefaultWidthMap[RS_BUTTON_MOVEMENT] = mMovementPanel->getRect().getWidth();
mObjectDefaultWidthMap[RS_BUTTON_CAMERA] = mCamPanel->getRect().getWidth();
mObjectDefaultWidthMap[RS_BUTTON_SPEAK] = mSpeakPanel->getRect().getWidth();
return TRUE;
}
@ -402,7 +409,6 @@ void LLBottomTray::reshape(S32 width, S32 height, BOOL called_from_parent)
}
}
lldebugs << "There is no enough width to reshape all children: " << extra_shrink_width << llendl;
if (should_be_reshaped)
{
lldebugs << "Reshape all children with width: " << width << llendl;
@ -473,7 +479,12 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width)
S32 buttons_freed_width = 0;
if (still_should_be_processed)
{
processHideButton(RS_BUTTON_SNAPSHOT, &delta_width, &buttons_freed_width);
processShrinkButtons(&delta_width, &buttons_freed_width);
if (delta_width < 0)
{
processHideButton(RS_BUTTON_SNAPSHOT, &delta_width, &buttons_freed_width);
}
if (delta_width < 0)
{
@ -493,7 +504,7 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width)
if (delta_width < 0)
{
extra_shrink_width = -delta_width;
lldebugs << "There is no enough room for bottom tray, resizing still should be processed: "
llwarns << "There is no enough width to reshape all children: "
<< extra_shrink_width << llendl;
}
@ -524,38 +535,43 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
const S32 available_width_chiclet = chiclet_panel_width - chiclet_panel_min_width;
// how many room we have to show hidden buttons
S32 available_width = delta_width + chatbar_available_shrink_width + available_width_chiclet;
S32 buttons_required_width = 0; //How many room will take shown buttons
S32 total_available_width = delta_width + chatbar_available_shrink_width + available_width_chiclet;
lldebugs << "Processing extending, available width:"
<< ", chatbar - " << chatbar_available_shrink_width
<< ", chiclets - " << available_width_chiclet
<< ", total - " << total_available_width
<< llendl;
S32 available_width = total_available_width;
if (available_width > 0)
{
lldebugs << "Trying to process: RS_BUTTON_GESTURES" << llendl;
processShowButton(RS_BUTTON_GESTURES, &available_width, &buttons_required_width);
processShowButton(RS_BUTTON_GESTURES, &available_width);
}
if (available_width > 0)
{
lldebugs << "Trying to process: RS_BUTTON_MOVEMENT" << llendl;
processShowButton(RS_BUTTON_MOVEMENT, &available_width, &buttons_required_width);
processShowButton(RS_BUTTON_MOVEMENT, &available_width);
}
if (available_width > 0)
{
lldebugs << "Trying to process: RS_BUTTON_CAMERA" << llendl;
processShowButton(RS_BUTTON_CAMERA, &available_width, &buttons_required_width);
processShowButton(RS_BUTTON_CAMERA, &available_width);
}
if (available_width > 0)
{
lldebugs << "Trying to process: RS_BUTTON_SNAPSHOT" << llendl;
processShowButton(RS_BUTTON_SNAPSHOT, &available_width, &buttons_required_width);
processShowButton(RS_BUTTON_SNAPSHOT, &available_width);
}
// if we have to show some buttons but whidth increasing is not enough...
if (buttons_required_width > 0 && delta_width < buttons_required_width)
processExtendButtons(&available_width);
// if we have to show/extend some buttons but resized delta width is not enough...
S32 processed_width = total_available_width - available_width;
if (processed_width > delta_width)
{
// ... let's shrink nearby chat & chiclet panels
S32 required_to_process_width = buttons_required_width;
S32 required_to_process_width = processed_width;
// 1. use delta width of resizing
required_to_process_width -= delta_width;
@ -585,7 +601,8 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
}
// shown buttons take some space, rest should be processed by nearby chatbar & chiclet panels
delta_width -= buttons_required_width;
delta_width -= processed_width;
// how many space can nearby chatbar take?
S32 chatbar_panel_width_ = mNearbyChatBar->getRect().getWidth();
@ -593,13 +610,21 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
{
S32 delta_panel_max = chatbar_panel_max_width - chatbar_panel_width_;
S32 delta_panel = llmin(delta_width, delta_panel_max);
lldebugs << "Unprocesed delta width: " << delta_width
<< ", can be applied to chatbar: " << delta_panel_max
<< ", will be applied: " << delta_panel
<< llendl;
delta_width -= delta_panel_max;
mNearbyChatBar->reshape(chatbar_panel_width_ + delta_panel, mNearbyChatBar->getRect().getHeight());
log(mNearbyChatBar, "applied unprocessed delta width");
}
}
bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32* available_width, S32* buttons_required_width)
bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32* available_width)
{
lldebugs << "Trying to show object type: " << shown_object_type << llendl;
LLPanel* panel = mStateProcessedObjectMap[shown_object_type];
if (NULL == panel)
{
@ -615,12 +640,11 @@ bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32* availa
if (can_be_shown)
{
*available_width -= required_width;
*buttons_required_width += required_width;
setTrayButtonVisible(shown_object_type, true);
lldebugs << "processing object type: " << shown_object_type
<< ", buttons_required_width: " << *buttons_required_width
lldebugs << "processed object type: " << shown_object_type
<< ", rest available width: " << *available_width
<< llendl;
mResizeState &= ~shown_object_type;
}
@ -630,6 +654,8 @@ bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32* availa
void LLBottomTray::processHideButton(EResizeState processed_object_type, S32* required_width, S32* buttons_freed_width)
{
lldebugs << "Trying to hide object type: " << processed_object_type << llendl;
LLPanel* panel = mStateProcessedObjectMap[processed_object_type];
if (NULL == panel)
{
@ -656,6 +682,176 @@ void LLBottomTray::processHideButton(EResizeState processed_object_type, S32* re
}
}
void LLBottomTray::processShrinkButtons(S32* required_width, S32* buttons_freed_width)
{
processShrinkButton(RS_BUTTON_CAMERA, required_width);
if (*required_width < 0)
{
processShrinkButton(RS_BUTTON_MOVEMENT, required_width);
}
if (*required_width < 0)
{
processShrinkButton(RS_BUTTON_GESTURES, required_width);
}
if (*required_width < 0)
{
S32 panel_min_width = 0;
std::string panel_name = mSpeakPanel->getName();
bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width, NULL);
if (!success)
{
lldebugs << "Panel was not found to get its min width: " << panel_name << llendl;
}
else
{
//
mSpeakBtn->setLabelVisible(false);
S32 panel_width = mSpeakPanel->getRect().getWidth();
S32 possible_shrink_width = panel_width - panel_min_width;
if (possible_shrink_width > 0)
{
mSpeakPanel->reshape(panel_width - possible_shrink_width, mSpeakPanel->getRect().getHeight());
*required_width += possible_shrink_width;
if (*required_width > 0)
{
*buttons_freed_width += *required_width;
}
lldebugs << "Shrunk panel: " << panel_name
<< ", shrunk width: " << possible_shrink_width
<< ", rest width to process: " << *required_width
<< llendl;
}
}
}
}
void LLBottomTray::processShrinkButton(EResizeState processed_object_type, S32* required_width)
{
LLPanel* panel = mStateProcessedObjectMap[processed_object_type];
if (NULL == panel)
{
lldebugs << "There is no object to process for type: " << processed_object_type << llendl;
return;
}
if (panel->getVisible())
{
S32 panel_width = panel->getRect().getWidth();
S32 panel_min_width = 0;
std::string panel_name = panel->getName();
bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width, NULL);
S32 possible_shrink_width = panel_width - panel_min_width;
if (!success)
{
lldebugs << "Panel was not found to get its min width: " << panel_name << llendl;
}
// we have some space to free by shrinking the button
else if (possible_shrink_width > 0)
{
// let calculate real width to shrink
// 1. apply all possible width
*required_width += possible_shrink_width;
// 2. it it is too much...
if (*required_width > 0)
{
// reduce applied shrunk width to the excessive value.
possible_shrink_width -= *required_width;
*required_width = 0;
}
panel->reshape(panel_width - possible_shrink_width, panel->getRect().getHeight());
lldebugs << "Shrunk panel: " << panel_name
<< ", shrunk width: " << possible_shrink_width
<< ", rest width to process: " << *required_width
<< llendl;
}
}
}
void LLBottomTray::processExtendButtons(S32* available_width)
{
// do not allow extending any buttons if we have some buttons hidden
if (mResizeState & RS_BUTTONS_CAN_BE_HIDDEN) return;
processExtendButton(RS_BUTTON_GESTURES, available_width);
if (*available_width > 0)
{
processExtendButton(RS_BUTTON_CAMERA, available_width);
}
if (*available_width > 0)
{
processExtendButton(RS_BUTTON_MOVEMENT, available_width);
}
if (*available_width > 0)
{
S32 panel_max_width = mObjectDefaultWidthMap[RS_BUTTON_SPEAK];
S32 panel_width = mSpeakPanel->getRect().getWidth();
S32 possible_extend_width = panel_max_width - panel_width;
if (possible_extend_width > 0 && possible_extend_width <= *available_width)
{
mSpeakBtn->setLabelVisible(true);
mSpeakPanel->reshape(panel_max_width, mSpeakPanel->getRect().getHeight());
log(mSpeakBtn, "speak button is extended");
*available_width -= possible_extend_width;
lldebugs << "Extending panel: " << mSpeakPanel->getName()
<< ", extended width: " << possible_extend_width
<< ", rest width to process: " << *available_width
<< llendl;
}
}
}
void LLBottomTray::processExtendButton(EResizeState processed_object_type, S32* available_width)
{
LLPanel* panel = mStateProcessedObjectMap[processed_object_type];
if (NULL == panel)
{
lldebugs << "There is no object to process for type: " << processed_object_type << llendl;
return;
}
if (!panel->getVisible()) return;
S32 panel_max_width = mObjectDefaultWidthMap[processed_object_type];
S32 panel_width = panel->getRect().getWidth();
S32 possible_extend_width = panel_max_width - panel_width;
if (possible_extend_width > 0)
{
// let calculate real width to extend
// 1. apply all possible width
*available_width -= possible_extend_width;
// 2. it it is too much...
if (*available_width < 0)
{
// reduce applied extended width to the excessive value.
possible_extend_width += *available_width;
*available_width = 0;
}
panel->reshape(panel_width + possible_extend_width, panel->getRect().getHeight());
lldebugs << "Extending panel: " << panel->getName()
<< ", extended width: " << possible_extend_width
<< ", rest width to process: " << *available_width
<< llendl;
}
}
bool LLBottomTray::canButtonBeShown(EResizeState processed_object_type) const
{
bool can_be_shown = mResizeState & processed_object_type;

View File

@ -98,15 +98,38 @@ private:
, RS_BUTTON_MOVEMENT = 0x0010
, RS_BUTTON_GESTURES = 0x0020
, RS_BUTTON_SPEAK = 0x0040
, RS_RESIZABLE_BUTTONS = /*RS_BUTTON_SNAPSHOT | */RS_BUTTON_CAMERA | RS_BUTTON_MOVEMENT | RS_BUTTON_GESTURES
/**
* Specifies buttons which can be hidden when bottom tray is shrunk.
* They are: Gestures, Movement (Move), Camera (View), Snapshot
*/
, RS_BUTTONS_CAN_BE_HIDDEN = RS_BUTTON_SNAPSHOT | RS_BUTTON_CAMERA | RS_BUTTON_MOVEMENT | RS_BUTTON_GESTURES
}EResizeState;
S32 processWidthDecreased(S32 delta_width);
void processWidthIncreased(S32 delta_width);
void log(LLView* panel, const std::string& descr);
bool processShowButton(EResizeState shown_object_type, S32* available_width, S32* buttons_required_width);
bool processShowButton(EResizeState shown_object_type, S32* available_width);
void processHideButton(EResizeState processed_object_type, S32* required_width, S32* buttons_freed_width);
/**
* Shrinks shown buttons to reduce total taken space.
*
* @param - required_width - width which buttons can use to be shrunk. It is a negative value.
* It is increased on the value processed by buttons.
*/
void processShrinkButtons(S32* required_width, S32* buttons_freed_width);
void processShrinkButton(EResizeState processed_object_type, S32* required_width);
/**
* Extends shown buttons to increase total taken space.
*
* @param - available_width - width which buttons can use to be extended. It is a positive value.
* It is decreased on the value processed by buttons.
*/
void processExtendButtons(S32* available_width);
void processExtendButton(EResizeState processed_object_type, S32* available_width);
/**
* Determines if specified by type object can be shown. It should be hidden by shrink before.
*
@ -140,6 +163,9 @@ private:
typedef std::map<EResizeState, LLPanel*> state_object_map_t;
state_object_map_t mStateProcessedObjectMap;
typedef std::map<EResizeState, S32> state_object_width_map_t;
state_object_width_map_t mObjectDefaultWidthMap;
protected:
LLBottomTray(const LLSD& key = LLSD());
@ -155,6 +181,7 @@ protected:
LLChicletPanel* mChicletPanel;
LLNotificationChiclet* mSysWell;
LLPanel* mSpeakPanel;
LLSpeakButton* mSpeakBtn;
LLNearbyChatBar* mNearbyChatBar;
LLLayoutStack* mToolbarStack;

View File

@ -45,6 +45,7 @@
//class LLInventoryObserver;
class LLMessageSystem;
class LLTrackingData;
class LLFriendObserver
{
public:

View File

@ -37,7 +37,6 @@
#include "llappviewer.h"
#include "llviewercontrol.h"
#include "llimview.h"
#include "llbottomtray.h"
#include "llviewerwindow.h"
#include "llrootview.h"
#include "llsyswellwindow.h"
@ -127,7 +126,7 @@ void LLChannelManager::onLoginCompleted()
gViewerWindow->getRootView()->addChild(mStartUpChannel);
// init channel's position and size
S32 channel_right_bound = gViewerWindow->getWorldViewRectRaw().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound);
mStartUpChannel->setMouseDownCallback(boost::bind(&LLSysWellWindow::onStartUpToastClick, LLFloaterReg::getTypedInstance<LLSysWellWindow>("syswell_window"), _2, _3, _4));

View File

@ -33,11 +33,9 @@
#include "llviewerprecompiledheaders.h"
#include "llchathistory.h"
#include "llpanel.h"
#include "lltextbox.h"
#include "lluictrlfactory.h"
#include "llscrollcontainer.h"
#include "llavatariconctrl.h"
#include "llimview.h"
#include "llcallingcard.h" //for LLAvatarTracker
#include "llagentdata.h"
@ -46,23 +44,10 @@
#include "llfloaterreg.h"
#include "llmutelist.h"
#include "llsidetray.h"//for blocked objects panel
static LLDefaultChildRegistry::Register<LLChatHistory> r("chat_history");
std::string formatCurrentTime()
{
time_t utc_time;
utc_time = time_corrected();
std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
+LLTrans::getString("TimeMin")+"]";
LLSD substitution;
substitution["datetime"] = (S32) utc_time;
LLStringUtil::format (timeStr, substitution);
return timeStr;
}
class LLChatHistoryHeader: public LLPanel
{
public:
@ -92,6 +77,8 @@ public:
else if (level == "block")
{
LLMuteList::getInstance()->add(LLMute(getAvatarId(), mFrom, LLMute::OBJECT));
LLSideTray::getInstance()->showPanel("panel_block_list_sidetray", LLSD().insert("blocked_to_select", getAvatarId()));
}
}
@ -196,11 +183,10 @@ public:
mSourceType = CHAT_SOURCE_SYSTEM;
}
LLTextBox* userName = getChild<LLTextBox>("user_name");
LLTextEditor* userName = getChild<LLTextEditor>("user_name");
LLUIColor color = style_params.color;
userName->setReadOnlyColor(color);
userName->setColor(color);
userName->setReadOnlyColor(style_params.readonly_color());
userName->setColor(style_params.color());
if(!chat.mFromName.empty())
{
@ -213,10 +199,8 @@ public:
userName->setValue(SL);
}
setTimeField(chat.mTimeStr);
LLTextBox* timeBox = getChild<LLTextBox>("time_box");
timeBox->setValue(formatCurrentTime());
LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon");
if(mSourceType != CHAT_SOURCE_AGENT)
@ -282,7 +266,28 @@ protected:
}
}
private:
void setTimeField(const std::string& time_value)
{
LLTextBox* time_box = getChild<LLTextBox>("time_box");
LLRect rect_before = time_box->getRect();
time_box->setValue(time_value);
// set necessary textbox width to fit all text
time_box->reshapeToFitText();
LLRect rect_after = time_box->getRect();
// move rect to the left to correct position...
S32 delta_pos_x = rect_before.getWidth() - rect_after.getWidth();
S32 delta_pos_y = rect_before.getHeight() - rect_after.getHeight();
time_box->translate(delta_pos_x, delta_pos_y);
//... & change width of the name control
LLTextBox* user_name = getChild<LLTextBox>("user_name");
const LLRect& user_rect = user_name->getRect();
user_name->reshape(user_rect.getWidth() + delta_pos_x, user_rect.getHeight());
}
protected:
LLHandle<LLView> mPopupMenuHandleAvatar;
@ -345,20 +350,14 @@ LLView* LLChatHistory::getHeader(const LLChat& chat,const LLStyle::Params& style
return header;
}
void LLChatHistory::appendWidgetMessage(const LLChat& chat, const LLStyle::Params& input_append_params)
void LLChatHistory::clear()
{
LLView* view = NULL;
std::string view_text = "\n[" + formatCurrentTime() + "] ";
if (utf8str_trim(chat.mFromName).size() != 0 && chat.mFromName != SYSTEM_FROM)
view_text += chat.mFromName + ": ";
mLastFromName.clear();
LLTextEditor::clear();
}
LLInlineViewSegment::Params p;
p.force_newline = true;
p.left_pad = mLeftWidgetPad;
p.right_pad = mRightWidgetPad;
void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_chat_history, const LLStyle::Params& input_append_params)
{
LLColor4 txt_color = LLUIColorTable::instance().getColor("White");
LLViewerChat::getChatColor(chat,txt_color);
LLFontGL* fontp = LLViewerChat::getChatFont();
@ -371,39 +370,63 @@ void LLChatHistory::appendWidgetMessage(const LLChat& chat, const LLStyle::Param
style_params.font.size(font_size);
style_params.font.style(input_append_params.font.style);
std::string header_text = "[" + chat.mTimeStr + "] ";
if (utf8str_trim(chat.mFromName).size() != 0 && chat.mFromName != SYSTEM_FROM)
header_text += chat.mFromName + ": ";
if (mLastFromName == chat.mFromName)
if (use_plain_text_chat_history)
{
view = getSeparator();
p.top_pad = mTopSeparatorPad;
p.bottom_pad = mBottomSeparatorPad;
appendText(header_text, getText().size() != 0, style_params);
}
else
{
view = getHeader(chat,style_params);
if (getText().size() == 0)
p.top_pad = 0;
LLView* view = NULL;
LLInlineViewSegment::Params p;
p.force_newline = true;
p.left_pad = mLeftWidgetPad;
p.right_pad = mRightWidgetPad;
if (mLastFromName == chat.mFromName)
{
view = getSeparator();
p.top_pad = mTopSeparatorPad;
p.bottom_pad = mBottomSeparatorPad;
}
else
p.top_pad = mTopHeaderPad;
p.bottom_pad = mBottomHeaderPad;
{
view = getHeader(chat, style_params);
if (getText().size() == 0)
p.top_pad = 0;
else
p.top_pad = mTopHeaderPad;
p.bottom_pad = mBottomHeaderPad;
}
p.view = view;
//Prepare the rect for the view
LLRect target_rect = getDocumentView()->getRect();
// squeeze down the widget by subtracting padding off left and right
target_rect.mLeft += mLeftWidgetPad + mHPad;
target_rect.mRight -= mRightWidgetPad;
view->reshape(target_rect.getWidth(), view->getRect().getHeight());
view->setOrigin(target_rect.mLeft, view->getRect().mBottom);
appendWidget(p, header_text, false);
mLastFromName = chat.mFromName;
}
p.view = view;
//Handle IRC styled /me messages.
std::string prefix = chat.mText.substr(0, 4);
if (prefix == "/me " || prefix == "/me'")
{
style_params.font.style = "ITALIC";
//Prepare the rect for the view
LLRect target_rect = getDocumentView()->getRect();
// squeeze down the widget by subtracting padding off left and right
target_rect.mLeft += mLeftWidgetPad + mHPad;
target_rect.mRight -= mRightWidgetPad;
view->reshape(target_rect.getWidth(), view->getRect().getHeight());
view->setOrigin(target_rect.mLeft, view->getRect().mBottom);
appendWidget(p, view_text, false);
//Append the text message
appendText(chat.mText, FALSE, style_params);
mLastFromName = chat.mFromName;
if (chat.mFromName.size() > 0)
appendText(chat.mFromName + " ", TRUE, style_params);
appendText(chat.mText.substr(4), FALSE, style_params);
}
else
appendText(chat.mText, FALSE, style_params);
blockUndo();
}

View File

@ -106,10 +106,11 @@ class LLChatHistory : public LLTextEditor
* If last user appended message, concurs with current user,
* separator is added before the message, otherwise header is added.
* @param chat - base chat message.
* @param time time of a message.
* @param message message itself.
* @param use_plain_text_chat_history - whether to add message as plain text.
* @param input_append_params - font style.
*/
void appendWidgetMessage(const LLChat& chat, const LLStyle::Params& input_append_params = LLStyle::Params());
void appendMessage(const LLChat& chat, const bool use_plain_text_chat_history = false, const LLStyle::Params& input_append_params = LLStyle::Params());
/*virtual*/ void clear();
private:
std::string mLastFromName;

View File

@ -175,8 +175,6 @@ void LLNearbyChatToastPanel::init(LLSD& notification)
caption->getChild<LLTextBox>("sender_name", false)->setText(str_sender , style_params);
caption->getChild<LLTextBox>("msg_time", false)->setText(appendTime() , style_params );
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
@ -189,8 +187,18 @@ void LLNearbyChatToastPanel::init(LLSD& notification)
msg_text->setText(mFromName, style_params);
}
mText = mText.substr(3);
style_params.font.style = "UNDERLINE";
style_params.font.style = "ITALIC";
#define INFINITE_REFLOW_BUG 0
#if INFINITE_REFLOW_BUG
// This causes LLTextBase::reflow() to infinite loop until the viewer
// runs out of memory, throws a bad_alloc exception from std::vector
// in mLineInfoList, and the main loop catches it and continues.
// It appears to be caused by addText() adding a line separator in the
// middle of a line. See EXT-2579, EXT-1949
msg_text->addText(mText,style_params);
#else
msg_text->appendText(mText, FALSE, style_params);
#endif
}
else
{

View File

@ -1,34 +1,34 @@
/**
* @file llchiclet.cpp
* @brief LLChiclet class implementation
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
* @file llchiclet.cpp
* @brief LLChiclet class implementation
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h" // must be first include
#include "llchiclet.h"
@ -43,6 +43,7 @@
#include "lllocalcliprect.h"
#include "llmenugl.h"
#include "lloutputmonitorctrl.h"
#include "llscriptfloater.h"
#include "lltextbox.h"
#include "llvoiceclient.h"
#include "llvoicecontrolpanel.h"
@ -55,6 +56,7 @@ static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notif
static LLDefaultChildRegistry::Register<LLIMP2PChiclet> t3("chiclet_im_p2p");
static LLDefaultChildRegistry::Register<LLIMGroupChiclet> t4("chiclet_im_group");
static LLDefaultChildRegistry::Register<LLAdHocChiclet> t5("chiclet_im_adhoc");
static LLDefaultChildRegistry::Register<LLScriptChiclet> t6("chiclet_script");
static const LLRect CHICLET_RECT(0, 25, 25, 0);
static const LLRect CHICLET_ICON_RECT(0, 22, 22, 0);
@ -81,27 +83,17 @@ LLNotificationChiclet::Params::Params()
button.tab_stop(FALSE);
button.label(LLStringUtil::null);
unread_notifications.name("unread");
unread_notifications.font(LLFontGL::getFontSansSerif());
unread_notifications.text_color=(LLColor4::white);
unread_notifications.font_halign(LLFontGL::HCENTER);
unread_notifications.mouse_opaque(FALSE);
}
LLNotificationChiclet::LLNotificationChiclet(const Params& p)
: LLChiclet(p)
, mButton(NULL)
, mCounterCtrl(NULL)
, mCounter(0)
{
LLButton::Params button_params = p.button;
button_params.rect(p.rect());
mButton = LLUICtrlFactory::create<LLButton>(button_params);
addChild(mButton);
LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
addChild(mCounterCtrl);
// connect counter handlers to the signals
connectCounterUpdatersToSignal("notify");
connectCounterUpdatersToSignal("groupnotify");
@ -126,13 +118,15 @@ void LLNotificationChiclet::connectCounterUpdatersToSignal(std::string notificat
void LLNotificationChiclet::setCounter(S32 counter)
{
mCounterCtrl->setCounter(counter);
}
std::string s_count;
if(counter != 0)
{
s_count = llformat("%d", counter);
}
void LLNotificationChiclet::setShowCounter(bool show)
{
LLChiclet::setShowCounter(show);
mCounterCtrl->setVisible(getShowCounter());
mButton->setLabel(s_count);
mCounter = counter;
}
boost::signals2::connection LLNotificationChiclet::setClickCallback(
@ -171,7 +165,7 @@ LLChiclet::~LLChiclet()
boost::signals2::connection LLChiclet::setLeftButtonClickCallback(
const commit_callback_t& cb)
{
return mCommitSignal.connect(cb);
return setCommitCallback(cb);
}
BOOL LLChiclet::handleMouseDown(S32 x, S32 y, MASK mask)
@ -482,6 +476,10 @@ void LLIMP2PChiclet::onMenuItemClicked(const LLSD& user_data)
{
LLAvatarActions::requestFriendshipDialog(other_participant_id);
}
else if("end" == level)
{
LLAvatarActions::endIM(other_participant_id);
}
}
//////////////////////////////////////////////////////////////////////////
@ -776,12 +774,16 @@ void LLIMGroupChiclet::onMenuItemClicked(const LLSD& user_data)
if("group chat" == level)
{
LLGroupActions::startChat(group_id);
LLGroupActions::startIM(group_id);
}
else if("info" == level)
{
LLGroupActions::show(group_id);
}
else if("end" == level)
{
LLGroupActions::endIM(group_id);
}
}
@ -922,34 +924,45 @@ void LLChicletPanel::onCurrentVoiceChannelChanged(const LLUUID& session_id)
s_previous_active_voice_session_id = session_id;
}
S32 LLChicletPanel::calcChickletPanleWidth()
{
S32 res = 0;
for (chiclet_list_t::iterator it = mChicletList.begin(); it
!= mChicletList.end(); it++)
{
res = (*it)->getRect().getWidth() + getChicletPadding();
}
return res;
}
bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index)
{
if(mScrollArea->addChild(chiclet))
{
// chicklets should be aligned to right edge of scroll panel
S32 offset = 0;
// chiclets should be aligned to right edge of scroll panel
S32 left_shift = 0;
if (!canScrollLeft())
{
offset = mScrollArea->getRect().getWidth()
- chiclet->getRect().getWidth() - calcChickletPanleWidth();
// init left shift for the first chiclet in the list...
if (mChicletList.empty())
{
// ...start from the right border of the scroll area for the first added chiclet
left_shift = mScrollArea->getRect().getWidth();
}
else
{
// ... start from the left border of the first chiclet minus padding
left_shift = getChiclet(0)->getRect().mLeft - getChicletPadding();
}
// take into account width of the being added chiclet
left_shift -= chiclet->getRequiredRect().getWidth();
// if we overflow the scroll area we do not need to shift chiclets
if (left_shift < 0)
{
left_shift = 0;
}
}
mChicletList.insert(mChicletList.begin() + index, chiclet);
getChiclet(0)->translate(offset, 0);
// shift first chiclet to place it in correct position.
// rest ones will be placed in arrange()
if (!canScrollLeft())
{
getChiclet(0)->translate(left_shift - getChiclet(0)->getRect().mLeft, 0);
}
chiclet->setLeftButtonClickCallback(boost::bind(&LLChicletPanel::onChicletClick, this, _1, _2));
chiclet->setChicletSizeChangedCallback(boost::bind(&LLChicletPanel::onChicletSizeChanged, this, _1, index));
@ -972,7 +985,10 @@ void LLChicletPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param)
void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD&param)
{
mCommitSignal(ctrl,param);
if (mCommitSignal)
{
(*mCommitSignal)(ctrl,param);
}
}
void LLChicletPanel::removeChiclet(chiclet_list_t::iterator it)
@ -1277,7 +1293,7 @@ void LLChicletPanel::onRightScrollHeldDown()
boost::signals2::connection LLChicletPanel::setChicletClickedCallback(
const commit_callback_t& cb)
{
return mCommitSignal.connect(cb);
return setCommitCallback(cb);
}
BOOL LLChicletPanel::handleScrollWheel(S32 x, S32 y, S32 clicks)
@ -1400,3 +1416,51 @@ LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p)
: LLOutputMonitorCtrl(p)
{
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
LLScriptChiclet::Params::Params()
: icon("icon")
{
// *TODO Vadim: Get rid of hardcoded values.
rect(CHICLET_RECT);
icon.rect(CHICLET_ICON_RECT);
}
LLScriptChiclet::LLScriptChiclet(const Params&p)
: LLIMChiclet(p)
, mChicletIconCtrl(NULL)
{
LLIconCtrl::Params icon_params = p.icon;
mChicletIconCtrl = LLUICtrlFactory::create<LLIconCtrl>(icon_params);
// Let "new message" icon be on top, else it will be hidden behind chiclet icon.
addChildInBack(mChicletIconCtrl);
}
void LLScriptChiclet::setSessionId(const LLUUID& session_id)
{
setShowNewMessagesIcon( getSessionId() != session_id );
LLIMChiclet::setSessionId(session_id);
LLUUID notification_id = LLScriptFloaterManager::getInstance()->findNotificationId(session_id);
LLNotificationPtr notification = LLNotifications::getInstance()->find(notification_id);
if(notification)
{
setToolTip(notification->getSubstitutions()["TITLE"].asString());
}
}
void LLScriptChiclet::onMouseDown()
{
LLScriptFloaterManager::getInstance()->toggleScriptFloater(getSessionId());
}
BOOL LLScriptChiclet::handleMouseDown(S32 x, S32 y, MASK mask)
{
onMouseDown();
return LLChiclet::handleMouseDown(x, y, mask);
}
// EOF

View File

@ -1,34 +1,34 @@
/**
* @file llchiclet.h
* @brief LLChiclet class header file
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
* @file llchiclet.h
* @brief LLChiclet class header file
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLCHICLET_H
#define LL_LLCHICLET_H
@ -44,9 +44,9 @@ class LLVoiceControlPanel;
class LLMenuGL;
class LLIMFloater;
/*
/**
* Class for displaying amount of messages/notifications(unread).
*/
*/
class LLChicletNotificationCounterCtrl : public LLTextBox
{
public:
@ -57,30 +57,30 @@ public:
{};
};
/*
/**
* Sets number of notifications
*/
*/
virtual void setCounter(S32 counter);
/*
/**
* Returns number of notifications
*/
*/
virtual S32 getCounter() const { return mCounter; }
/*
/**
* Returns width, required to display amount of notifications in text form.
* Width is the only valid value.
*/
*/
/*virtual*/ LLRect getRequiredRect();
/*
/**
* Sets number of notifications using LLSD
*/
*/
/*virtual*/ void setValue(const LLSD& value);
/*
/**
* Returns number of notifications wrapped in LLSD
*/
*/
/*virtual*/ LLSD getValue() const;
protected:
@ -94,9 +94,9 @@ private:
S32 mInitialWidth;
};
/*
/**
* Class for displaying avatar's icon in P2P chiclet.
*/
*/
class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl
{
public:
@ -147,9 +147,9 @@ protected:
std::string mDefaultIcon;
};
/*
/**
* Class for displaying of speaker's voice indicator
*/
*/
class LLChicletSpeakerCtrl : public LLOutputMonitorCtrl
{
public:
@ -164,7 +164,7 @@ protected:
friend class LLUICtrlFactory;
};
/*
/**
* Base class for all chiclets.
*/
class LLChiclet : public LLUICtrl
@ -180,59 +180,59 @@ public:
/*virtual*/ ~LLChiclet();
/*
/**
* Associates chat session id with chiclet.
*/
*/
virtual void setSessionId(const LLUUID& session_id) { mSessionId = session_id; }
/*
/**
* Returns associated chat session.
*/
*/
virtual const LLUUID& getSessionId() const { return mSessionId; }
/*
/**
* Sets number of unread notifications.
*/
*/
virtual void setCounter(S32 counter) = 0;
/*
/**
* Returns number of unread notifications.
*/
*/
virtual S32 getCounter() = 0;
/*
/**
* Sets show counter state.
*/
*/
virtual void setShowCounter(bool show) { mShowCounter = show; }
/*
/**
* Returns show counter state.
*/
*/
virtual bool getShowCounter() {return mShowCounter;};
/*
/**
* Connects chiclet clicked event with callback.
*/
*/
/*virtual*/ boost::signals2::connection setLeftButtonClickCallback(
const commit_callback_t& cb);
typedef boost::function<void (LLChiclet* ctrl, const LLSD& param)>
chiclet_size_changed_callback_t;
/*
/**
* Connects chiclets size changed event with callback.
*/
*/
virtual boost::signals2::connection setChicletSizeChangedCallback(
const chiclet_size_changed_callback_t& cb);
/*
/**
* Sets IM Session id using LLSD
*/
*/
/*virtual*/ LLSD getValue() const;
/*
/**
* Returns IM Session id using LLSD
*/
*/
/*virtual*/ void setValue(const LLSD& value);
protected:
@ -240,14 +240,14 @@ protected:
friend class LLUICtrlFactory;
LLChiclet(const Params& p);
/*
/**
* Notifies subscribers about click on chiclet.
*/
*/
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
/*
/**
* Notifies subscribers about chiclet size changed event.
*/
*/
virtual void onChicletSizeChanged();
private:
@ -263,11 +263,11 @@ private:
};
/*
* Base class for Instant Message chiclets.
* IMChiclet displays icon, number of unread messages(optional)
* and voice chat status(optional).
*/
/**
* Base class for Instant Message chiclets.
* IMChiclet displays icon, number of unread messages(optional)
* and voice chat status(optional).
*/
class LLIMChiclet : public LLChiclet
{
public:
@ -288,50 +288,50 @@ public:
/*virtual*/ ~LLIMChiclet() {};
/*
/**
* Sets IM session name. This name will be displayed in chiclet tooltip.
*/
*/
virtual void setIMSessionName(const std::string& name) { setToolTip(name); }
/*
/**
* Sets id of person/group user is chatting with.
* Session id should be set before calling this
*/
*/
virtual void setOtherParticipantId(const LLUUID& other_participant_id) { mOtherParticipantId = other_participant_id; }
/*
/**
* Gets id of person/group user is chatting with.
*/
virtual LLUUID getOtherParticipantId() { return mOtherParticipantId; }
/*
* Init Speaker Control with speaker's ID
*/
/**
* Init Speaker Control with speaker's ID
*/
virtual void initSpeakerControl();
/*
/**
* set status (Shows/Hide) for voice control.
*/
*/
virtual void setShowSpeaker(bool show);
/*
/**
* Returns voice chat status control visibility.
*/
*/
virtual bool getShowSpeaker() {return mShowSpeaker;};
/*
* Shows/Hides for voice control for a chiclet.
*/
/**
* Shows/Hides for voice control for a chiclet.
*/
virtual void toggleSpeakerControl();
/*
* Shows/hides overlay icon concerning new unread messages.
*/
/**
* Shows/hides overlay icon concerning new unread messages.
*/
virtual void setShowNewMessagesIcon(bool show);
/*
* Returns visibility of overlay icon concerning new unread messages.
*/
/**
* Returns visibility of overlay icon concerning new unread messages.
*/
virtual bool getShowNewMessagesIcon();
virtual void draw();
@ -418,45 +418,45 @@ public:
/* virtual */ void setOtherParticipantId(const LLUUID& other_participant_id);
/*
* Sets number of unread messages. Will update chiclet's width if number text
* exceeds size of counter and notify it's parent about size change.
*/
/**
* Sets number of unread messages. Will update chiclet's width if number text
* exceeds size of counter and notify it's parent about size change.
*/
/*virtual*/ void setCounter(S32);
/*
* Init Speaker Control with speaker's ID
*/
/**
* Init Speaker Control with speaker's ID
*/
/*virtual*/ void initSpeakerControl();
/*
* Returns number of unread messages.
*/
/**
* Returns number of unread messages.
*/
/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
protected:
LLIMP2PChiclet(const Params& p);
friend class LLUICtrlFactory;
/*
* Creates chiclet popup menu. Will create P2P or Group IM Chat menu
* based on other participant's id.
*/
/**
* Creates chiclet popup menu. Will create P2P or Group IM Chat menu
* based on other participant's id.
*/
virtual void createPopupMenu();
/*
* Processes clicks on chiclet popup menu.
*/
/**
* Processes clicks on chiclet popup menu.
*/
virtual void onMenuItemClicked(const LLSD& user_data);
/*
* Displays popup menu.
*/
/**
* Displays popup menu.
*/
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
/*
* Enables/disables menus based on relationship with other participant.
*/
/**
* Enables/disables menus based on relationship with other participant.
*/
virtual void updateMenuItems();
private:
@ -492,39 +492,39 @@ public:
*/
/*virtual*/ void setSessionId(const LLUUID& session_id);
/*
* Sets number of unread messages. Will update chiclet's width if number text
* exceeds size of counter and notify it's parent about size change.
*/
/**
* Sets number of unread messages. Will update chiclet's width if number text
* exceeds size of counter and notify it's parent about size change.
*/
/*virtual*/ void setCounter(S32);
/*
* Keep Speaker Control with actual speaker's ID
*/
/**
* Keep Speaker Control with actual speaker's ID
*/
/*virtual*/ void draw();
/*
* Init Speaker Control with speaker's ID
*/
/**
* Init Speaker Control with speaker's ID
*/
/*virtual*/ void initSpeakerControl();
/*
* Returns number of unread messages.
*/
/**
* Returns number of unread messages.
*/
/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
protected:
LLAdHocChiclet(const Params& p);
friend class LLUICtrlFactory;
/*
* Displays popup menu.
*/
/**
* Displays popup menu.
*/
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
/*
* Finds a current speaker and resets the SpeakerControl with speaker's ID
*/
/**
* Finds a current speaker and resets the SpeakerControl with speaker's ID
*/
/*virtual*/ void switchToCurrentSpeaker();
private:
@ -533,6 +533,46 @@ private:
LLMenuGL* mPopupMenu;
};
/**
* Chiclet for script floaters.
*/
class LLScriptChiclet : public LLIMChiclet
{
public:
struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
{
Optional<LLIconCtrl::Params> icon;
Params();
};
/*virtual*/ void setSessionId(const LLUUID& session_id);
/*virtual*/ void setCounter(S32 counter){}
/*virtual*/ S32 getCounter() { return 0; }
/**
* Toggle script floater
*/
/*virtual*/ void onMouseDown();
/**
* Override default handler
*/
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
protected:
LLScriptChiclet(const Params&);
friend class LLUICtrlFactory;
private:
LLIconCtrl* mChicletIconCtrl;
};
/**
* Implements Group chat chiclet.
*/
@ -559,9 +599,9 @@ public:
*/
/*virtual*/ void setSessionId(const LLUUID& session_id);
/*
* Keep Speaker Control with actual speaker's ID
*/
/**
* Keep Speaker Control with actual speaker's ID
*/
/*virtual*/ void draw();
/**
@ -570,20 +610,20 @@ public:
*/
/*virtual*/ void changed(LLGroupChange gc);
/*
* Sets number of unread messages. Will update chiclet's width if number text
* exceeds size of counter and notify it's parent about size change.
*/
/**
* Sets number of unread messages. Will update chiclet's width if number text
* exceeds size of counter and notify it's parent about size change.
*/
/*virtual*/ void setCounter(S32);
/*
* Init Speaker Control with speaker's ID
*/
/**
* Init Speaker Control with speaker's ID
*/
/*virtual*/ void initSpeakerControl();
/*
* Returns number of unread messages.
*/
/**
* Returns number of unread messages.
*/
/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
~LLIMGroupChiclet();
@ -592,25 +632,25 @@ protected:
LLIMGroupChiclet(const Params& p);
friend class LLUICtrlFactory;
/*
* Finds a current speaker and resets the SpeakerControl with speaker's ID
*/
/**
* Finds a current speaker and resets the SpeakerControl with speaker's ID
*/
/*virtual*/ void switchToCurrentSpeaker();
/*
* Creates chiclet popup menu. Will create P2P or Group IM Chat menu
* based on other participant's id.
*/
/**
* Creates chiclet popup menu. Will create P2P or Group IM Chat menu
* based on other participant's id.
*/
virtual void createPopupMenu();
/*
* Processes clicks on chiclet popup menu.
*/
/**
* Processes clicks on chiclet popup menu.
*/
virtual void onMenuItemClicked(const LLSD& user_data);
/*
* Displays popup menu.
*/
/**
* Displays popup menu.
*/
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
private:
@ -619,10 +659,10 @@ private:
LLMenuGL* mPopupMenu;
};
/*
/**
* Implements notification chiclet. Used to display total amount of unread messages
* across all IM sessions, total amount of system notifications.
*/
*/
class LLNotificationChiclet : public LLChiclet
{
public:
@ -638,13 +678,14 @@ public:
/*virtual*/ void setCounter(S32 counter);
/*virtual*/S32 getCounter() { return mCounterCtrl->getCounter(); }
/*virtual*/ void setShowCounter(bool show);
// *TODO: mantipov: seems getCounter is not necessary for LLNotificationChiclet
// but inherited interface requires it to implement.
// Probably it can be safe removed.
/*virtual*/S32 getCounter() { return mCounter; }
boost::signals2::connection setClickCallback(const commit_callback_t& cb);
/*virtual*/ ~ LLNotificationChiclet();
/*virtual*/ ~LLNotificationChiclet();
// methods for updating a number of unread System notifications
void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications); }
@ -662,13 +703,13 @@ protected:
protected:
LLButton* mButton;
LLChicletNotificationCounterCtrl* mCounterCtrl;
S32 mCounter;
};
/*
/**
* Storage class for all IM chiclets. Provides mechanism to display,
* scroll, create, remove chiclets.
*/
*/
class LLChicletPanel : public LLPanel
{
public:
@ -685,62 +726,62 @@ public:
virtual ~LLChicletPanel();
/*
/**
* Creates chiclet and adds it to chiclet list at specified index.
*/
*/
template<class T> T* createChiclet(const LLUUID& session_id, S32 index);
/*
/**
* Creates chiclet and adds it to chiclet list at right.
*/
*/
template<class T> T* createChiclet(const LLUUID& session_id);
/*
/**
* Returns pointer to chiclet of specified type at specified index.
*/
*/
template<class T> T* getChiclet(S32 index);
/*
/**
* Returns pointer to LLChiclet at specified index.
*/
*/
LLChiclet* getChiclet(S32 index) { return getChiclet<LLChiclet>(index); }
/*
/**
* Searches a chiclet using IM session id.
*/
*/
template<class T> T* findChiclet(const LLUUID& im_session_id);
/*
/**
* Returns number of hosted chiclets.
*/
*/
S32 getChicletCount() {return mChicletList.size();};
/*
/**
* Returns index of chiclet in list.
*/
*/
S32 getChicletIndex(const LLChiclet* chiclet);
/*
/**
* Removes chiclet by index.
*/
*/
void removeChiclet(S32 index);
/*
/**
* Removes chiclet by pointer.
*/
*/
void removeChiclet(LLChiclet* chiclet);
/*
/**
* Removes chiclet by IM session id.
*/
*/
void removeChiclet(const LLUUID& im_session_id);
/*
/**
* Removes all chiclets.
*/
*/
void removeAll();
/*
/**
* Scrolls the panel to the specified chiclet
*/
void scrollToChiclet(const LLChiclet* chiclet);
@ -750,14 +791,14 @@ public:
/*virtual*/ BOOL postBuild();
/*
* Handler for the Voice Client's signal. Finds a corresponding chiclet and toggles its SpeakerControl
*/
/**
* Handler for the Voice Client's signal. Finds a corresponding chiclet and toggles its SpeakerControl
*/
void onCurrentVoiceChannelChanged(const LLUUID& session_id);
/*
/**
* Reshapes controls and rearranges chiclets if needed.
*/
*/
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE );
/*virtual*/ void draw();
@ -768,100 +809,107 @@ protected:
LLChicletPanel(const Params&p);
friend class LLUICtrlFactory;
S32 calcChickletPanleWidth();
/*
* Adds chiclet to list and rearranges all chiclets.
*/
/**
* Adds chiclet to list and rearranges all chiclets.
* They should be right aligned, most recent right. See EXT-1293
*
* It calculates position of the first chiclet in the list. Other chiclets are placed in arrange().
*
* @see arrange()
*/
bool addChiclet(LLChiclet*, S32 index);
/*
* Arranges chiclets.
*/
/**
* Arranges chiclets to have them in correct positions.
*
* Method bases on assumption that first chiclet has correct rect and starts from the its position.
*
* @see addChiclet()
*/
void arrange();
/*
/**
* Returns true if chiclets can be scrolled right.
*/
*/
bool canScrollRight();
/*
* Returns true if chiclets can be scrolled left.
*/
/**
* Returns true if chiclets can be scrolled left.
*/
bool canScrollLeft();
/*
* Shows or hides chiclet scroll buttons if chiclets can or can not be scrolled.
*/
/**
* Shows or hides chiclet scroll buttons if chiclets can or can not be scrolled.
*/
void showScrollButtonsIfNeeded();
/*
/**
* Shifts chiclets left or right.
*/
*/
void shiftChiclets(S32 offset, S32 start_index = 0);
/*
/**
* Removes gaps between first chiclet and scroll area left side,
* last chiclet and scroll area right side.
*/
*/
void trimChiclets();
/*
/**
* Scrolls chiclets to right or left.
*/
*/
void scroll(S32 offset);
/*
/**
* Verifies that chiclets can be scrolled left, then calls scroll()
*/
*/
void scrollLeft();
/*
/**
* Verifies that chiclets can be scrolled right, then calls scroll()
*/
*/
void scrollRight();
/*
/**
* Callback for left scroll button clicked
*/
*/
void onLeftScrollClick();
/*
* Callback for right scroll button clicked
*/
/**
* Callback for right scroll button clicked
*/
void onRightScrollClick();
/*
* Callback for right scroll button held down event
*/
/**
* Callback for right scroll button held down event
*/
void onLeftScrollHeldDown();
/*
/**
* Callback for left scroll button held down event
*/
void onRightScrollHeldDown();
/*
/**
* Callback for mouse wheel scrolled, calls scrollRight() or scrollLeft()
*/
*/
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
/*
/**
* Notifies subscribers about click on chiclet.
* Do not place any code here, instead subscribe on event (see setChicletClickedCallback).
*/
*/
void onChicletClick(LLUICtrl*ctrl,const LLSD&param);
/*
/**
* Callback for chiclet size changed event, rearranges chiclets.
*/
*/
void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param);
typedef std::vector<LLChiclet*> chiclet_list_t;
/*
/**
* Removes chiclet from scroll area and chiclet list.
*/
*/
void removeChiclet(chiclet_list_t::iterator it);
S32 getChicletPadding() { return mChicletPadding; }

View File

@ -37,52 +37,70 @@
#include "lltrans.h"
#include "llui.h"
static S32 age_days_from_date(const std::string& date_string,
const LLDate& now)
static S32 DAYS_PER_MONTH_NOLEAP[] =
{ 31, 28, 21, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static S32 DAYS_PER_MONTH_LEAP[] =
{ 31, 29, 21, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static S32 days_from_month(S32 year, S32 month)
{
// Convert string date to malleable representation
S32 month, day, year;
S32 matched = sscanf(date_string.c_str(), "%d/%d/%d", &month, &day, &year);
if (matched != 3) return S32_MIN;
// Create ISO-8601 date string
std::string iso8601_date_string =
llformat("%04d-%02d-%02dT00:00:00Z", year, month, day);
LLDate date(iso8601_date_string);
// Correct for the fact that account creation dates are in Pacific time,
// == UTC - 8
F64 date_secs_since_epoch = date.secondsSinceEpoch();
date_secs_since_epoch += 8.0 * 60.0 * 60.0;
// Convert seconds from epoch to seconds from now
F64 now_secs_since_epoch = now.secondsSinceEpoch();
F64 age_secs = now_secs_since_epoch - date_secs_since_epoch;
// We don't care about sub-day times
const F64 SEC_PER_DAY = 24.0 * 60.0 * 60.0;
S32 age_days = lltrunc(age_secs / SEC_PER_DAY);
return age_days;
if (year % 4 == 0
&& year % 100 != 0)
{
// leap year
return DAYS_PER_MONTH_LEAP[month];
}
else
{
return DAYS_PER_MONTH_NOLEAP[month];
}
}
std::string LLDateUtil::ageFromDate(const std::string& date_string,
const LLDate& now)
{
S32 age_days = age_days_from_date(date_string, now);
if (age_days == S32_MIN) return "???";
S32 born_month, born_day, born_year;
S32 matched = sscanf(date_string.c_str(), "%d/%d/%d", &born_month, &born_day, &born_year);
if (matched != 3) return "???";
LLDate born_date;
born_date.fromYMDHMS(born_year, born_month, born_day);
F64 born_date_secs_since_epoch = born_date.secondsSinceEpoch();
// Correct for the fact that account creation dates are in Pacific time,
// == UTC - 8
born_date_secs_since_epoch += 8.0 * 60.0 * 60.0;
born_date.secondsSinceEpoch(born_date_secs_since_epoch);
// explode out to month/day/year again
born_date.split(&born_year, &born_month, &born_day);
S32 now_year, now_month, now_day;
now.split(&now_year, &now_month, &now_day);
// Do grade-school subtraction, from right-to-left, borrowing from the left
// when things go negative
S32 age_days = (now_day - born_day);
if (age_days < 0)
{
now_month -= 1;
if (now_month == 0)
{
now_year -= 1;
now_month = 12;
}
age_days += days_from_month(now_year, now_month);
}
S32 age_months = (now_month - born_month);
if (age_months < 0)
{
now_year -= 1;
age_months += 12;
}
S32 age_years = (now_year - born_year);
// Noun pluralization depends on language
std::string lang = LLUI::getLanguage();
// Try for age in round number of years
LLStringUtil::format_map_t args;
S32 age_years = age_days / 365;
age_days = age_days % 365;
// *NOTE: This is wrong. Not all months have 30 days, but we don't have a library
// for relative date arithmetic. :-( JC
S32 age_months = age_days / 30;
age_days = age_days % 30;
if (age_months > 0 || age_years > 0)
{

View File

@ -232,13 +232,15 @@ public:
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask)
{
mMouseDownSignal(this, x, y, mask);
if (mMouseDownSignal)
(*mMouseDownSignal)(this, x, y, mask);
return LLMenuItemCallGL::handleMouseDown(x, y, mask);
}
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask)
{
mMouseUpSignal(this, x, y, mask);
if (mMouseUpSignal)
(*mMouseUpSignal)(this, x, y, mask);
return LLMenuItemCallGL::handleMouseUp(x, y, mask);
}

View File

@ -42,6 +42,7 @@
#include "llworld.h"
// Linden libraries
#include "llbutton.h"
#include "lllineeditor.h"
#include "llscrolllistctrl.h"
#include "llscrolllistitem.h"
@ -56,7 +57,8 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(callback_t callback,
BOOL closeOnSelect)
{
// *TODO: Use a key to allow this not to be an effective singleton
LLFloaterAvatarPicker* floater = LLFloaterReg::showTypedInstance<LLFloaterAvatarPicker>("avatar_picker");
LLFloaterAvatarPicker* floater =
LLFloaterReg::showTypedInstance<LLFloaterAvatarPicker>("avatar_picker");
floater->mCallback = callback;
floater->mCallbackUserdata = userdata;
@ -64,6 +66,15 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(callback_t callback,
floater->mNearMeListComplete = FALSE;
floater->mCloseOnSelect = closeOnSelect;
if (!closeOnSelect)
{
// Use Select/Close
std::string select_string = floater->getString("Select");
std::string close_string = floater->getString("Close");
floater->getChild<LLButton>("ok_btn")->setLabel(select_string);
floater->getChild<LLButton>("cancel_btn")->setLabel(close_string);
}
return floater;
}
@ -102,10 +113,9 @@ BOOL LLFloaterAvatarPicker::postBuild()
friends->setDoubleClickCallback(onBtnSelect, this);
childSetCommitCallback("Friends", onList, this);
childSetAction("Select", onBtnSelect, this);
childDisable("Select");
childSetAction("Cancel", onBtnClose, this);
childSetAction("ok_btn", onBtnSelect, this);
childDisable("ok_btn");
childSetAction("cancel_btn", onBtnClose, this);
childSetFocus("Edit");
@ -132,7 +142,7 @@ BOOL LLFloaterAvatarPicker::postBuild()
void LLFloaterAvatarPicker::onTabChanged()
{
childSetEnabled("Select", visibleItemsSelected());
childSetEnabled("ok_btn", visibleItemsSelected());
}
// Destroys the object
@ -234,7 +244,7 @@ void LLFloaterAvatarPicker::onList(LLUICtrl* ctrl, void* userdata)
LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata;
if (self)
{
self->childSetEnabled("Select", self->visibleItemsSelected());
self->childSetEnabled("ok_btn", self->visibleItemsSelected());
}
}
@ -270,13 +280,13 @@ void LLFloaterAvatarPicker::populateNearMe()
if (empty)
{
childDisable("NearMe");
childDisable("Select");
childDisable("ok_btn");
near_me_scroller->setCommentText(getString("no_one_near"));
}
else
{
childEnable("NearMe");
childEnable("Select");
childEnable("ok_btn");
near_me_scroller->selectFirstItem();
onList(near_me_scroller, this);
near_me_scroller->setFocus(TRUE);
@ -357,7 +367,7 @@ void LLFloaterAvatarPicker::find()
getChild<LLScrollListCtrl>("SearchResults")->deleteAllItems();
getChild<LLScrollListCtrl>("SearchResults")->setCommentText(getString("searching"));
childSetEnabled("Select", FALSE);
childSetEnabled("ok_btn", FALSE);
mNumResultsReturned = 0;
}
@ -414,7 +424,7 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*
map["[TEXT]"] = floater->childGetText("Edit");
avatar_name = floater->getString("not_found", map);
search_results->setEnabled(FALSE);
floater->childDisable("Select");
floater->childDisable("ok_btn");
}
else
{
@ -430,7 +440,7 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*
if (found_one)
{
floater->childEnable("Select");
floater->childEnable("ok_btn");
search_results->selectFirstItem();
floater->onList(search_results, floater);
search_results->setFocus(TRUE);

View File

@ -903,7 +903,7 @@ void LLFloaterBuyLandUI::tellUserError(
// virtual
BOOL LLFloaterBuyLandUI::postBuild()
{
mVisibleSignal.connect(boost::bind(&LLFloaterBuyLandUI::onVisibilityChange, this, _2));
setVisibleCallback(boost::bind(&LLFloaterBuyLandUI::onVisibilityChange, this, _2));
mCurrency.prepare();

View File

@ -129,7 +129,7 @@ void LLFloaterChat::draw()
BOOL LLFloaterChat::postBuild()
{
// Hide the chat overlay when our history is visible.
mVisibleSignal.connect(boost::bind(&LLFloaterChat::updateConsoleVisibility, this));
setVisibleCallback(boost::bind(&LLFloaterChat::updateConsoleVisibility, this));
mPanel = (LLPanelActiveSpeakers*)getChild<LLPanel>("active_speakers_panel");
@ -180,16 +180,12 @@ void add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4&
edit->blockUndo();
}
void log_chat_text(const LLChat& chat)
{
LLLogChat::saveHistory(std::string("chat"), chat.mFromName, chat.mFromID, chat.mText);
}
// static
void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file)
{
if ( (gSavedPerAccountSettings.getS32("IMLogOptions")!=LOG_IM) && log_to_file)
if (log_to_file && (gSavedPerAccountSettings.getBOOL("LogChat")))
{
log_chat_text(chat);
LLLogChat::saveHistory("chat", chat.mFromName, chat.mFromID, chat.mText);
}
LLColor4 color = get_text_color(chat);
@ -305,55 +301,27 @@ void LLFloaterChat::onClickToggleShowMute(LLUICtrl* caller, void *data)
}
// Put a line of chat in all the right places
void LLFloaterChat::addChat(const LLChat& chat,
BOOL from_instant_message,
BOOL local_agent)
void LLFloaterChat::addChat(const LLChat& chat, BOOL from_instant_message, BOOL local_agent)
{
LLColor4 text_color = get_text_color(chat);
BOOL invisible_script_debug_chat = ((gSavedSettings.getBOOL("ShowScriptErrors") == FALSE) ||
(chat.mChatType == CHAT_TYPE_DEBUG_MSG
&& (gSavedSettings.getS32("ShowScriptErrorsLocation") == 1)));
if (!invisible_script_debug_chat
&& !chat.mMuted
&& gConsole
&& !local_agent)
{
F32 size = CHAT_MSG_SIZE;
if (chat.mSourceType == CHAT_SOURCE_SYSTEM)
{
text_color = LLUIColorTable::instance().getColor("SystemChatColor");
}
else if(from_instant_message)
{
text_color = LLUIColorTable::instance().getColor("IMChatColor");
size = INSTANT_MSG_SIZE;
}
// Disabling the console for 2.0 - SJB
#if 0
// We display anything if it's not an IM. If it's an IM, check pref...
if ( !from_instant_message || gSavedSettings.getBOOL("IMInChatConsole") )
{
gConsole->addLine(chat.mText, size, text_color);
}
#endif
}
if(from_instant_message && (gSavedPerAccountSettings.getS32("IMLogOptions")== LOG_BOTH_TOGETHER))
log_chat_text(chat);
if(from_instant_message && gSavedSettings.getBOOL("IMInChatHistory"))
addChatHistory(chat,false);
triggerAlerts(chat.mText);
// Add the sender to the list of people with which we've recently interacted.
if(chat.mSourceType == CHAT_SOURCE_AGENT && chat.mFromID.notNull())
LLRecentPeople::instance().add(chat.mFromID);
if(!from_instant_message)
addChatHistory(chat);
bool add_chat = true;
bool log_chat = true;
if(from_instant_message)
{
if (!gSavedSettings.getBOOL("IMInChat"))
add_chat = false;
//log_chat = false;
}
if (add_chat)
{
addChatHistory(chat, log_chat);
}
}
// Moved from lltextparser.cpp to break llui/llaudio library dependency.

View File

@ -45,14 +45,6 @@ class LLChat;
class LLPanelActiveSpeakers;
class LLLogChat;
enum ELogOptions
{
LOG_CHAT = 0,
LOG_IM = 1,
LOG_BOTH_TOGETHER = 2,
LOG_BOTH_SEPARATE = 3
};
class LLFloaterChat : public LLFloater
{
public:

View File

@ -114,7 +114,7 @@ LLFloaterChatterBox::~LLFloaterChatterBox()
BOOL LLFloaterChatterBox::postBuild()
{
mVisibleSignal.connect(boost::bind(&LLFloaterChatterBox::onVisibilityChange, this, _2));
setVisibleCallback(boost::bind(&LLFloaterChatterBox::onVisibilityChange, this, _2));
if (gSavedSettings.getBOOL("ContactsTornOff"))
{

View File

@ -34,32 +34,24 @@
#include "llfloatergesture.h"
#include "lldir.h"
#include "llinventory.h"
#include "llmultigesture.h"
#include "llinventorybridge.h"
#include "llinventorymodel.h"
#include "llinventoryclipboard.h"
#include "llagent.h"
#include "llviewerwindow.h"
#include "llbutton.h"
#include "llcombobox.h"
#include "llappearancemgr.h"
#include "llclipboard.h"
#include "llgesturemgr.h"
#include "llinventorymodel.h"
#include "llinventorypanel.h"
#include "llfloaterinventory.h"
#include "llkeyboard.h"
#include "lllineeditor.h"
#include "llmenugl.h"
#include "llmultigesture.h"
#include "llpreviewgesture.h"
#include "llresizehandle.h"
#include "llscrollbar.h"
#include "llscrollcontainer.h"
#include "llscrolllistctrl.h"
#include "lltextbox.h"
#include "lltrans.h"
#include "lluictrlfactory.h"
#include "llviewergesture.h"
#include "llviewertexturelist.h"
#include "llviewermenu.h"
#include "llviewerinventory.h"
#include "llvoavatar.h"
#include "llviewercontrol.h"
BOOL item_name_precedes( LLInventoryItem* a, LLInventoryItem* b )
@ -77,6 +69,35 @@ public:
private:
LLFloaterGesture* mFloater;
};
//-----------------------------
// GestureCallback
//-----------------------------
class GestureShowCallback : public LLInventoryCallback
{
public:
void fire(const LLUUID &inv_item)
{
LLPreviewGesture::show(inv_item, LLUUID::null);
}
};
class GestureCopiedCallback : public LLInventoryCallback
{
private:
LLFloaterGesture* mFloater;
public:
GestureCopiedCallback(LLFloaterGesture* floater): mFloater(floater)
{}
void fire(const LLUUID &inv_item)
{
if(mFloater)
{
mFloater->addGesture(inv_item,NULL,mFloater->getChild<LLScrollListCtrl>("gesture_list"));
}
}
};
//---------------------------------------------------------------------------
// LLFloaterGesture
@ -86,7 +107,13 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key)
{
mObserver = new LLFloaterGestureObserver(this);
LLGestureManager::instance().addObserver(mObserver);
//LLUICtrlFactory::getInstance()->buildFloater(this, "floater_gesture.xml");
mCommitCallbackRegistrar.add("Gesture.Action.ToogleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
mCommitCallbackRegistrar.add("Gesture.Action.ShowPreview", boost::bind(&LLFloaterGesture::onClickEdit, this));
mCommitCallbackRegistrar.add("Gesture.Action.CopyPast", boost::bind(&LLFloaterGesture::onCopyPastAction, this, _2));
mCommitCallbackRegistrar.add("Gesture.Action.SaveToCOF", boost::bind(&LLFloaterGesture::addToCurrentOutFit, this));
mEnableCallbackRegistrar.add("Gesture.EnableAction", boost::bind(&LLFloaterGesture::isActionEnabled, this, _2));
}
void LLFloaterGesture::done()
@ -151,18 +178,18 @@ BOOL LLFloaterGesture::postBuild()
label = getTitle();
setTitle(label);
getChild<LLUICtrl>("gesture_list")->setCommitCallback(boost::bind(&LLFloaterGesture::onCommitList, this));
getChild<LLScrollListCtrl>("gesture_list")->setDoubleClickCallback(boost::bind(&LLFloaterGesture::onClickPlay, this));
getChild<LLUICtrl>("inventory_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickInventory, this));
mGestureList = getChild<LLScrollListCtrl>("gesture_list");
mGestureList->setCommitCallback(boost::bind(&LLFloaterGesture::onCommitList, this));
mGestureList->setDoubleClickCallback(boost::bind(&LLFloaterGesture::onClickPlay, this));
getChild<LLUICtrl>("edit_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickEdit, this));
getChild<LLUICtrl>("play_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickPlay, this));
getChild<LLUICtrl>("stop_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickPlay, this));
getChild<LLButton>("activate_btn")->setClickedCallback(boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
getChild<LLUICtrl>("new_gesture_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickNew, this));
getChild<LLButton>("del_btn")->setClickedCallback(boost::bind(&LLFloaterGesture::onDeleteSelected, this));
childSetVisible("play_btn", true);
childSetVisible("stop_btn", false);
@ -177,14 +204,13 @@ BOOL LLFloaterGesture::postBuild()
buildGestureList();
childSetFocus("gesture_list");
mGestureList->setFocus(TRUE);
LLCtrlListInterface *list = childGetListInterface("gesture_list");
if (list)
if (mGestureList)
{
const BOOL ascending = TRUE;
list->sortByColumn(std::string("name"), ascending);
list->selectFirstItem();
mGestureList->sortByColumn(std::string("name"), ascending);
mGestureList->selectFirstItem();
}
// Update button labels
@ -198,18 +224,17 @@ void LLFloaterGesture::refreshAll()
{
buildGestureList();
LLCtrlListInterface *list = childGetListInterface("gesture_list");
if (!list) return;
if (!mGestureList) return;
if (mSelectedID.isNull())
{
list->selectFirstItem();
mGestureList->selectFirstItem();
}
else
{
if (! list->setCurrentByID(mSelectedID))
if (! mGestureList->setCurrentByID(mSelectedID))
{
list->selectFirstItem();
mGestureList->selectFirstItem();
}
}
@ -219,20 +244,16 @@ void LLFloaterGesture::refreshAll()
void LLFloaterGesture::buildGestureList()
{
LLCtrlListInterface *list = childGetListInterface("gesture_list");
LLCtrlScrollInterface *scroll = childGetScrollInterface("gesture_list");
if (! (list && scroll)) return;
LLUUID selected_item = list->getCurrentID();
std::vector<LLUUID> selected_items;
getSelectedIds(selected_items);
LL_DEBUGS("Gesture")<< "Rebuilding gesture list "<< LL_ENDL;
list->operateOnAll(LLCtrlListInterface::OP_DELETE);
mGestureList->deleteAllItems();
LLGestureManager::item_map_t::const_iterator it;
const LLGestureManager::item_map_t& active_gestures = LLGestureManager::instance().getActiveGestures();
for (it = active_gestures.begin(); it != active_gestures.end(); ++it)
{
addGesture(it->first,it->second, list);
addGesture(it->first,it->second, mGestureList);
}
if (gInventory.isCategoryComplete(mGestureFolderID))
{
@ -248,16 +269,17 @@ void LLFloaterGesture::buildGestureList()
if (active_gestures.find(item->getUUID()) == active_gestures.end())
{
// if gesture wasn't loaded yet, we can display only name
addGesture(item->getUUID(), NULL, list);
addGesture(item->getUUID(), NULL, mGestureList);
}
}
}
// attempt to preserve scroll position through re-builds
// since we do re-build any time anything dirties
if(list->selectByValue(LLSD(selected_item)))
for(std::vector<LLUUID>::iterator it = selected_items.begin(); it != selected_items.end(); it++)
{
scroll->scrollToShowSelected();
mGestureList->selectByID(*it);
}
mGestureList->scrollToShowSelected();
}
void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gesture,LLCtrlListInterface * list )
@ -345,33 +367,59 @@ void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gestur
list->addElement(element, ADD_BOTTOM);
}
void LLFloaterGesture::onClickInventory()
void LLFloaterGesture::getSelectedIds(std::vector<LLUUID>& ids)
{
LLCtrlListInterface *list = childGetListInterface("gesture_list");
if (!list) return;
const LLUUID& item_id = list->getCurrentID();
std::vector<LLScrollListItem*> items = mGestureList->getAllSelected();
for(std::vector<LLScrollListItem*>::const_iterator it = items.begin(); it != items.end(); it++)
{
ids.push_back((*it)->getUUID());
}
}
LLFloaterInventory* inv = LLFloaterInventory::showAgentInventory();
if (!inv) return;
inv->getPanel()->setSelection(item_id, TRUE);
bool LLFloaterGesture::isActionEnabled(const LLSD& command)
{
// paste copy_uuid edit_gesture
std::string command_name = command.asString();
if("paste" == command_name)
{
if(!LLInventoryClipboard::instance().hasContents())
return false;
LLDynamicArray<LLUUID> ids;
LLInventoryClipboard::instance().retrieve(ids);
for(LLDynamicArray<LLUUID>::iterator it = ids.begin(); it != ids.end(); it++)
{
LLInventoryItem* item = gInventory.getItem(*it);
if(item && item->getInventoryType() == LLInventoryType::IT_GESTURE)
{
return true;
}
}
return false;
}
else if("copy_uuid" == command_name || "edit_gesture" == command_name
|| "inspect" == command_name)
{
return mGestureList->getAllSelected().size() == 1;
}
return true;
}
void LLFloaterGesture::onClickPlay()
{
LLCtrlListInterface *list = childGetListInterface("gesture_list");
if (!list) return;
const LLUUID& item_id = list->getCurrentID();
const LLUUID& item_id = mGestureList->getCurrentID();
if(item_id.isNull()) return;
LL_DEBUGS("Gesture")<<" Trying to play gesture id: "<< item_id <<LL_ENDL;
if(!LLGestureManager::instance().isGestureActive(item_id))
{
// we need to inform server about gesture activating to be consistent with LLPreviewGesture.
// we need to inform server about gesture activating to be consistent with LLPreviewGesture and LLGestureComboBox.
BOOL inform_server = TRUE;
BOOL deactivate_similar = FALSE;
LLGestureManager::instance().setGestureLoadedCallback(item_id, boost::bind(&LLFloaterGesture::playGesture, this, item_id));
LLGestureManager::instance().activateGestureWithAsset(item_id, gInventory.getItem(item_id)->getAssetUUID(), inform_server, deactivate_similar);
LL_DEBUGS("Gesture")<< "Activating gesture with inventory ID: " << item_id <<LL_ENDL;
LLGestureManager::instance().setGestureLoadedCallback(item_id, boost::bind(&LLFloaterGesture::playGesture, this, item_id));
}
else
{
@ -379,15 +427,6 @@ void LLFloaterGesture::onClickPlay()
}
}
class GestureShowCallback : public LLInventoryCallback
{
public:
void fire(const LLUUID &inv_item)
{
LLPreviewGesture::show(inv_item, LLUUID::null);
}
};
void LLFloaterGesture::onClickNew()
{
LLPointer<LLInventoryCallback> cb = new GestureShowCallback();
@ -396,12 +435,98 @@ void LLFloaterGesture::onClickNew()
LLInventoryType::IT_GESTURE, NOT_WEARABLE, PERM_MOVE | PERM_TRANSFER, cb);
}
void LLFloaterGesture::onActivateBtnClick()
{
std::vector<LLUUID> ids;
getSelectedIds(ids);
if(ids.empty())
return;
LLGestureManager* gm = LLGestureManager::getInstance();
std::vector<LLUUID>::const_iterator it = ids.begin();
BOOL first_gesture_state = gm->isGestureActive(*it);
BOOL is_mixed = FALSE;
while( ++it != ids.end() )
{
if(first_gesture_state != gm->isGestureActive(*it))
{
is_mixed = TRUE;
break;
}
}
for(std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); it++)
{
if(is_mixed)
{
gm->activateGesture(*it);
}
else
{
if(first_gesture_state)
{
gm->deactivateGesture(*it);
}
else
{
gm->activateGesture(*it);
}
}
}
}
void LLFloaterGesture::onCopyPastAction(const LLSD& command)
{
std::string command_name = command.asString();
// since we select this comman inventory item had already arrived .
if("copy_gesture" == command_name)
{
std::vector<LLUUID> ids;
getSelectedIds(ids);
// make sure that clopboard is empty
LLInventoryClipboard::instance().reset();
for(std::vector<LLUUID>::iterator it = ids.begin(); it != ids.end(); it++)
{
LLInventoryItem* item = gInventory.getItem(*it);
if(item && item->getInventoryType() == LLInventoryType::IT_GESTURE)
{
LLInventoryClipboard::instance().add(item->getUUID());
}
}
}
else if ("paste" == command_name)
{
LLInventoryClipboard& clipbord = LLInventoryClipboard::instance();
LLDynamicArray<LLUUID> ids;
clipbord.retrieve(ids);
if(ids.empty() || !gInventory.isCategoryComplete(mGestureFolderID))
return;
LLInventoryCategory* gesture_dir = gInventory.getCategory(mGestureFolderID);
LLPointer<GestureCopiedCallback> cb = new GestureCopiedCallback(this);
for(LLDynamicArray<LLUUID>::iterator it = ids.begin(); it != ids.end(); it++)
{
LLInventoryItem* item = gInventory.getItem(*it);
LLStringUtil::format_map_t string_args;
string_args["[COPY_NAME]"] = item->getName();
if(item && item->getInventoryType() == LLInventoryType::IT_GESTURE)
{
LL_DEBUGS("Gesture")<< "Copying gesture " << item->getName() << " "<< item->getUUID() << " into "
<< gesture_dir->getName() << " "<< gesture_dir->getUUID() << LL_ENDL;
copy_inventory_item(gAgent.getID(), item->getPermissions().getOwner(), item->getUUID(),
gesture_dir->getUUID(), getString("copy_name", string_args), cb);
}
}
clipbord.reset();
}
else if ("copy_uuid" == command_name)
{
gClipboard.copyFromString(utf8str_to_wstring(mGestureList->getCurrentID().asString()), mGestureList->getCurrentID());
}
}
void LLFloaterGesture::onClickEdit()
{
LLCtrlListInterface *list = childGetListInterface("gesture_list");
if (!list) return;
const LLUUID& item_id = list->getCurrentID();
const LLUUID& item_id = mGestureList->getCurrentID();
LLInventoryItem* item = gInventory.getItem(item_id);
if (!item) return;
@ -415,7 +540,7 @@ void LLFloaterGesture::onClickEdit()
void LLFloaterGesture::onCommitList()
{
const LLUUID& item_id = childGetValue("gesture_list").asUUID();
const LLUUID& item_id = mGestureList->getCurrentID();
mSelectedID = item_id;
if (LLGestureManager::instance().isGesturePlaying(item_id))
@ -429,8 +554,60 @@ void LLFloaterGesture::onCommitList()
childSetVisible("stop_btn", false);
}
}
void LLFloaterGesture::onDeleteSelected()
{
std::vector<LLUUID> ids;
getSelectedIds(ids);
if(ids.empty())
return;
const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
LLGestureManager* gm = LLGestureManager::getInstance();
for(std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); it++)
{
const LLUUID& selected_item = *it;
LLInventoryItem* inv_item = gInventory.getItem(selected_item);
if (inv_item && inv_item->getInventoryType() == LLInventoryType::IT_GESTURE)
{
if(gm->isGestureActive(selected_item))
{
gm->deactivateGesture(selected_item);
}
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate old_folder(inv_item->getParentUUID(), -1);
update.push_back(old_folder);
LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1);
update.push_back(new_folder);
gInventory.accountForUpdate(update);
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(inv_item);
new_item->setParent(trash_id);
// no need to restamp it though it's a move into trash because
// it's a brand new item already.
new_item->updateParentOnServer(FALSE);
gInventory.updateItem(new_item);
}
}
gInventory.notifyObservers();
buildGestureList();
}
void LLFloaterGesture::addToCurrentOutFit()
{
std::vector<LLUUID> ids;
getSelectedIds(ids);
LLAppearanceManager* am = LLAppearanceManager::getInstance();
for(std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); it++)
{
am->addCOFItemLink(*it);
}
}
void LLFloaterGesture::playGesture(LLUUID item_id)
{
LL_DEBUGS("Gesture")<<"Playing gesture "<< item_id<<LL_ENDL;
if (LLGestureManager::instance().isGesturePlaying(item_id))
{
LLGestureManager::instance().stopGesture(item_id);

View File

@ -36,11 +36,10 @@
#ifndef LL_LLFLOATERGESTURE_H
#define LL_LLFLOATERGESTURE_H
#include <vector>
#include "llfloater.h"
#include "llinventorymodel.h"
#include "llinventoryobserver.h"
#include "lldarray.h"
class LLScrollContainer;
class LLView;
@ -53,6 +52,7 @@ class LLScrollListCtrl;
class LLFloaterGestureObserver;
class LLFloaterGestureInventoryObserver;
class LLMultiGesture;
class LLMenuGL;
class LLFloaterGesture
: public LLFloater, LLInventoryFetchDescendentsObserver
@ -65,22 +65,46 @@ public:
virtual BOOL postBuild();
virtual void done ();
void refreshAll();
/**
* @brief Add new scrolllistitem into gesture_list.
* @param item_id inventory id of gesture
* @param gesture can be NULL , if item was not loaded yet
*/
void addGesture(const LLUUID& item_id, LLMultiGesture* gesture, LLCtrlListInterface * list);
protected:
// Reads from the gesture manager's list of active gestures
// and puts them in this list.
void buildGestureList();
void addGesture(const LLUUID& item_id, LLMultiGesture* gesture, LLCtrlListInterface * list);
void onClickInventory();
void playGesture(LLUUID item_id);
private:
void addToCurrentOutFit();
/**
* @brief This method is using to collect selected items.
* In some places gesture_list can be rebuilt by gestureObservers during iterating data from LLScrollListCtrl::getAllSelected().
* Therefore we have to copy these items to avoid viewer crash.
* @see LLFloaterGesture::onActivateBtnClick
*/
void getSelectedIds(std::vector<LLUUID>& ids);
bool isActionEnabled(const LLSD& command);
/**
* @brief Activation rules:
* According to Gesture Spec:
* 1. If all selected gestures are active: set to inactive
* 2. If all selected gestures are inactive: set to active
* 3. If selected gestures are in a mixed state: set all to active
*/
void onActivateBtnClick();
void onClickEdit();
void onClickPlay();
void onClickNew();
void onCommitList();
void playGesture(LLUUID item_id);
void onCopyPastAction(const LLSD& command);
void onDeleteSelected();
protected:
LLUUID mSelectedID;
LLUUID mGestureFolderID;
LLScrollListCtrl* mGestureList;
LLFloaterGestureObserver* mObserver;
};

View File

@ -415,7 +415,7 @@ LLPanelRegionTools::LLPanelRegionTools()
BOOL LLPanelRegionTools::postBuild()
{
getChild<LLLineEditor>("region name")->setKeystrokeCallback(onChangeSimName, this);
childSetPrevalidate("region name", &LLLineEditor::prevalidatePrintableNotPipe);
childSetPrevalidate("region name", &LLLineEditor::prevalidateASCIIPrintableNoPipe);
childSetPrevalidate("estate", &LLLineEditor::prevalidatePositiveS32);
childSetPrevalidate("parentestate", &LLLineEditor::prevalidatePositiveS32);
childDisable("parentestate");

View File

@ -327,7 +327,7 @@ void LLPanelGroups::startIM()
if (group_list && (group_id = group_list->getCurrentID()).notNull())
{
LLGroupActions::startChat(group_id);
LLGroupActions::startIM(group_id);
}
}

View File

@ -64,10 +64,7 @@ BOOL LLFloaterInventory::postBuild()
void LLFloaterInventory::draw()
{
if (LLInventoryModel::isEverythingFetched())
{
updateTitle();
}
updateTitle();
LLFloater::draw();
}
@ -85,10 +82,14 @@ void LLFloaterInventory::updateTitle()
{
setTitle(getString("TitleFetching", string_args));
}
else
else if (LLInventoryModel::isEverythingFetched())
{
setTitle(getString("TitleCompleted", string_args));
}
else
{
setTitle(getString("Title"));
}
}
void LLFloaterInventory::changed(U32 mask)

View File

@ -239,7 +239,7 @@ LLFloaterLand::LLFloaterLand(const LLSD& seed)
BOOL LLFloaterLand::postBuild()
{
mVisibleSignal.connect(boost::bind(&LLFloaterLand::onVisibilityChange, this, _2));
setVisibleCallback(boost::bind(&LLFloaterLand::onVisibilityChange, this, _2));
LLTabContainer* tab = getChild<LLTabContainer>("landtab");
@ -347,13 +347,14 @@ BOOL LLPanelLandGeneral::postBuild()
{
mEditName = getChild<LLLineEditor>("Name");
mEditName->setCommitCallback(onCommitAny, this);
childSetPrevalidate("Name", LLLineEditor::prevalidatePrintableNotPipe);
childSetPrevalidate("Name", LLLineEditor::prevalidateASCIIPrintableNoPipe);
mEditDesc = getChild<LLTextEditor>("Description");
mEditDesc->setCommitOnFocusLost(TRUE);
mEditDesc->setCommitCallback(onCommitAny, this);
childSetPrevalidate("Description", LLLineEditor::prevalidatePrintableNotPipe);
// No prevalidate function - historically the prevalidate function was broken,
// allowing residents to put in characters like U+2661 WHITE HEART SUIT, so
// preserve that ability.
mTextSalePending = getChild<LLTextBox>("SalePending");
mTextOwnerLabel = getChild<LLTextBox>("Owner:");

View File

@ -83,7 +83,6 @@ BOOL LLFloaterMap::postBuild()
{
mMap = getChild<LLNetMap>("Net Map");
mMap->setScale(gSavedSettings.getF32("MiniMapScale"));
mMap->setRotateMap(gSavedSettings.getBOOL( "MiniMapRotate" ));
mMap->setToolTipMsg(getString("ToolTipMsg"));
sendChildToBack(mMap);
@ -178,7 +177,8 @@ void LLFloaterMap::draw()
{
F32 rotation = 0;
if( mMap->getRotateMap() )
static LLUICachedControl<bool> rotate_map("MiniMapRotate", true);
if( rotate_map )
{
// rotate subsequent draws to agent rotation
rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );

View File

@ -111,7 +111,7 @@ BOOL LLFloaterNameDesc::postBuild()
if (NameEditor)
{
NameEditor->setMaxTextLength(DB_INV_ITEM_NAME_STR_LEN);
NameEditor->setPrevalidate(&LLLineEditor::prevalidatePrintableNotPipe);
NameEditor->setPrevalidate(&LLLineEditor::prevalidateASCIIPrintableNoPipe);
}
y -= llfloor(PREVIEW_LINE_HEIGHT * 1.2f);
@ -123,7 +123,7 @@ BOOL LLFloaterNameDesc::postBuild()
if (DescEditor)
{
DescEditor->setMaxTextLength(DB_INV_ITEM_DESC_STR_LEN);
DescEditor->setPrevalidate(&LLLineEditor::prevalidatePrintableNotPipe);
DescEditor->setPrevalidate(&LLLineEditor::prevalidateASCIIPrintableNoPipe);
}
y -= llfloor(PREVIEW_LINE_HEIGHT * 1.2f);

View File

@ -56,6 +56,7 @@
#include "llfloaterabout.h"
#include "llfloaterhardwaresettings.h"
#include "llfloatervoicedevicesettings.h"
#include "llimfloater.h"
#include "llkeyboard.h"
#include "llmodaldialog.h"
#include "llnavigationbar.h"
@ -164,7 +165,6 @@ BOOL LLVoiceSetKeyDialog::handleKeyHere(KEY key, MASK mask)
{
mParent->setKey(key);
}
closeFloater();
return result;
}
@ -310,7 +310,8 @@ F32 LLFloaterPreference::sAspectRatio = 0.0;
LLFloaterPreference::LLFloaterPreference(const LLSD& key)
: LLFloater(key),
mGotPersonalInfo(false),
mOriginalIMViaEmail(false)
mOriginalIMViaEmail(false),
mCancelOnClose(true)
{
//Build Floater is now Called from LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
@ -338,7 +339,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.ClickEnablePopup", boost::bind(&LLFloaterPreference::onClickEnablePopup, this));
mCommitCallbackRegistrar.add("Pref.ClickDisablePopup", boost::bind(&LLFloaterPreference::onClickDisablePopup, this));
mCommitCallbackRegistrar.add("Pref.LogPath", boost::bind(&LLFloaterPreference::onClickLogPath, this));
mCommitCallbackRegistrar.add("Pref.Logging", boost::bind(&LLFloaterPreference::onCommitLogging, this));
mCommitCallbackRegistrar.add("Pref.UpdateMeterText", boost::bind(&LLFloaterPreference::updateMeterText, this, _1));
mCommitCallbackRegistrar.add("Pref.HardwareSettings", boost::bind(&LLFloaterPreference::onOpenHardwareSettings, this));
mCommitCallbackRegistrar.add("Pref.HardwareDefaults", boost::bind(&LLFloaterPreference::setHardwareDefaults, this));
@ -358,6 +358,8 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
BOOL LLFloaterPreference::postBuild()
{
gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2));
LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab")))
tabcontainer->selectFirstTab();
@ -391,6 +393,20 @@ void LLFloaterPreference::draw()
LLFloater::draw();
}
void LLFloaterPreference::saveSettings()
{
LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
child_list_t::const_iterator end = tabcontainer->getChildList()->end();
for ( ; iter != end; ++iter)
{
LLView* view = *iter;
LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
if (panel)
panel->saveSettings();
}
}
void LLFloaterPreference::apply()
{
LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
@ -445,6 +461,8 @@ void LLFloaterPreference::apply()
// LLWString busy_response = utf8str_to_wstring(getChild<LLUICtrl>("busy_response")->getValue().asString());
// LLWStringUtil::replaceTabsWithSpaces(busy_response, 4);
gSavedSettings.setBOOL("PlainTextChatHistory", childGetValue("plain_text_chat_history").asBoolean());
if(mGotPersonalInfo)
{
@ -552,6 +570,11 @@ void LLFloaterPreference::onOpen(const LLSD& key)
LLPanelLogin::setAlwaysRefresh(true);
refresh();
// Make sure the current state of prefs are saved away when
// when the floater is opened. That will make cancel do its
// job
saveSettings();
}
void LLFloaterPreference::onVertexShaderEnable()
@ -570,7 +593,7 @@ void LLFloaterPreference::onClose(bool app_quitting)
{
gSavedSettings.setS32("LastPrefTab", getChild<LLTabContainer>("pref core")->getCurrentPanelIndex());
LLPanelLogin::setAlwaysRefresh(false);
cancel(); // will be a no-op if OK or apply was performed just prior.
if (mCancelOnClose) cancel();
}
void LLFloaterPreference::onOpenHardwareSettings()
@ -593,7 +616,11 @@ void LLFloaterPreference::onBtnOK()
if (canClose())
{
apply();
// Here we do not want to cancel on close, so we do this funny thing
// that prevents cancel from undoing our changes when we hit OK
mCancelOnClose = false;
closeFloater(false);
mCancelOnClose = true;
gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
LLUIColorTable::instance().saveUserSettings();
std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
@ -621,6 +648,7 @@ void LLFloaterPreference::onBtnApply( )
}
}
apply();
saveSettings();
LLPanelLogin::refreshLocation( false );
}
@ -637,7 +665,8 @@ void LLFloaterPreference::onBtnCancel()
}
refresh();
}
closeFloater(); // side effect will also cancel any unsaved changes.
cancel();
closeFloater();
}
// static
@ -1133,27 +1162,6 @@ void LLFloaterPreference::onClickLogPath()
gSavedPerAccountSettings.setString("InstantMessageLogFolder",chat_log_top_folder);
}
void LLFloaterPreference::onCommitLogging()
{
enableHistory();
}
void LLFloaterPreference::enableHistory()
{
if (childGetValue("log_instant_messages").asBoolean())
{
childEnable("ChatIMLogs");
childEnable("log_path_button");
childEnable("show_timestamps_check_im");
}
else
{
childDisable("ChatIMLogs");
childDisable("log_path_button");
childDisable("show_timestamps_check_im");
}
}
void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email)
{
mGotPersonalInfo = true;
@ -1183,6 +1191,8 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im
childSetLabelArg("online_visibility", "[DIR_VIS]", mDirectoryVisibility);
childEnable("send_im_to_email");
childSetValue("send_im_to_email", im_via_email);
childEnable("plain_text_chat_history");
childSetValue("plain_text_chat_history", gSavedSettings.getBOOL("PlainTextChatHistory"));
childEnable("log_instant_messages");
// childEnable("log_chat");
// childEnable("busy_response");
@ -1193,7 +1203,12 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im
// childSetText("busy_response", gSavedSettings.getString("BusyModeResponse2"));
enableHistory();
childEnable("log_nearby_chat");
childEnable("log_instant_messages");
childEnable("show_timestamps_check_im");
childEnable("log_path_string");
childEnable("log_path_button");
std::string display_email(email);
childSetText("email_address",display_email);
@ -1509,6 +1524,11 @@ BOOL LLPanelPreference::postBuild()
}
void LLPanelPreference::apply()
{
// no-op
}
void LLPanelPreference::saveSettings()
{
// Save the value of all controls in the hierarchy
mSavedValues.clear();

Some files were not shown because too many files have changed in this diff Show More