merge snowstorm repo
commit
6007d1235e
1
.hgtags
1
.hgtags
|
|
@ -480,3 +480,4 @@ fe4f7c5e9fd27e09d03deb1cc9ab3e5093f6309e 3.6.3-release
|
|||
83357f31d8dbf048a8bfdc323f363bf4d588aca1 CHOP-951-a
|
||||
91ed595b716f14f07409595b734fda891a59379e 3.6.4-release
|
||||
bf6d453046011a11de2643fac610cc5258650f82 3.6.5-release
|
||||
ae457ece77001767ae9613148c495e7b98cc0f4a 3.6.7-release
|
||||
|
|
|
|||
15
BuildParams
15
BuildParams
|
|
@ -27,9 +27,6 @@ Linux.distcc_version =
|
|||
Linux.gcc_version = /usr/bin/gcc-4.6
|
||||
Linux.cxx_version = /usr/bin/g++-4.6
|
||||
|
||||
# Setup default sourceid so Windows can pick up the TeamCity override
|
||||
sourceid = ""
|
||||
|
||||
################################################################
|
||||
#### Examples of how to set the viewer_channel ####
|
||||
#
|
||||
|
|
@ -50,6 +47,18 @@ sourceid = ""
|
|||
################################################################
|
||||
viewer_channel = "Second Life Test"
|
||||
|
||||
# Setup default packaging parameters.
|
||||
sourceid = ""
|
||||
additional_packages = "Amazon Desura B C"
|
||||
Amazon_sourceid = "1207v_Amazon"
|
||||
Amazon_viewer_channel_suffix = " Amazon"
|
||||
Desura_sourceid = "1208_desura"
|
||||
Desura_viewer_channel_suffix = " Desura"
|
||||
B_sourceid = "1301_B"
|
||||
B_viewer_channel_suffix = " B"
|
||||
C_sourceid = "1302_C"
|
||||
C_viewer_channel_suffix = " C"
|
||||
|
||||
# Report changes since...
|
||||
viewer-development.show_changes_since = last_sprint
|
||||
|
||||
|
|
|
|||
28
build.sh
28
build.sh
|
|
@ -38,22 +38,22 @@ build_dir_CYGWIN()
|
|||
|
||||
installer_Darwin()
|
||||
{
|
||||
ls -1td "$(build_dir_Darwin ${last_built_variant:-Release})/newview/"*.dmg 2>/dev/null | sed 1q
|
||||
ls -1tr "$(build_dir_Darwin ${last_built_variant:-Release})/newview/"*"$additional_package_name"*.dmg 2>/dev/null | sed 1q
|
||||
}
|
||||
|
||||
installer_Linux()
|
||||
{
|
||||
ls -1td "$(build_dir_Linux ${last_built_variant:-Release})/newview/"*.tar.bz2 2>/dev/null | sed 1q
|
||||
ls -1tr "$(build_dir_Linux ${last_built_variant:-Release})/newview/"*"$additional_package_name"*.tar.bz2 2>/dev/null | grep -v symbols | sed 1q
|
||||
}
|
||||
|
||||
installer_CYGWIN()
|
||||
{
|
||||
v=${last_built_variant:-Release}
|
||||
d=$(build_dir_CYGWIN $v)
|
||||
if [ -r "$d/newview/$v/touched.bat" ]
|
||||
if [ -r "$d/newview/$additional_package_name$v/touched.bat" ]
|
||||
then
|
||||
p=$(sed 's:.*=::' "$d/newview/$v/touched.bat")
|
||||
echo "$d/newview/$v/$p"
|
||||
p=$(sed 's:.*=::' "$d/newview/$additional_package_name$v/touched.bat")
|
||||
echo "$d/newview/$additional_package_name$v/$p"
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
@ -367,10 +367,28 @@ then
|
|||
# Coverity doesn't package, so it's ok, anything else is fail
|
||||
succeeded=$build_coverity
|
||||
else
|
||||
# Upload base package.
|
||||
upload_item installer "$package" binary/octet-stream
|
||||
upload_item quicklink "$package" binary/octet-stream
|
||||
[ -f $build_dir/summary.json ] && upload_item installer $build_dir/summary.json text/plain
|
||||
|
||||
# Upload additional packages.
|
||||
for package_id in $additional_packages
|
||||
do
|
||||
case $arch in
|
||||
CYGWIN) export additional_package_name="$package_id/" ;;
|
||||
*) export additional_package_name=$package_id ;;
|
||||
esac
|
||||
package=$(installer_$arch)
|
||||
if [ x"$package" != x ]
|
||||
then
|
||||
upload_item installer "$package" binary/octet-stream
|
||||
else
|
||||
record_failure "Failed to upload $package_id package."
|
||||
fi
|
||||
done
|
||||
export additional_package_name=""
|
||||
|
||||
case "$last_built_variant" in
|
||||
Release)
|
||||
# Upload crash reporter files
|
||||
|
|
|
|||
|
|
@ -175,8 +175,11 @@ Ansariel Hiller
|
|||
STORM-1685
|
||||
STORM-1713
|
||||
STORM-1899
|
||||
STORM-1932
|
||||
STORM-1933
|
||||
MAINT-2368
|
||||
STORM-1931
|
||||
MAINT-2773
|
||||
Aralara Rajal
|
||||
Arare Chantilly
|
||||
CHUIBUG-191
|
||||
|
|
@ -304,9 +307,13 @@ Christopher Organiser
|
|||
Ciaran Laval
|
||||
Cinder Roxley
|
||||
BUG-2326
|
||||
OPEN-185
|
||||
STORM-1703
|
||||
STORM-1948
|
||||
STORM-1888
|
||||
STORM-1958
|
||||
STORM-1952
|
||||
STORM-1951
|
||||
Clara Young
|
||||
Coaldust Numbers
|
||||
VWR-1095
|
||||
|
|
@ -653,7 +660,7 @@ Jonathan Yap
|
|||
STORM-1809
|
||||
STORM-1793
|
||||
STORM-1810
|
||||
STORM-1877
|
||||
STORM-1838
|
||||
STORM-1892
|
||||
STORM-1894
|
||||
STORM-1860
|
||||
|
|
@ -663,8 +670,11 @@ Jonathan Yap
|
|||
STORM-1858
|
||||
STORM-1862
|
||||
STORM-1918
|
||||
STORM-1929
|
||||
STORM-1953
|
||||
OPEN-161
|
||||
STORM-1953
|
||||
STORM-1957
|
||||
Kadah Coba
|
||||
STORM-1060
|
||||
STORM-1843
|
||||
|
|
@ -680,6 +690,7 @@ Kagehi Kohn
|
|||
Kaimen Takahe
|
||||
Katharine Berry
|
||||
STORM-1900
|
||||
OPEN-149
|
||||
STORM-1940
|
||||
STORM-1941
|
||||
Keklily Longfall
|
||||
|
|
@ -929,6 +940,7 @@ Nicky Dasmijn
|
|||
STORM-1936
|
||||
BUG-3605
|
||||
CHUIBUG-197
|
||||
OPEN-187
|
||||
STORM-1937
|
||||
Nicky Perian
|
||||
OPEN-1
|
||||
|
|
@ -1298,6 +1310,7 @@ Westley Streeter
|
|||
Whimsy Winx
|
||||
Whirly Fizzle
|
||||
STORM-1895
|
||||
VWR-29543
|
||||
MAINT-873
|
||||
STORM-1930
|
||||
Whoops Babii
|
||||
|
|
@ -1361,6 +1374,7 @@ YongYong Francois
|
|||
Zak Westminster
|
||||
Zai Lynch
|
||||
VWR-19505
|
||||
STORM-1902
|
||||
Zana Kohime
|
||||
Zaren Alexander
|
||||
Zarkonnen Decosta
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
|
|||
|
||||
else (DEFINED ENV{revision})
|
||||
find_program(MERCURIAL hg)
|
||||
if (DEFINED MERCURIAL)
|
||||
find_program(WORDCOUNT wc)
|
||||
find_program(SED sed)
|
||||
if (DEFINED MERCURIAL AND DEFINED WORDCOUNT AND DEFINED SED)
|
||||
execute_process(
|
||||
# <FS:TS> FIRE-11737: Reverting to old revisions shows tip in build string
|
||||
# This command gets the revision number of the current
|
||||
|
|
@ -24,7 +26,9 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
|
|||
# building an earlier revision. Instead, we use
|
||||
# "hg identify -n" to get the local revision number
|
||||
# of the actual state of the repository.
|
||||
#COMMAND ${MERCURIAL} log -r tip --template "{rev}"
|
||||
#COMMAND ${MERCURIAL} log -r tip:0 --template '\\n'
|
||||
#COMMAND ${WORDCOUNT} -l
|
||||
#COMMAND ${SED} "s/ //g"
|
||||
COMMAND ${MERCURIAL} identify -n
|
||||
OUTPUT_VARIABLE VIEWER_VERSION_REVISION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
|
|
@ -36,13 +40,13 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
|
|||
if ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
|
||||
message("Revision (from hg) ${VIEWER_VERSION_REVISION}")
|
||||
else ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
|
||||
message("Revision not set (repository not found?); using 0")
|
||||
set(VIEWER_VERSION_REVISION 0 )
|
||||
message("Revision not set, repository not found, using ${VIEWER_VERSION_REVISION}")
|
||||
endif ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
|
||||
else (DEFINED MERCURIAL)
|
||||
else (DEFINED MERCURIAL AND DEFINED WORDCOUNT AND DEFINED SED)
|
||||
message("Revision not set: 'hg', 'wc' or 'sed' not found; using 0")
|
||||
set(VIEWER_VERSION_REVISION 0)
|
||||
message("Revision not set, 'hg' not found (${MERCURIAL}), using ${VIEWER_VERSION_REVISION}")
|
||||
endif (DEFINED MERCURIAL)
|
||||
endif (DEFINED MERCURIAL AND DEFINED WORDCOUNT AND DEFINED SED)
|
||||
endif (DEFINED ENV{revision})
|
||||
message("Building '${VIEWER_CHANNEL}' Version ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
|
||||
else ( EXISTS ${VIEWER_VERSION_BASE_FILE} )
|
||||
|
|
|
|||
|
|
@ -229,15 +229,98 @@ def main():
|
|||
for opt in args:
|
||||
print "Option:", opt, "=", args[opt]
|
||||
|
||||
# pass in sourceid as an argument now instead of an environment variable
|
||||
try:
|
||||
args['sourceid'] = os.environ["sourceid"]
|
||||
except KeyError:
|
||||
args['sourceid'] = ""
|
||||
|
||||
# Build base package.
|
||||
touch = args.get('touch')
|
||||
if touch:
|
||||
print 'Creating base package'
|
||||
args['package_id'] = "" # base package has no package ID
|
||||
wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
|
||||
wm.do(*args['actions'])
|
||||
# Store package file for later if making touched file.
|
||||
base_package_file = ""
|
||||
if touch:
|
||||
print 'Created base package ', wm.package_file
|
||||
base_package_file = "" + wm.package_file
|
||||
|
||||
# handle multiple packages if set
|
||||
try:
|
||||
additional_packages = os.environ["additional_packages"]
|
||||
except KeyError:
|
||||
additional_packages = ""
|
||||
if additional_packages:
|
||||
# Determine destination prefix / suffix for additional packages.
|
||||
base_dest_postfix = args['dest']
|
||||
base_dest_prefix = ""
|
||||
base_dest_parts = args['dest'].split(os.sep)
|
||||
if len(base_dest_parts) > 1:
|
||||
base_dest_postfix = base_dest_parts[len(base_dest_parts) - 1]
|
||||
base_dest_prefix = base_dest_parts[0]
|
||||
i = 1
|
||||
while i < len(base_dest_parts) - 1:
|
||||
base_dest_prefix = base_dest_prefix + os.sep + base_dest_parts[i]
|
||||
i = i + 1
|
||||
# Determine touched prefix / suffix for additional packages.
|
||||
base_touch_postfix = ""
|
||||
base_touch_prefix = ""
|
||||
if touch:
|
||||
base_touch_postfix = touch
|
||||
base_touch_parts = touch.split('/')
|
||||
if "arwin" in args['platform']:
|
||||
if len(base_touch_parts) > 1:
|
||||
base_touch_postfix = base_touch_parts[len(base_touch_parts) - 1]
|
||||
base_touch_prefix = base_touch_parts[0]
|
||||
i = 1
|
||||
while i < len(base_touch_parts) - 1:
|
||||
base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i]
|
||||
i = i + 1
|
||||
else:
|
||||
if len(base_touch_parts) > 2:
|
||||
base_touch_postfix = base_touch_parts[len(base_touch_parts) - 2] + '/' + base_touch_parts[len(base_touch_parts) - 1]
|
||||
base_touch_prefix = base_touch_parts[0]
|
||||
i = 1
|
||||
while i < len(base_touch_parts) - 2:
|
||||
base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i]
|
||||
i = i + 1
|
||||
# Store base channel name.
|
||||
base_channel_name = args['channel']
|
||||
# Build each additional package.
|
||||
package_id_list = additional_packages.split(" ")
|
||||
for package_id in package_id_list:
|
||||
try:
|
||||
args['package_id'] = package_id
|
||||
args['channel'] = base_channel_name + os.environ[package_id + "_viewer_channel_suffix"]
|
||||
if package_id + "_sourceid" in os.environ:
|
||||
args['sourceid'] = os.environ[package_id + "_sourceid"]
|
||||
else:
|
||||
args['sourceid'] = ""
|
||||
args['dest'] = base_dest_prefix + os.sep + package_id + os.sep + base_dest_postfix
|
||||
except KeyError:
|
||||
sys.stderr.write("Failed to create package for package_id: %s" % package_id)
|
||||
sys.stderr.flush()
|
||||
continue
|
||||
if touch:
|
||||
print 'Creating additional package for ', package_id, ' in ', args['dest']
|
||||
wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
|
||||
wm.do(*args['actions'])
|
||||
if touch:
|
||||
print 'Created additional package ', wm.package_file, ' for ', package_id
|
||||
faketouch = base_touch_prefix + '/' + package_id + '/' + base_touch_postfix
|
||||
fp = open(faketouch, 'w')
|
||||
fp.write('set package_file=%s\n' % wm.package_file)
|
||||
fp.close()
|
||||
|
||||
# Write out the package file in this format, so that it can easily be called
|
||||
# and used in a .bat file - yeah, it sucks, but this is the simplest...
|
||||
touch = args.get('touch')
|
||||
if touch:
|
||||
fp = open(touch, 'w')
|
||||
fp.write('set package_file=%s\n' % wm.package_file)
|
||||
fp.write('set package_file=%s\n' % base_package_file)
|
||||
fp.close()
|
||||
print 'touched', touch
|
||||
return 0
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ class LLColor4
|
|||
LLColor4(F32 r, F32 g, F32 b); // Initializes LLColor4 to (r, g, b, 1)
|
||||
LLColor4(F32 r, F32 g, F32 b, F32 a); // Initializes LLColor4 to (r. g, b, a)
|
||||
LLColor4(U32 clr); // Initializes LLColor4 to (r=clr>>24, etc))
|
||||
LLColor4(const F32 *vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1)
|
||||
LLColor4(const F32 *vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], vec[3])
|
||||
LLColor4(const LLColor3 &vec, F32 a = 1.f); // Initializes LLColor4 to (vec, a)
|
||||
explicit LLColor4(const LLSD& sd);
|
||||
explicit LLColor4(const LLColor4U& color4u); // "explicit" to avoid automatic conversion
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ enum EInstantMessage
|
|||
IM_LURE_ACCEPTED = 23,
|
||||
IM_LURE_DECLINED = 24,
|
||||
IM_GODLIKE_LURE_USER = 25,
|
||||
IM_YET_TO_BE_USED = 26,
|
||||
IM_TELEPORT_REQUEST = 26,
|
||||
|
||||
// IM that notifie of a new group election.
|
||||
// Name is name of person who called vote.
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ set(llui_SOURCE_FILES
|
|||
llmultislider.cpp
|
||||
llmultisliderctrl.cpp
|
||||
llnotifications.cpp
|
||||
llnotificationslistener.cpp
|
||||
llnotificationsutil.cpp
|
||||
llpanel.cpp
|
||||
llprogressbar.cpp
|
||||
|
|
@ -132,6 +133,7 @@ set(llui_SOURCE_FILES
|
|||
llviewmodel.cpp
|
||||
llview.cpp
|
||||
llviewquery.cpp
|
||||
llviewereventrecorder.cpp
|
||||
llwindowshade.cpp
|
||||
llxuiparser.cpp
|
||||
)
|
||||
|
|
@ -189,6 +191,7 @@ set(llui_HEADER_FILES
|
|||
llmultislider.h
|
||||
llnotificationptr.h
|
||||
llnotifications.h
|
||||
llnotificationslistener.h
|
||||
llnotificationsutil.h
|
||||
llnotificationtemplate.h
|
||||
llnotificationvisibilityrule.h
|
||||
|
|
@ -246,6 +249,7 @@ set(llui_HEADER_FILES
|
|||
llviewinject.h
|
||||
llviewmodel.h
|
||||
llview.h
|
||||
llviewereventrecorder.h
|
||||
llviewquery.h
|
||||
llwindowshade.h
|
||||
llxuiparser.h
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "lluictrlfactory.h"
|
||||
#include "llhelp.h"
|
||||
#include "lldockablefloater.h"
|
||||
#include "llviewereventrecorder.h"
|
||||
|
||||
#include "llcheckboxctrl.h" // <FS:Zi> Add checkbox control toggle
|
||||
|
||||
|
|
@ -479,6 +480,8 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
*/
|
||||
LLUICtrl::handleMouseDown(x, y, mask);
|
||||
|
||||
LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
|
||||
|
||||
if(mMouseDownSignal) (*mMouseDownSignal)(this, LLSD());
|
||||
|
||||
mMouseDownTimer.start();
|
||||
|
|
@ -509,6 +512,7 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
|
|||
* by calling LLUICtrl::mMouseUpSignal(x, y, mask);
|
||||
*/
|
||||
LLUICtrl::handleMouseUp(x, y, mask);
|
||||
LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
|
||||
|
||||
// Regardless of where mouseup occurs, handle callback
|
||||
if(mMouseUpSignal) (*mMouseUpSignal)(this, LLSD());
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
// mini-map floater, etc.
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llviewereventrecorder.h"
|
||||
#include "llfloater.h"
|
||||
|
||||
#include "llfocusmgr.h"
|
||||
|
|
@ -671,7 +671,10 @@ void LLFloater::handleVisibilityChange ( BOOL new_visibility )
|
|||
|
||||
void LLFloater::openFloater(const LLSD& key)
|
||||
{
|
||||
llinfos << "Opening floater " << getName() << llendl;
|
||||
llinfos << "Opening floater " << getName() << " full path: " << getPathname() << llendl;
|
||||
|
||||
LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), true,"floater"); // Last param is event subtype or empty string
|
||||
|
||||
mKey = key; // in case we need to open ourselves again
|
||||
|
||||
if (getSoundFlags() != SILENT
|
||||
|
|
@ -741,6 +744,7 @@ void LLFloater::openFloater(const LLSD& key)
|
|||
void LLFloater::closeFloater(bool app_quitting)
|
||||
{
|
||||
llinfos << "Closing floater " << getName() << llendl;
|
||||
LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), false,"floater"); // Last param is event subtype or empty string
|
||||
if (app_quitting)
|
||||
{
|
||||
LLFloater::sQuitting = true;
|
||||
|
|
@ -1607,6 +1611,17 @@ BOOL LLFloater::handleScrollWheel(S32 x, S32 y, S32 clicks)
|
|||
return TRUE;//always
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLFloater::handleMouseUp(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
lldebugs << "LLFloater::handleMouseUp calling LLPanel (really LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << llendl;
|
||||
BOOL handled = LLPanel::handleMouseUp(x,y,mask); // Not implemented in LLPanel so this actually calls LLView
|
||||
if (handled) {
|
||||
LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
|
|
@ -1627,7 +1642,11 @@ BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
else
|
||||
{
|
||||
bringToFront( x, y );
|
||||
return LLPanel::handleMouseDown( x, y, mask );
|
||||
BOOL handled = LLPanel::handleMouseDown( x, y, mask );
|
||||
if (handled) {
|
||||
LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -291,6 +291,7 @@ public:
|
|||
S32 getHeaderHeight() const { return mHeaderHeight; }
|
||||
|
||||
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
|
||||
|
|
|
|||
|
|
@ -1214,6 +1214,7 @@ LLNotifications::LLNotifications()
|
|||
: LLNotificationChannelBase(LLNotificationFilters::includeEverything),
|
||||
mIgnoreAllNotifications(false)
|
||||
{
|
||||
mListener.reset(new LLNotificationsListener(*this));
|
||||
LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,8 @@
|
|||
#include "llrefcount.h"
|
||||
#include "llsdparam.h"
|
||||
|
||||
#include "llnotificationslistener.h"
|
||||
|
||||
class LLAvatarName;
|
||||
typedef enum e_notification_priority
|
||||
{
|
||||
|
|
@ -983,6 +985,8 @@ private:
|
|||
|
||||
bool mIgnoreAllNotifications;
|
||||
|
||||
boost::scoped_ptr<LLNotificationsListener> mListener;
|
||||
|
||||
std::vector<LLNotificationChannelPtr> mDefaultChannels;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,359 @@
|
|||
/**
|
||||
* @file llnotificationslistener.cpp
|
||||
* @author Brad Kittenbrink
|
||||
* @date 2009-07-08
|
||||
* @brief Implementation for llnotificationslistener.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llnotificationslistener.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llnotificationtemplate.h"
|
||||
#include "llsd.h"
|
||||
#include "llui.h"
|
||||
|
||||
LLNotificationsListener::LLNotificationsListener(LLNotifications & notifications) :
|
||||
LLEventAPI("LLNotifications",
|
||||
"LLNotifications listener to (e.g.) pop up a notification"),
|
||||
mNotifications(notifications)
|
||||
{
|
||||
add("requestAdd",
|
||||
"Add a notification with specified [\"name\"], [\"substitutions\"] and [\"payload\"].\n"
|
||||
"If optional [\"reply\"] specified, arrange to send user response on that LLEventPump.",
|
||||
&LLNotificationsListener::requestAdd);
|
||||
/* add("listChannels",
|
||||
"Post to [\"reply\"] a map of info on existing channels",
|
||||
&LLNotificationsListener::listChannels,
|
||||
LLSD().with("reply", LLSD()));
|
||||
*/
|
||||
add("listChannelNotifications",
|
||||
"Post to [\"reply\"] an array of info on notifications in channel [\"channel\"]",
|
||||
&LLNotificationsListener::listChannelNotifications,
|
||||
LLSD().with("reply", LLSD()).with("channel", LLSD()));
|
||||
add("respond",
|
||||
"Respond to notification [\"uuid\"] with data in [\"response\"]",
|
||||
&LLNotificationsListener::respond,
|
||||
LLSD().with("uuid", LLSD()));
|
||||
add("cancel",
|
||||
"Cancel notification [\"uuid\"]",
|
||||
&LLNotificationsListener::cancel,
|
||||
LLSD().with("uuid", LLSD()));
|
||||
add("ignore",
|
||||
"Ignore future notification [\"name\"]\n"
|
||||
"(from <notification name= > in notifications.xml)\n"
|
||||
"according to boolean [\"ignore\"].\n"
|
||||
"If [\"name\"] is omitted or undefined, [un]ignore all future notifications.\n"
|
||||
"Note that ignored notifications are not forwarded unless intercepted before\n"
|
||||
"the \"Ignore\" channel.",
|
||||
&LLNotificationsListener::ignore);
|
||||
add("forward",
|
||||
"Forward to [\"pump\"] future notifications on channel [\"channel\"]\n"
|
||||
"according to boolean [\"forward\"]. When enabled, only types matching\n"
|
||||
"[\"types\"] are forwarded, as follows:\n"
|
||||
"omitted or undefined: forward all notifications\n"
|
||||
"string: forward only the specific named [sig]type\n"
|
||||
"array of string: forward any notification matching any named [sig]type.\n"
|
||||
"When boolean [\"respond\"] is true, we auto-respond to each forwarded\n"
|
||||
"notification.",
|
||||
&LLNotificationsListener::forward,
|
||||
LLSD().with("channel", LLSD()));
|
||||
}
|
||||
|
||||
// This is here in the .cpp file so we don't need the definition of class
|
||||
// Forwarder in the header file.
|
||||
LLNotificationsListener::~LLNotificationsListener()
|
||||
{
|
||||
}
|
||||
|
||||
void LLNotificationsListener::requestAdd(const LLSD& event_data) const
|
||||
{
|
||||
if(event_data.has("reply"))
|
||||
{
|
||||
mNotifications.add(event_data["name"],
|
||||
event_data["substitutions"],
|
||||
event_data["payload"],
|
||||
boost::bind(&LLNotificationsListener::NotificationResponder,
|
||||
this,
|
||||
event_data["reply"].asString(),
|
||||
_1, _2
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
mNotifications.add(event_data["name"],
|
||||
event_data["substitutions"],
|
||||
event_data["payload"]);
|
||||
}
|
||||
}
|
||||
|
||||
void LLNotificationsListener::NotificationResponder(const std::string& reply_pump,
|
||||
const LLSD& notification,
|
||||
const LLSD& response) const
|
||||
{
|
||||
LLSD reponse_event;
|
||||
reponse_event["notification"] = notification;
|
||||
reponse_event["response"] = response;
|
||||
LLEventPumps::getInstance()->obtain(reply_pump).post(reponse_event);
|
||||
}
|
||||
/*
|
||||
void LLNotificationsListener::listChannels(const LLSD& params) const
|
||||
{
|
||||
LLReqID reqID(params);
|
||||
LLSD response(reqID.makeResponse());
|
||||
for (LLNotifications::
|
||||
|
||||
|
||||
|
||||
for (LLNotifications::ChannelMap::const_iterator cmi(mNotifications.mChannels.begin()),
|
||||
cmend(mNotifications.mChannels.end());
|
||||
cmi != cmend; ++cmi)
|
||||
{
|
||||
LLSD channelInfo;
|
||||
channelInfo["parent"] = cmi->second->getParentChannelName();
|
||||
response[cmi->first] = channelInfo;
|
||||
}
|
||||
LLEventPumps::instance().obtain(params["reply"]).post(response);
|
||||
}
|
||||
*/
|
||||
void LLNotificationsListener::listChannelNotifications(const LLSD& params) const
|
||||
{
|
||||
LLReqID reqID(params);
|
||||
LLSD response(reqID.makeResponse());
|
||||
LLNotificationChannelPtr channel(mNotifications.getChannel(params["channel"]));
|
||||
if (channel)
|
||||
{
|
||||
LLSD notifications(LLSD::emptyArray());
|
||||
for (LLNotificationChannel::Iterator ni(channel->begin()), nend(channel->end());
|
||||
ni != nend; ++ni)
|
||||
{
|
||||
notifications.append(asLLSD(*ni));
|
||||
}
|
||||
response["notifications"] = notifications;
|
||||
}
|
||||
LLEventPumps::instance().obtain(params["reply"]).post(response);
|
||||
}
|
||||
|
||||
void LLNotificationsListener::respond(const LLSD& params) const
|
||||
{
|
||||
LLNotificationPtr notification(mNotifications.find(params["uuid"]));
|
||||
if (notification)
|
||||
{
|
||||
notification->respond(params["response"]);
|
||||
}
|
||||
}
|
||||
|
||||
void LLNotificationsListener::cancel(const LLSD& params) const
|
||||
{
|
||||
LLNotificationPtr notification(mNotifications.find(params["uuid"]));
|
||||
if (notification)
|
||||
{
|
||||
mNotifications.cancel(notification);
|
||||
}
|
||||
}
|
||||
|
||||
void LLNotificationsListener::ignore(const LLSD& params) const
|
||||
{
|
||||
// Calling a method named "ignore", but omitting its "ignore" Boolean
|
||||
// argument, should by default cause something to be ignored. Explicitly
|
||||
// pass ["ignore"] = false to cancel ignore.
|
||||
bool ignore = true;
|
||||
if (params.has("ignore"))
|
||||
{
|
||||
ignore = params["ignore"].asBoolean();
|
||||
}
|
||||
// This method can be used to affect either a single notification name or
|
||||
// all future notifications. The two use substantially different mechanisms.
|
||||
if (params["name"].isDefined())
|
||||
{
|
||||
// ["name"] was passed: ignore just that notification
|
||||
LLNotificationTemplatePtr templatep = mNotifications.getTemplate(params["name"]);
|
||||
if (templatep)
|
||||
{
|
||||
templatep->mForm->setIgnored(ignore);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no ["name"]: ignore all future notifications
|
||||
mNotifications.setIgnoreAllNotifications(ignore);
|
||||
}
|
||||
}
|
||||
|
||||
class LLNotificationsListener::Forwarder: public LLEventTrackable
|
||||
{
|
||||
LOG_CLASS(LLNotificationsListener::Forwarder);
|
||||
public:
|
||||
Forwarder(LLNotifications& llnotifications, const std::string& channel):
|
||||
mNotifications(llnotifications),
|
||||
mRespond(false)
|
||||
{
|
||||
// Connect to the specified channel on construction. Because
|
||||
// LLEventTrackable is a base, we should automatically disconnect when
|
||||
// destroyed.
|
||||
LLNotificationChannelPtr channelptr(llnotifications.getChannel(channel));
|
||||
if (channelptr)
|
||||
{
|
||||
// Insert our processing as a "passed filter" listener. This way
|
||||
// we get to run before all the "changed" listeners, and we get to
|
||||
// swipe it (hide it from the other listeners) if desired.
|
||||
channelptr->connectPassedFilter(boost::bind(&Forwarder::handle, this, _1));
|
||||
}
|
||||
}
|
||||
|
||||
void setPumpName(const std::string& name) { mPumpName = name; }
|
||||
void setTypes(const LLSD& types) { mTypes = types; }
|
||||
void setRespond(bool respond) { mRespond = respond; }
|
||||
|
||||
private:
|
||||
bool handle(const LLSD& notification) const;
|
||||
bool matchType(const LLSD& filter, const std::string& type) const;
|
||||
|
||||
LLNotifications& mNotifications;
|
||||
std::string mPumpName;
|
||||
LLSD mTypes;
|
||||
bool mRespond;
|
||||
};
|
||||
|
||||
void LLNotificationsListener::forward(const LLSD& params)
|
||||
{
|
||||
std::string channel(params["channel"]);
|
||||
// First decide whether we're supposed to start forwarding or stop it.
|
||||
// Default to true.
|
||||
bool forward = true;
|
||||
if (params.has("forward"))
|
||||
{
|
||||
forward = params["forward"].asBoolean();
|
||||
}
|
||||
if (! forward)
|
||||
{
|
||||
// This is a request to stop forwarding notifications on the specified
|
||||
// channel. The rest of the params don't matter.
|
||||
// Because mForwarders contains scoped_ptrs, erasing the map entry
|
||||
// DOES delete the heap Forwarder object. Because Forwarder derives
|
||||
// from LLEventTrackable, destroying it disconnects it from the
|
||||
// channel.
|
||||
mForwarders.erase(channel);
|
||||
return;
|
||||
}
|
||||
// From here on, we know we're being asked to start (or modify) forwarding
|
||||
// on the specified channel. Find or create an appropriate Forwarder.
|
||||
ForwarderMap::iterator
|
||||
entry(mForwarders.insert(ForwarderMap::value_type(channel, ForwarderMap::mapped_type())).first);
|
||||
if (! entry->second)
|
||||
{
|
||||
entry->second.reset(new Forwarder(mNotifications, channel));
|
||||
}
|
||||
// Now, whether this Forwarder is brand-new or not, update it with the new
|
||||
// request info.
|
||||
Forwarder& fwd(*entry->second);
|
||||
fwd.setPumpName(params["pump"]);
|
||||
fwd.setTypes(params["types"]);
|
||||
fwd.setRespond(params["respond"]);
|
||||
}
|
||||
|
||||
bool LLNotificationsListener::Forwarder::handle(const LLSD& notification) const
|
||||
{
|
||||
LL_INFOS("LLNotificationsListener") << "handle(" << notification << ")" << LL_ENDL;
|
||||
if (notification["sigtype"].asString() == "delete")
|
||||
{
|
||||
LL_INFOS("LLNotificationsListener") << "ignoring delete" << LL_ENDL;
|
||||
// let other listeners see the "delete" operation
|
||||
return false;
|
||||
}
|
||||
LLNotificationPtr note(mNotifications.find(notification["id"]));
|
||||
if (! note)
|
||||
{
|
||||
LL_INFOS("LLNotificationsListener") << notification["id"] << " not found" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
if (! matchType(mTypes, note->getType()))
|
||||
{
|
||||
LL_INFOS("LLNotificationsListener") << "didn't match types " << mTypes << LL_ENDL;
|
||||
// We're not supposed to intercept this particular notification. Let
|
||||
// other listeners process it.
|
||||
return false;
|
||||
}
|
||||
LL_INFOS("LLNotificationsListener") << "sending via '" << mPumpName << "'" << LL_ENDL;
|
||||
// This is a notification we care about. Forward it through specified
|
||||
// LLEventPump.
|
||||
LLEventPumps::instance().obtain(mPumpName).post(asLLSD(note));
|
||||
// Are we also being asked to auto-respond?
|
||||
if (mRespond)
|
||||
{
|
||||
LL_INFOS("LLNotificationsListener") << "should respond" << LL_ENDL;
|
||||
note->respond(LLSD::emptyMap());
|
||||
// Did that succeed in removing the notification? Only cancel() if
|
||||
// it's still around -- otherwise we get an LL_ERRS crash!
|
||||
note = mNotifications.find(notification["id"]);
|
||||
if (note)
|
||||
{
|
||||
LL_INFOS("LLNotificationsListener") << "respond() didn't clear, canceling" << LL_ENDL;
|
||||
mNotifications.cancel(note);
|
||||
}
|
||||
}
|
||||
// If we've auto-responded to this notification, then it's going to be
|
||||
// deleted. Other listeners would get the change operation, try to look it
|
||||
// up and be baffled by lookup failure. So when we auto-respond, suppress
|
||||
// this notification: don't pass it to other listeners.
|
||||
return mRespond;
|
||||
}
|
||||
|
||||
bool LLNotificationsListener::Forwarder::matchType(const LLSD& filter, const std::string& type) const
|
||||
{
|
||||
// Decide whether this notification matches filter:
|
||||
// undefined: forward all notifications
|
||||
if (filter.isUndefined())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// array of string: forward any notification matching any named type
|
||||
if (filter.isArray())
|
||||
{
|
||||
for (LLSD::array_const_iterator ti(filter.beginArray()), tend(filter.endArray());
|
||||
ti != tend; ++ti)
|
||||
{
|
||||
if (ti->asString() == type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Didn't match any entry in the array
|
||||
return false;
|
||||
}
|
||||
// string: forward only the specific named type
|
||||
return (filter.asString() == type);
|
||||
}
|
||||
|
||||
LLSD LLNotificationsListener::asLLSD(LLNotificationPtr note)
|
||||
{
|
||||
LLSD notificationInfo(note->asLLSD());
|
||||
// For some reason the following aren't included in LLNotification::asLLSD().
|
||||
notificationInfo["summary"] = note->summarize();
|
||||
notificationInfo["id"] = note->id();
|
||||
notificationInfo["type"] = note->getType();
|
||||
notificationInfo["message"] = note->getMessage();
|
||||
notificationInfo["label"] = note->getLabel();
|
||||
return notificationInfo;
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* @file llnotificationslistener.h
|
||||
* @author Brad Kittenbrink
|
||||
* @date 2009-07-08
|
||||
* @brief Wrap subset of LLNotifications API in event API for test scripts.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLNOTIFICATIONSLISTENER_H
|
||||
#define LL_LLNOTIFICATIONSLISTENER_H
|
||||
|
||||
#include "lleventapi.h"
|
||||
#include "llnotificationptr.h"
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class LLNotifications;
|
||||
class LLSD;
|
||||
|
||||
class LLNotificationsListener : public LLEventAPI
|
||||
{
|
||||
public:
|
||||
LLNotificationsListener(LLNotifications & notifications);
|
||||
~LLNotificationsListener();
|
||||
|
||||
private:
|
||||
void requestAdd(LLSD const & event_data) const;
|
||||
|
||||
void NotificationResponder(const std::string& replypump,
|
||||
const LLSD& notification,
|
||||
const LLSD& response) const;
|
||||
|
||||
void listChannels(const LLSD& params) const;
|
||||
void listChannelNotifications(const LLSD& params) const;
|
||||
void respond(const LLSD& params) const;
|
||||
void cancel(const LLSD& params) const;
|
||||
void ignore(const LLSD& params) const;
|
||||
void forward(const LLSD& params);
|
||||
|
||||
static LLSD asLLSD(LLNotificationPtr);
|
||||
|
||||
class Forwarder;
|
||||
typedef std::map<std::string, boost::shared_ptr<Forwarder> > ForwarderMap;
|
||||
ForwarderMap mForwarders;
|
||||
LLNotifications & mNotifications;
|
||||
};
|
||||
|
||||
#endif // LL_LLNOTIFICATIONSLISTENER_H
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
#include "linden_common.h"
|
||||
|
||||
#include "lltabcontainer.h"
|
||||
|
||||
#include "llviewereventrecorder.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include "lllocalcliprect.h"
|
||||
#include "llrect.h"
|
||||
|
|
@ -632,6 +632,11 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask )
|
|||
tab_button->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
if (handled) {
|
||||
// Note: May need to also capture local coords right here ?
|
||||
LLViewerEventRecorder::instance().update_xui(getPathname( ));
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
|
@ -683,30 +688,33 @@ BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask )
|
|||
BOOL handled = FALSE;
|
||||
BOOL has_scroll_arrows = (getMaxScrollPos() > 0) && !getTabsHidden();
|
||||
|
||||
S32 local_x = x - getRect().mLeft;
|
||||
S32 local_y = y - getRect().mBottom;
|
||||
|
||||
if (has_scroll_arrows)
|
||||
{
|
||||
if (mJumpPrevArrowBtn && mJumpPrevArrowBtn->getRect().pointInRect(x, y))
|
||||
{
|
||||
S32 local_x = x - mJumpPrevArrowBtn->getRect().mLeft;
|
||||
S32 local_y = y - mJumpPrevArrowBtn->getRect().mBottom;
|
||||
local_x = x - mJumpPrevArrowBtn->getRect().mLeft;
|
||||
local_y = y - mJumpPrevArrowBtn->getRect().mBottom;
|
||||
handled = mJumpPrevArrowBtn->handleMouseUp(local_x, local_y, mask);
|
||||
}
|
||||
else if (mJumpNextArrowBtn && mJumpNextArrowBtn->getRect().pointInRect(x, y))
|
||||
{
|
||||
S32 local_x = x - mJumpNextArrowBtn->getRect().mLeft;
|
||||
S32 local_y = y - mJumpNextArrowBtn->getRect().mBottom;
|
||||
local_x = x - mJumpNextArrowBtn->getRect().mLeft;
|
||||
local_y = y - mJumpNextArrowBtn->getRect().mBottom;
|
||||
handled = mJumpNextArrowBtn->handleMouseUp(local_x, local_y, mask);
|
||||
}
|
||||
else if (mPrevArrowBtn && mPrevArrowBtn->getRect().pointInRect(x, y))
|
||||
{
|
||||
S32 local_x = x - mPrevArrowBtn->getRect().mLeft;
|
||||
S32 local_y = y - mPrevArrowBtn->getRect().mBottom;
|
||||
local_x = x - mPrevArrowBtn->getRect().mLeft;
|
||||
local_y = y - mPrevArrowBtn->getRect().mBottom;
|
||||
handled = mPrevArrowBtn->handleMouseUp(local_x, local_y, mask);
|
||||
}
|
||||
else if (mNextArrowBtn && mNextArrowBtn->getRect().pointInRect(x, y))
|
||||
{
|
||||
S32 local_x = x - mNextArrowBtn->getRect().mLeft;
|
||||
S32 local_y = y - mNextArrowBtn->getRect().mBottom;
|
||||
local_x = x - mNextArrowBtn->getRect().mLeft;
|
||||
local_y = y - mNextArrowBtn->getRect().mBottom;
|
||||
handled = mNextArrowBtn->handleMouseUp(local_x, local_y, mask);
|
||||
}
|
||||
}
|
||||
|
|
@ -730,6 +738,10 @@ BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask )
|
|||
}
|
||||
gFocusMgr.setMouseCapture(NULL);
|
||||
}
|
||||
if (handled) {
|
||||
// Note: may need to capture local coords here
|
||||
LLViewerEventRecorder::instance().update_xui(getPathname( ));
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
|
@ -1160,21 +1172,21 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
|
|||
|
||||
if (mIsVertical)
|
||||
{
|
||||
p.name(std::string("vert tab button"));
|
||||
p.image_unselected(mMiddleTabParams.tab_left_image_unselected);
|
||||
p.image_selected(mMiddleTabParams.tab_left_image_selected);
|
||||
p.follows.flags = p.follows.flags() | FOLLOWS_TOP;
|
||||
p.name("vtab_"+std::string(child->getName()));
|
||||
p.image_unselected(mMiddleTabParams.tab_left_image_unselected);
|
||||
p.image_selected(mMiddleTabParams.tab_left_image_selected);
|
||||
p.follows.flags = p.follows.flags() | FOLLOWS_TOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
p.name(std::string(child->getName()) + " tab");
|
||||
p.visible(false);
|
||||
p.image_unselected(tab_img);
|
||||
p.image_selected(tab_selected_img);
|
||||
p.follows.flags = p.follows.flags() | (getTabPosition() == TOP ? FOLLOWS_TOP : FOLLOWS_BOTTOM);
|
||||
// Try to squeeze in a bit more text
|
||||
p.pad_left( mLabelPadLeft );
|
||||
p.pad_right(2);
|
||||
{
|
||||
p.name("htab_"+std::string(child->getName()));
|
||||
p.visible(false);
|
||||
p.image_unselected(tab_img);
|
||||
p.image_selected(tab_selected_img);
|
||||
p.follows.flags = p.follows.flags() | (getTabPosition() == TOP ? FOLLOWS_TOP : FOLLOWS_BOTTOM);
|
||||
// Try to squeeze in a bit more text
|
||||
p.pad_left( mLabelPadLeft );
|
||||
p.pad_right(2);
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Enable tab flashing
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define LLUICTRL_CPP
|
||||
#include "lluictrl.h"
|
||||
|
||||
#include "llviewereventrecorder.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include "llpanel.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
|
@ -316,22 +316,40 @@ void LLUICtrl::onMouseLeave(S32 x, S32 y, MASK mask)
|
|||
//virtual
|
||||
BOOL LLUICtrl::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
|
||||
lldebugs << "LLUICtrl::handleMouseDown calling LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << llendl;
|
||||
|
||||
BOOL handled = LLView::handleMouseDown(x,y,mask);
|
||||
|
||||
if (mMouseDownSignal)
|
||||
{
|
||||
(*mMouseDownSignal)(this,x,y,mask);
|
||||
}
|
||||
lldebugs << "LLUICtrl::handleMousedown - handled is returning as: " << handled << " " << llendl;
|
||||
|
||||
if (handled) {
|
||||
LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-56,-56,getPathname());
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
//virtual
|
||||
BOOL LLUICtrl::handleMouseUp(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
|
||||
lldebugs << "LLUICtrl::handleMouseUp calling LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << llendl;
|
||||
|
||||
BOOL handled = LLView::handleMouseUp(x,y,mask);
|
||||
if (handled) {
|
||||
LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-56,-56,getPathname());
|
||||
}
|
||||
if (mMouseUpSignal)
|
||||
{
|
||||
(*mMouseUpSignal)(this,x,y,mask);
|
||||
}
|
||||
|
||||
lldebugs << "LLUICtrl::handleMouseUp - handled for xui " << getPathname() << " - is returning as: " << handled << " " << llendl;
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,9 @@
|
|||
#include "lluictrlfactory.h"
|
||||
#include "lltooltip.h"
|
||||
#include "llsdutil.h"
|
||||
|
||||
#include "llsdserialize.h"
|
||||
#include "llviewereventrecorder.h"
|
||||
#include "llkeyboard.h"
|
||||
// for ui edit hack
|
||||
#include "llbutton.h"
|
||||
#include "lllineeditor.h"
|
||||
|
|
@ -697,13 +699,27 @@ void LLView::setVisible(BOOL visible)
|
|||
// virtual
|
||||
void LLView::handleVisibilityChange ( BOOL new_visibility )
|
||||
{
|
||||
BOOL old_visibility;
|
||||
BOOST_FOREACH(LLView* viewp, mChildList)
|
||||
{
|
||||
// only views that are themselves visible will have their overall visibility affected by their ancestors
|
||||
if (viewp->getVisible())
|
||||
old_visibility=viewp->getVisible();
|
||||
|
||||
if (old_visibility!=new_visibility)
|
||||
{
|
||||
LLViewerEventRecorder::instance().logVisibilityChange( viewp->getPathname(), viewp->getName(), new_visibility,"widget");
|
||||
}
|
||||
|
||||
if (old_visibility)
|
||||
{
|
||||
viewp->handleVisibilityChange ( new_visibility );
|
||||
}
|
||||
|
||||
// Consider changing returns to confirm success and know which widget grabbed it
|
||||
// For now assume success and log at highest xui possible
|
||||
// NOTE we log actual state - which may differ if it somehow failed to set visibility
|
||||
lldebugs << "LLView::handleVisibilityChange - now: " << getVisible() << " xui: " << viewp->getPathname() << " name: " << viewp->getName() << llendl;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -752,6 +768,7 @@ bool LLView::visibleEnabledAndContains(S32 local_x, S32 local_y)
|
|||
&& getEnabled();
|
||||
}
|
||||
|
||||
// This is NOT event recording related
|
||||
void LLView::logMouseEvent()
|
||||
{
|
||||
if (sDebugMouseHandling)
|
||||
|
|
@ -798,7 +815,14 @@ LLView* LLView::childrenHandleMouseEvent(const METHOD& method, S32 x, S32 y, XDA
|
|||
if ((viewp->*method)( local_x, local_y, extra )
|
||||
|| (allow_mouse_block && viewp->blockMouseEvent( local_x, local_y )))
|
||||
{
|
||||
lldebugs << "LLView::childrenHandleMouseEvent calling updatemouseeventinfo - local_x|global x "<< local_x << " " << x << "local/global y " << local_y << " " << y << llendl;
|
||||
lldebugs << "LLView::childrenHandleMouseEvent getPathname for viewp result: " << viewp->getPathname() << "for this view: " << getPathname() << llendl;
|
||||
|
||||
LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
|
||||
|
||||
// This is NOT event recording related
|
||||
viewp->logMouseEvent();
|
||||
|
||||
return viewp;
|
||||
}
|
||||
}
|
||||
|
|
@ -821,6 +845,7 @@ LLView* LLView::childrenHandleToolTip(S32 x, S32 y, MASK mask)
|
|||
if (viewp->handleToolTip(local_x, local_y, mask)
|
||||
|| viewp->blockMouseEvent(local_x, local_y))
|
||||
{
|
||||
// This is NOT event recording related
|
||||
viewp->logMouseEvent();
|
||||
return viewp;
|
||||
}
|
||||
|
|
@ -879,6 +904,7 @@ LLView* LLView::childrenHandleHover(S32 x, S32 y, MASK mask)
|
|||
if (viewp->handleHover(local_x, local_y, mask)
|
||||
|| viewp->blockMouseEvent(local_x, local_y))
|
||||
{
|
||||
// This is NOT event recording related
|
||||
viewp->logMouseEvent();
|
||||
return viewp;
|
||||
}
|
||||
|
|
@ -968,10 +994,12 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
|
|||
|
||||
if (!handled)
|
||||
{
|
||||
// For event logging we don't care which widget handles it
|
||||
// So we capture the key at the end of this function once we know if it was handled
|
||||
handled = handleKeyHere( key, mask );
|
||||
if (handled && LLView::sDebugKeys)
|
||||
if (handled)
|
||||
{
|
||||
llinfos << "Key handled by " << getName() << llendl;
|
||||
llwarns << "Key handled by " << getName() << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1019,6 +1047,11 @@ BOOL LLView::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
|
|||
handled = mParentView->handleUnicodeChar(uni_char, FALSE);
|
||||
}
|
||||
|
||||
if (handled)
|
||||
{
|
||||
LLViewerEventRecorder::instance().logKeyUnicodeEvent(uni_char);
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
|
@ -1048,12 +1081,16 @@ BOOL LLView::hasMouseCapture()
|
|||
|
||||
BOOL LLView::handleMouseUp(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
return childrenHandleMouseUp( x, y, mask ) != NULL;
|
||||
LLView* r = childrenHandleMouseUp( x, y, mask );
|
||||
|
||||
return (r!=NULL);
|
||||
}
|
||||
|
||||
BOOL LLView::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
return childrenHandleMouseDown( x, y, mask ) != NULL;
|
||||
LLView* r= childrenHandleMouseDown(x, y, mask );
|
||||
|
||||
return (r!=NULL);
|
||||
}
|
||||
|
||||
BOOL LLView::handleDoubleClick(S32 x, S32 y, MASK mask)
|
||||
|
|
@ -1126,7 +1163,7 @@ LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask)
|
|||
|
||||
LLView* LLView::childrenHandleMouseUp(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
return childrenHandleMouseEvent(&LLView::handleMouseUp, x, y, mask);
|
||||
return childrenHandleMouseEvent(&LLView::handleMouseUp, x, y, mask);
|
||||
}
|
||||
|
||||
LLView* LLView::childrenHandleRightMouseUp(S32 x, S32 y, MASK mask)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,296 @@
|
|||
/**
|
||||
* @file llviewereventrecorder.cpp
|
||||
* @brief Viewer event recording and playback support for mouse and keyboard events
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
*
|
||||
* Copyright (c) 2013, Linden Research, Inc.
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
#include "llviewereventrecorder.h"
|
||||
#include "llui.h"
|
||||
#include "llleap.h"
|
||||
|
||||
LLViewerEventRecorder::LLViewerEventRecorder() {
|
||||
|
||||
clear(UNDEFINED);
|
||||
|
||||
// Remove any previous event log file
|
||||
std::string old_log_ui_events_to_llsd_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.old");
|
||||
LLFile::remove(old_log_ui_events_to_llsd_file);
|
||||
|
||||
|
||||
mLogFilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.llsd");
|
||||
LLFile::rename(mLogFilename, old_log_ui_events_to_llsd_file);
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool LLViewerEventRecorder::displayViewerEventRecorderMenuItems() {
|
||||
return LLUI::sSettingGroups["config"]->getBOOL("ShowEventRecorderMenuItems");
|
||||
}
|
||||
|
||||
|
||||
void LLViewerEventRecorder::setEventLoggingOn() {
|
||||
if (! mLog.is_open()) {
|
||||
mLog.open(mLogFilename, llofstream::out);
|
||||
}
|
||||
logEvents=true;
|
||||
lldebugs << "LLViewerEventRecorder::setEventLoggingOn event logging turned on" << llendl;
|
||||
}
|
||||
|
||||
void LLViewerEventRecorder::setEventLoggingOff() {
|
||||
logEvents=false;
|
||||
mLog.flush();
|
||||
mLog.close();
|
||||
lldebugs << "LLViewerEventRecorder::setEventLoggingOff event logging turned off" << llendl;
|
||||
}
|
||||
|
||||
|
||||
LLViewerEventRecorder::~LLViewerEventRecorder() {
|
||||
if (mLog.is_open()) {
|
||||
mLog.close();
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerEventRecorder::clear_xui() {
|
||||
xui.clear();
|
||||
}
|
||||
|
||||
void LLViewerEventRecorder::clear(S32 r) {
|
||||
|
||||
xui.clear();
|
||||
|
||||
local_x=r;
|
||||
local_y=r;
|
||||
|
||||
global_x=r;
|
||||
global_y=r;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void LLViewerEventRecorder::setMouseLocalCoords(S32 x, S32 y) {
|
||||
local_x=x;
|
||||
local_y=y;
|
||||
}
|
||||
|
||||
void LLViewerEventRecorder::setMouseGlobalCoords(S32 x, S32 y) {
|
||||
global_x=x;
|
||||
global_y=y;
|
||||
}
|
||||
|
||||
void LLViewerEventRecorder::updateMouseEventInfo(S32 local_x, S32 local_y, S32 global_x, S32 global_y, std::string mName) {
|
||||
|
||||
LLView * target_view = LLUI::resolvePath(LLUI::getRootView(), xui);
|
||||
if (! target_view) {
|
||||
lldebugs << "LLViewerEventRecorder::updateMouseEventInfo - xui path on file at moment is NOT valid - so DO NOT record these local coords" << llendl;
|
||||
return;
|
||||
}
|
||||
lldebugs << "LLViewerEventRecorder::updateMouseEventInfo b4 updatemouseeventinfo - local_x|global x "<< this->local_x << " " << this->global_x << "local/global y " << this->local_y << " " << this->global_y << " mname: " << mName << " xui: " << xui << llendl;
|
||||
|
||||
|
||||
if (this->local_x < 1 && this->local_y<1 && local_x && local_y) {
|
||||
this->local_x=local_x;
|
||||
this->local_y=local_y;
|
||||
}
|
||||
this->global_x=global_x;
|
||||
this->global_y=global_y;
|
||||
|
||||
// ONLY record deepest xui path for hierarchy searches - or first/only xui for floaters/panels reached via mouse captor - and llmousehandler
|
||||
if (mName!="" && mName!="/" && xui=="") {
|
||||
// xui=std::string("/")+mName+xui;
|
||||
//xui=mName+xui;
|
||||
xui = mName; // TODO review confirm we never call with partial path - also cAN REMOVE CHECK FOR "" - ON OTHER HAND IT'S PRETTY HARMLESS
|
||||
}
|
||||
|
||||
lldebugs << "LLViewerEventRecorder::updateMouseEventInfo after updatemouseeventinfo - local_x|global x "<< this->local_x << " " << this->global_x << "local/global y " << this->local_y << " " << this->global_y << " mname: " << mName << " xui: " << xui << llendl;
|
||||
}
|
||||
|
||||
void LLViewerEventRecorder::logVisibilityChange(std::string xui, std::string name, BOOL visibility, std::string event_subtype) {
|
||||
|
||||
LLSD event=LLSD::emptyMap();
|
||||
|
||||
event.insert("event",LLSD(std::string("visibility")));
|
||||
|
||||
if (visibility) {
|
||||
event.insert("visibility",LLSD(true));
|
||||
} else {
|
||||
event.insert("visibility",LLSD(false));
|
||||
}
|
||||
|
||||
if (event_subtype!="") {
|
||||
event.insert("event_subtype", LLSD(event_subtype));
|
||||
}
|
||||
|
||||
if(name!="") {
|
||||
event.insert("name",LLSD(name));
|
||||
}
|
||||
|
||||
if (xui!="") {
|
||||
event.insert("path",LLSD(xui));
|
||||
}
|
||||
|
||||
event.insert("timestamp",LLSD(LLDate::now().asString()));
|
||||
recordEvent(event);
|
||||
}
|
||||
|
||||
|
||||
std::string LLViewerEventRecorder::get_xui() {
|
||||
return xui;
|
||||
}
|
||||
void LLViewerEventRecorder::update_xui(std::string xui) {
|
||||
if (xui!="" && this->xui=="" ) {
|
||||
lldebugs << "LLViewerEventRecorder::update_xui to " << xui << llendl;
|
||||
this->xui=xui;
|
||||
} else {
|
||||
lldebugs << "LLViewerEventRecorder::update_xui called with empty string" << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerEventRecorder::logKeyEvent(KEY key, MASK mask) {
|
||||
|
||||
// NOTE: Event recording only logs keydown events - the viewer itself hides keyup events at a fairly low level in the code and does not appear to care about them anywhere
|
||||
|
||||
LLSD event = LLSD::emptyMap();
|
||||
|
||||
event.insert("event",LLSD("type"));
|
||||
|
||||
// keysym ...or
|
||||
// keycode...or
|
||||
// char
|
||||
event.insert("keysym",LLSD(LLKeyboard::stringFromKey(key)));
|
||||
|
||||
// path (optional) - for now we are not recording path for key events during record - should not be needed for full record and playback of recorded steps
|
||||
// as a vita script - it does become useful if you edit the resulting vita script and wish to remove some steps leading to a key event - that sort of edit might
|
||||
// break the test script and it would be useful to have more context to make these sorts of edits safer
|
||||
|
||||
// TODO replace this with a call which extracts to an array of names of masks (just like vita expects during playback)
|
||||
// This is looking more and more like an object is a good idea, for this part a handy method call to setMask(mask) would be nice :-)
|
||||
// call the func - llkeyboard::llsdStringarrayFromMask
|
||||
|
||||
LLSD key_mask=LLSD::emptyArray();
|
||||
|
||||
if (mask & MASK_CONTROL) { key_mask.append(LLSD("CTL")); } // Mac command key - has code of 0x1 in llcommon/indra_contstants
|
||||
if (mask & MASK_ALT) { key_mask.append(LLSD("ALT")); }
|
||||
if (mask & MASK_SHIFT) { key_mask.append(LLSD("SHIFT")); }
|
||||
if (mask & MASK_MAC_CONTROL) { key_mask.append(LLSD("MAC_CONTROL")); }
|
||||
|
||||
event.insert("mask",key_mask);
|
||||
event.insert("timestamp",LLSD(LLDate::now().asString()));
|
||||
|
||||
// Although vita has keyDown and keyUp requests it does not have type as a high-level concept
|
||||
// (maybe it should) - instead it has a convenience method that generates the keydown and keyup events
|
||||
// Here we will use "type" as our event type
|
||||
|
||||
lldebugs << "LLVIewerEventRecorder::logKeyEvent Serialized LLSD for event " << event.asString() << "\n" << llendl;
|
||||
|
||||
|
||||
//lldebugs << "[VITA] key_name: " << LLKeyboard::stringFromKey(key) << "mask: "<< mask << "handled by " << getName() << llendl;
|
||||
lldebugs << "LLVIewerEventRecorder::logKeyEvent key_name: " << LLKeyboard::stringFromKey(key) << "mask: "<< mask << llendl;
|
||||
|
||||
|
||||
recordEvent(event);
|
||||
|
||||
}
|
||||
|
||||
void LLViewerEventRecorder::playbackRecording() {
|
||||
|
||||
LLSD LeapCommand;
|
||||
|
||||
// ivita sets this on startup, it also sends commands to the viewer to make start, stop, and playback menu items visible in viewer
|
||||
LeapCommand =LLUI::sSettingGroups["config"]->getLLSD("LeapPlaybackEventsCommand");
|
||||
|
||||
lldebugs << "[VITA] launching playback - leap command is: " << LLSDXMLStreamer(LeapCommand) << llendl;
|
||||
LLLeap::create("", LeapCommand, false); // exception=false
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LLViewerEventRecorder::recordEvent(LLSD event) {
|
||||
lldebugs << "LLViewerEventRecorder::recordEvent event written to log: " << LLSDXMLStreamer(event) << llendl;
|
||||
mLog << event << std::endl;
|
||||
|
||||
}
|
||||
void LLViewerEventRecorder::logKeyUnicodeEvent(llwchar uni_char) {
|
||||
if (! logEvents) return;
|
||||
|
||||
// Note: keyUp is not captured since the viewer seems to not care about keyUp events
|
||||
|
||||
LLSD event=LLSD::emptyMap();
|
||||
|
||||
event.insert("timestamp",LLSD(LLDate::now().asString()));
|
||||
|
||||
|
||||
// keysym ...or
|
||||
// keycode...or
|
||||
// char
|
||||
|
||||
lldebugs << "Wrapped in conversion to wstring " << wstring_to_utf8str(LLWString( 1, uni_char)) << "\n" << llendl;
|
||||
|
||||
event.insert("char",
|
||||
LLSD( wstring_to_utf8str(LLWString( 1,uni_char)) )
|
||||
);
|
||||
|
||||
// path (optional) - for now we are not recording path for key events during record - should not be needed for full record and playback of recorded steps
|
||||
// as a vita script - it does become useful if you edit the resulting vita script and wish to remove some steps leading to a key event - that sort of edit might
|
||||
// break the test script and it would be useful to have more context to make these sorts of edits safer
|
||||
|
||||
// TODO need to consider mask keys too? Doesn't seem possible - at least not easily at this point
|
||||
|
||||
event.insert("event",LLSD("keyDown"));
|
||||
|
||||
lldebugs << "[VITA] unicode key: " << uni_char << llendl;
|
||||
lldebugs << "[VITA] dumpxml " << LLSDXMLStreamer(event) << "\n" << llendl;
|
||||
|
||||
|
||||
recordEvent(event);
|
||||
|
||||
}
|
||||
|
||||
void LLViewerEventRecorder::logMouseEvent(std::string button_state,std::string button_name)
|
||||
{
|
||||
if (! logEvents) return;
|
||||
|
||||
LLSD event=LLSD::emptyMap();
|
||||
|
||||
event.insert("event",LLSD(std::string("mouse"+ button_state)));
|
||||
event.insert("button",LLSD(button_name));
|
||||
if (xui!="") {
|
||||
event.insert("path",LLSD(xui));
|
||||
}
|
||||
|
||||
if (local_x>0 && local_y>0) {
|
||||
event.insert("local_x",LLSD(local_x));
|
||||
event.insert("local_y",LLSD(local_y));
|
||||
}
|
||||
|
||||
if (global_x>0 && global_y>0) {
|
||||
event.insert("global_x",LLSD(global_x));
|
||||
event.insert("global_y",LLSD(global_y));
|
||||
}
|
||||
event.insert("timestamp",LLSD(LLDate::now().asString()));
|
||||
recordEvent(event);
|
||||
|
||||
|
||||
clear(UNDEFINED);
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* @file llviewereventrecorder.h
|
||||
* @brief Viewer event recording and playback support for mouse and keyboard events
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
*
|
||||
* Copyright (c) 2013, Linden Research, Inc.
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_VIEWER_EVENT_RECORDER
|
||||
#define LL_VIEWER_EVENT_RECORDER
|
||||
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "lldir.h"
|
||||
#include "llsd.h"
|
||||
#include "llfile.h"
|
||||
#include "llvfile.h"
|
||||
#include "lldate.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llkeyboard.h"
|
||||
#include "llstring.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "llsingleton.h" // includes llerror which we need here so we can skip the include here
|
||||
|
||||
class LLViewerEventRecorder : public LLSingleton<LLViewerEventRecorder>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
LLViewerEventRecorder(); // TODO Protect constructor better if we can (not happy in private section) - could add a factory... - we are singleton
|
||||
~LLViewerEventRecorder();
|
||||
|
||||
|
||||
void updateMouseEventInfo(S32 local_x,S32 local_y, S32 global_x, S32 global_y, std::string mName);
|
||||
void setMouseLocalCoords(S32 x,S32 y);
|
||||
void setMouseGlobalCoords(S32 x,S32 y);
|
||||
|
||||
void logMouseEvent(std::string button_state, std::string button_name );
|
||||
void logKeyEvent(KEY key, MASK mask);
|
||||
void logKeyUnicodeEvent(llwchar uni_char);
|
||||
|
||||
void logVisibilityChange(std::string xui, std::string name, BOOL visibility, std::string event_subtype);
|
||||
|
||||
void clear_xui();
|
||||
std::string get_xui();
|
||||
void update_xui(std::string xui);
|
||||
|
||||
bool getLoggingStatus();
|
||||
void setEventLoggingOn();
|
||||
void setEventLoggingOff();
|
||||
|
||||
void playbackRecording();
|
||||
|
||||
bool displayViewerEventRecorderMenuItems();
|
||||
|
||||
|
||||
protected:
|
||||
// On if we wish to log events at the moment - toggle via Develop/Recorder submenu
|
||||
bool logEvents;
|
||||
|
||||
std::string mLogFilename;
|
||||
llofstream mLog;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Mouse event info
|
||||
S32 global_x;
|
||||
S32 global_y;
|
||||
S32 local_x;
|
||||
S32 local_y;
|
||||
|
||||
// XUI path of UI element
|
||||
std::string xui;
|
||||
|
||||
// Actually write the event out to llsd log file
|
||||
void recordEvent(LLSD event);
|
||||
|
||||
void clear(S32 r);
|
||||
|
||||
static const S32 UNDEFINED=-1;
|
||||
};
|
||||
#endif
|
||||
|
|
@ -1308,6 +1308,8 @@ void LLWindowMacOSX::setupFailure(const std::string& text, const std::string& ca
|
|||
OSMessageBox(text, caption, type);
|
||||
}
|
||||
|
||||
// Note on event recording - QUIT is a known special case and we are choosing NOT to record it for the record and playback feature
|
||||
// it is handled at a very low-level
|
||||
const char* cursorIDToName(int id)
|
||||
{
|
||||
BOOL use_legacy_cursors = gSavedSettings.getBOOL("UseLegacyCursors");
|
||||
|
|
|
|||
|
|
@ -477,7 +477,7 @@ LLControlVariable* LLControlGroup::declareControl(const std::string& name, eCont
|
|||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Control named " << name << " already exists, ignoring new declaration." << llendl;
|
||||
LL_WARNS("Settings") << "Control named " << name << " already exists, ignoring new declaration." << LL_ENDL;
|
||||
}
|
||||
return existing_control;
|
||||
}
|
||||
|
|
@ -719,14 +719,14 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
|
|||
|
||||
if (!xml_controls.parseFile(filename))
|
||||
{
|
||||
llwarns << "Unable to open control file " << filename << llendl;
|
||||
LL_WARNS("Settings") << "Unable to open control file " << filename << LL_ENDL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
LLXmlTreeNode* rootp = xml_controls.getRoot();
|
||||
if (!rootp || !rootp->hasAttribute("version"))
|
||||
{
|
||||
llwarns << "No valid settings header found in control file " << filename << llendl;
|
||||
LL_WARNS("Settings") << "No valid settings header found in control file " << filename << LL_ENDL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -739,7 +739,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
|
|||
// Check file version
|
||||
if (version != CURRENT_VERSION)
|
||||
{
|
||||
llinfos << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << llendl;
|
||||
LL_INFOS("Settings") << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << LL_ENDL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -757,7 +757,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
|
|||
if (!name.empty())
|
||||
{
|
||||
//read in to end of line
|
||||
llwarns << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << llendl;
|
||||
LL_WARNS("Settings") << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << LL_ENDL;
|
||||
}
|
||||
child_nodep = rootp->getNextChild();
|
||||
continue;
|
||||
|
|
@ -911,7 +911,7 @@ U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only
|
|||
LLControlVariable* control = iter->second;
|
||||
if (!control)
|
||||
{
|
||||
llwarns << "Tried to save invalid control: " << iter->first << llendl;
|
||||
LL_WARNS("Settings") << "Tried to save invalid control: " << iter->first << LL_ENDL;
|
||||
}
|
||||
else if( control->shouldSave(nondefault_only) )
|
||||
{
|
||||
|
|
@ -928,12 +928,12 @@ U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only
|
|||
{
|
||||
LLSDSerialize::toPrettyXML(settings, file);
|
||||
file.close();
|
||||
llinfos << "Saved to " << filename << llendl;
|
||||
LL_INFOS("Settings") << "Saved to " << filename << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is a warning because sometime we want to use settings files which can't be written...
|
||||
llwarns << "Unable to open settings file: " << filename << llendl;
|
||||
LL_WARNS("Settings") << "Unable to open settings file: " << filename << LL_ENDL;
|
||||
return 0;
|
||||
}
|
||||
return num_saved;
|
||||
|
|
@ -946,14 +946,14 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
|
|||
infile.open(filename);
|
||||
if(!infile.is_open())
|
||||
{
|
||||
llwarns << "Cannot find file " << filename << " to load." << llendl;
|
||||
LL_WARNS("Settings") << "Cannot find file " << filename << " to load." << LL_ENDL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(settings, infile))
|
||||
{
|
||||
infile.close();
|
||||
llwarns << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << llendl;
|
||||
LL_WARNS("Settings") << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << LL_ENDL;
|
||||
return loadFromFileLegacy(filename, TRUE, TYPE_STRING);
|
||||
}
|
||||
|
||||
|
|
@ -1079,6 +1079,7 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
|
|||
++validitems;
|
||||
}
|
||||
|
||||
LL_DEBUGS("Settings") << "Loaded " << validitems << " settings from " << filename << LL_ENDL;
|
||||
return validitems;
|
||||
}
|
||||
|
||||
|
|
@ -1115,7 +1116,7 @@ void main()
|
|||
BOOL_CONTROL baz;
|
||||
|
||||
U32 count = gGlobals.loadFromFile("controls.ini");
|
||||
llinfos << "Loaded " << count << " controls" << llendl;
|
||||
LL_INFOS("Settings") << "Loaded " << count << " controls" << LL_ENDL;
|
||||
|
||||
// test insertion
|
||||
foo = new LLControlVariable<F32>("gFoo", 5.f, 1.f, 20.f);
|
||||
|
|
@ -1376,19 +1377,19 @@ LLColor4 convert_from_llsd<LLColor4>(const LLSD& sd, eControlType type, const st
|
|||
LLColor4 color(sd);
|
||||
if (color.mV[VRED] < 0.f || color.mV[VRED] > 1.f)
|
||||
{
|
||||
llwarns << "Color " << control_name << " red value out of range: " << color << llendl;
|
||||
LL_WARNS("Settings") << "Color " << control_name << " red value out of range: " << color << LL_ENDL;
|
||||
}
|
||||
else if (color.mV[VGREEN] < 0.f || color.mV[VGREEN] > 1.f)
|
||||
{
|
||||
llwarns << "Color " << control_name << " green value out of range: " << color << llendl;
|
||||
LL_WARNS("Settings") << "Color " << control_name << " green value out of range: " << color << LL_ENDL;
|
||||
}
|
||||
else if (color.mV[VBLUE] < 0.f || color.mV[VBLUE] > 1.f)
|
||||
{
|
||||
llwarns << "Color " << control_name << " blue value out of range: " << color << llendl;
|
||||
LL_WARNS("Settings") << "Color " << control_name << " blue value out of range: " << color << LL_ENDL;
|
||||
}
|
||||
else if (color.mV[VALPHA] < 0.f || color.mV[VALPHA] > 1.f)
|
||||
{
|
||||
llwarns << "Color " << control_name << " alpha value out of range: " << color << llendl;
|
||||
LL_WARNS("Settings") << "Color " << control_name << " alpha value out of range: " << color << LL_ENDL;
|
||||
}
|
||||
|
||||
return LLColor4(sd);
|
||||
|
|
|
|||
|
|
@ -6947,6 +6947,16 @@
|
|||
<key>Value</key>
|
||||
<array />
|
||||
</map>
|
||||
<key>LeapPlaybackEventsCommand</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Command line to use leap to launch playback of event recordings</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>LLSD</string>
|
||||
<key>Value</key>
|
||||
</map>
|
||||
<key>LSLFindCaseInsensitivity</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -12998,6 +13008,17 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>ShowEventRecorderMenuItems</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether or not Event Recorder menu choices - Start / Stop event recording should appear in the (currently) Develop menu</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>ShowHoverTips</key>
|
||||
|
|
|
|||
|
|
@ -241,6 +241,10 @@
|
|||
#include "llmachineid.h"
|
||||
#include "llmainlooprepeater.h"
|
||||
|
||||
|
||||
#include "llviewereventrecorder.h"
|
||||
|
||||
|
||||
// *FIX: These extern globals should be cleaned up.
|
||||
// The globals either represent state/config/resource-storage of either
|
||||
// this app, or another 'component' of the viewer. App globals should be
|
||||
|
|
@ -768,6 +772,7 @@ LLAppViewer::LLAppViewer() :
|
|||
LLAppViewer::~LLAppViewer()
|
||||
{
|
||||
delete mSettingsLocationList;
|
||||
LLViewerEventRecorder::instance().~LLViewerEventRecorder();
|
||||
|
||||
LLLoginInstance::instance().setUpdaterService(0);
|
||||
|
||||
|
|
@ -2565,13 +2570,13 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
|
|||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
llinfos << "Attempting to load settings for the group " << file.name()
|
||||
<< " - from location " << location_key << llendl;
|
||||
LL_INFOS("Settings") << "Attempting to load settings for the group " << file.name()
|
||||
<< " - from location " << location_key << LL_ENDL;
|
||||
|
||||
LLControlGroup* settings_group = LLControlGroup::getInstance(file.name);
|
||||
if(!settings_group)
|
||||
{
|
||||
llwarns << "No matching settings group for name " << file.name() << llendl;
|
||||
LL_WARNS("Settings") << "No matching settings group for name " << file.name() << LL_ENDL;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -2600,7 +2605,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
|
|||
|
||||
if(settings_group->loadFromFile(full_settings_path, set_defaults, file.persistent))
|
||||
{ // success!
|
||||
llinfos << "Loaded settings file " << full_settings_path << llendl;
|
||||
LL_INFOS("Settings") << "Loaded settings file " << full_settings_path << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{ // failed to load
|
||||
|
|
@ -2614,7 +2619,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
|
|||
// only complain if we actually have a filename at this point
|
||||
if (!full_settings_path.empty())
|
||||
{
|
||||
llinfos << "Cannot load " << full_settings_path << " - No settings found." << llendl;
|
||||
LL_INFOS("Settings") << "Cannot load " << full_settings_path << " - No settings found." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2780,8 +2785,8 @@ bool LLAppViewer::initConfiguration()
|
|||
LLFile::remove(user_settings_filename);
|
||||
}
|
||||
|
||||
llinfos << "Using command line specified settings filename: "
|
||||
<< user_settings_filename << llendl;
|
||||
LL_INFOS("Settings") << "Using command line specified settings filename: "
|
||||
<< user_settings_filename << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2839,8 +2844,8 @@ bool LLAppViewer::initConfiguration()
|
|||
{
|
||||
std::string session_settings_filename = clp.getOption("sessionsettings")[0];
|
||||
gSavedSettings.setString("SessionSettingsFile", session_settings_filename);
|
||||
llinfos << "Using session settings filename: "
|
||||
<< session_settings_filename << llendl;
|
||||
LL_INFOS("Settings") << "Using session settings filename: "
|
||||
<< session_settings_filename << LL_ENDL;
|
||||
}
|
||||
loadSettingsFromDirectory("Session",true); // AO The session file turns into the new defaults
|
||||
|
||||
|
|
@ -2848,10 +2853,10 @@ bool LLAppViewer::initConfiguration()
|
|||
{
|
||||
std::string user_session_settings_filename = clp.getOption("usersessionsettings")[0];
|
||||
gSavedSettings.setString("UserSessionSettingsFile", user_session_settings_filename);
|
||||
llinfos << "Using user session settings filename: " << user_session_settings_filename << llendl;
|
||||
}
|
||||
LL_INFOS("Settings") << "Using user session settings filename: "
|
||||
<< user_session_settings_filename << LL_ENDL;
|
||||
|
||||
|
||||
}
|
||||
loadSettingsFromDirectory("UserSession");
|
||||
|
||||
//AO: Re-read user settings again. This is a Firestorm hack to get user settings to override modes
|
||||
|
|
@ -2942,6 +2947,10 @@ bool LLAppViewer::initConfiguration()
|
|||
}
|
||||
}
|
||||
|
||||
if (clp.hasOption("logevents")) {
|
||||
LLViewerEventRecorder::instance().setEventLoggingOn();
|
||||
}
|
||||
|
||||
std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel"));
|
||||
if(! CmdLineChannel.empty())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -175,21 +175,20 @@ void ll_nvapi_init(NvDRSSessionHandle hSession)
|
|||
nvapi_error(status);
|
||||
return;
|
||||
}
|
||||
|
||||
// (5) Now we apply (or save) our changes to the system
|
||||
status = NvAPI_DRS_SaveSettings(hSession);
|
||||
if (status != NVAPI_OK)
|
||||
{
|
||||
nvapi_error(status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (status != NVAPI_OK)
|
||||
{
|
||||
nvapi_error(status);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// (5) Now we apply (or save) our changes to the system
|
||||
status = NvAPI_DRS_SaveSettings(hSession);
|
||||
if (status != NVAPI_OK)
|
||||
{
|
||||
nvapi_error(status);
|
||||
}
|
||||
}
|
||||
|
||||
//#define DEBUGGING_SEH_FILTER 1
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@
|
|||
#include "llcallingcard.h"
|
||||
#include "llslurl.h" // IDEVO
|
||||
#include "llsidepanelinventory.h"
|
||||
#include "llavatarname.h"
|
||||
#include "llagentui.h"
|
||||
|
||||
// Firestorm includes
|
||||
#include "fsfloaterim.h"
|
||||
|
|
@ -508,6 +510,72 @@ void LLAvatarActions::pay(const LLUUID& id)
|
|||
}
|
||||
}
|
||||
|
||||
void LLAvatarActions::teleport_request_callback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option;
|
||||
if (response.isInteger())
|
||||
{
|
||||
option = response.asInteger();
|
||||
}
|
||||
else
|
||||
{
|
||||
option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
}
|
||||
|
||||
if (0 == option)
|
||||
{
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
||||
msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
|
||||
msg->nextBlockFast(_PREHASH_MessageBlock);
|
||||
msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
|
||||
msg->addUUIDFast(_PREHASH_ToAgentID, notification["substitutions"]["uuid"] );
|
||||
msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
|
||||
msg->addU8Fast(_PREHASH_Dialog, IM_TELEPORT_REQUEST);
|
||||
msg->addUUIDFast(_PREHASH_ID, LLUUID::null);
|
||||
msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
|
||||
|
||||
std::string name;
|
||||
LLAgentUI::buildFullname(name);
|
||||
|
||||
msg->addStringFast(_PREHASH_FromAgentName, name);
|
||||
msg->addStringFast(_PREHASH_Message, response["message"]);
|
||||
msg->addU32Fast(_PREHASH_ParentEstateID, 0);
|
||||
msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
|
||||
msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
|
||||
|
||||
gMessageSystem->addBinaryDataFast(
|
||||
_PREHASH_BinaryBucket,
|
||||
EMPTY_BINARY_BUCKET,
|
||||
EMPTY_BINARY_BUCKET_SIZE);
|
||||
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLAvatarActions::teleportRequest(const LLUUID& id)
|
||||
{
|
||||
LLSD notification;
|
||||
notification["uuid"] = id;
|
||||
LLAvatarName av_name;
|
||||
if (!LLAvatarNameCache::get(id, &av_name))
|
||||
{
|
||||
// unlikely ... they just picked this name from somewhere...
|
||||
LLAvatarNameCache::get(id, boost::bind(&LLAvatarActions::teleportRequest, id));
|
||||
return; // reinvoke this when the name resolves
|
||||
}
|
||||
notification["NAME"] = av_name.getCompleteName();
|
||||
|
||||
LLSD payload;
|
||||
|
||||
LLNotificationsUtil::add("TeleportRequestPrompt", notification, payload, teleport_request_callback);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLAvatarActions::kick(const LLUUID& id)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -114,6 +114,12 @@ public:
|
|||
*/
|
||||
static void pay(const LLUUID& id);
|
||||
|
||||
/**
|
||||
* Request teleport from other avatar
|
||||
*/
|
||||
static void teleportRequest(const LLUUID& id);
|
||||
static void teleport_request_callback(const LLSD& notification, const LLSD& response);
|
||||
|
||||
/**
|
||||
* Share items with the avatar.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -341,25 +341,25 @@ void LLNotificationChiclet::setCounter(S32 counter)
|
|||
|
||||
bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification )
|
||||
{
|
||||
bool display_notification;
|
||||
bool displayNotification;
|
||||
if ( (notification->getName() == "ScriptDialog") // special case for scripts
|
||||
// if there is no toast window for the notification, filter it
|
||||
|| (!LLNotificationWellWindow::getInstance()->findItemByID(notification->getID()))
|
||||
)
|
||||
{
|
||||
display_notification = false;
|
||||
displayNotification = false;
|
||||
}
|
||||
else if( !(notification->canLogToIM() && notification->hasFormElements())
|
||||
&& (!notification->getPayload().has("give_inventory_notification")
|
||||
|| notification->getPayload()["give_inventory_notification"]))
|
||||
{
|
||||
display_notification = true;
|
||||
displayNotification = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
display_notification = false;
|
||||
displayNotification = false;
|
||||
}
|
||||
return display_notification;
|
||||
return displayNotification;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -316,6 +316,10 @@ void LLConversationLogList::onCustomAction(const LLSD& userdata)
|
|||
{
|
||||
LLAvatarActions::offerTeleport(selected_conversation_participant_id);
|
||||
}
|
||||
else if ("request_teleport" == command_name)
|
||||
{
|
||||
LLAvatarActions::teleportRequest(selected_conversation_participant_id);
|
||||
}
|
||||
else if("add_friend" == command_name)
|
||||
{
|
||||
if (!LLAvatarActions::isFriend(selected_conversation_participant_id))
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32
|
|||
items.push_back(std::string("view_profile"));
|
||||
items.push_back(std::string("im"));
|
||||
items.push_back(std::string("offer_teleport"));
|
||||
items.push_back(std::string("request_teleport"));
|
||||
items.push_back(std::string("voice_call"));
|
||||
items.push_back(std::string("chat_history"));
|
||||
items.push_back(std::string("separator_chat_history"));
|
||||
|
|
|
|||
|
|
@ -1081,6 +1081,10 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec
|
|||
{
|
||||
LLAvatarActions::offerTeleport(selectedIDS);
|
||||
}
|
||||
else if ("request_teleport" == command)
|
||||
{
|
||||
LLAvatarActions::teleportRequest(selectedIDS.front());
|
||||
}
|
||||
else if ("voice_call" == command)
|
||||
{
|
||||
LLAvatarActions::startCall(userID);
|
||||
|
|
|
|||
|
|
@ -2257,7 +2257,6 @@ S32 LLPanelLandOptions::getDirectoryFee()
|
|||
// virtual
|
||||
void LLPanelLandOptions::draw()
|
||||
{
|
||||
refreshSearch(); // Is this necessary? JC
|
||||
LLPanel::draw();
|
||||
}
|
||||
|
||||
|
|
@ -2271,13 +2270,8 @@ void LLPanelLandOptions::refreshSearch()
|
|||
mCheckShowDirectory->set(FALSE);
|
||||
mCheckShowDirectory->setEnabled(FALSE);
|
||||
|
||||
// *TODO:Translate
|
||||
// <FS:Ansariel> FIRE-7773: Parcel categories don't stay selected
|
||||
//const std::string& none_string = LLParcel::getCategoryUIString(LLParcel::C_NONE);
|
||||
//mCategoryCombo->setSimple(none_string);
|
||||
const std::string& none_string = LLParcel::getCategoryString(LLParcel::C_NONE);
|
||||
mCategoryCombo->setValue(none_string);
|
||||
// </FS:Ansariel>
|
||||
mCategoryCombo->setEnabled(FALSE);
|
||||
return;
|
||||
}
|
||||
|
|
@ -2304,14 +2298,9 @@ void LLPanelLandOptions::refreshSearch()
|
|||
mCheckShowDirectory ->set(show_directory);
|
||||
|
||||
// Set by string in case the order in UI doesn't match the order by index.
|
||||
// *TODO:Translate
|
||||
LLParcel::ECategory cat = parcel->getCategory();
|
||||
// <FS:Ansariel> FIRE-7773: Parcel categories don't stay selected
|
||||
//const std::string& category_string = LLParcel::getCategoryUIString(cat);
|
||||
//mCategoryCombo->setSimple(category_string);
|
||||
const std::string& category_string = LLParcel::getCategoryString(cat);
|
||||
mCategoryCombo->setValue(category_string);
|
||||
// </FS:Ansariel>
|
||||
|
||||
std::string tooltip;
|
||||
bool enable_show_directory = false;
|
||||
|
|
|
|||
|
|
@ -837,6 +837,9 @@ void LLFloaterPreference::cancel()
|
|||
// hide autoreplace settings floater
|
||||
LLFloaterReg::hideInstance("prefs_autoreplace");
|
||||
|
||||
// hide spellchecker settings folder
|
||||
LLFloaterReg::hideInstance("prefs_spellchecker");
|
||||
|
||||
// <FS:CR> STORM-1888
|
||||
// hide spellchecker settings floater
|
||||
LLFloaterReg::hideInstance("prefs_spellchecker");
|
||||
|
|
|
|||
|
|
@ -1912,10 +1912,7 @@ void LLPanelEstateInfo::accessAddCore3(const uuid_vec_t& ids, void* data)
|
|||
LLSD args;
|
||||
args["NUM_ADDED"] = llformat("%d",ids.size());
|
||||
args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
|
||||
// <FS:Ansariel> Fixed unlocalizable strings
|
||||
//args["LIST_TYPE"] = "Allowed Residents";
|
||||
args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents");
|
||||
// </FS:Ansariel>
|
||||
args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
|
||||
LLNotificationsUtil::add("MaxAgentOnRegionBatch", args);
|
||||
delete change_info;
|
||||
|
|
@ -1931,10 +1928,7 @@ void LLPanelEstateInfo::accessAddCore3(const uuid_vec_t& ids, void* data)
|
|||
LLSD args;
|
||||
args["NUM_ADDED"] = llformat("%d",ids.size());
|
||||
args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
|
||||
// <FS:Ansariel> Fixed unlocalizable strings
|
||||
//args["LIST_TYPE"] = "Banned Residents";
|
||||
args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents");
|
||||
// </FS:Ansariel>
|
||||
args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
|
||||
LLNotificationsUtil::add("MaxAgentOnRegionBatch", args);
|
||||
delete change_info;
|
||||
|
|
@ -2999,15 +2993,10 @@ bool LLDispatchSetEstateAccess::operator()(
|
|||
}
|
||||
|
||||
|
||||
// <FS:Ansariel> FIRE-5998: Unlocalizable label
|
||||
//std::string msg = llformat("Banned residents: (%d, max %d)",
|
||||
// totalBannedAgents,
|
||||
// ESTATE_MAX_ACCESS_IDS);
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[BANNEDAGENTS]"] = llformat("%d", totalBannedAgents);
|
||||
args["[MAXBANNED]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS);
|
||||
std::string msg = LLTrans::getString("RegionInfoBannedResidents", args);
|
||||
// </FS:Ansariel>
|
||||
panel->getChild<LLUICtrl>("ban_resident_label")->setValue(LLSD(msg));
|
||||
|
||||
if (banned_agent_name_list)
|
||||
|
|
@ -3027,15 +3016,10 @@ bool LLDispatchSetEstateAccess::operator()(
|
|||
|
||||
if (access_flags & ESTATE_ACCESS_MANAGERS)
|
||||
{
|
||||
// <FS:Ansariel> FIRE-5998: Unlocalizable label
|
||||
//std::string msg = llformat("Estate Managers: (%d, max %d)",
|
||||
// num_estate_managers,
|
||||
// ESTATE_MAX_MANAGERS);
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[ESTATEMANAGERS]"] = llformat("%d", num_estate_managers);
|
||||
args["[MAXMANAGERS]"] = llformat("%d", ESTATE_MAX_MANAGERS);
|
||||
std::string msg = LLTrans::getString("RegionInfoEstateManagers", args);
|
||||
// </FS:Ansariel>
|
||||
panel->getChild<LLUICtrl>("estate_manager_label")->setValue(LLSD(msg));
|
||||
|
||||
LLNameListCtrl* estate_manager_name_list =
|
||||
|
|
|
|||
|
|
@ -5062,6 +5062,16 @@ void LLCallingCardBridge::performAction(LLInventoryModel* model, std::string act
|
|||
LLAvatarActions::offerTeleport(item->getCreatorUUID());
|
||||
}
|
||||
}
|
||||
else if ("request_lure" == action)
|
||||
{
|
||||
LLViewerInventoryItem *item = getItem();
|
||||
if (item && (item->getCreatorUUID() != gAgent.getID()) &&
|
||||
(!item->getCreatorUUID().isNull()))
|
||||
{
|
||||
LLAvatarActions::teleportRequest(item->getCreatorUUID());
|
||||
}
|
||||
}
|
||||
|
||||
else LLItemBridge::performAction(model, action);
|
||||
}
|
||||
|
||||
|
|
@ -5148,6 +5158,7 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
|||
items.push_back(std::string("Send Instant Message Separator"));
|
||||
items.push_back(std::string("Send Instant Message"));
|
||||
items.push_back(std::string("Offer Teleport..."));
|
||||
items.push_back(std::string("Request Teleport..."));
|
||||
items.push_back(std::string("Conference Chat"));
|
||||
|
||||
if (!good_card)
|
||||
|
|
@ -5157,6 +5168,7 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
|||
if (!good_card || !user_online)
|
||||
{
|
||||
disabled_items.push_back(std::string("Offer Teleport..."));
|
||||
disabled_items.push_back(std::string("Request Teleport..."));
|
||||
disabled_items.push_back(std::string("Conference Chat"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -558,13 +558,11 @@ void LLNetMap::draw()
|
|||
// Draw avatars
|
||||
for (U32 i = 0; i < avatar_ids.size(); i++)
|
||||
{
|
||||
// <FS:CR> FIRE-11118 - skip our dot, we'll draw one later.
|
||||
//pos_map = globalPosToView(positions[i]);
|
||||
LLUUID uuid = avatar_ids[i];
|
||||
if (uuid == gAgent.getID())
|
||||
continue;
|
||||
// Skip self, we'll draw it later
|
||||
if (uuid == gAgent.getID()) continue;
|
||||
|
||||
pos_map = globalPosToView(positions[i]);
|
||||
// </FS:CR>
|
||||
|
||||
// <FS:Ansariel> Check for unknown Z-offset => AVATAR_UNKNOWN_Z_OFFSET
|
||||
//unknown_relative_z = positions[i].mdV[VZ] == COARSEUPDATE_MAX_Z &&
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ LLContextMenu* PeopleContextMenu::createMenu()
|
|||
registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, id));
|
||||
registrar.add("Avatar.BlockUnblock", boost::bind(&LLAvatarActions::toggleBlock, id));
|
||||
registrar.add("Avatar.InviteToGroup", boost::bind(&LLAvatarActions::inviteToGroup, id));
|
||||
registrar.add("Avatar.TeleportRequest", boost::bind(&PeopleContextMenu::requestTeleport, this));
|
||||
registrar.add("Avatar.Calllog", boost::bind(&LLAvatarActions::viewChatHistory, id));
|
||||
// <FS:Ansariel> Firestorm additions
|
||||
registrar.add("Avatar.GroupInvite", boost::bind(&LLAvatarActions::inviteToGroup, id));
|
||||
|
|
@ -133,6 +134,7 @@ void PeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
|
|||
items.push_back(std::string("view_profile"));
|
||||
items.push_back(std::string("im"));
|
||||
items.push_back(std::string("offer_teleport"));
|
||||
items.push_back(std::string("request_teleport"));
|
||||
items.push_back(std::string("voice_call"));
|
||||
items.push_back(std::string("chat_history"));
|
||||
items.push_back(std::string("separator_chat_history"));
|
||||
|
|
@ -269,6 +271,13 @@ bool PeopleContextMenu::checkContextMenuItem(const LLSD& userdata)
|
|||
return false;
|
||||
}
|
||||
|
||||
void PeopleContextMenu::requestTeleport()
|
||||
{
|
||||
// boost::bind cannot recognize overloaded method LLAvatarActions::teleportRequest(),
|
||||
// so we have to use a wrapper.
|
||||
LLAvatarActions::teleportRequest(mUUIDs.front());
|
||||
}
|
||||
|
||||
void PeopleContextMenu::offerTeleport()
|
||||
{
|
||||
// boost::bind cannot recognize overloaded method LLAvatarActions::offerTeleport(),
|
||||
|
|
@ -298,6 +307,7 @@ void NearbyPeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
|
|||
items.push_back(std::string("view_profile"));
|
||||
items.push_back(std::string("im"));
|
||||
items.push_back(std::string("offer_teleport"));
|
||||
items.push_back(std::string("request_teleport"));
|
||||
items.push_back(std::string("voice_call"));
|
||||
items.push_back(std::string("chat_history"));
|
||||
items.push_back(std::string("separator_chat_history"));
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ private:
|
|||
bool enableContextMenuItem(const LLSD& userdata);
|
||||
bool checkContextMenuItem(const LLSD& userdata);
|
||||
void offerTeleport();
|
||||
void requestTeleport();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1057,12 +1057,8 @@ void LLBasicCertificateStore::validate(int validation_policy,
|
|||
throw LLInvalidCertificate((*current_cert));
|
||||
}
|
||||
std::string sha1_hash((const char *)cert_x509->sha1_hash, SHA_DIGEST_LENGTH);
|
||||
|
||||
// <FS:ND> LLBasicCertificate::getOpenSSLX509 returns a copy made with X509_dup
|
||||
X509_free( cert_x509 );
|
||||
cert_x509 = 0;
|
||||
// </FS:ND>
|
||||
|
||||
cert_x509 = NULL;
|
||||
t_cert_cache::iterator cache_entry = mTrustedCertCache.find(sha1_hash);
|
||||
if(cache_entry != mTrustedCertCache.end())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -750,7 +750,10 @@ BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL
|
|||
{
|
||||
// it is sufficient to set this value once per call to handlekey
|
||||
// without clearing it, as it is only used in the subsequent call to scanKey
|
||||
mKeyHandledByUI[translated_key] = gViewerWindow->handleKey(translated_key, translated_mask);
|
||||
mKeyHandledByUI[translated_key] = gViewerWindow->handleKey(translated_key, translated_mask);
|
||||
// mKeyHandledByUI is not what you think ... this indicates whether the UI has handled this keypress yet (any keypress)
|
||||
// NOT whether some UI shortcut wishes to handle the keypress
|
||||
|
||||
}
|
||||
return mKeyHandledByUI[translated_key];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "llinventorypanel.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llviewereventrecorder.h"
|
||||
|
||||
// newview includes
|
||||
#include "llagent.h"
|
||||
|
|
@ -2202,6 +2203,43 @@ class LLAdvancedDropPacket : public view_listener_t
|
|||
};
|
||||
|
||||
|
||||
////////////////////
|
||||
// EVENT Recorder //
|
||||
///////////////////
|
||||
|
||||
|
||||
class LLAdvancedViewerEventRecorder : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
std::string command = userdata.asString();
|
||||
if ("start playback" == command)
|
||||
{
|
||||
llinfos << "Event Playback starting" << llendl;
|
||||
LLViewerEventRecorder::instance().playbackRecording();
|
||||
llinfos << "Event Playback completed" << llendl;
|
||||
}
|
||||
else if ("stop playback" == command)
|
||||
{
|
||||
// Future
|
||||
}
|
||||
else if ("start recording" == command)
|
||||
{
|
||||
LLViewerEventRecorder::instance().setEventLoggingOn();
|
||||
llinfos << "Event recording started" << llendl;
|
||||
}
|
||||
else if ("stop recording" == command)
|
||||
{
|
||||
LLViewerEventRecorder::instance().setEventLoggingOff();
|
||||
llinfos << "Event recording stopped" << llendl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////
|
||||
// AGENT PILOT //
|
||||
|
|
@ -10308,6 +10346,8 @@ void initialize_menus()
|
|||
// Don't prepend MenuName.Foo because these can be used in any menu.
|
||||
enable.add("IsGodCustomerService", boost::bind(&is_god_customer_service));
|
||||
|
||||
enable.add("displayViewerEventRecorderMenuItems",boost::bind(&LLViewerEventRecorder::displayViewerEventRecorderMenuItems,&LLViewerEventRecorder::instance()));
|
||||
|
||||
view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts");
|
||||
|
||||
// <FS:Ansariel> [FS communication UI]
|
||||
|
|
@ -10601,6 +10641,7 @@ void initialize_menus()
|
|||
view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot");
|
||||
view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop");
|
||||
view_listener_t::addMenu(new LLAdvancedCheckAgentPilotLoop(), "Advanced.CheckAgentPilotLoop");
|
||||
view_listener_t::addMenu(new LLAdvancedViewerEventRecorder(), "Advanced.EventRecorder");
|
||||
|
||||
// Advanced > Debugging
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint");
|
||||
|
|
|
|||
|
|
@ -2545,7 +2545,7 @@ static std::string clean_name_from_im(const std::string& name, EInstantMessage t
|
|||
case IM_LURE_ACCEPTED:
|
||||
case IM_LURE_DECLINED:
|
||||
case IM_GODLIKE_LURE_USER:
|
||||
case IM_YET_TO_BE_USED:
|
||||
case IM_TELEPORT_REQUEST:
|
||||
case IM_GROUP_ELECTION_DEPRECATED:
|
||||
//IM_GOTO_URL
|
||||
//IM_FROM_TASK_AS_ALERT
|
||||
|
|
@ -3611,6 +3611,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
|
|||
break;
|
||||
|
||||
case IM_LURE_USER:
|
||||
case IM_TELEPORT_REQUEST:
|
||||
{
|
||||
// [RLVa:KB] - Checked: 2010-12-11 (RLVa-1.2.2c) | Added: RLVa-1.2.2c
|
||||
// If the lure sender is a specific @accepttp exception they will override muted and busy status
|
||||
|
|
@ -3650,7 +3651,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
|
|||
bool canUserAccessDstRegion = true;
|
||||
bool doesUserRequireMaturityIncrease = false;
|
||||
|
||||
if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
|
||||
// Do not parse the (empty) lure bucket for TELEPORT_REQUEST
|
||||
if (IM_TELEPORT_REQUEST != dialog && parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
|
||||
{
|
||||
region_access_str = LLViewerRegion::accessToString(region_access);
|
||||
region_access_icn = LLViewerRegion::getAccessIcon(region_access);
|
||||
|
|
@ -3744,7 +3746,18 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
|
|||
}
|
||||
else
|
||||
{
|
||||
LLNotification::Params params("TeleportOffered");
|
||||
LLNotification::Params params;
|
||||
if (IM_LURE_USER == dialog)
|
||||
{
|
||||
params.name = "TeleportOffered";
|
||||
params.functor.name = "TeleportOffered";
|
||||
}
|
||||
else if (IM_TELEPORT_REQUEST == dialog)
|
||||
{
|
||||
params.name = "TeleportRequest";
|
||||
params.functor.name = "TeleportRequest";
|
||||
}
|
||||
|
||||
params.substitutions = args;
|
||||
params.payload = payload;
|
||||
|
||||
|
|
@ -8490,28 +8503,13 @@ void send_group_notice(const LLUUID& group_id,
|
|||
bin_bucket_size);
|
||||
}
|
||||
|
||||
bool handle_lure_callback(const LLSD& notification, const LLSD& response)
|
||||
void send_lures(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
static const unsigned OFFER_RECIPIENT_LIMIT = 250;
|
||||
if(notification["payload"]["ids"].size() > OFFER_RECIPIENT_LIMIT)
|
||||
{
|
||||
// More than OFFER_RECIPIENT_LIMIT targets will overload the message
|
||||
// producing an llerror.
|
||||
LLSD args;
|
||||
args["OFFERS"] = notification["payload"]["ids"].size();
|
||||
args["LIMIT"] = static_cast<int>(OFFER_RECIPIENT_LIMIT);
|
||||
LLNotificationsUtil::add("TooManyTeleportOffers", args);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string text = response["message"].asString();
|
||||
LLSLURL slurl;
|
||||
LLAgentUI::buildSLURL(slurl);
|
||||
text.append("\r\n").append(slurl.getSLURLString());
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
|
||||
if(0 == option)
|
||||
{
|
||||
// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0)
|
||||
if ( (RlvActions::hasBehaviour(RLV_BHVR_SENDIM)) || (RlvActions::hasBehaviour(RLV_BHVR_SENDIMTO)) )
|
||||
{
|
||||
|
|
@ -8528,41 +8526,63 @@ bool handle_lure_callback(const LLSD& notification, const LLSD& response)
|
|||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_StartLure);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlockFast(_PREHASH_Info);
|
||||
msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in.
|
||||
msg->addStringFast(_PREHASH_Message, text);
|
||||
for(LLSD::array_const_iterator it = notification["payload"]["ids"].beginArray();
|
||||
it != notification["payload"]["ids"].endArray();
|
||||
++it)
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_StartLure);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->nextBlockFast(_PREHASH_Info);
|
||||
msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in.
|
||||
msg->addStringFast(_PREHASH_Message, text);
|
||||
for(LLSD::array_const_iterator it = notification["payload"]["ids"].beginArray();
|
||||
it != notification["payload"]["ids"].endArray();
|
||||
++it)
|
||||
{
|
||||
LLUUID target_id = it->asUUID();
|
||||
|
||||
msg->nextBlockFast(_PREHASH_TargetData);
|
||||
msg->addUUIDFast(_PREHASH_TargetID, target_id);
|
||||
|
||||
// Record the offer.
|
||||
{
|
||||
LLUUID target_id = it->asUUID();
|
||||
|
||||
msg->nextBlockFast(_PREHASH_TargetData);
|
||||
msg->addUUIDFast(_PREHASH_TargetID, target_id);
|
||||
|
||||
// Record the offer.
|
||||
{
|
||||
std::string target_name;
|
||||
gCacheName->getFullName(target_id, target_name); // for im log filenames
|
||||
LLSD args;
|
||||
args["TO_NAME"] = LLSLURL("agent", target_id, "displayname").getSLURLString();
|
||||
std::string target_name;
|
||||
gCacheName->getFullName(target_id, target_name); // for im log filenames
|
||||
LLSD args;
|
||||
args["TO_NAME"] = LLSLURL("agent", target_id, "displayname").getSLURLString();;
|
||||
|
||||
LLSD payload;
|
||||
LLSD payload;
|
||||
|
||||
//*TODO please rewrite all keys to the same case, lower or upper
|
||||
payload["from_id"] = target_id;
|
||||
LLNotificationsUtil::add("TeleportOfferSent", args, payload);
|
||||
//*TODO please rewrite all keys to the same case, lower or upper
|
||||
payload["from_id"] = target_id;
|
||||
payload["SUPPRESS_TOAST"] = true;
|
||||
LLNotificationsUtil::add("TeleportOfferSent", args, payload);
|
||||
|
||||
// Add the recepient to the recent people list.
|
||||
LLRecentPeople::instance().add(target_id);
|
||||
}
|
||||
// Add the recepient to the recent people list.
|
||||
LLRecentPeople::instance().add(target_id);
|
||||
}
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
bool handle_lure_callback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
static const unsigned OFFER_RECIPIENT_LIMIT = 250;
|
||||
if(notification["payload"]["ids"].size() > OFFER_RECIPIENT_LIMIT)
|
||||
{
|
||||
// More than OFFER_RECIPIENT_LIMIT targets will overload the message
|
||||
// producing an llerror.
|
||||
LLSD args;
|
||||
args["OFFERS"] = notification["payload"]["ids"].size();
|
||||
args["LIMIT"] = static_cast<int>(OFFER_RECIPIENT_LIMIT);
|
||||
LLNotificationsUtil::add("TooManyTeleportOffers", args);
|
||||
return false;
|
||||
}
|
||||
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
|
||||
if(0 == option)
|
||||
{
|
||||
send_lures(notification, response);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -8618,6 +8638,58 @@ void handle_lure(const uuid_vec_t& ids)
|
|||
}
|
||||
}
|
||||
|
||||
bool teleport_request_callback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLUUID from_id = notification["payload"]["from_id"].asUUID();
|
||||
if(from_id.isNull())
|
||||
{
|
||||
llwarns << "from_id is NULL" << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string from_name;
|
||||
gCacheName->getFullName(from_id, from_name);
|
||||
|
||||
if(LLMuteList::getInstance()->isMuted(from_id) && !LLMuteList::getInstance()->isLinden(from_name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
S32 option = 0;
|
||||
if (response.isInteger())
|
||||
{
|
||||
option = response.asInteger();
|
||||
}
|
||||
else
|
||||
{
|
||||
option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
}
|
||||
|
||||
switch(option)
|
||||
{
|
||||
// Yes
|
||||
case 0:
|
||||
{
|
||||
LLSD dummy_notification;
|
||||
dummy_notification["payload"]["ids"][0] = from_id;
|
||||
|
||||
LLSD dummy_response;
|
||||
dummy_response["message"] = response["message"];
|
||||
|
||||
send_lures(dummy_notification, dummy_response);
|
||||
}
|
||||
break;
|
||||
|
||||
// No
|
||||
case 1:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static LLNotificationFunctorRegistration teleport_request_callback_reg("TeleportRequest", teleport_request_callback);
|
||||
|
||||
void send_improved_im(const LLUUID& to_id,
|
||||
const std::string& name,
|
||||
|
|
|
|||
|
|
@ -1016,21 +1016,17 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
|
|||
objectp = *idle_iter;
|
||||
llassert(objectp->isActive());
|
||||
objectp->idleUpdate(agent, world, frame_time);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//update flexible objects
|
||||
LLVolumeImplFlexible::updateClass();
|
||||
|
||||
//update animated textures
|
||||
// <FS:Ansariel> FIRE-10557 / BUG-2814 / MAINT-2773: Disable texture animation doesn't work
|
||||
//LLViewerTextureAnim::updateClass();
|
||||
if (gAnimateTextures)
|
||||
{
|
||||
LLViewerTextureAnim::updateClass();
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -202,6 +202,8 @@
|
|||
#include "llagentui.h"
|
||||
#include "llwearablelist.h"
|
||||
|
||||
#include "llviewereventrecorder.h"
|
||||
|
||||
#include "llnotifications.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llnotificationmanager.h"
|
||||
|
|
@ -1010,27 +1012,18 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
|
|||
{
|
||||
llinfos << buttonname << " Mouse " << buttonstatestr << " handled by captor " << mouse_captor->getName() << llendl;
|
||||
}
|
||||
return mouse_captor->handleAnyMouseClick(local_x, local_y, mask, clicktype, down);
|
||||
}
|
||||
|
||||
// Topmost view gets a chance before the hierarchy
|
||||
//LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
|
||||
//if (top_ctrl)
|
||||
//{
|
||||
// S32 local_x, local_y;
|
||||
// top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
|
||||
// if (top_ctrl->pointInView(local_x, local_y))
|
||||
// {
|
||||
// return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down) ;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (down)
|
||||
// {
|
||||
// gFocusMgr.setTopCtrl(NULL);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
BOOL r = mouse_captor->handleAnyMouseClick(local_x, local_y, mask, clicktype, down);
|
||||
if (r) {
|
||||
|
||||
lldebugs << "LLViewerWindow::handleAnyMouseClick viewer with mousecaptor calling updatemouseeventinfo - local_x|global x "<< local_x << " " << x << "local/global y " << local_y << " " << y << llendl;
|
||||
|
||||
LLViewerEventRecorder::instance().setMouseGlobalCoords(x,y);
|
||||
LLViewerEventRecorder::instance().logMouseEvent(std::string(buttonstatestr),std::string(buttonname));
|
||||
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// Mark the click as handled and return if we aren't within the root view to avoid spurious bugs
|
||||
if( !mRootView->pointInView(x, y) )
|
||||
|
|
@ -1038,27 +1031,44 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
|
|||
return TRUE;
|
||||
}
|
||||
// Give the UI views a chance to process the click
|
||||
if( mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) )
|
||||
|
||||
BOOL r= mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) ;
|
||||
if (r)
|
||||
{
|
||||
|
||||
lldebugs << "LLViewerWindow::handleAnyMouseClick calling updatemouseeventinfo - global x "<< " " << x << "global y " << y << "buttonstate: " << buttonstatestr << " buttonname " << buttonname << llendl;
|
||||
|
||||
LLViewerEventRecorder::instance().setMouseGlobalCoords(x,y);
|
||||
|
||||
// Clear local coords - this was a click on root window so these are not needed
|
||||
// By not including them, this allows the test skeleton generation tool to be smarter when generating code
|
||||
// the code generator can be smarter because when local coords are present it can try the xui path with local coords
|
||||
// and fallback to global coordinates only if needed.
|
||||
// The drawback to this approach is sometimes a valid xui path will appear to work fine, but NOT interact with the UI element
|
||||
// (VITA support not implemented yet or not visible to VITA due to widget further up xui path not being visible to VITA)
|
||||
// For this reason it's best to provide hints where possible here by leaving out local coordinates
|
||||
LLViewerEventRecorder::instance().setMouseLocalCoords(-1,-1);
|
||||
LLViewerEventRecorder::instance().logMouseEvent(buttonstatestr,buttonname);
|
||||
|
||||
if (LLView::sDebugMouseHandling)
|
||||
{
|
||||
llinfos << buttonname << " Mouse " << buttonstatestr << " " << LLView::sMouseHandlerMessage << llendl;
|
||||
}
|
||||
llinfos << buttonname << " Mouse " << buttonstatestr << " " << LLViewerEventRecorder::instance().get_xui() << llendl;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else if (LLView::sDebugMouseHandling)
|
||||
{
|
||||
llinfos << buttonname << " Mouse " << buttonstatestr << " not handled by view" << llendl;
|
||||
}
|
||||
} else if (LLView::sDebugMouseHandling)
|
||||
{
|
||||
llinfos << buttonname << " Mouse " << buttonstatestr << " not handled by view" << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
// Do not allow tool manager to handle mouseclicks if we have disconnected
|
||||
if(!gDisconnected && LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) )
|
||||
{
|
||||
LLViewerEventRecorder::instance().clear_xui();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// If we got this far on a down-click, it wasn't handled.
|
||||
// Up-clicks, though, are always handled as far as the OS is concerned.
|
||||
BOOL default_rtn = !down;
|
||||
|
|
@ -1433,7 +1443,8 @@ BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask)
|
|||
void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
|
||||
{
|
||||
LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
|
||||
return gViewerKeyboard.scanKey(key, key_down, key_up, key_level);
|
||||
gViewerKeyboard.scanKey(key, key_down, key_up, key_level);
|
||||
return; // Be clear this function returns nothing
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2743,6 +2754,8 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
|
|||
||(gLoginMenuBarView && gLoginMenuBarView->handleKey(key, mask, TRUE))
|
||||
||(gMenuHolder && gMenuHolder->handleKey(key, mask, TRUE)))
|
||||
{
|
||||
lldebugs << "LLviewerWindow::handleKey handle nav keys for nav" << llendl;
|
||||
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -2757,12 +2770,14 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
|
|||
&& keyboard_focus
|
||||
&& keyboard_focus->handleKey(key,mask,FALSE))
|
||||
{
|
||||
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask))
|
||||
||(gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)))
|
||||
{
|
||||
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
@ -2772,6 +2787,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
|
|||
// if nothing has focus, go to first or last UI element as appropriate
|
||||
if (key == KEY_TAB && (mask & MASK_CONTROL || gFocusMgr.getKeyboardFocus() == NULL))
|
||||
{
|
||||
llwarns << "LLviewerWindow::handleKey give floaters first chance at tab key " << llendl;
|
||||
if (gMenuHolder) gMenuHolder->hideMenus();
|
||||
|
||||
// if CTRL-tabbing (and not just TAB with no focus), go into window cycle mode
|
||||
|
|
@ -2786,11 +2802,13 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
|
|||
{
|
||||
mRootView->focusNextRoot();
|
||||
}
|
||||
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
|
||||
return TRUE;
|
||||
}
|
||||
// hidden edit menu for cut/copy/paste
|
||||
if (gEditMenu && gEditMenu->handleAcceleratorKey(key, mask))
|
||||
{
|
||||
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -2859,18 +2877,27 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
|
|||
|
||||
if (keyboard_focus->handleKey(key, mask, FALSE))
|
||||
{
|
||||
|
||||
lldebugs << "LLviewerWindow::handleKey - in 'traverse up' - no loops seen... just called keyboard_focus->handleKey an it returned true" << llendl;
|
||||
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
|
||||
return TRUE;
|
||||
} else {
|
||||
lldebugs << "LLviewerWindow::handleKey - in 'traverse up' - no loops seen... just called keyboard_focus->handleKey an it returned FALSE" << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
if( LLToolMgr::getInstance()->getCurrentTool()->handleKey(key, mask) )
|
||||
{
|
||||
lldebugs << "LLviewerWindow::handleKey toolbar handling?" << llendl;
|
||||
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Try for a new-format gesture
|
||||
if (LLGestureMgr::instance().triggerGesture(key, mask))
|
||||
{
|
||||
lldebugs << "LLviewerWindow::handleKey new gesture feature" << llendl;
|
||||
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -2878,6 +2905,8 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
|
|||
// don't pass it down to the menus.
|
||||
if (gGestureList.trigger(key, mask))
|
||||
{
|
||||
lldebugs << "LLviewerWindow::handleKey check gesture trigger" << llendl;
|
||||
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -2937,7 +2966,7 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
|
|||
// HACK: Numeric keypad <enter> on Mac is Unicode 3
|
||||
// HACK: Control-M on Windows is Unicode 13
|
||||
if ((uni_char == 13 && mask != MASK_CONTROL)
|
||||
|| (uni_char == 3 && mask == MASK_NONE))
|
||||
|| (uni_char == 3 && mask == MASK_NONE) )
|
||||
{
|
||||
if (mask != MASK_ALT)
|
||||
{
|
||||
|
|
@ -2960,14 +2989,7 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
//// Topmost view gets a chance before the hierarchy
|
||||
//LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
|
||||
//if (top_ctrl && top_ctrl->handleUnicodeChar( uni_char, FALSE ) )
|
||||
//{
|
||||
// return TRUE;
|
||||
//}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
|
@ -2976,8 +2998,6 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
|
|||
|
||||
void LLViewerWindow::handleScrollWheel(S32 clicks)
|
||||
{
|
||||
LLView::sMouseHandlerMessage.clear();
|
||||
|
||||
LLUI::resetMouseIdleTimer();
|
||||
|
||||
LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
|
||||
|
|
|
|||
|
|
@ -265,7 +265,9 @@ void LLWindowListener::getPaths(LLSD const & request)
|
|||
void LLWindowListener::keyDown(LLSD const & evt)
|
||||
{
|
||||
Response response(LLSD(), evt);
|
||||
|
||||
KEY key = getKEY(evt);
|
||||
MASK mask = getMask(evt);
|
||||
|
||||
if (evt.has("path"))
|
||||
{
|
||||
std::string path(evt["path"]);
|
||||
|
|
@ -280,8 +282,6 @@ void LLWindowListener::keyDown(LLSD const & evt)
|
|||
response.setResponse(target_view->getInfo());
|
||||
|
||||
gFocusMgr.setKeyboardFocus(target_view);
|
||||
KEY key = getKEY(evt);
|
||||
MASK mask = getMask(evt);
|
||||
gViewerKeyboard.handleKey(key, mask, false);
|
||||
if(key < 0x80) mWindow->handleUnicodeChar(key, mask);
|
||||
}
|
||||
|
|
@ -294,7 +294,8 @@ void LLWindowListener::keyDown(LLSD const & evt)
|
|||
}
|
||||
else
|
||||
{
|
||||
mKbGetter()->handleTranslatedKeyDown(getKEY(evt), getMask(evt));
|
||||
gViewerKeyboard.handleKey(key, mask, false);
|
||||
if(key < 0x80) mWindow->handleUnicodeChar(key, mask);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -573,6 +573,17 @@ bool LLWorldMap::insertItem(U32 x_world, U32 y_world, std::string& name, LLUUID&
|
|||
|
||||
tooltip_fmt.setArg("[AREA]", llformat("%d", extra));
|
||||
tooltip_fmt.setArg("[PRICE]", llformat("%d", extra2));
|
||||
|
||||
// Check for division by zero
|
||||
if (extra != 0)
|
||||
{
|
||||
tooltip_fmt.setArg("[SQMPRICE]", llformat("%.1f", (F32)extra2 / (F32)extra));
|
||||
}
|
||||
else
|
||||
{
|
||||
tooltip_fmt.setArg("[SQMPRICE]", LLTrans::getString("Unknown"));
|
||||
}
|
||||
|
||||
new_item.setTooltip(tooltip_fmt.getString());
|
||||
|
||||
if (type == MAP_ITEM_LAND_FOR_SALE)
|
||||
|
|
|
|||
|
|
@ -52,6 +52,13 @@
|
|||
<on_click function="Avatar.DoToSelected" parameter="offer_teleport"/>
|
||||
<on_enable function="Avatar.EnableItem" parameter="can_offer_teleport"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Request teleport"
|
||||
layout="topleft"
|
||||
name="request_teleport">
|
||||
<on_click function="Avatar.DoToSelected" parameter="request_teleport"/>
|
||||
<on_enable function="Avatar.EnableItem" parameter="can_offer_teleport"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Voice call"
|
||||
layout="topleft"
|
||||
|
|
|
|||
|
|
@ -67,6 +67,16 @@
|
|||
function="Calllog.Enable"
|
||||
parameter="can_offer_teleport"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Request Teleport"
|
||||
name="request_teleport">
|
||||
<on_click
|
||||
function="Calllog.Action"
|
||||
parameter="request_teleport"/>
|
||||
<on_enable
|
||||
function="Calllog.Enable"
|
||||
parameter="can_offer_teleport"/>
|
||||
</menu_item_call>
|
||||
<menu_item_separator />
|
||||
<menu_item_call
|
||||
label="Add Friend"
|
||||
|
|
|
|||
|
|
@ -614,6 +614,14 @@
|
|||
function="Inventory.DoToSelected"
|
||||
parameter="lure" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Request Teleport..."
|
||||
layout="topleft"
|
||||
name="Request Teleport...">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="request_lure" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Start Conference Chat"
|
||||
layout="topleft"
|
||||
|
|
|
|||
|
|
@ -28,6 +28,15 @@
|
|||
function="Avatar.EnableItem"
|
||||
parameter="can_offer_teleport"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Request Teleport"
|
||||
name="request_teleport">
|
||||
<menu_item_call.on_click
|
||||
function="Avatar.TeleportRequest"/>
|
||||
<menu_item_call.on_enable
|
||||
function="Avatar.EnableItem"
|
||||
parameter="can_offer_teleport"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Voice call"
|
||||
layout="topleft"
|
||||
|
|
@ -134,5 +143,4 @@
|
|||
function="Avatar.EnableItem"
|
||||
parameter="can_block" />
|
||||
</menu_item_check>
|
||||
<menu_item_separator />
|
||||
</context_menu>
|
||||
|
|
|
|||
|
|
@ -3957,6 +3957,34 @@
|
|||
label="Recorder"
|
||||
name="Recorder"
|
||||
tear_off="true">
|
||||
<menu_item_call visible="false"
|
||||
label="Start event recording"
|
||||
name="Start event recording">
|
||||
<menu_item_call.on_visible
|
||||
function="displayViewerEventRecorderMenuItems" />
|
||||
<menu_item_call.on_click
|
||||
function="Advanced.EventRecorder"
|
||||
parameter="start recording" />
|
||||
</menu_item_call>
|
||||
<menu_item_call visible="false"
|
||||
label="Stop event recording"
|
||||
name="Stop event recording">
|
||||
<menu_item_call.on_visible
|
||||
function="displayViewerEventRecorderMenuItems" />
|
||||
<menu_item_call.on_click
|
||||
function="Advanced.EventRecorder"
|
||||
parameter="stop recording" />
|
||||
</menu_item_call>
|
||||
<menu_item_call visible="false"
|
||||
label="Playback event recording"
|
||||
name="Playback event recording">
|
||||
<menu_item_call.on_visible
|
||||
function="displayViewerEventRecorderMenuItems" />
|
||||
<menu_item_call.on_click
|
||||
function="Advanced.EventRecorder"
|
||||
parameter="start playback" />
|
||||
</menu_item_call>
|
||||
|
||||
<menu_item_call
|
||||
label="Start Playback"
|
||||
name="Start Playback">
|
||||
|
|
|
|||
|
|
@ -4221,6 +4221,27 @@ Join me in [REGION]
|
|||
</form>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="TeleportRequestPrompt"
|
||||
type="alertmodal">
|
||||
Request a teleport to [NAME] with the following message
|
||||
<tag>confirm</tag>
|
||||
<form name="form">
|
||||
<input name="message" type="text">
|
||||
|
||||
</input>
|
||||
<button
|
||||
default="true"
|
||||
index="0"
|
||||
name="OK"
|
||||
text="OK"/>
|
||||
<button
|
||||
index="1"
|
||||
name="Cancel"
|
||||
text="Cancel"/>
|
||||
</form>
|
||||
</notification>
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="TooManyTeleportOffers"
|
||||
|
|
@ -7099,7 +7120,7 @@ Joining this group costs a fee and the invitation cannot be accepted because of
|
|||
sound="UISndTeleportOffer">
|
||||
[NAME_SLURL] has offered to teleport you to their location:
|
||||
|
||||
“[MESSAGE]”
|
||||
"[MESSAGE]”
|
||||
<icon>[MATURITY_ICON]</icon> - [MATURITY_STR]
|
||||
<tag>confirm</tag>
|
||||
<form name="form">
|
||||
|
|
@ -7164,6 +7185,27 @@ However, this region contains content accessible to adults only.
|
|||
Teleport offer sent to [TO_NAME]
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notify.tga"
|
||||
name="TeleportRequest"
|
||||
log_to_im="true"
|
||||
type="offer">
|
||||
[NAME_SLURL] is requesting to be teleported to your location.
|
||||
[MESSAGE]
|
||||
|
||||
Offer a teleport?
|
||||
<tag>confirm</tag>
|
||||
<form name="form">
|
||||
<button
|
||||
index="0"
|
||||
name="Yes"
|
||||
text="Yes"/>
|
||||
<button
|
||||
index="1"
|
||||
name="No"
|
||||
text="No"/>
|
||||
</form>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notify.tga"
|
||||
|
|
@ -7213,7 +7255,6 @@ However, this region contains content accessible to adults only.
|
|||
icon="notify.tga"
|
||||
name="FriendshipOffered"
|
||||
log_to_im="true"
|
||||
show_toast="false"
|
||||
type="notify">
|
||||
<tag>friendship</tag>
|
||||
You have offered friendship to [TO_NAME]
|
||||
|
|
@ -7264,7 +7305,6 @@ However, this region contains content accessible to adults only.
|
|||
icon="notify.tga"
|
||||
name="FriendshipAcceptedByMe"
|
||||
log_to_im="true"
|
||||
show_toast="false"
|
||||
type="notify">
|
||||
<tag>friendship</tag>
|
||||
Friendship offer accepted.
|
||||
|
|
@ -7274,7 +7314,6 @@ Friendship offer accepted.
|
|||
icon="notify.tga"
|
||||
name="FriendshipDeclinedByMe"
|
||||
log_to_im="true"
|
||||
show_toast="false"
|
||||
type="notify">
|
||||
<tag>friendship</tag>
|
||||
Friendship offer declined.
|
||||
|
|
|
|||
|
|
@ -216,6 +216,16 @@
|
|||
width="256" />
|
||||
<check_box
|
||||
control_name="FSEnableRightclickMenuInMouselook"
|
||||
<check_box
|
||||
control_name="AutomaticFly"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
label="Hold jump or crouch key to start or stop flying"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="automatic_fly"
|
||||
width="237"
|
||||
top_pad="0"/>
|
||||
follows="left|top"
|
||||
enabled_control="EnableMouselook"
|
||||
height="16"
|
||||
|
|
|
|||
|
|
@ -323,7 +323,6 @@
|
|||
image_pressed="Pause_Press"
|
||||
image_pressed_selected="Play_Press"
|
||||
is_toggle="true"
|
||||
left_delta="60"
|
||||
left_pad="2"
|
||||
top="1"
|
||||
name="media_toggle_btn"
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ Please try logging in again in a minute.</string>
|
|||
<!-- world map -->
|
||||
<string name="texture_loading">Loading...</string>
|
||||
<string name="worldmap_offline">Offline</string>
|
||||
<string name="worldmap_item_tooltip_format">[AREA] m² L$[PRICE]</string>
|
||||
<string name="worldmap_item_tooltip_format">[AREA] m² L$[PRICE] ([SQMPRICE] L$/m²)</string>
|
||||
<string name="worldmap_results_none_found">None found.</string>
|
||||
<string name="worldmap_agent_position">You are here</string>
|
||||
|
||||
|
|
@ -877,13 +877,11 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
|
|||
</string>
|
||||
<string name="RegionInfoAllowedResidents">Allowed Residents: ([ALLOWEDAGENTS], max [MAXACCESS])</string>
|
||||
<string name="RegionInfoAllowedGroups">Allowed Groups: ([ALLOWEDGROUPS], max [MAXACCESS])</string>
|
||||
<!-- FS:Ansariel: Estate managers and banned residents strings -->
|
||||
<string name="RegionInfoEstateManagers">Estate Managers: ([ESTATEMANAGERS], max [MAXMANAGERS])</string>
|
||||
<string name="RegionInfoBannedResidents">Banned Residents: ([BANNEDAGENTS], max [MAXBANNED])</string>
|
||||
<string name="RegionInfoListTypeAllowedAgents">Allowed Residents</string>
|
||||
<string name="RegionInfoListTypeBannedAgents">Banned Residents</string>
|
||||
<!-- END FS:Ansariel: Estate managers and banned residents strings -->
|
||||
|
||||
|
||||
<!-- script limits floater -->
|
||||
<string name="ScriptLimitsParcelScriptMemory">Parcel Script Memory</string>
|
||||
<string name="ScriptLimitsParcelsOwned">Parcels Listed: [PARCELS]</string>
|
||||
|
|
|
|||
|
|
@ -1320,7 +1320,7 @@ Intenta iniciar sesión de nuevo en unos instantes.
|
|||
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
|
||||
</string>
|
||||
<string name="MarketplaceURL_CreateStore">
|
||||
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
|
||||
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
|
||||
</string>
|
||||
<string name="MarketplaceURL_Dashboard">
|
||||
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
|
||||
|
|
|
|||
|
|
@ -1271,7 +1271,7 @@ Veuillez réessayer de vous connecter dans une minute.
|
|||
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
|
||||
</string>
|
||||
<string name="MarketplaceURL_CreateStore">
|
||||
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
|
||||
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
|
||||
</string>
|
||||
<string name="MarketplaceURL_Dashboard">
|
||||
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
|
||||
|
|
|
|||
|
|
@ -1262,7 +1262,7 @@ Prova ad accedere nuovamente tra un minuto.
|
|||
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
|
||||
</string>
|
||||
<string name="MarketplaceURL_CreateStore">
|
||||
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
|
||||
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
|
||||
</string>
|
||||
<string name="MarketplaceURL_Dashboard">
|
||||
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
|
||||
|
|
|
|||
|
|
@ -1271,7 +1271,7 @@ support@secondlife.com にお問い合わせください。
|
|||
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
|
||||
</string>
|
||||
<string name="MarketplaceURL_CreateStore">
|
||||
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
|
||||
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
|
||||
</string>
|
||||
<string name="MarketplaceURL_Dashboard">
|
||||
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
|
||||
|
|
|
|||
|
|
@ -1223,7 +1223,7 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
|
|||
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
|
||||
</string>
|
||||
<string name="MarketplaceURL_CreateStore">
|
||||
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
|
||||
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
|
||||
</string>
|
||||
<string name="MarketplaceURL_Dashboard">
|
||||
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
|
||||
|
|
|
|||
|
|
@ -1271,7 +1271,7 @@ support@secondlife.com.
|
|||
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
|
||||
</string>
|
||||
<string name="MarketplaceURL_CreateStore">
|
||||
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
|
||||
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
|
||||
</string>
|
||||
<string name="MarketplaceURL_Dashboard">
|
||||
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
|
||||
|
|
|
|||
|
|
@ -1271,7 +1271,7 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
|
|||
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
|
||||
</string>
|
||||
<string name="MarketplaceURL_CreateStore">
|
||||
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
|
||||
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
|
||||
</string>
|
||||
<string name="MarketplaceURL_Dashboard">
|
||||
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
|
||||
|
|
|
|||
|
|
@ -1390,7 +1390,7 @@ Only large parcels can be listed in search.
|
|||
<combo_box.item
|
||||
label="Any Category"
|
||||
name="item0"
|
||||
value="any" />
|
||||
value="none" />
|
||||
<combo_box.item
|
||||
label="Linden Location"
|
||||
name="item1"
|
||||
|
|
|
|||
|
|
@ -133,26 +133,37 @@ class ViewerManifest(LLManifest):
|
|||
self.path("beamsColors")
|
||||
|
||||
|
||||
# CHOP-955: If we have "sourceid" in the build process
|
||||
# environment, generate it into settings_install.xml.
|
||||
try:
|
||||
sourceid = os.environ["sourceid"]
|
||||
except KeyError:
|
||||
# no sourceid, no settings_install.xml file
|
||||
pass
|
||||
else:
|
||||
if sourceid:
|
||||
# Single-entry subset of the LLSD content of settings.xml
|
||||
content = dict(sourceid=dict(Comment='Identify referring agency to Linden web servers',
|
||||
Persist=1,
|
||||
Type='String',
|
||||
Value=sourceid))
|
||||
# put_in_file(src=) need not be an actual pathname; it
|
||||
# only needs to be non-empty
|
||||
settings_install = self.put_in_file(llsd.format_pretty_xml(content),
|
||||
"settings_install.xml",
|
||||
src="environment")
|
||||
print "Put sourceid '%s' in %s" % (sourceid, settings_install)
|
||||
# CHOP-955: If we have "sourceid" or "viewer_channel" in the
|
||||
# build process environment, generate it into
|
||||
# settings_install.xml.
|
||||
settings_template = dict(
|
||||
sourceid=dict(Comment='Identify referring agency to Linden web servers',
|
||||
Persist=1,
|
||||
Type='String',
|
||||
Value=''),
|
||||
CmdLineChannel=dict(Comment='Command line specified channel name',
|
||||
Persist=0,
|
||||
Type='String',
|
||||
Value=''))
|
||||
settings_install = {}
|
||||
for key, setting in (("sourceid", "sourceid"),
|
||||
("channel", "CmdLineChannel")):
|
||||
if key in self.args:
|
||||
# only set if value is non-empty
|
||||
if self.args[key]:
|
||||
# copy corresponding setting from settings_template
|
||||
settings_install[setting] = settings_template[setting].copy()
|
||||
# then fill in Value
|
||||
settings_install[setting]["Value"] = self.args[key]
|
||||
print "Put %s '%s' in settings_install.xml" % (setting, self.args[key])
|
||||
|
||||
# did we actually copy anything into settings_install dict?
|
||||
if settings_install:
|
||||
# put_in_file(src=) need not be an actual pathname; it
|
||||
# only needs to be non-empty
|
||||
self.put_in_file(llsd.format_pretty_xml(settings_install),
|
||||
"settings_install.xml",
|
||||
src="environment")
|
||||
|
||||
self.end_prefix("app_settings")
|
||||
|
||||
|
|
@ -733,6 +744,9 @@ class WindowsManifest(ViewerManifest):
|
|||
installer_file = self.args['installer_name']
|
||||
else:
|
||||
installer_file = installer_file % substitution_strings
|
||||
if len(self.args['package_id']) > 0:
|
||||
installer_file = installer_file.replace(self.args['package_id'], "")
|
||||
installer_file = installer_file.replace(".exe", self.args['package_id'] + ".exe")
|
||||
substitution_strings['installer_file'] = installer_file
|
||||
|
||||
tempfile = "secondlife_setup_tmp.nsi"
|
||||
|
|
@ -1044,7 +1058,9 @@ class DarwinManifest(ViewerManifest):
|
|||
#[FS:CR] Understood and disregarded!
|
||||
volname = (self.app_name() + " " + '.'.join(self.args['version']) + " Installer")
|
||||
|
||||
#if self.default_channel():
|
||||
#if len(self.args['package_id']) > 0:
|
||||
# imagename = imagename + self.args['package_id']
|
||||
#elif self.default_channel():
|
||||
# if not self.default_grid():
|
||||
# # beta case
|
||||
# imagename = imagename + '_' + self.args['grid'].upper()
|
||||
|
|
@ -1057,7 +1073,7 @@ class DarwinManifest(ViewerManifest):
|
|||
# make sure we don't have stale files laying about
|
||||
self.remove(sparsename, finalname)
|
||||
|
||||
self.run_command('hdiutil create %(sparse)r -volname %(vol)r -fs HFS+ -type SPARSE -megabytes 700 -layout SPUD' % {
|
||||
self.run_command('hdiutil create %(sparse)r -volname %(vol)r -fs HFS+ -type SPARSE -megabytes 1000 -layout SPUD' % {
|
||||
'sparse':sparsename,
|
||||
'vol':volname})
|
||||
|
||||
|
|
@ -1151,6 +1167,7 @@ class DarwinManifest(ViewerManifest):
|
|||
|
||||
print "Converting temp disk image to final disk image"
|
||||
self.run_command('hdiutil convert %(sparse)r -format UDZO -imagekey zlib-level=9 -o %(final)r' % {'sparse':sparsename, 'final':finalname})
|
||||
self.run_command('hdiutil internet-enable -yes %(final)r' % {'final':finalname})
|
||||
# get rid of the temp file
|
||||
self.package_file = finalname
|
||||
self.remove(sparsename)
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ void LLUpdateChecker::checkVersion(std::string const & urlBase,
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
const char * LLUpdateChecker::Implementation::sLegacyProtocolVersion = "v1.0";
|
||||
const char * LLUpdateChecker::Implementation::sProtocolVersion = "v1.1";
|
||||
|
||||
|
||||
|
|
@ -150,40 +149,11 @@ void LLUpdateChecker::Implementation::completed(U32 status,
|
|||
server_error += content["error_text"].asString();
|
||||
}
|
||||
|
||||
if (status == 404)
|
||||
{
|
||||
if (mProtocol == sProtocolVersion)
|
||||
{
|
||||
mProtocol = sLegacyProtocolVersion;
|
||||
std::string retryUrl = buildUrl(mUrlBase, mChannel, mVersion, mPlatform, mPlatformVersion, mUniqueId, mWillingToTest);
|
||||
|
||||
LL_WARNS("UpdaterService")
|
||||
<< "update response using " << sProtocolVersion
|
||||
<< " was HTTP 404 (" << server_error
|
||||
<< "); retry with legacy protocol " << mProtocol
|
||||
<< "\n at " << retryUrl
|
||||
<< LL_ENDL;
|
||||
|
||||
mHttpClient.get(retryUrl, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("UpdaterService")
|
||||
<< "update response using " << sLegacyProtocolVersion
|
||||
<< " was 404 (" << server_error
|
||||
<< "); request failed"
|
||||
<< LL_ENDL;
|
||||
mClient.error(reason);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("UpdaterService") << "response error " << status
|
||||
<< " " << reason
|
||||
<< " (" << server_error << ")"
|
||||
<< LL_ENDL;
|
||||
mClient.error(reason);
|
||||
}
|
||||
LL_WARNS("UpdaterService") << "response error " << status
|
||||
<< " " << reason
|
||||
<< " (" << server_error << ")"
|
||||
<< LL_ENDL;
|
||||
mClient.error(reason);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -213,11 +183,8 @@ std::string LLUpdateChecker::Implementation::buildUrl(std::string const & urlBas
|
|||
path.append(channel);
|
||||
path.append(version);
|
||||
path.append(platform);
|
||||
if (mProtocol != sLegacyProtocolVersion)
|
||||
{
|
||||
path.append(platform_version);
|
||||
path.append(willing_to_test ? "testok" : "testno");
|
||||
path.append((char*)uniqueid);
|
||||
}
|
||||
path.append(platform_version);
|
||||
path.append(willing_to_test ? "testok" : "testno");
|
||||
path.append((char*)uniqueid);
|
||||
return LLURI::buildHTTP(urlBase, path).asString();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue