Merge branch 'master' into DRTVWR-497

master
Andrey Lihatskiy 2020-02-06 21:31:34 +02:00
commit fa39ff67f0
167 changed files with 3132 additions and 1077 deletions

119
.clang-format Normal file
View File

@ -0,0 +1,119 @@
---
Language: Cpp
# BasedOnStyle: Microsoft
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Allman
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
- Regex: '.*'
Priority: 1
SortPriority: 0
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 1000
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SortUsingDeclarations: true
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Latest
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
UseCRLF: false
UseTab: Never
...

View File

@ -1,45 +1,56 @@
syntax: glob
# WinMerge temp files
*.bak
# Compiled python bytecode
*.pyc
# Emacs temp files
*~
.*.swp
#OSX image cache file
# By extension
*.DS_Store
#*.orig
*.bak
*.diff
*.orig
*.pyc
*.rej
*.swp
*~
# Specific paths and/or names
LICENSES
indra/.distcc
build-linux-*
build-darwin-*
build-vc80/
build-vc100/
build-vc120/
build-vc120-32/
build-vc120-64/
indra/build-vc[0-9]*
build-linux-*
build-stamp
build-vc120*
build-vc150*
configure-stamp
debian/files
debian/secondlife-appearance-utility*
debian/secondlife-viewer*
indra/.distcc
indra/CMakeFiles
indra/build-vc[0-9]*
indra/lib/mono/1.0/*.dll
indra/lib/mono/indra/*.dll
indra/lib/mono/indra/*.exe
indra/lib/mono/indra/*.pdb
indra/lib/python/eventlet/
indra/lib/python/mulib.*
indra/llwindow/glh/glh_linear.h
indra/newview/app_settings/dictionaries
indra/newview/app_settings/mozilla
indra/newview/app_settings/mozilla-runtime-*
indra/newview/app_settings/mozilla_debug
indra/newview/app_settings/static_*.db2
indra/newview/avatar_icons_cache.txt
indra/newview/avatar_lad.log
indra/newview/browser_profile
indra/newview/character
indra/newview/dbghelp.dll
indra/newview/filters.xml
indra/newview/fmod.dll
indra/newview/fmod.log
indra/newview/mozilla-theme
indra/newview/mozilla-universal-darwin.tgz
indra/newview/res/ll_icon.*
indra/newview/pilot.txt
indra/newview/pilot.xml
indra/newview/res-sdl/ll_icon.*
indra/newview/res/ll_icon.*
indra/newview/search_history.txt
indra/newview/teleport_history.txt
indra/newview/typed_locations.txt
indra/newview/vivox-runtime
indra/server-linux-*
indra/temp
@ -47,36 +58,15 @@ indra/test/linden_file.dat
indra/test_apps/llmediatest/dependencies/i686-win32
indra/test_apps/terrain_mule/*.dll
indra/viewer-linux-*
indra/web/dataservice/lib/shared/vault.*
indra/web/dataservice/locale.*
indra/web/dataservice/vendor.*
indra/web/doc/asset-upload/plugins/lsl_compiler/lslc
indra/web/doc/asset-upload/plugins/verify-notecard
indra/web/doc/asset-upload/plugins/verify-texture
installed.xml
libraries
tarfile_tmp
debian/secondlife-viewer*
debian/secondlife-appearance-utility*
debian/files
build-stamp
configure-stamp
^indra/lib/python/mulib.*
^web/locale.*
^web/secondlife.com.*
^web/config.*
^indra/web/dataservice/locale.*
^indra/web/dataservice/lib/shared/vault.*
^indra/web/dataservice/vendor.*
glob:indra/newview/dbghelp.dll
glob:*.cpp.orig
glob:*.cpp.bak
glob:*.h.bak
glob:*.h.orig
glob:indra/newview/typed_locations.txt
glob:indra/newview/teleport_history.txt
glob:indra/newview/search_history.txt
glob:indra/newview/filters.xml
glob:indra/newview/avatar_icons_cache.txt
glob:indra/newview/avatar_lad.log
glob:*.diff
indra/newview/pilot.txt
indra/newview/pilot.xml
*.rej
web/config.*
web/locale.*
web/secondlife.com.*

View File

@ -3427,7 +3427,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>package_description</key>
<map>
<key>canonical_repo</key>
<string>https://bitbucket.org/lindenlab/viewer-release</string>
<string>https://bitbucket.org/lindenlab/viewer</string>
<key>copyright</key>
<string>Copyright (c) 2014, Linden Research, Inc.</string>
<key>description</key>

View File

@ -259,6 +259,23 @@ then
export additional_packages=
fi
begin_section "select viewer channel"
# Look for a branch-specific viewer_channel setting
# changeset_branch is set in the sling-buildscripts
viewer_build_branch=$(echo -n "${changeset_branch:-$(repo_branch ${BUILDSCRIPTS_SRC:-$(pwd)})}" | tr -Cs 'A-Za-z0-9_' '_' | sed -E 's/^_+//; s/_+$//')
if [ -n "$viewer_build_branch" ]
then
branch_viewer_channel_var="${viewer_build_branch}_viewer_channel"
if [ -n "${!branch_viewer_channel_var}" ]
then
viewer_channel="${!branch_viewer_channel_var}"
record_event "Overriding viewer_channel for branch '$changeset_branch' to '$viewer_channel'"
else
record_event "No branch-specific viewer_channel for branch '$viewer_build_branch'; to set a branch build channel set '$branch_viewer_channel_var'"
fi
fi
end_section "select viewer channel"
python_cmd "$helpers/codeticket.py" addinput "Viewer Channel" "${viewer_channel}"
initialize_version # provided by buildscripts build.sh; sets version id

View File

@ -56,7 +56,7 @@ struct WearableEntry : public LLDictionaryEntry
BOOL mAllowMultiwear;
};
class LLWearableDictionary : public LLParamSingleton<LLWearableDictionary>,
class LLWearableDictionary : public LLSingleton<LLWearableDictionary>,
public LLDictionary<LLWearableType::EType, WearableEntry>
{
LLSINGLETON(LLWearableDictionary);
@ -64,6 +64,12 @@ class LLWearableDictionary : public LLParamSingleton<LLWearableDictionary>,
LLWearableDictionary::LLWearableDictionary()
{
if (!LLWearableType::instanceExists())
{
// LLWearableType is effectively a wrapper around LLWearableDictionary and is used as storage for LLTranslationBridge
// Todo: consider merging LLWearableType and LLWearableDictionary
LL_WARNS() << "Initing LLWearableDictionary without LLWearableType" << LL_ENDL;
}
addEntry(LLWearableType::WT_SHAPE, new WearableEntry("shape", "New Shape", LLAssetType::AT_BODYPART, LLInventoryType::ICONNAME_BODYPART_SHAPE, FALSE, FALSE));
addEntry(LLWearableType::WT_SKIN, new WearableEntry("skin", "New Skin", LLAssetType::AT_BODYPART, LLInventoryType::ICONNAME_BODYPART_SKIN, FALSE, FALSE));
addEntry(LLWearableType::WT_HAIR, new WearableEntry("hair", "New Hair", LLAssetType::AT_BODYPART, LLInventoryType::ICONNAME_BODYPART_HAIR, FALSE, FALSE));
@ -92,6 +98,7 @@ LLWearableDictionary::LLWearableDictionary()
LLWearableType::LLWearableType(LLTranslationBridge* trans)
{
// LLTranslationBridge exists, but is not ready at this point in time since strings.xml is not yet loaded
mTrans = trans;
}
@ -100,14 +107,6 @@ LLWearableType::~LLWearableType()
delete mTrans;
}
void LLWearableType::initSingleton()
{
// To make sure all wrapping functions will crash without initing LLWearableType;
LLWearableDictionary::initParamSingleton();
// Todo: consider merging LLWearableType and LLWearableDictionary
}
// static
LLWearableType::EType LLWearableType::typeNameToType(const std::string& type_name)
{

View File

@ -47,7 +47,6 @@ class LLWearableType : public LLParamSingleton<LLWearableType>
LLSINGLETON(LLWearableType, LLTranslationBridge* trans);
~LLWearableType();
friend struct WearableEntry;
void initSingleton();
public:
enum EType
{

View File

@ -664,12 +664,14 @@ bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifie
return result;
}
void LLPluginClassMedia::scrollEvent(int x, int y, MASK modifiers)
void LLPluginClassMedia::scrollEvent(int x, int y, int clicks_x, int clicks_y, MASK modifiers)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "scroll_event");
message.setValueS32("x", x);
message.setValueS32("y", y);
message.setValueS32("clicks_x", clicks_x);
message.setValueS32("clicks_y", clicks_y);
message.setValue("modifiers", translateModifiers(modifiers));
sendMessage(message);

View File

@ -118,7 +118,7 @@ public:
bool keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data);
void scrollEvent(int x, int y, MASK modifiers);
void scrollEvent(int x, int y, int clicks_x, int clicks_y, MASK modifiers);
// enable/disable media plugin debugging messages and info spam
void enableMediaPluginDebugging( bool enable );

View File

@ -1650,7 +1650,7 @@ LLPointer<LLUIImage> LLRender2D::getUIImage(const std::string& name, S32 priorit
// static
void LLRender2D::resetProvider()
{
if (LLRender2D::instanceExists)
if (LLRender2D::instanceExists())
{
LLRender2D::getInstance()->mImageProvider = NULL;
}

View File

@ -47,10 +47,18 @@ static LLDefaultChildRegistry::Register<LLCheckBoxCtrl> r("check_box");
template class LLCheckBoxCtrl* LLView::getChild<class LLCheckBoxCtrl>(
const std::string& name, BOOL recurse) const;
void LLCheckBoxCtrl::WordWrap::declareValues()
{
declare("none", EWordWrap::WRAP_NONE);
declare("down", EWordWrap::WRAP_DOWN);
declare("up", EWordWrap::WRAP_UP);
}
LLCheckBoxCtrl::Params::Params()
: initial_value("initial_value", false),
label_text("label_text"),
check_button("check_button"),
word_wrap("word_wrap", EWordWrap::WRAP_NONE),
radio_style("radio_style")
{}
@ -59,14 +67,14 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)
: LLUICtrl(p),
mTextEnabledColor(p.label_text.text_color()),
mTextDisabledColor(p.label_text.text_readonly_color()),
mFont(p.font())
mFont(p.font()),
mWordWrap(p.word_wrap)
{
mViewModel->setValue(LLSD(p.initial_value));
mViewModel->resetDirty();
static LLUICachedControl<S32> llcheckboxctrl_spacing ("UICheckboxctrlSpacing", 0);
static LLUICachedControl<S32> llcheckboxctrl_hpad ("UICheckboxctrlHPad", 0);
static LLUICachedControl<S32> llcheckboxctrl_vpad ("UICheckboxctrlVPad", 0);
static LLUICachedControl<S32> llcheckboxctrl_btn_size ("UICheckboxctrlBtnSize", 0);
// must be big enough to hold all children
setUseBoundingRect(TRUE);
@ -85,20 +93,47 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)
{
tbparams.font(p.font);
}
mLabel = LLUICtrlFactory::create<LLTextBox> (tbparams);
mLabel = LLUICtrlFactory::create<LLTextBox>(tbparams);
if (mWordWrap != WRAP_NONE)
{
// Not setWordWrap(mWordWrap != WRAP_NONE) because there might be some old lurking code that sets it manually
mLabel->setWordWrap(true);
S32 new_width = getRect().getWidth() - p.check_button.rect().getWidth() - llcheckboxctrl_hpad;
LLRect label_rect = mLabel->getRect();
label_rect.mRight = label_rect.mLeft + new_width;
mLabel->setRect(label_rect);
}
mLabel->reshapeToFitText();
addChild(mLabel);
LLRect label_rect = mLabel->getRect();
if (mLabel->getLineCount() > 1)
{
if (mWordWrap == WRAP_DOWN)
{
// reshapeToFitText uses LLView::reshape() which always reshapes
// from bottom to top, but we want to extend the bottom
// Note: might be better idea to use getRect().mTop of LLCheckBoxCtrl (+pad) as top point of new rect
S32 delta = ll_round((F32)mLabel->getFont()->getLineHeight() * mLabel->getLineSpacingMult()) - label_rect.getHeight();
label_rect.translate(0, delta);
mLabel->setRect(label_rect);
}
// else
// WRAP_UP is essentially done by reshapeToFitText() (extends from bottom to top)
// howhever it doesn't respect rect of checkbox
// todo: this should be fixed, but there are at least couple checkboxes that use this feature as is.
}
addChild(mLabel);
// Button
// Note: button cover the label by extending all the way to the right.
// Note: button cover the label by extending all the way to the right and down.
LLRect btn_rect = p.check_button.rect();
btn_rect.setOriginAndSize(
btn_rect.mLeft,
btn_rect.mBottom,
llmin(btn_rect.mBottom, label_rect.mBottom),
llmax(btn_rect.mRight, label_rect.mRight - btn_rect.mLeft),
llmax( label_rect.getHeight(), btn_rect.mTop));
llmax(label_rect.getHeight(), btn_rect.mTop));
std::string active_true_id, active_false_id;
std::string inactive_true_id, inactive_false_id;
@ -152,17 +187,26 @@ void LLCheckBoxCtrl::clear()
void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
{
S32 label_top = mLabel->getRect().mTop;
mLabel->reshapeToFitText();
LLRect label_rect = mLabel->getRect();
if (label_top != label_rect.mTop && mWordWrap == WRAP_DOWN)
{
// reshapeToFitText uses LLView::reshape() which always reshapes
// from bottom to top, but we want to extend the bottom so
// reposition control
S32 delta = label_top - label_rect.mTop;
label_rect.translate(0, delta);
mLabel->setRect(label_rect);
}
// Button
// Note: button cover the label by extending all the way to the right.
// Note: button cover the label by extending all the way to the right and down.
LLRect btn_rect = mButton->getRect();
btn_rect.setOriginAndSize(
btn_rect.mLeft,
btn_rect.mBottom,
llmin(btn_rect.mBottom, label_rect.mBottom),
llmax(btn_rect.getWidth(), label_rect.mRight - btn_rect.mLeft),
llmax(label_rect.mTop - btn_rect.mBottom, btn_rect.getHeight()));
mButton->setShape(btn_rect);

View File

@ -50,6 +50,19 @@ class LLCheckBoxCtrl
, public ll::ui::SearchableControl
{
public:
enum EWordWrap
{
WRAP_NONE,
WRAP_UP,
WRAP_DOWN
};
struct WordWrap : public LLInitParam::TypeValuesHelper<EWordWrap, WordWrap>
{
static void declareValues();
};
struct Params
: public LLInitParam::Block<Params, LLUICtrl::Params>
{
@ -58,6 +71,8 @@ public:
Optional<LLTextBox::Params> label_text;
Optional<LLButton::Params> check_button;
Optional<EWordWrap, WordWrap> word_wrap;
Ignored radio_style;
Params();
@ -129,6 +144,8 @@ protected:
LLUIColor mTextEnabledColor;
LLUIColor mTextDisabledColor;
EWordWrap mWordWrap; // off, shifts text up, shifts text down
};
// Build time optimization, generate once in .cpp file

View File

@ -788,6 +788,12 @@ void LLMenuItemCallGL::initFromParams(const Params& p)
{
setEnabledControlVariable(control);
}
else
{
LL_WARNS() << "Failed to assign 'enabled' control variable to menu " << getName()
<< ": control " << p.on_enable.control_name()
<< " does not exist." << LL_ENDL;
}
}
}
if (p.on_click.isProvided())

View File

@ -68,7 +68,8 @@ LLNotificationForm::FormIgnore::FormIgnore()
control("control"),
invert_control("invert_control", false),
save_option("save_option", false),
session_only("session_only", false)
session_only("session_only", false),
checkbox_only("checkbox_only", false)
{}
LLNotificationForm::FormButton::FormButton()
@ -195,10 +196,15 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica
{
if (p.ignore.isProvided())
{
// For all cases but IGNORE_CHECKBOX_ONLY this is name for use in preferences
mIgnoreMsg = p.ignore.text;
LLUI *ui_inst = LLUI::getInstance();
if (!p.ignore.save_option)
if (p.ignore.checkbox_only)
{
mIgnore = IGNORE_CHECKBOX_ONLY;
}
else if (!p.ignore.save_option)
{
mIgnore = p.ignore.session_only ? IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY : IGNORE_WITH_DEFAULT_RESPONSE;
}
@ -215,7 +221,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica
mIgnoreSetting = ui_inst->mSettingGroups["config"]->getControl(p.ignore.control);
mInvertSetting = p.ignore.invert_control;
}
else
else if (mIgnore > IGNORE_NO)
{
ui_inst->mSettingGroups["ignores"]->declareBOOL(name, show_notification, "Show notification with this name", LLControlVariable::PERSIST_NONDFT);
mIgnoreSetting = ui_inst->mSettingGroups["ignores"]->getControl(name);
@ -389,13 +395,12 @@ LLControlVariablePtr LLNotificationForm::getIgnoreSetting()
bool LLNotificationForm::getIgnored()
{
bool show = true;
if (mIgnore != LLNotificationForm::IGNORE_NO
if (mIgnore > LLNotificationForm::IGNORE_NO
&& mIgnoreSetting)
{
show = mIgnoreSetting->getValue().asBoolean();
if (mInvertSetting) show = !show;
}
return !show;
}
@ -696,7 +701,7 @@ void LLNotification::respond(const LLSD& response)
mTemporaryResponder = false;
}
if (mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
if (mForm->getIgnoreType() > LLNotificationForm::IGNORE_NO)
{
mForm->setIgnored(mIgnored);
if (mIgnored && mForm->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)

View File

@ -180,6 +180,7 @@ public:
Optional<std::string> control;
Optional<bool> invert_control;
Optional<bool> session_only;
Optional<bool> checkbox_only;
FormIgnore();
};
@ -232,7 +233,8 @@ public:
typedef enum e_ignore_type
{
IGNORE_NO,
IGNORE_CHECKBOX_ONLY = -1, // ignore won't be handled, will set value/checkbox only
IGNORE_NO = 0,
IGNORE_WITH_DEFAULT_RESPONSE,
IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY,
IGNORE_WITH_LAST_RESPONSE,

View File

@ -408,6 +408,16 @@ BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks)
return handled;
}
BOOL LLScrollbar::handleScrollHWheel(S32 x, S32 y, S32 clicks)
{
BOOL handled = FALSE;
if (LLScrollbar::HORIZONTAL == mOrientation)
{
handled = changeLine(clicks * mStepSize, TRUE);
}
return handled;
}
BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string &tooltip_msg)
{

View File

@ -88,6 +88,7 @@ public:
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks);
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string &tooltip_msg);

View File

@ -272,6 +272,25 @@ BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks )
return FALSE;
}
BOOL LLScrollContainer::handleScrollHWheel(S32 x, S32 y, S32 clicks)
{
if (LLUICtrl::handleScrollHWheel(x,y,clicks))
{
return TRUE;
}
LLScrollbar* horizontal = mScrollbar[HORIZONTAL];
if (horizontal->getVisible()
&& horizontal->getEnabled()
&& horizontal->handleScrollHWheel( 0, 0, clicks ) )
{
updateScroll();
return TRUE;
}
return FALSE;
}
BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop,
EDragAndDropType cargo_type,

View File

@ -107,6 +107,7 @@ public:
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
virtual BOOL handleScrollHWheel( S32 x, S32 y, S32 clicks );
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,

View File

@ -1601,6 +1601,20 @@ BOOL LLScrollListCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks)
return handled;
}
BOOL LLScrollListCtrl::handleScrollHWheel(S32 x, S32 y, S32 clicks)
{
BOOL handled = FALSE;
// Pretend the mouse is over the scrollbar
handled = mScrollbar->handleScrollHWheel( 0, 0, clicks );
if (mMouseWheelOpaque)
{
return TRUE;
}
return handled;
}
// *NOTE: Requires a valid row_index and column_index
LLRect LLScrollListCtrl::getCellRect(S32 row_index, S32 column_index)
{

View File

@ -317,6 +317,7 @@ public:
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
/*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
/*virtual*/ BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks);
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
/*virtual*/ void setEnabled(BOOL enabled);
/*virtual*/ void setFocus( BOOL b );

View File

@ -3113,6 +3113,7 @@ BOOL LLTextSegment::handleRightMouseUp(S32 x, S32 y, MASK mask) { return FALSE;
BOOL LLTextSegment::handleDoubleClick(S32 x, S32 y, MASK mask) { return FALSE; }
BOOL LLTextSegment::handleHover(S32 x, S32 y, MASK mask) { return FALSE; }
BOOL LLTextSegment::handleScrollWheel(S32 x, S32 y, S32 clicks) { return FALSE; }
BOOL LLTextSegment::handleScrollHWheel(S32 x, S32 y, S32 clicks) { return FALSE; }
BOOL LLTextSegment::handleToolTip(S32 x, S32 y, MASK mask) { return FALSE; }
const std::string& LLTextSegment::getName() const
{

View File

@ -103,6 +103,7 @@ public:
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
/*virtual*/ BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks);
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
/*virtual*/ const std::string& getName() const;
/*virtual*/ void onMouseCaptureLost();
@ -440,6 +441,8 @@ public:
S32 getVPad() { return mVPad; }
S32 getHPad() { return mHPad; }
F32 getLineSpacingMult() { return mLineSpacingMult; }
S32 getLineSpacingPixels() { return mLineSpacingPixels; } // only for multiline
S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, bool hit_past_end_of_line = true) const;
LLRect getLocalRectFromDocIndex(S32 pos) const;

View File

@ -137,13 +137,29 @@ void LLUICtrl::initFromParams(const Params& p)
{
LLControlVariable* control = findControl(p.enabled_controls.enabled);
if (control)
{
setEnabledControlVariable(control);
}
else
{
LL_WARNS() << "Failed to assign 'enabled' control variable to " << getName()
<< ": control " << p.enabled_controls.enabled()
<< " does not exist." << LL_ENDL;
}
}
else if(p.enabled_controls.disabled.isChosen())
{
LLControlVariable* control = findControl(p.enabled_controls.disabled);
if (control)
{
setDisabledControlVariable(control);
}
else
{
LL_WARNS() << "Failed to assign 'disabled' control variable to " << getName()
<< ": control " << p.enabled_controls.disabled()
<< " does not exist." << LL_ENDL;
}
}
}
if(p.controls_visibility.isProvided())
@ -152,13 +168,29 @@ void LLUICtrl::initFromParams(const Params& p)
{
LLControlVariable* control = findControl(p.controls_visibility.visible);
if (control)
{
setMakeVisibleControlVariable(control);
}
else
{
LL_WARNS() << "Failed to assign visibility control variable to " << getName()
<< ": control " << p.controls_visibility.visible()
<< " does not exist." << LL_ENDL;
}
}
else if (p.controls_visibility.invisible.isChosen())
{
LLControlVariable* control = findControl(p.controls_visibility.invisible);
if (control)
{
setMakeInvisibleControlVariable(control);
}
else
{
LL_WARNS() << "Failed to assign invisibility control variable to " << getName()
<< ": control " << p.controls_visibility.invisible()
<< " does not exist." << LL_ENDL;
}
}
}
@ -497,6 +529,11 @@ void LLUICtrl::setControlName(const std::string& control_name, LLView *context)
if (!control_name.empty())
{
LLControlVariable* control = context->findControl(control_name);
if (!control)
{
LL_WARNS() << "Failed to assign control variable to " << getName()
<< ": control "<< control_name << " does not exist." << LL_ENDL;
}
setControlVariable(control);
}
}

View File

@ -1060,6 +1060,11 @@ BOOL LLView::handleScrollWheel(S32 x, S32 y, S32 clicks)
return childrenHandleScrollWheel( x, y, clicks ) != NULL;
}
BOOL LLView::handleScrollHWheel(S32 x, S32 y, S32 clicks)
{
return childrenHandleScrollHWheel( x, y, clicks ) != NULL;
}
BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
return childrenHandleRightMouseDown( x, y, mask ) != NULL;
@ -1085,6 +1090,11 @@ LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks)
return childrenHandleMouseEvent(&LLView::handleScrollWheel, x, y, clicks, false);
}
LLView* LLView::childrenHandleScrollHWheel(S32 x, S32 y, S32 clicks)
{
return childrenHandleMouseEvent(&LLView::handleScrollHWheel, x, y, clicks, false);
}
// Called during downward traversal
LLView* LLView::childrenHandleKey(KEY key, MASK mask)
{

View File

@ -426,6 +426,7 @@ public:
/*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
/*virtual*/ BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks);
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
@ -556,6 +557,7 @@ protected:
LLView* childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask);
LLView* childrenHandleDoubleClick(S32 x, S32 y, MASK mask);
LLView* childrenHandleScrollWheel(S32 x, S32 y, S32 clicks);
LLView* childrenHandleScrollHWheel(S32 x, S32 y, S32 clicks);
LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask);
LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask);
LLView* childrenHandleToolTip(S32 x, S32 y, MASK mask);

View File

@ -613,6 +613,7 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)
IDxDiagContainer *device_containerp = NULL;
IDxDiagContainer *file_containerp = NULL;
IDxDiagContainer *driver_containerp = NULL;
DWORD dw_device_count;
// CoCreate a IDxDiagProvider*
LL_DEBUGS("AppInit") << "CoCreateInstance IID_IDxDiagProvider" << LL_ENDL;
@ -663,9 +664,18 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)
hr = dx_diag_rootp->GetChildContainer(L"DxDiag_DisplayDevices", &devices_containerp);
if(FAILED(hr) || !devices_containerp)
{
// do not release 'dirty' devices_containerp at this stage, only dx_diag_rootp
devices_containerp = NULL;
goto LCleanup;
}
// make sure there is something inside
hr = devices_containerp->GetNumberOfChildContainers(&dw_device_count);
if (FAILED(hr) || dw_device_count == 0)
{
goto LCleanup;
}
// Get device 0
LL_DEBUGS("AppInit") << "devices_containerp->GetChildContainer" << LL_ENDL;
hr = devices_containerp->GetChildContainer(L"0", &device_containerp);
@ -872,6 +882,7 @@ LLSD LLDXHardware::getDisplayInfo()
IDxDiagContainer *device_containerp = NULL;
IDxDiagContainer *file_containerp = NULL;
IDxDiagContainer *driver_containerp = NULL;
DWORD dw_device_count;
// CoCreate a IDxDiagProvider*
LL_INFOS() << "CoCreateInstance IID_IDxDiagProvider" << LL_ENDL;
@ -922,9 +933,18 @@ LLSD LLDXHardware::getDisplayInfo()
hr = dx_diag_rootp->GetChildContainer(L"DxDiag_DisplayDevices", &devices_containerp);
if(FAILED(hr) || !devices_containerp)
{
// do not release 'dirty' devices_containerp at this stage, only dx_diag_rootp
devices_containerp = NULL;
goto LCleanup;
}
// make sure there is something inside
hr = devices_containerp->GetNumberOfChildContainers(&dw_device_count);
if (FAILED(hr) || dw_device_count == 0)
{
goto LCleanup;
}
// Get device 0
LL_INFOS() << "devices_containerp->GetChildContainer" << LL_ENDL;
hr = devices_containerp->GetChildContainer(L"0", &device_containerp);
@ -976,6 +996,10 @@ LLSD LLDXHardware::getDisplayInfo()
}
LCleanup:
if (ret.emptyMap())
{
LL_INFOS() << "Failed to get data, cleaning up" << LL_ENDL;
}
SAFE_RELEASE(file_containerp);
SAFE_RELEASE(driver_containerp);
SAFE_RELEASE(device_containerp);

View File

@ -66,6 +66,7 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask) = 0;
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) = 0;
virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks) = 0;
virtual BOOL handleToolTip(S32 x, S32 y, MASK mask) = 0;
virtual const std::string& getName() const = 0;

View File

@ -467,7 +467,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (void) scrollWheel:(NSEvent *)theEvent
{
callScrollMoved(-[theEvent deltaY]);
callScrollMoved(-[theEvent deltaX], -[theEvent deltaY]);
}
- (void) mouseExited:(NSEvent *)theEvent

View File

@ -130,6 +130,10 @@ void LLWindowCallbacks::handleScrollWheel(LLWindow *window, S32 clicks)
{
}
void LLWindowCallbacks::handleScrollHWheel(LLWindow *window, S32 clicks)
{
}
void LLWindowCallbacks::handleResize(LLWindow *window, const S32 width, const S32 height)
{
}

View File

@ -56,6 +56,7 @@ public:
virtual void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask);
virtual void handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask);
virtual void handleScrollWheel(LLWindow *window, S32 clicks);
virtual void handleScrollHWheel(LLWindow *window, S32 clicks);
virtual void handleResize(LLWindow *window, S32 width, S32 height);
virtual void handleFocus(LLWindow *window);
virtual void handleFocusLost(LLWindow *window);

View File

@ -142,7 +142,7 @@ void callDoubleClick(float *pos, unsigned int mask);
void callResize(unsigned int width, unsigned int height);
void callMouseMoved(float *pos, unsigned int mask);
void callMouseDragged(float *pos, unsigned int mask);
void callScrollMoved(float delta);
void callScrollMoved(float deltaX, float deltaY);
void callMouseExit();
void callWindowFocus();
void callWindowUnfocus();

View File

@ -356,9 +356,13 @@ void callMouseDragged(float *pos, MASK mask)
gWindowImplementation->getCallbacks()->handleMouseDragged(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
}
void callScrollMoved(float delta)
void callScrollMoved(float deltaX, float deltaY)
{
gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, delta);
if ( gWindowImplementation && gWindowImplementation->getCallbacks() )
{
gWindowImplementation->getCallbacks()->handleScrollHWheel(gWindowImplementation, deltaX);
gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, deltaY);
}
}
void callMouseExit()

View File

@ -2662,6 +2662,42 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
return 0;
}
*/
case WM_MOUSEHWHEEL:
{
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEHWHEEL");
static short h_delta = 0;
RECT client_rect;
// eat scroll events that occur outside our window, since we use mouse position to direct scroll
// instead of keyboard focus
// NOTE: mouse_coord is in *window* coordinates for scroll events
POINT mouse_coord = {(S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param)};
if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord)
&& GetClientRect(window_imp->mWindowHandle, &client_rect))
{
// we have a valid mouse point and client rect
if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x
|| mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y)
{
// mouse is outside of client rect, so don't do anything
return 0;
}
}
S16 incoming_h_delta = HIWORD(w_param);
h_delta += incoming_h_delta;
// If the user rapidly spins the wheel, we can get messages with
// large deltas, like 480 or so. Thus we need to scroll more quickly.
if (h_delta <= -WHEEL_DELTA || WHEEL_DELTA <= h_delta)
{
window_imp->mCallbacks->handleScrollHWheel(window_imp, h_delta / WHEEL_DELTA);
h_delta = 0;
}
return 0;
}
// Handle mouse movement within the window
case WM_MOUSEMOVE:
{

View File

@ -660,12 +660,18 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
}
else if (message_name == "scroll_event")
{
S32 x = message_in.getValueS32("x");
S32 y = message_in.getValueS32("y");
// Mouse coordinates for cef to be able to scroll 'containers'
//S32 x = message_in.getValueS32("x");
//S32 y = message_in.getValueS32("y");
// Wheel's clicks
S32 delta_x = message_in.getValueS32("clicks_x");
S32 delta_y = message_in.getValueS32("clicks_y");
const int scaling_factor = 40;
y *= -scaling_factor;
delta_x *= -scaling_factor;
delta_y *= -scaling_factor;
mCEFLib->mouseWheel(x, y);
// mCEFLib->mouseWheel(x, y, delta_x, delta_y);
mCEFLib->mouseWheel(delta_x, delta_y);
}
else if (message_name == "text_event")
{

View File

@ -244,6 +244,7 @@ set(viewer_SOURCE_FILES
llfloaterexperienceprofile.cpp
llfloaterexperiences.cpp
llfloaterfonttest.cpp
llfloaterforgetuser.cpp
llfloatergesture.cpp
llfloatergodtools.cpp
llfloatergotoline.cpp
@ -659,6 +660,7 @@ set(viewer_SOURCE_FILES
llviewerobject.cpp
llviewerobjectlist.cpp
llvieweroctree.cpp
llviewerparcelaskplay.cpp
llviewerparcelmedia.cpp
llviewerparcelmediaautoplay.cpp
llviewerparcelmgr.cpp
@ -865,6 +867,7 @@ set(viewer_HEADER_FILES
llfloaterexperienceprofile.h
llfloaterexperiences.h
llfloaterfonttest.h
llfloaterforgetuser.h
llfloatergesture.h
llfloatergodtools.h
llfloatergotoline.h
@ -1274,6 +1277,7 @@ set(viewer_HEADER_FILES
llviewerobject.h
llviewerobjectlist.h
llvieweroctree.h
llviewerparcelaskplay.h
llviewerparcelmedia.h
llviewerparcelmediaautoplay.h
llviewerparcelmgr.h

View File

@ -1 +1 @@
6.3.6
6.3.7

View File

@ -150,16 +150,6 @@
is_running_function="Floater.IsOpen"
is_running_parameters="moveview"
/>
<command name="outbox"
available_in_toybox="false"
icon="Command_Outbox_Icon"
label_ref="Command_Outbox_Label"
tooltip_ref="Command_Outbox_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
execute_parameters="outbox"
is_running_function="Floater.IsOpen"
is_running_parameters="outbox"
/>
<command name="people"
available_in_toybox="true"
icon="Command_People_Icon"

View File

@ -4913,7 +4913,7 @@
<key>InventoryOutboxDisplayBoth</key>
<map>
<key>Comment</key>
<string>Show the legacy Merchant Outbox UI as well as the Marketplace Listings UI</string>
<string>(Deprecated) Show the legacy Merchant Outbox UI as well as the Marketplace Listings UI</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@ -7494,11 +7494,11 @@
<key>ParcelMediaAutoPlayEnable</key>
<map>
<key>Comment</key>
<string>Auto play parcel media when available</string>
<string>Auto play parcel media when available. 0 - Do not autoplay; 1- Autoplay; 2 - Ask</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<string>S32</string>
<key>Value</key>
<integer>1</integer>
</map>
@ -8434,6 +8434,17 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>RememberUser</key>
<map>
<key>Comment</key>
<string>Keep user name for next login</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>RememberPassword</key>
<map>
<key>Comment</key>
@ -9276,7 +9287,7 @@
<key>RenderShadowResolutionScale</key>
<map>
<key>Comment</key>
<string>Scale of shadow map resolution vs. screen resolution</string>
<string>Scale of shadow map resolution vs. screen resolution (only positivie values are allowed)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>

View File

@ -1713,6 +1713,24 @@ void LLAppearanceMgr::slamCategoryLinks(const LLUUID& src_id, const LLUUID& dst_
LLInventoryModel::item_array_t* items;
LLSD contents = LLSD::emptyArray();
gInventory.getDirectDescendentsOf(src_id, cats, items);
if (!cats || !items)
{
// NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean
// that the cat just doesn't have any items or subfolders).
LLViewerInventoryCategory* category = gInventory.getCategory(src_id);
if (category)
{
LL_WARNS() << "Category '" << category->getName() << "' descendents corrupted, linking content failed." << LL_ENDL;
}
else
{
LL_WARNS() << "Category could not be retrieved, linking content failed." << LL_ENDL;
}
llassert(cats != NULL && items != NULL);
return;
}
LL_INFOS() << "copying " << items->size() << " items" << LL_ENDL;
for (LLInventoryModel::item_array_t::const_iterator iter = items->begin();
iter != items->end();

View File

@ -68,6 +68,7 @@
#include "llviewerwindow.h"
#include "llviewerdisplay.h"
#include "llviewermedia.h"
#include "llviewerparcelaskplay.h"
#include "llviewerparcelmedia.h"
#include "llviewermediafocus.h"
#include "llviewermessage.h"
@ -670,7 +671,8 @@ LLAppViewer::LLAppViewer()
mReportedCrash(false),
mNumSessions(0),
mPurgeCache(false),
mPurgeOnExit(false),
mPurgeCacheOnExit(false),
mPurgeUserDataOnExit(false),
mSecondInstance(false),
mSavedFinalSnapshot(false),
mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded.
@ -1923,6 +1925,11 @@ bool LLAppViewer::cleanup()
{
gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
LL_INFOS() << "Saved settings" << LL_ENDL;
if (LLViewerParcelAskPlay::instanceExists())
{
LLViewerParcelAskPlay::getInstance()->saveSettings();
}
}
std::string warnings_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Warnings"));
@ -1943,7 +1950,7 @@ bool LLAppViewer::cleanup()
LLConversationLog::instance().cache();
}
if (mPurgeOnExit)
if (mPurgeCacheOnExit)
{
LL_INFOS() << "Purging all cache files on exit" << LL_ENDL;
gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*");
@ -1984,6 +1991,14 @@ bool LLAppViewer::cleanup()
}
}
if (mPurgeUserDataOnExit)
{
// Ideally we should not save anything from this session since it is going to be purged now,
// but this is a very 'rare' case (user deleting himself), not worth overcomplicating 'save&cleanup' code
std::string user_path = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter() + LLStartUp::getUserId();
gDirUtilp->deleteDirAndContents(user_path);
}
// Delete workers first
// shotdown all worker threads before deleting them in case of co-dependencies
mAppCoreHttp.requestStop();
@ -4455,7 +4470,7 @@ void LLAppViewer::badNetworkHandler()
// Flush all of our caches on exit in the case of disconnect due to
// invalid packets.
mPurgeOnExit = TRUE;
mPurgeCacheOnExit = TRUE;
std::ostringstream message;
message <<

View File

@ -190,6 +190,7 @@ public:
void addOnIdleCallback(const boost::function<void()>& cb); // add a callback to fire (once) when idle
void purgeUserDataOnExit() { mPurgeUserDataOnExit = true; }
void purgeCache(); // Clear the local cache.
void purgeCacheImmediate(); //clear local cache immediately.
S32 updateTextureThreads(F32 max_time);
@ -281,7 +282,8 @@ private:
std::string mSerialNumber;
bool mPurgeCache;
bool mPurgeOnExit;
bool mPurgeCacheOnExit;
bool mPurgeUserDataOnExit;
LLViewerJoystick* joystick;
bool mSavedFinalSnapshot;

View File

@ -171,7 +171,10 @@ void LLControlAvatar::matchVolumeTransform()
if (attached_av)
{
LLViewerJointAttachment *attach = attached_av->getTargetAttachmentPoint(mRootVolp);
setPositionAgent(mRootVolp->getRenderPosition());
if (getRegion() && !isDead())
{
setPositionAgent(mRootVolp->getRenderPosition());
}
attach->updateWorldPRSParent();
LLVector3 joint_pos = attach->getWorldPosition();
LLQuaternion joint_rot = attach->getWorldRotation();
@ -227,7 +230,10 @@ void LLControlAvatar::matchVolumeTransform()
#endif
setRotation(bind_rot*obj_rot);
mRoot->setWorldRotation(bind_rot*obj_rot);
setPositionAgent(vol_pos);
if (getRegion() && !isDead())
{
setPositionAgent(vol_pos);
}
mRoot->setPosition(vol_pos + mPositionConstraintFixup);
F32 global_scale = gSavedSettings.getF32("AnimatedObjectsGlobalScale");

View File

@ -490,7 +490,7 @@ bool LLConversationLog::saveToFile(const std::string& filename)
(S32)conv_it->getConversationType(),
(S32)0,
(S32)conv_it->hasOfflineMessages(),
conv_it->getConversationName().c_str(),
LLURI::escape(conv_it->getConversationName()).c_str(),
participant_id.c_str(),
conversation_id.c_str(),
LLURI::escape(conv_it->getHistoryFileName()).c_str());
@ -545,7 +545,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
params.time(LLUnits::Seconds::fromValue(time))
.conversation_type((SessionType)stype)
.has_offline_ims(has_offline_ims)
.conversation_name(conv_name_buffer)
.conversation_name(LLURI::unescape(conv_name_buffer))
.participant_id(LLUUID(part_id_buffer))
.session_id(LLUUID(conv_id_buffer))
.history_filename(LLURI::unescape(history_file_name));

View File

@ -456,7 +456,7 @@ void LLFace::setTextureIndex(U8 index)
}
else
{
if (mDrawInfo && !mDrawInfo->mTextureList.empty())
if (mDrawInfo && mDrawInfo->mTextureList.size() <= 1)
{
LL_ERRS() << "Face with no texture index references indexed texture draw info." << LL_ENDL;
}

View File

@ -1493,18 +1493,24 @@ void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
}
// static
std::string LLFavoritesOrderStorage::getStoredFavoritesFilename()
std::string LLFavoritesOrderStorage::getStoredFavoritesFilename(const std::string &grid)
{
std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
return (user_dir.empty() ? ""
: gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
"stored_favorites_"
+ LLGridManager::getInstance()->getGrid()
+ grid
+ ".xml")
);
}
// static
std::string LLFavoritesOrderStorage::getStoredFavoritesFilename()
{
return getStoredFavoritesFilename(LLGridManager::getInstance()->getGrid());
}
// static
void LLFavoritesOrderStorage::destroyClass()
{
@ -1602,6 +1608,64 @@ void LLFavoritesOrderStorage::load()
}
}
// static
void LLFavoritesOrderStorage::removeFavoritesRecordOfUser(const std::string &user, const std::string &grid)
{
std::string filename = getStoredFavoritesFilename(grid);
if (!filename.empty())
{
LLSD fav_llsd;
llifstream file;
file.open(filename.c_str());
if (file.is_open())
{
LLSDSerialize::fromXML(fav_llsd, file);
file.close();
// Note : use the "John Doe" and not the "john.doe" version of the name.
// See saveFavoritesSLURLs() here above for the reason why.
if (fav_llsd.has(user))
{
LLSD user_llsd = fav_llsd[user];
if ((user_llsd.beginArray() != user_llsd.endArray()) && user_llsd.beginArray()->has("id"))
{
for (LLSD::array_iterator iter = user_llsd.beginArray(); iter != user_llsd.endArray(); ++iter)
{
LLSD value;
value["id"] = iter->get("id").asUUID();
iter->assign(value);
}
fav_llsd[user] = user_llsd;
llofstream file;
file.open(filename.c_str());
if (file.is_open())
{
LLSDSerialize::toPrettyXML(fav_llsd, file);
file.close();
}
}
else
{
LL_INFOS("FavoritesBar") << "Removed favorites for " << user << LL_ENDL;
fav_llsd.erase(user);
}
}
llofstream out_file;
out_file.open(filename.c_str());
if (out_file.is_open())
{
LLSDSerialize::toPrettyXML(fav_llsd, out_file);
LL_INFOS("FavoritesBar") << "saved favorites to '" << filename << "' "
<< LL_ENDL;
out_file.close();
}
}
}
}
// static
void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
{
std::string filename = getStoredFavoritesFilename();

View File

@ -208,9 +208,15 @@ public:
* @see cleanup()
*/
static void destroyClass();
static std::string getStoredFavoritesFilename(const std::string &grid);
static std::string getStoredFavoritesFilename();
static std::string getSavedOrderFileName();
// Remove record of specified user's favorites from file on disk.
static void removeFavoritesRecordOfUser(const std::string &user, const std::string &grid);
// Remove record of current user's favorites from file on disk.
static void removeFavoritesRecordOfUser();
BOOL saveFavoritesRecord(bool pref_changed = false);
void showFavoritesOnLoginChanged(BOOL show);
@ -232,9 +238,6 @@ private:
void load();
// Remove record of current user's favorites from file on disk.
void removeFavoritesRecordOfUser();
void onLandmarkLoaded(const LLUUID& asset_id, class LLLandmark* landmark);
void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);

View File

@ -50,6 +50,7 @@ LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_i
mShowHistory(false),
mMessages(NULL),
mHistoryThreadsBusy(false),
mIsGroup(false),
mOpened(false)
{
}
@ -75,6 +76,7 @@ BOOL LLFloaterConversationPreview::postBuild()
{
name = conv->getConversationName();
file = conv->getHistoryFileName();
mIsGroup = (LLIMModel::LLIMSession::GROUP_SESSION == conv->getConversationType());
}
else
{
@ -82,6 +84,10 @@ BOOL LLFloaterConversationPreview::postBuild()
file = "chat";
}
mChatHistoryFileName = file;
if (mIsGroup)
{
mChatHistoryFileName += GROUP_CHAT_SUFFIX;
}
LLStringUtil::format_map_t args;
args["[NAME]"] = name;
std::string title = getString("Title", args);
@ -145,6 +151,7 @@ void LLFloaterConversationPreview::onOpen(const LLSD& key)
LLSD load_params;
load_params["load_all_history"] = true;
load_params["cut_off_todays_date"] = false;
load_params["is_group"] = mIsGroup;
// The temporary message list with "Loading..." text
// Will be deleted upon loading completion in setPages() method

View File

@ -66,6 +66,7 @@ private:
bool mShowHistory;
bool mHistoryThreadsBusy;
bool mOpened;
bool mIsGroup;
};
#endif /* LLFLOATERCONVERSATIONPREVIEW_H_ */

View File

@ -0,0 +1,348 @@
/**
* @file llfloaterforgetuser.cpp
* @brief LLFloaterForgetUser class definition.
*
* $LicenseInfo:firstyear=2019&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2019, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterforgetuser.h"
#include "llappviewer.h"
#include "llcheckboxctrl.h"
#include "llfavoritesbar.h"
#include "llnotificationsutil.h"
#include "llpanellogin.h" // for helper function getUserName() and to repopulate list if nessesary
#include "llscrolllistctrl.h"
#include "llsecapi.h"
#include "llstartup.h"
#include "llviewercontrol.h"
#include "llviewernetwork.h"
LLFloaterForgetUser::LLFloaterForgetUser(const LLSD &key)
: LLFloater("floater_forget_user"),
mLoginPanelDirty(false)
{
}
LLFloaterForgetUser::~LLFloaterForgetUser()
{
if (mLoginPanelDirty)
{
LLPanelLogin::resetFields();
}
}
BOOL LLFloaterForgetUser::postBuild()
{
mScrollList = getChild<LLScrollListCtrl>("user_list");
bool show_grid_marks = gSavedSettings.getBOOL("ForceShowGrid");
show_grid_marks |= !LLGridManager::getInstance()->isInProductionGrid();
std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
if (!show_grid_marks)
{
// Figure out if there are records for more than one grid in storage
for (std::map<std::string, std::string>::iterator grid_iter = known_grids.begin();
grid_iter != known_grids.end();
grid_iter++)
{
if (!grid_iter->first.empty()
&& grid_iter->first != MAINGRID) // a workaround since 'mIsInProductionGrid' might not be set
{
if (!gSecAPIHandler->emptyCredentialMap("login_list", grid_iter->first))
{
show_grid_marks = true;
break;
}
// "Legacy" viewer support
LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(grid_iter->first);
if (cred.notNull())
{
const LLSD &ident = cred->getIdentifier();
if (ident.isMap() && ident.has("type"))
{
show_grid_marks = true;
break;
}
}
}
}
}
mUserGridsCount.clear();
if (!show_grid_marks)
{
// just load maingrid
loadGridToList(MAINGRID, false);
}
else
{
for (std::map<std::string, std::string>::iterator grid_iter = known_grids.begin();
grid_iter != known_grids.end();
grid_iter++)
{
if (!grid_iter->first.empty())
{
loadGridToList(grid_iter->first, true);
}
}
}
mScrollList->selectFirstItem();
bool enable_button = mScrollList->getFirstSelectedIndex() != -1;
LLCheckBoxCtrl *chk_box = getChild<LLCheckBoxCtrl>("delete_data");
chk_box->setEnabled(enable_button);
chk_box->set(FALSE);
LLButton *button = getChild<LLButton>("forget");
button->setEnabled(enable_button);
button->setCommitCallback(boost::bind(&LLFloaterForgetUser::onForgetClicked, this));
return TRUE;
}
void LLFloaterForgetUser::onForgetClicked()
{
LLScrollListCtrl *scroll_list = getChild<LLScrollListCtrl>("user_list");
LLSD user_data = scroll_list->getSelectedValue();
const std::string user_id = user_data["user_id"];
LLCheckBoxCtrl *chk_box = getChild<LLCheckBoxCtrl>("delete_data");
BOOL delete_data = chk_box->getValue();
if (delete_data && mUserGridsCount[user_id] > 1)
{
// more than 1 grid uses this id
LLNotificationsUtil::add("LoginRemoveMultiGridUserData", LLSD(), LLSD(), boost::bind(&LLFloaterForgetUser::onConfirmForget, this, _1, _2));
return;
}
processForgetUser();
}
bool LLFloaterForgetUser::onConfirmForget(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0)
{
processForgetUser();
}
return false;
}
// static
bool LLFloaterForgetUser::onConfirmLogout(const LLSD& notification, const LLSD& response, const std::string &fav_id, const std::string &grid)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0)
{
// Remove creds
gSecAPIHandler->removeFromCredentialMap("login_list", grid, LLStartUp::getUserId());
LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(grid);
if (cred.notNull() && cred->userID() == LLStartUp::getUserId())
{
gSecAPIHandler->deleteCredential(cred);
}
// Clean favorites
LLFavoritesOrderStorage::removeFavoritesRecordOfUser(fav_id, grid);
// mark data for removal
LLAppViewer::instance()->purgeUserDataOnExit();
LLAppViewer::instance()->requestQuit();
}
return false;
}
void LLFloaterForgetUser::processForgetUser()
{
LLScrollListCtrl *scroll_list = getChild<LLScrollListCtrl>("user_list");
LLCheckBoxCtrl *chk_box = getChild<LLCheckBoxCtrl>("delete_data");
BOOL delete_data = chk_box->getValue();
LLSD user_data = scroll_list->getSelectedValue();
const std::string user_id = user_data["user_id"];
const std::string grid = user_data["grid"];
const std::string user_name = user_data["label"]; // for favorites
if (delete_data && user_id == LLStartUp::getUserId() && LLStartUp::getStartupState() > STATE_LOGIN_WAIT)
{
// we can't delete data for user that is currently logged in
// we need to pass grid because we are deleting data universal to grids, but specific grid's user
LLNotificationsUtil::add("LoginCantRemoveCurUsername", LLSD(), LLSD(), boost::bind(onConfirmLogout, _1, _2, user_name, grid));
return;
}
// key is used for name of user's folder and in credencials
// user_name is edentical to favorite's username
forgetUser(user_id, user_name, grid, delete_data);
mLoginPanelDirty = true;
if (delete_data)
{
mUserGridsCount[user_id] = 0; //no data left to care about
}
else
{
mUserGridsCount[user_id]--;
}
// Update UI
scroll_list->deleteSelectedItems();
scroll_list->selectFirstItem();
if (scroll_list->getFirstSelectedIndex() == -1)
{
LLButton *button = getChild<LLButton>("forget");
button->setEnabled(false);
chk_box->setEnabled(false);
}
}
//static
void LLFloaterForgetUser::forgetUser(const std::string &userid, const std::string &fav_id, const std::string &grid, bool delete_data)
{
// Remove creds
gSecAPIHandler->removeFromCredentialMap("login_list", grid, userid);
LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(grid);
if (cred.notNull() && cred->userID() == userid)
{
gSecAPIHandler->deleteCredential(cred);
}
// Clean data
if (delete_data)
{
std::string user_path = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter() + userid;
gDirUtilp->deleteDirAndContents(user_path);
// Clean favorites
LLFavoritesOrderStorage::removeFavoritesRecordOfUser(fav_id, grid);
// Note: we do not clean user-related files from cache because there are id dependent (inventory)
// files and cache has separate cleaning mechanism either way.
// Also this only cleans user from current grid, not all of them.
}
}
void LLFloaterForgetUser::loadGridToList(const std::string &grid, bool show_grid_name)
{
std::string grid_label;
if (show_grid_name)
{
grid_label = LLGridManager::getInstance()->getGridId(grid); //login id (shortened label)
}
if (gSecAPIHandler->hasCredentialMap("login_list", grid))
{
LLSecAPIHandler::credential_map_t credencials;
gSecAPIHandler->loadCredentialMap("login_list", grid, credencials);
LLSecAPIHandler::credential_map_t::iterator cr_iter = credencials.begin();
LLSecAPIHandler::credential_map_t::iterator cr_end = credencials.end();
while (cr_iter != cr_end)
{
if (cr_iter->second.notNull()) // basic safety
{
std::string user_label = LLPanelLogin::getUserName(cr_iter->second);
LLSD user_data;
user_data["user_id"] = cr_iter->first;
user_data["label"] = user_label;
user_data["grid"] = grid;
if (show_grid_name)
{
user_label += " (" + grid_label + ")";
}
LLScrollListItem::Params item_params;
item_params.value(user_data);
item_params.columns.add()
.value(user_label)
.column("user")
.font(LLFontGL::getFontSansSerifSmall());
mScrollList->addRow(item_params, ADD_BOTTOM);
// Add one to grid count
std::map<std::string, S32>::iterator found = mUserGridsCount.find(cr_iter->first);
if (found != mUserGridsCount.end())
{
found->second++;
}
else
{
mUserGridsCount[cr_iter->first] = 1;
}
}
cr_iter++;
}
}
else
{
// "Legacy" viewer support
LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(grid);
if (cred.notNull())
{
const LLSD &ident = cred->getIdentifier();
if (ident.isMap() && ident.has("type"))
{
std::string user_label = LLPanelLogin::getUserName(cred);
LLSD user_data;
user_data["user_id"] = cred->userID();
user_data["label"] = user_label;
user_data["grid"] = grid;
if (show_grid_name)
{
user_label += " (" + grid_label + ")";
}
LLScrollListItem::Params item_params;
item_params.value(user_data);
item_params.columns.add()
.value(user_label)
.column("user")
.font(LLFontGL::getFontSansSerifSmall());
mScrollList->addRow(item_params, ADD_BOTTOM);
// Add one to grid count
std::map<std::string, S32>::iterator found = mUserGridsCount.find(cred->userID());
if (found != mUserGridsCount.end())
{
found->second++;
}
else
{
mUserGridsCount[cred->userID()] = 1;
}
}
}
}
}

View File

@ -0,0 +1,56 @@
/**
* @file llfloaterforgetuser.h
* @brief LLFloaterForgetUser class declaration.
*
* $LicenseInfo:firstyear=2019&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2019, 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_LLFLOATERFORGETUSER_H
#define LL_LLFLOATERFORGETUSER_H
#include "llfloater.h"
class LLScrollListCtrl;
class LLFloaterForgetUser : public LLFloater
{
public:
LLFloaterForgetUser(const LLSD &key);
~LLFloaterForgetUser();
BOOL postBuild();
void onForgetClicked();
private:
bool onConfirmForget(const LLSD& notification, const LLSD& response);
static bool onConfirmLogout(const LLSD& notification, const LLSD& response, const std::string &favorites_id, const std::string &grid);
void processForgetUser();
static void forgetUser(const std::string &userid, const std::string &fav_id, const std::string &grid, bool delete_data);
void loadGridToList(const std::string &grid, bool show_grid_name);
LLScrollListCtrl *mScrollList;
bool mLoginPanelDirty;
std::map<std::string, S32> mUserGridsCount;
};
#endif

View File

@ -108,7 +108,7 @@ LLFloaterGroupInvite::~LLFloaterGroupInvite()
}
// static
void LLFloaterGroupInvite::showForGroup(const LLUUID& group_id, uuid_vec_t *agent_ids)
void LLFloaterGroupInvite::showForGroup(const LLUUID& group_id, uuid_vec_t *agent_ids, bool request_update)
{
const LLFloater::Params& floater_params = LLFloater::getDefaultParams();
S32 floater_header_size = floater_params.header_height;
@ -126,9 +126,12 @@ void LLFloaterGroupInvite::showForGroup(const LLUUID& group_id, uuid_vec_t *agen
group_id,
(LLFloaterGroupInvite*)NULL);
// refresh group information
gAgent.sendAgentDataUpdateRequest();
LLGroupMgr::getInstance()->clearGroupData(group_id);
if (request_update)
{
// refresh group information
gAgent.sendAgentDataUpdateRequest();
LLGroupMgr::getInstance()->clearGroupData(group_id);
}
if (!fgi)

View File

@ -37,7 +37,7 @@ class LLFloaterGroupInvite
public:
virtual ~LLFloaterGroupInvite();
static void showForGroup(const LLUUID &group_id, uuid_vec_t *agent_ids = NULL);
static void showForGroup(const LLUUID &group_id, uuid_vec_t *agent_ids = NULL, bool request_update = true);
protected:
LLFloaterGroupInvite(const LLUUID& group_id = LLUUID::null);

View File

@ -2209,7 +2209,7 @@ void LLPanelLandOptions::refreshSearch()
// effort to reduce search spam from small parcels. See also
// the search crawler "grid-crawl.py" in secondlife.com/doc/app/search/ JC
const S32 MIN_PARCEL_AREA_FOR_SEARCH = 128;
bool large_enough = parcel->getArea() > MIN_PARCEL_AREA_FOR_SEARCH;
bool large_enough = parcel->getArea() >= MIN_PARCEL_AREA_FOR_SEARCH;
if (large_enough)
{
if (can_change)

View File

@ -32,6 +32,8 @@
#include "llagent.h"
#include "llappearancemgr.h"
#include "lllineeditor.h"
#include "llnotificationsutil.h"
#include "llnotifications.h"
#include "lltextbox.h"
#include "llviewercontrol.h"
@ -142,37 +144,72 @@ void LLFloaterLinkReplace::onStartClicked()
LL_WARNS() << "Cannot replace. Source and target are identical." << LL_ENDL;
return;
}
const LLUUID& source_item_id = gInventory.getLinkedItemID(mSourceUUID);
LLViewerInventoryItem *source_item = gInventory.getItem(source_item_id);
const LLUUID& target_item_id = gInventory.getLinkedItemID(mTargetUUID);
LLViewerInventoryItem *target_item = gInventory.getItem(target_item_id);
LLInventoryModel::cat_array_t cat_array;
LLLinkedItemIDMatches is_linked_item_match(mSourceUUID);
gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
cat_array,
mRemainingInventoryItems,
LLInventoryModel::INCLUDE_TRASH,
is_linked_item_match);
LL_INFOS() << "Found " << mRemainingInventoryItems.size() << " inventory links that need to be replaced." << LL_ENDL;
if (mRemainingInventoryItems.size() > 0)
LLNotification::Params params("ConfirmReplaceLink");
params.functor.function(boost::bind(&LLFloaterLinkReplace::onStartClickedResponse, this, _1, _2));
if (source_item && source_item->isWearableType() && source_item->getWearableType() <= LLWearableType::WT_EYES)
{
LLViewerInventoryItem* target_item = gInventory.getItem(mTargetUUID);
if (target_item)
if(target_item && target_item->isWearableType() && source_item->getWearableType() == target_item->getWearableType())
{
mRemainingItems = (U32)mRemainingInventoryItems.size();
LLStringUtil::format_map_t args;
args["NUM"] = llformat("%d", mRemainingItems);
mStatusText->setText(getString("ItemsRemaining", args));
mStartBtn->setEnabled(FALSE);
mRefreshBtn->setEnabled(FALSE);
mEventTimer.start();
tick();
LLNotifications::instance().forceResponse(params, 0);
}
else
{
mStatusText->setText(getString("TargetNotFound"));
LL_WARNS() << "Link replace target not found." << LL_ENDL;
LLSD args;
args["TYPE"] = LLWearableType::getTypeName(source_item->getWearableType());
params.substitutions(args);
LLNotifications::instance().add(params);
}
}
else
{
LLNotifications::instance().forceResponse(params, 0);
}
}
void LLFloaterLinkReplace::onStartClickedResponse(const LLSD& notification, const LLSD& response)
{
if (LLNotificationsUtil::getSelectedOption(notification, response) == 0)
{
LLInventoryModel::cat_array_t cat_array;
LLLinkedItemIDMatches is_linked_item_match(mSourceUUID);
gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
cat_array,
mRemainingInventoryItems,
LLInventoryModel::INCLUDE_TRASH,
is_linked_item_match);
LL_INFOS() << "Found " << mRemainingInventoryItems.size() << " inventory links that need to be replaced." << LL_ENDL;
if (mRemainingInventoryItems.size() > 0)
{
LLViewerInventoryItem* target_item = gInventory.getItem(mTargetUUID);
if (target_item)
{
mRemainingItems = (U32)mRemainingInventoryItems.size();
LLStringUtil::format_map_t args;
args["NUM"] = llformat("%d", mRemainingItems);
mStatusText->setText(getString("ItemsRemaining", args));
mStartBtn->setEnabled(FALSE);
mRefreshBtn->setEnabled(FALSE);
mEventTimer.start();
tick();
}
else
{
mStatusText->setText(getString("TargetNotFound"));
LL_WARNS() << "Link replace target not found." << LL_ENDL;
}
}
}
}

View File

@ -94,6 +94,7 @@ public:
private:
void checkEnableStart();
void onStartClicked();
void onStartClickedResponse(const LLSD& notification, const LLSD& response);
void decreaseOpenItemCount();
void updateFoundLinks();
void processBatch(LLInventoryModel::item_array_t items);

View File

@ -419,6 +419,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.TranslationSettings", boost::bind(&LLFloaterPreference::onClickTranslationSettings, this));
mCommitCallbackRegistrar.add("Pref.AutoReplace", boost::bind(&LLFloaterPreference::onClickAutoReplace, this));
mCommitCallbackRegistrar.add("Pref.PermsDefault", boost::bind(&LLFloaterPreference::onClickPermsDefault, this));
mCommitCallbackRegistrar.add("Pref.RememberedUsernames", boost::bind(&LLFloaterPreference::onClickRememberedUsernames, this));
mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
mCommitCallbackRegistrar.add("Pref.Advanced", boost::bind(&LLFloaterPreference::onClickAdvanced, this));
@ -1241,7 +1242,7 @@ void LLFloaterPreference::buildPopupLists()
LLNotificationFormPtr formp = templatep->mForm;
LLNotificationForm::EIgnoreType ignore = formp->getIgnoreType();
if (ignore == LLNotificationForm::IGNORE_NO)
if (ignore <= LLNotificationForm::IGNORE_NO)
continue;
LLSD row;
@ -1823,7 +1824,7 @@ void LLFloaterPreference::resetAllIgnored()
iter != LLNotifications::instance().templatesEnd();
++iter)
{
if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
if (iter->second->mForm->getIgnoreType() > LLNotificationForm::IGNORE_NO)
{
iter->second->mForm->setIgnored(false);
}
@ -1836,7 +1837,7 @@ void LLFloaterPreference::setAllIgnored()
iter != LLNotifications::instance().templatesEnd();
++iter)
{
if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
if (iter->second->mForm->getIgnoreType() > LLNotificationForm::IGNORE_NO)
{
iter->second->mForm->setIgnored(true);
}
@ -2256,6 +2257,11 @@ void LLFloaterPreference::onClickPermsDefault()
LLFloaterReg::showInstance("perms_default");
}
void LLFloaterPreference::onClickRememberedUsernames()
{
LLFloaterReg::showInstance("forget_username");
}
void LLFloaterPreference::onDeleteTranscripts()
{
LLSD args;
@ -2668,7 +2674,7 @@ void LLPanelPreference::updateMediaAutoPlayCheckbox(LLUICtrl* ctrl)
bool music_enabled = getChild<LLCheckBoxCtrl>("enable_music")->get();
bool media_enabled = getChild<LLCheckBoxCtrl>("enable_media")->get();
getChild<LLCheckBoxCtrl>("media_auto_play_btn")->setEnabled(music_enabled || media_enabled);
getChild<LLCheckBoxCtrl>("media_auto_play_combo")->setEnabled(music_enabled || media_enabled);
}
}

View File

@ -168,7 +168,6 @@ public:
void refreshUI();
void onCommitParcelMediaAutoPlayEnable();
void onCommitMediaEnabled();
void onCommitMusicEnabled();
void applyResolution();
@ -181,6 +180,7 @@ public:
void onClickProxySettings();
void onClickTranslationSettings();
void onClickPermsDefault();
void onClickRememberedUsernames();
void onClickAutoReplace();
void onClickSpellChecker();
void onClickRenderExceptions();

View File

@ -29,6 +29,7 @@
#include "llimprocessing.h"
#include "llagent.h"
#include "llappviewer.h"
#include "llavatarnamecache.h"
#include "llfirstuse.h"
#include "llfloaterreg.h"
@ -1474,6 +1475,7 @@ void LLIMProcessing::requestOfflineMessages()
static BOOL requested = FALSE;
if (!requested
&& gMessageSystem
&& !gDisconnected
&& LLMuteList::getInstance()->isLoaded()
&& isAgentAvatarValid()
&& gAgent.getRegion()

View File

@ -843,7 +843,7 @@ void LLIMModel::LLIMSession::loadHistory()
std::list<LLSD> chat_history;
//involves parsing of a chat history
LLLogChat::loadChatHistory(mHistoryFileName, chat_history);
LLLogChat::loadChatHistory(mHistoryFileName, chat_history, LLSD(), isGroupChat());
addMessagesFromHistory(chat_history);
}
}
@ -907,6 +907,11 @@ bool LLIMModel::LLIMSession::isP2P()
return IM_NOTHING_SPECIAL == mType;
}
bool LLIMModel::LLIMSession::isGroupChat()
{
return IM_SESSION_GROUP_START == mType || (IM_SESSION_INVITE == mType && gAgent.isInGroup(mSessionID));
}
bool LLIMModel::LLIMSession::isOtherParticipantAvaline()
{
return !mOtherParticipantIsAvatar;
@ -964,6 +969,10 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
mHistoryFileName = LLCacheName::buildUsername(mName);
}
}
else if (isGroupChat())
{
mHistoryFileName = mName + GROUP_CHAT_SUFFIX;
}
}
//static

View File

@ -91,6 +91,7 @@ public:
bool isOutgoingAdHoc() const;
bool isAdHoc();
bool isP2P();
bool isGroupChat();
bool isOtherParticipantAvaline();
bool isP2PSessionType() const { return mSessionType == P2P_SESSION;}

View File

@ -291,7 +291,6 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
if (!gSavedSettings.getBOOL("InventoryOutboxMakeVisible"))
{
getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
}
// hide marketplace listing box, unless we are a marketplace panel
if (!gSavedSettings.getBOOL("InventoryOutboxMakeVisible") && !mParams.use_marketplace_folders)

View File

@ -67,6 +67,8 @@ const std::string LL_IM_FROM("from");
const std::string LL_IM_FROM_ID("from_id");
const std::string LL_TRANSCRIPT_FILE_EXTENSION("txt");
const std::string GROUP_CHAT_SUFFIX(" (group)");
const static char IM_SYMBOL_SEPARATOR(':');
const static std::string IM_SEPARATOR(std::string() + IM_SYMBOL_SEPARATOR + " ");
const static std::string NEW_LINE("\n");
@ -355,7 +357,7 @@ void LLLogChat::saveHistory(const std::string& filename,
}
// static
void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params)
void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params, bool is_group)
{
if (file_name.empty())
{
@ -368,10 +370,25 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
if (!fptr)
{
fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
if (is_group)
{
std::string old_name(file_name);
old_name.erase(old_name.size() - GROUP_CHAT_SUFFIX.size());
fptr = LLFile::fopen(LLLogChat::makeLogFileName(old_name), "r");
if (fptr)
{
fclose(fptr);
LLFile::copy(LLLogChat::makeLogFileName(old_name), LLLogChat::makeLogFileName(file_name));
}
fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");
}
if (!fptr)
{
return; //No previous conversation with this name.
fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
if (!fptr)
{
return; //No previous conversation with this name.
}
}
}
@ -1053,12 +1070,28 @@ void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LL
if (!fptr)
{
fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
bool is_group = load_params.has("is_group") ? load_params["is_group"].asBoolean() : false;
if (is_group)
{
std::string old_name(file_name);
old_name.erase(old_name.size() - GROUP_CHAT_SUFFIX.size());
fptr = LLFile::fopen(LLLogChat::makeLogFileName(old_name), "r");
if (fptr)
{
fclose(fptr);
LLFile::copy(LLLogChat::makeLogFileName(old_name), LLLogChat::makeLogFileName(file_name));
}
fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");
}
if (!fptr)
{
mNewLoad = false;
(*mLoadEndSignal)(messages, file_name);
return; //No previous conversation with this name.
fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
if (!fptr)
{
mNewLoad = false;
(*mLoadEndSignal)(messages, file_name);
return; //No previous conversation with this name.
}
}
}

View File

@ -106,7 +106,7 @@ public:
static void getListOfTranscriptFiles(std::vector<std::string>& list);
static void getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions);
static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD());
static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD(), bool is_group = false);
typedef boost::signals2::signal<void ()> save_history_signal_t;
boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb);
@ -196,6 +196,7 @@ protected:
virtual ~LLChatLogParser() {};
};
extern const std::string GROUP_CHAT_SUFFIX;
// LLSD map lookup constants
extern const std::string LL_IM_TIME; //("time");

View File

@ -139,8 +139,11 @@ LLPointer<LLCredential> LLLoginHandler::initializeLoginInfo()
// so try to load it from the UserLoginInfo
result = loadSavedUserLoginInfo();
if (result.isNull())
{
result = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
{
// Since legacy viewer store login info one per grid, newer viewers have to
// reuse same information to remember last user and for compatibility,
// but otherwise login info is stored in separate map in gSecAPIHandler
result = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
}
return result;

View File

@ -202,11 +202,28 @@ BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks )
{
if (LLPanel::handleScrollWheel(x, y, clicks)) return TRUE;
if (mMediaSource && mMediaSource->hasMedia())
mMediaSource->getMediaPlugin()->scrollEvent(0, clicks, gKeyboard->currentMask(TRUE));
{
convertInputCoords(x, y);
mMediaSource->scrollWheel(x, y, 0, clicks, gKeyboard->currentMask(TRUE));
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
//
BOOL LLMediaCtrl::handleScrollHWheel(S32 x, S32 y, S32 clicks)
{
if (LLPanel::handleScrollHWheel(x, y, clicks)) return TRUE;
if (mMediaSource && mMediaSource->hasMedia())
{
convertInputCoords(x, y);
mMediaSource->scrollWheel(x, y, clicks, 0, gKeyboard->currentMask(TRUE));
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
// virtual
BOOL LLMediaCtrl::handleToolTip(S32 x, S32 y, MASK mask)

View File

@ -92,6 +92,7 @@ public:
virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
virtual BOOL handleScrollHWheel( S32 x, S32 y, S32 clicks );
virtual BOOL handleToolTip(S32 x, S32 y, MASK mask);
// navigation

View File

@ -574,6 +574,8 @@ BOOL LLPanelStandStopFlying::postBuild()
//mStopFlyingButton->setCommitCallback(boost::bind(&LLFloaterMove::setFlyingMode, FALSE));
mStopFlyingButton->setCommitCallback(boost::bind(&LLPanelStandStopFlying::onStopFlyingButtonClick, this));
mStopFlyingButton->setVisible(FALSE);
gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLPanelStandStopFlying::updatePosition, this));
return TRUE;
}

View File

@ -764,6 +764,7 @@ void LLPanelClassifiedEdit::processProperties(void* data, EAvatarProcessorType t
setClassifiedName(c_info->name);
setDescription(c_info->description);
setSnapshotId(c_info->snapshot_id);
setParcelId(c_info->parcel_id);
setPosGlobal(c_info->pos_global);
setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global));

View File

@ -1153,7 +1153,7 @@ void LLPanelGroupMembersSubTab::onInviteMember(void *userdata)
void LLPanelGroupMembersSubTab::handleInviteMember()
{
LLFloaterGroupInvite::showForGroup(mGroupID);
LLFloaterGroupInvite::showForGroup(mGroupID, NULL, false);
}
void LLPanelGroupMembersSubTab::onEjectMembers(void *userdata)

View File

@ -77,6 +77,60 @@ LLPanelLogin *LLPanelLogin::sInstance = NULL;
BOOL LLPanelLogin::sCapslockDidNotification = FALSE;
BOOL LLPanelLogin::sCredentialSet = FALSE;
// Helper functions
LLPointer<LLCredential> load_user_credentials(std::string &user_key)
{
if (gSecAPIHandler->hasCredentialMap("login_list", LLGridManager::getInstance()->getGrid()))
{
// user_key should be of "name Resident" format
return gSecAPIHandler->loadFromCredentialMap("login_list", LLGridManager::getInstance()->getGrid(), user_key);
}
else
{
// legacy (or legacy^2, since it also tries to load from settings)
return gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
}
}
// keys are lower case to be case insensitive so they are not always
// identical to names which retain user input, like:
// "AwEsOmE Resident" -> "awesome_resident"
std::string get_user_key_from_name(const std::string &username)
{
std::string key = username;
LLStringUtil::trim(key);
LLStringUtil::toLower(key);
if (!LLGridManager::getInstance()->isSystemGrid())
{
size_t separator_index = username.find_first_of(" ");
if (separator_index == username.npos)
{
// CRED_IDENTIFIER_TYPE_ACCOUNT
return key;
}
}
// CRED_IDENTIFIER_TYPE_AGENT
size_t separator_index = username.find_first_of(" ._");
std::string first = username.substr(0, separator_index);
std::string last;
if (separator_index != username.npos)
{
last = username.substr(separator_index + 1, username.npos);
LLStringUtil::trim(last);
}
else
{
// ...on Linden grids, single username users as considered to have
// last name "Resident"
// *TODO: Make login.cgi support "account_name" like above
last = "resident";
}
key = first + "_" + last;
return key;
}
class LLLoginLocationAutoHandler : public LLCommandHandler
{
public:
@ -168,6 +222,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
mCallback(callback),
mCallbackData(cb_data),
mListener(new LLPanelLoginListener(this)),
mFirstLoginThisInstall(gSavedSettings.getBOOL("FirstLoginThisInstall")),
mUsernameLength(0),
mPasswordLength(0),
mLocationLength(0),
@ -186,7 +241,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
login_holder->addChild(this);
}
if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
if (mFirstLoginThisInstall)
{
buildFromFile( "panel_login_first.xml");
}
@ -206,35 +261,39 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
sendChildToBack(getChildView("forgot_password_text"));
sendChildToBack(getChildView("sign_up_text"));
LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo");
updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this));
LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo");
server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this));
// Load all of the grids, sorted, and then add a bar and the current grid at the top
server_choice_combo->removeall();
std::string current_grid = LLGridManager::getInstance()->getGrid();
if (!mFirstLoginThisInstall)
{
LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo");
updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this));
std::string current_grid = LLGridManager::getInstance()->getGrid();
std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin();
grid_choice != known_grids.end();
grid_choice++)
{
if (!grid_choice->first.empty() && current_grid != grid_choice->first)
{
LL_DEBUGS("AppInit")<<"adding "<<grid_choice->first<<LL_ENDL;
server_choice_combo->add(grid_choice->second, grid_choice->first);
}
}
server_choice_combo->sortByName();
LL_DEBUGS("AppInit")<<"adding current "<<current_grid<<LL_ENDL;
server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
current_grid,
ADD_TOP);
server_choice_combo->selectFirstItem();
LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo");
server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this));
// Load all of the grids, sorted, and then add a bar and the current grid at the top
server_choice_combo->removeall();
std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin();
grid_choice != known_grids.end();
grid_choice++)
{
if (!grid_choice->first.empty() && current_grid != grid_choice->first)
{
LL_DEBUGS("AppInit") << "adding " << grid_choice->first << LL_ENDL;
server_choice_combo->add(grid_choice->second, grid_choice->first);
}
}
server_choice_combo->sortByName();
LL_DEBUGS("AppInit") << "adding current " << current_grid << LL_ENDL;
server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
current_grid,
ADD_TOP);
server_choice_combo->selectFirstItem();
}
LLSLURL start_slurl(LLStartUp::getStartSLURL());
// The StartSLURL might have been set either by an explicit command-line
@ -297,14 +356,30 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
loadLoginPage();
LLComboBox* username_combo(getChild<LLComboBox>("username_combo"));
username_combo->setTextChangedCallback(boost::bind(&LLPanelLogin::addFavoritesToStartLocation, this));
username_combo->setTextChangedCallback(boost::bind(&LLPanelLogin::onUserNameTextEnty, this));
// STEAM-14: When user presses Enter with this field in focus, initiate login
username_combo->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
username_combo->setCommitCallback(boost::bind(&LLPanelLogin::onUserListCommit, this));
username_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
username_combo->setKeystrokeOnEsc(TRUE);
if (!mFirstLoginThisInstall)
{
LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name");
remember_name->setCommitCallback(boost::bind(&LLPanelLogin::onRememberUserCheck, this));
}
}
void LLPanelLogin::addFavoritesToStartLocation()
{
if (mFirstLoginThisInstall)
{
// first login panel has no favorites, just update name length and buttons
std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple();
mUsernameLength = user_defined_name.length();
updateLoginButtons();
return;
}
// Clear the combo.
LLComboBox* combo = getChild<LLComboBox>("start_location_combo");
if (!combo) return;
@ -316,14 +391,14 @@ void LLPanelLogin::addFavoritesToStartLocation()
// Load favorites into the combo.
std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple();
LLStringUtil::trim(user_defined_name);
LLStringUtil::toLower(user_defined_name);
std::replace(user_defined_name.begin(), user_defined_name.end(), '.', ' ');
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites_" + LLGridManager::getInstance()->getGrid() + ".xml");
std::string old_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
mUsernameLength = user_defined_name.length();
updateLoginButtons();
std::string::size_type index = user_defined_name.find(' ');
std::string::size_type index = user_defined_name.find_first_of(" ._");
if (index != std::string::npos)
{
std::string username = user_defined_name.substr(0, index);
@ -332,6 +407,10 @@ void LLPanelLogin::addFavoritesToStartLocation()
{
user_defined_name = username;
}
else
{
user_defined_name = username + " " + lastname;
}
}
LLSD fav_llsd;
@ -442,24 +521,6 @@ void LLPanelLogin::giveFocus()
}
}
// static
void LLPanelLogin::showLoginWidgets()
{
if (sInstance)
{
// *NOTE: Mani - This may or may not be obselete code.
// It seems to be part of the defunct? reg-in-client project.
sInstance->getChildView("login_widgets")->setVisible( true);
LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
// *TODO: Append all the usual login parameters, like first_login=Y etc.
std::string splash_screen_url = LLGridManager::getInstance()->getLoginPage();
web_browser->navigateTo( splash_screen_url, "text/html" );
LLUICtrl* username_combo = sInstance->getChild<LLUICtrl>("username_combo");
username_combo->setFocus(TRUE);
}
}
// static
void LLPanelLogin::show(const LLRect &rect,
void (*callback)(S32 option, void* user_data),
@ -480,9 +541,54 @@ void LLPanelLogin::show(const LLRect &rect,
gFocusMgr.setDefaultKeyboardFocus(sInstance);
}
//static
void LLPanelLogin::populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd)
{
if (!sInstance)
{
LL_WARNS() << "Attempted fillFields with no login view shown" << LL_ENDL;
return;
}
if (sInstance->mFirstLoginThisInstall)
{
LLUICtrl* remember_check = sInstance->getChild<LLUICtrl>("remember_check");
remember_check->setValue(remember_psswrd);
// no list to populate
setFields(credential);
}
else
{
sInstance->getChild<LLUICtrl>("remember_name")->setValue(remember_user);
LLUICtrl* remember_password = sInstance->getChild<LLUICtrl>("remember_password");
remember_password->setValue(remember_psswrd);
remember_password->setEnabled(remember_user);
sInstance->populateUserList(credential);
}
}
//static
void LLPanelLogin::resetFields()
{
if (!sInstance)
{
// class not existing at this point might happen since this
// function is used to reset list in case of changes by external sources
return;
}
if (sInstance->mFirstLoginThisInstall)
{
// no list to populate
LL_WARNS() << "Shouldn't happen, user should have no ability to modify list on first install" << LL_ENDL;
}
else
{
LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
sInstance->populateUserList(cred);
}
}
// static
void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
BOOL remember)
void LLPanelLogin::setFields(LLPointer<LLCredential> credential)
{
if (!sInstance)
{
@ -492,36 +598,43 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
sCredentialSet = TRUE;
LL_INFOS("Credentials") << "Setting login fields to " << *credential << LL_ENDL;
LLSD identifier = credential->getIdentifier();
if((std::string)identifier["type"] == "agent")
LLSD identifier = credential.notNull() ? credential->getIdentifier() : LLSD();
if(identifier.has("type") && (std::string)identifier["type"] == "agent")
{
// not nessesary for panel_login.xml, needed for panel_login_first.xml
std::string firstname = identifier["first_name"].asString();
std::string lastname = identifier["last_name"].asString();
std::string login_id = firstname;
if (!lastname.empty() && lastname != "Resident")
if (!lastname.empty() && lastname != "Resident" && lastname != "resident")
{
// support traditional First Last name SLURLs
login_id += " ";
login_id += lastname;
}
sInstance->getChild<LLComboBox>("username_combo")->setLabel(login_id);
sInstance->getChild<LLComboBox>("username_combo")->setLabel(login_id);
sInstance->mUsernameLength = login_id.length();
}
else if((std::string)identifier["type"] == "account")
else if(identifier.has("type") && (std::string)identifier["type"] == "account")
{
sInstance->getChild<LLComboBox>("username_combo")->setLabel((std::string)identifier["account_name"]);
std::string login_id = identifier["account_name"].asString();
sInstance->getChild<LLComboBox>("username_combo")->setLabel(login_id);
sInstance->mUsernameLength = login_id.length();
}
else
{
sInstance->getChild<LLComboBox>("username_combo")->setLabel(std::string());
sInstance->getChild<LLComboBox>("username_combo")->setLabel(std::string());
sInstance->mUsernameLength = 0;
}
sInstance->addFavoritesToStartLocation();
// if the password exists in the credential, set the password field with
// a filler to get some stars
LLSD authenticator = credential->getAuthenticator();
LLSD authenticator = credential.notNull() ? credential->getAuthenticator() : LLSD();
LL_INFOS("Credentials") << "Setting authenticator field " << authenticator["type"].asString() << LL_ENDL;
if(authenticator.isMap() &&
authenticator.has("secret") &&
(authenticator["secret"].asString().size() > 0) && remember)
(authenticator["secret"].asString().size() > 0))
{
// This is a MD5 hex digest of a password.
@ -535,38 +648,28 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
}
else
{
sInstance->getChild<LLUICtrl>("password_edit")->setValue(std::string());
sInstance->getChild<LLUICtrl>("password_edit")->setValue(std::string());
sInstance->mPasswordLength = 0;
}
sInstance->getChild<LLUICtrl>("remember_check")->setValue(remember);
}
// static
void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
BOOL& remember)
bool& remember_user,
bool& remember_psswrd)
{
if (!sInstance)
{
LL_WARNS() << "Attempted getFields with no login view shown" << LL_ENDL;
return;
}
// load the credential so we can pass back the stored password or hash if the user did
// not modify the password field.
credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
LLSD identifier = LLSD::emptyMap();
LLSD authenticator = LLSD::emptyMap();
if(credential.notNull())
{
authenticator = credential->getAuthenticator();
}
std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString();
LLStringUtil::trim(username);
std::string username = sInstance->getChild<LLComboBox>("username_combo")->getSimple();
std::string password = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString();
LLStringUtil::trim(username);
LL_INFOS("Credentials", "Authentication") << "retrieving username:" << username << LL_ENDL;
// determine if the username is a first/last form or not.
@ -586,6 +689,14 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
authenticator["secret"] = password;
}
else
{
credential = load_user_credentials(username);
if (credential.notNull())
{
authenticator = credential->getAuthenticator();
}
}
}
else
{
@ -597,7 +708,7 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
if (separator_index != username.npos)
{
last = username.substr(separator_index+1, username.npos);
LLStringUtil::trim(last);
LLStringUtil::trim(last);
}
else
{
@ -625,10 +736,29 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
pass.hex_digest(md5pass);
authenticator["secret"] = md5pass;
}
else
{
std::string key = first + "_" + last;
LLStringUtil::toLower(key);
credential = load_user_credentials(key);
if (credential.notNull())
{
authenticator = credential->getAuthenticator();
}
}
}
}
credential = gSecAPIHandler->createCredential(LLGridManager::getInstance()->getGrid(), identifier, authenticator);
remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
if (!sInstance->mFirstLoginThisInstall)
{
remember_psswrd = sInstance->getChild<LLUICtrl>("remember_password")->getValue();
remember_user = sInstance->getChild<LLUICtrl>("remember_name")->getValue();
}
else
{
remember_psswrd = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
remember_user = remember_psswrd; // on panel_login_first "remember_check" is named as 'remember me'
}
}
@ -641,11 +771,8 @@ BOOL LLPanelLogin::areCredentialFieldsDirty()
}
else
{
std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString();
LLStringUtil::trim(username);
std::string password = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString();
LLComboBox* combo = sInstance->getChild<LLComboBox>("username_combo");
if(combo && combo->isDirty())
if (combo && combo->getCurrentIndex() == -1 && !combo->getValue().asString().empty())
{
return true;
}
@ -898,8 +1025,8 @@ void LLPanelLogin::onClickConnect(void *)
{
sCredentialSet = FALSE;
LLPointer<LLCredential> cred;
BOOL remember;
getFields(cred, remember);
bool remember_1, remember_2;
getFields(cred, remember_1, remember_2);
std::string identifier_type;
cred->identifierType(identifier_type);
LLSD allowed_credential_types;
@ -952,6 +1079,65 @@ void LLPanelLogin::onClickSignUp(void*)
}
}
// static
void LLPanelLogin::onUserNameTextEnty(void*)
{
sInstance->mPasswordModified = true;
sInstance->getChild<LLUICtrl>("password_edit")->setValue(std::string());
sInstance->mPasswordLength = 0;
sInstance->addFavoritesToStartLocation(); //will call updateLoginButtons()
}
// static
void LLPanelLogin::onUserListCommit(void*)
{
if (sInstance)
{
LLComboBox* username_combo(sInstance->getChild<LLComboBox>("username_combo"));
static S32 ind = -1;
if (ind != username_combo->getCurrentIndex())
{
std::string user_key = username_combo->getSelectedValue();
LLPointer<LLCredential> cred = gSecAPIHandler->loadFromCredentialMap("login_list", LLGridManager::getInstance()->getGrid(), user_key);
setFields(cred);
sInstance->mPasswordModified = false;
}
else
{
std::string pass = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString();
if (pass.empty())
{
sInstance->giveFocus();
}
else
{
onClickConnect(NULL);
}
}
}
}
// static
// At the moment only happens if !mFirstLoginThisInstall
void LLPanelLogin::onRememberUserCheck(void*)
{
if (sInstance && !sInstance->mFirstLoginThisInstall)
{
LLCheckBoxCtrl* remember_name(sInstance->getChild<LLCheckBoxCtrl>("remember_name"));
LLCheckBoxCtrl* remember_psswrd(sInstance->getChild<LLCheckBoxCtrl>("remember_password"));
LLComboBox* user_combo(sInstance->getChild<LLComboBox>("username_combo"));
bool remember = remember_name->getValue().asBoolean();
if (user_combo->getCurrentIndex() != -1 && !remember)
{
remember = true;
remember_name->setValue(true);
LLNotificationsUtil::add("LoginCantRemoveUsername");
}
remember_psswrd->setEnabled(remember);
}
}
// static
void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
{
@ -976,12 +1162,37 @@ void LLPanelLogin::updateServer()
try
{
// if they've selected another grid, we should load the credentials
// for that grid and set them to the UI.
if(!sInstance->areCredentialFieldsDirty())
// for that grid and set them to the UI. But if there were any modifications to
// fields, modifications should carry over.
// Not sure if it should carry over password but it worked like this before login changes
// Example: you started typing in and found that your are under wrong grid,
// you switch yet don't lose anything
if (sInstance->areCredentialFieldsDirty())
{
LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
bool remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
sInstance->setFields(credential, remember);
// save modified creds
LLComboBox* user_combo = sInstance->getChild<LLComboBox>("username_combo");
LLLineEditor* pswd_edit = sInstance->getChild<LLLineEditor>("password_edit");
std::string username = user_combo->getSimple();
LLStringUtil::trim(username);
std::string password = pswd_edit->getValue().asString();
// populate dropbox and setFields
// Note: following call is related to initializeLoginInfo()
LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
sInstance->populateUserList(credential);
// restore creds
user_combo->setTextEntry(username);
pswd_edit->setValue(password);
sInstance->mUsernameLength = username.length();
sInstance->mPasswordLength = password.length();
}
else
{
// populate dropbox and setFields
// Note: following call is related to initializeLoginInfo()
LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
sInstance->populateUserList(credential);
}
// update the login panel links
@ -1011,14 +1222,82 @@ void LLPanelLogin::updateLoginButtons()
LLButton* login_btn = getChild<LLButton>("connect_btn");
login_btn->setEnabled(mUsernameLength != 0 && mPasswordLength != 0);
if (!mFirstLoginThisInstall)
{
LLComboBox* user_combo = getChild<LLComboBox>("username_combo");
LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name");
if (user_combo->getCurrentIndex() != -1)
{
remember_name->setValue(true);
} // Note: might be good idea to do "else remember_name->setValue(mRememberedState)" but it might behave 'weird' to user
}
}
void LLPanelLogin::populateUserList(LLPointer<LLCredential> credential)
{
LLComboBox* user_combo = getChild<LLComboBox>("username_combo");
user_combo->removeall();
user_combo->clear();
mUsernameLength = 0;
mPasswordLength = 0;
if (gSecAPIHandler->hasCredentialMap("login_list", LLGridManager::getInstance()->getGrid()))
{
LLSecAPIHandler::credential_map_t credencials;
gSecAPIHandler->loadCredentialMap("login_list", LLGridManager::getInstance()->getGrid(), credencials);
LLSecAPIHandler::credential_map_t::iterator cr_iter = credencials.begin();
LLSecAPIHandler::credential_map_t::iterator cr_end = credencials.end();
while (cr_iter != cr_end)
{
if (cr_iter->second.notNull()) // basic safety in case of future changes
{
// cr_iter->first == user_id , to be able to be find it in case we select it
user_combo->add(LLPanelLogin::getUserName(cr_iter->second), cr_iter->first, ADD_BOTTOM, TRUE);
}
cr_iter++;
}
if (credential.isNull() || !user_combo->setSelectedByValue(LLSD(credential->userID()), true))
{
// selection failed, just deselect whatever might be selected
user_combo->setValue(std::string());
getChild<LLUICtrl>("password_edit")->setValue(std::string());
updateLoginButtons();
}
else
{
setFields(credential);
}
}
else
{
if (credential.notNull())
{
const LLSD &ident = credential->getIdentifier();
if (ident.isMap() && ident.has("type"))
{
user_combo->add(LLPanelLogin::getUserName(credential), credential->userID(), ADD_BOTTOM, TRUE);
setFields(credential);
}
else
{
updateLoginButtons();
}
}
else
{
updateLoginButtons();
}
}
}
void LLPanelLogin::onSelectServer()
{
// The user twiddled with the grid choice ui.
// apply the selection to the grid setting.
LLPointer<LLCredential> credential;
LLComboBox* server_combo = getChild<LLComboBox>("server_combo");
LLSD server_combo_val = server_combo->getSelectedValue();
LL_INFOS("AppInit") << "grid "<<server_combo_val.asString()<< LL_ENDL;
@ -1077,3 +1356,34 @@ bool LLPanelLogin::getShowFavorites()
{
return gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin");
}
// static
std::string LLPanelLogin::getUserName(LLPointer<LLCredential> &cred)
{
if (cred.isNull())
{
return "unknown";
}
const LLSD &ident = cred->getIdentifier();
if (!ident.isMap())
{
return "unknown";
}
else if ((std::string)ident["type"] == "agent")
{
std::string second_name = ident["last_name"];
if (second_name == "resident" || second_name == "Resident")
{
return (std::string)ident["first_name"];
}
return (std::string)ident["first_name"] + " " + (std::string)ident["last_name"];
}
else if ((std::string)ident["type"] == "account")
{
return LLCacheName::cleanFullName((std::string)ident["account_name"]);
}
return "unknown";
}

View File

@ -55,9 +55,9 @@ public:
void (*callback)(S32 option, void* user_data),
void* callback_data);
static void setFields(LLPointer<LLCredential> credential, BOOL remember);
static void getFields(LLPointer<LLCredential>& credential, BOOL& remember);
static void populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd);
static void resetFields();
static void getFields(LLPointer<LLCredential>& credential, bool& remember_user, bool& remember_psswrd);
static BOOL isCredentialSet() { return sCredentialSet; }
@ -72,8 +72,6 @@ public:
void setSiteIsAlive( bool alive );
void showLoginWidgets();
static void loadLoginPage();
static void giveFocus();
static void setAlwaysRefresh(bool refresh);
@ -88,6 +86,9 @@ public:
// called from prefs when initializing panel
static bool getShowFavorites();
// extract name from cred in a format apropriate for username field
static std::string getUserName(LLPointer<LLCredential> &cred);
private:
friend class LLPanelLoginListener;
void addFavoritesToStartLocation();
@ -95,11 +96,16 @@ private:
void onSelectServer();
void onLocationSLURL();
static void setFields(LLPointer<LLCredential> credential);
static void onClickConnect(void*);
static void onClickNewAccount(void*);
static void onClickVersion(void*);
static void onClickForgotPassword(void*);
static void onClickSignUp(void*);
static void onUserNameTextEnty(void*);
static void onUserListCommit(void*);
static void onRememberUserCheck(void*);
static void onPassKey(LLLineEditor* caller, void* user_data);
static void updateServerCombo();
@ -107,6 +113,7 @@ private:
boost::scoped_ptr<LLPanelLoginListener> mListener;
void updateLoginButtons();
void populateUserList(LLPointer<LLCredential> credential);
void (*mCallback)(S32 option, void *userdata);
void* mCallbackData;

View File

@ -43,6 +43,7 @@
#include "llbutton.h"
#include "lltextbox.h"
#include "llviewermedia.h"
#include "llviewerparcelaskplay.h"
#include "llviewerparcelmedia.h"
#include "llviewerregion.h"
#include "llviewermediafocus.h"
@ -83,10 +84,11 @@ LLPanelNearByMedia::LLPanelNearByMedia()
{
mHoverTimer.stop();
mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
gSavedSettings.getBOOL("MediaTentativeAutoPlay");
// This is just an initial value, mParcelAudioAutoStart does not affect ParcelMediaAutoPlayEnable
mParcelAudioAutoStart = gSavedSettings.getS32("ParcelMediaAutoPlayEnable") != 0
&& gSavedSettings.getBOOL("MediaTentativeAutoPlay");
gSavedSettings.getControl(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING)->getSignal()->connect(boost::bind(&LLPanelNearByMedia::handleMediaAutoPlayChanged, this, _2));
gSavedSettings.getControl("ParcelMediaAutoPlayEnable")->getSignal()->connect(boost::bind(&LLPanelNearByMedia::handleMediaAutoPlayChanged, this, _2));
mCommitCallbackRegistrar.add("MediaListCtrl.EnableAll", boost::bind(&LLPanelNearByMedia::onClickEnableAll, this));
mCommitCallbackRegistrar.add("MediaListCtrl.DisableAll", boost::bind(&LLPanelNearByMedia::onClickDisableAll, this));
@ -177,9 +179,18 @@ BOOL LLPanelNearByMedia::postBuild()
void LLPanelNearByMedia::handleMediaAutoPlayChanged(const LLSD& newvalue)
{
// update mParcelAudioAutoStart if AUTO_PLAY_MEDIA_SETTING changes
mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
gSavedSettings.getBOOL("MediaTentativeAutoPlay");
// update mParcelAudioAutoStartMode if "ParcelMediaAutoPlayEnable" changes
S32 value = gSavedSettings.getS32("ParcelMediaAutoPlayEnable");
mParcelAudioAutoStart = value != 0
&& gSavedSettings.getBOOL("MediaTentativeAutoPlay");
LLViewerParcelAskPlay *inst = LLViewerParcelAskPlay::getInstance();
if (value == 2 && !inst->hasData())
{
// Init if nessesary
inst->loadSettings();
}
inst->cancelNotification();
}
/*virtual*/

View File

@ -1561,12 +1561,13 @@ void LLPanelObjectInventory::refresh()
//LL_INFOS() << "LLPanelObjectInventory::refresh()" << LL_ENDL;
BOOL has_inventory = FALSE;
const BOOL non_root_ok = TRUE;
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(NULL, non_root_ok);
if(node)
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
LLSelectNode* node = selection->getFirstRootNode(NULL, non_root_ok);
if(node && node->mValid)
{
LLViewerObject* object = node->getObject();
if(object && ((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1)
|| (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)))
if(object && ((selection->getRootObjectCount() == 1)
|| (selection->getObjectCount() == 1)))
{
// determine if we need to make a request. Start with a
// default based on if we have inventory at all.

View File

@ -675,6 +675,12 @@ void LLPanelPlaces::onShowOnMapButtonClicked()
}
else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
{
if (mItem.isNull())
{
LL_WARNS() << "NULL landmark item" << LL_ENDL;
llassert(mItem.notNull());
return;
}
LLLandmark* landmark = gLandmarkList.getAsset(mItem->getAssetUUID());
if (!landmark)
return;

View File

@ -547,17 +547,17 @@ void LLPanelPrimMediaControls::updateShape()
switch (mScrollState)
{
case SCROLL_UP:
media_impl->scrollWheel(0, -1, MASK_NONE);
media_impl->scrollWheel(0, 0, 0, -1, MASK_NONE);
break;
case SCROLL_DOWN:
media_impl->scrollWheel(0, 1, MASK_NONE);
media_impl->scrollWheel(0, 0, 0, 1, MASK_NONE);
break;
case SCROLL_LEFT:
media_impl->scrollWheel(1, 0, MASK_NONE);
media_impl->scrollWheel(0, 0, 1, 0, MASK_NONE);
// media_impl->handleKeyHere(KEY_LEFT, MASK_NONE);
break;
case SCROLL_RIGHT:
media_impl->scrollWheel(-1, 0, MASK_NONE);
media_impl->scrollWheel(0, 0, -1, 0, MASK_NONE);
// media_impl->handleKeyHere(KEY_RIGHT, MASK_NONE);
break;
case SCROLL_NONE:
@ -1134,7 +1134,7 @@ void LLPanelPrimMediaControls::onScrollUp(void* user_data)
if(impl)
{
impl->scrollWheel(0, -1, MASK_NONE);
impl->scrollWheel(0, 0, 0, -1, MASK_NONE);
}
}
void LLPanelPrimMediaControls::onScrollUpHeld(void* user_data)
@ -1151,7 +1151,7 @@ void LLPanelPrimMediaControls::onScrollRight(void* user_data)
if(impl)
{
impl->scrollWheel(-1, 0, MASK_NONE);
impl->scrollWheel(0, 0, -1, 0, MASK_NONE);
// impl->handleKeyHere(KEY_RIGHT, MASK_NONE);
}
}
@ -1170,7 +1170,7 @@ void LLPanelPrimMediaControls::onScrollLeft(void* user_data)
if(impl)
{
impl->scrollWheel(1, 0, MASK_NONE);
impl->scrollWheel(0, 0, 1, 0, MASK_NONE);
// impl->handleKeyHere(KEY_LEFT, MASK_NONE);
}
}
@ -1189,7 +1189,7 @@ void LLPanelPrimMediaControls::onScrollDown(void* user_data)
if(impl)
{
impl->scrollWheel(0, 1, MASK_NONE);
impl->scrollWheel(0, 0, 0, 1, MASK_NONE);
}
}
void LLPanelPrimMediaControls::onScrollDownHeld(void* user_data)

View File

@ -140,7 +140,7 @@ void LLPanelVolumePulldown::updateMediaAutoPlayCheckbox(LLUICtrl* ctrl)
bool music_enabled = getChild<LLCheckBoxCtrl>("enable_music")->get();
bool media_enabled = getChild<LLCheckBoxCtrl>("enable_media")->get();
getChild<LLCheckBoxCtrl>("media_auto_play_btn")->setEnabled(music_enabled || media_enabled);
getChild<LLCheckBoxCtrl>("media_auto_play_combo")->setEnabled(music_enabled || media_enabled);
}
}

View File

@ -464,7 +464,19 @@ public:
// delete a protected data item from the store
virtual void deleteProtectedData(const std::string& data_type,
const std::string& data_id)=0;
// persist data in a protected store's map
virtual void addToProtectedMap(const std::string& data_type,
const std::string& data_id,
const std::string& map_elem,
const LLSD& data)=0;
// remove data from protected store's map
virtual void removeFromProtectedMap(const std::string& data_type,
const std::string& data_id,
const std::string& map_elem)=0;
public:
virtual LLPointer<LLCredential> createCredential(const std::string& grid,
const LLSD& identifier,
const LLSD& authenticator)=0;
@ -474,6 +486,42 @@ public:
virtual void saveCredential(LLPointer<LLCredential> cred, bool save_authenticator)=0;
virtual void deleteCredential(LLPointer<LLCredential> cred)=0;
// has map of credentials declared as specific storage
virtual bool hasCredentialMap(const std::string& storage,
const std::string& grid)=0;
// returns true if map is empty or does not exist
virtual bool emptyCredentialMap(const std::string& storage,
const std::string& grid)=0;
// load map of credentials from specific storage
typedef std::map<std::string, LLPointer<LLCredential> > credential_map_t;
virtual void loadCredentialMap(const std::string& storage,
const std::string& grid,
credential_map_t& credential_map)=0;
// load single username from map of credentials from specific storage
virtual LLPointer<LLCredential> loadFromCredentialMap(const std::string& storage,
const std::string& grid,
const std::string& userid)=0;
// add item to map of credentials from specific storage
virtual void addToCredentialMap(const std::string& storage,
LLPointer<LLCredential> cred,
bool save_authenticator)=0;
// remove item from map of credentials from specific storage
virtual void removeFromCredentialMap(const std::string& storage,
LLPointer<LLCredential> cred)=0;
// remove item from map of credentials from specific storage
virtual void removeFromCredentialMap(const std::string& storage,
const std::string& grid,
const std::string& userid)=0;
virtual void removeCredentialMap(const std::string& storage,
const std::string& grid)=0;
};

View File

@ -52,6 +52,7 @@
#include "llmachineid.h"
static const std::string DEFAULT_CREDENTIAL_STORAGE = "credential";
// 128 bits of salt data...
#define STORE_SALT_SIZE 16
@ -1533,6 +1534,38 @@ void LLSecAPIBasicHandler::setProtectedData(const std::string& data_type,
mProtectedDataMap[data_type][data_id] = data;
}
// persist data in a protected store's map
void LLSecAPIBasicHandler::addToProtectedMap(const std::string& data_type,
const std::string& data_id,
const std::string& map_elem,
const LLSD& data)
{
if (!mProtectedDataMap.has(data_type) || !mProtectedDataMap[data_type].isMap()) {
mProtectedDataMap[data_type] = LLSD::emptyMap();
}
if (!mProtectedDataMap[data_type].has(data_id) || !mProtectedDataMap[data_type][data_id].isMap()) {
mProtectedDataMap[data_type][data_id] = LLSD::emptyMap();
}
mProtectedDataMap[data_type][data_id][map_elem] = data;
}
// remove data from protected store's map
void LLSecAPIBasicHandler::removeFromProtectedMap(const std::string& data_type,
const std::string& data_id,
const std::string& map_elem)
{
if (mProtectedDataMap.has(data_type) &&
mProtectedDataMap[data_type].isMap() &&
mProtectedDataMap[data_type].has(data_id) &&
mProtectedDataMap[data_type][data_id].isMap() &&
mProtectedDataMap[data_type][data_id].has(map_elem))
{
mProtectedDataMap[data_type][data_id].erase(map_elem);
}
}
//
// Create a credential object from an identifier and authenticator. credentials are
// per grid.
@ -1545,10 +1578,10 @@ LLPointer<LLCredential> LLSecAPIBasicHandler::createCredential(const std::string
return result;
}
// Load a credential from the credential store, given the grid
// Load a credential from default credential store, given the grid
LLPointer<LLCredential> LLSecAPIBasicHandler::loadCredential(const std::string& grid)
{
LLSD credential = getProtectedData("credential", grid);
LLSD credential = getProtectedData(DEFAULT_CREDENTIAL_STORAGE, grid);
LLPointer<LLSecAPIBasicCredential> result = new LLSecAPIBasicCredential(grid);
if(credential.isMap() &&
credential.has("identifier"))
@ -1603,7 +1636,7 @@ void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool sav
credential["authenticator"] = cred->getAuthenticator();
}
LL_DEBUGS("SECAPI") << "Saving Credential " << cred->getGrid() << ":" << cred->userID() << " " << save_authenticator << LL_ENDL;
setProtectedData("credential", cred->getGrid(), credential);
setProtectedData(DEFAULT_CREDENTIAL_STORAGE, cred->getGrid(), credential);
//*TODO: If we're saving Agni credentials, should we write the
// credentials to the legacy password.dat/etc?
_writeProtectedData();
@ -1613,11 +1646,150 @@ void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool sav
void LLSecAPIBasicHandler::deleteCredential(LLPointer<LLCredential> cred)
{
LLSD undefVal;
deleteProtectedData("credential", cred->getGrid());
deleteProtectedData(DEFAULT_CREDENTIAL_STORAGE, cred->getGrid());
cred->setCredentialData(undefVal, undefVal);
_writeProtectedData();
}
// has map of credentials declared as specific storage
bool LLSecAPIBasicHandler::hasCredentialMap(const std::string& storage, const std::string& grid)
{
if (storage == DEFAULT_CREDENTIAL_STORAGE)
{
LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
}
LLSD credential = getProtectedData(storage, grid);
return credential.isMap();
}
// returns true if map is empty or does not exist
bool LLSecAPIBasicHandler::emptyCredentialMap(const std::string& storage, const std::string& grid)
{
if (storage == DEFAULT_CREDENTIAL_STORAGE)
{
LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
}
LLSD credential = getProtectedData(storage, grid);
return !credential.isMap() || credential.size() == 0;
}
// Load map of credentials from specified credential store, given the grid
void LLSecAPIBasicHandler::loadCredentialMap(const std::string& storage, const std::string& grid, credential_map_t& credential_map)
{
if (storage == DEFAULT_CREDENTIAL_STORAGE)
{
LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
}
LLSD credential = getProtectedData(storage, grid);
if (credential.isMap())
{
LLSD::map_const_iterator crd_it = credential.beginMap();
for (; crd_it != credential.endMap(); crd_it++)
{
LLSD::String name = crd_it->first;
const LLSD &link_map = crd_it->second;
LLPointer<LLSecAPIBasicCredential> result = new LLSecAPIBasicCredential(grid);
if (link_map.has("identifier"))
{
LLSD identifier = link_map["identifier"];
LLSD authenticator;
if (link_map.has("authenticator"))
{
authenticator = link_map["authenticator"];
}
result->setCredentialData(identifier, authenticator);
}
credential_map[name] = result;
}
}
}
LLPointer<LLCredential> LLSecAPIBasicHandler::loadFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey)
{
if (storage == DEFAULT_CREDENTIAL_STORAGE)
{
LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
}
LLPointer<LLSecAPIBasicCredential> result = new LLSecAPIBasicCredential(grid);
LLSD credential = getProtectedData(storage, grid);
if (credential.isMap() && credential.has(userkey) && credential[userkey].has("identifier"))
{
LLSD identifier = credential[userkey]["identifier"];
LLSD authenticator;
if (credential[userkey].has("authenticator"))
{
authenticator = credential[userkey]["authenticator"];
}
result->setCredentialData(identifier, authenticator);
}
return result;
}
// add item to map of credentials from specific storage
void LLSecAPIBasicHandler::addToCredentialMap(const std::string& storage, LLPointer<LLCredential> cred, bool save_authenticator)
{
if (storage == DEFAULT_CREDENTIAL_STORAGE)
{
LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
}
std::string user_id = cred->userID();
LLSD credential = LLSD::emptyMap();
credential["identifier"] = cred->getIdentifier();
if (save_authenticator)
{
credential["authenticator"] = cred->getAuthenticator();
}
LL_DEBUGS("SECAPI") << "Saving Credential " << cred->getGrid() << ":" << cred->userID() << " " << save_authenticator << LL_ENDL;
addToProtectedMap(storage, cred->getGrid(), user_id, credential);
_writeProtectedData();
}
// remove item from map of credentials from specific storage
void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, LLPointer<LLCredential> cred)
{
if (storage == DEFAULT_CREDENTIAL_STORAGE)
{
LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
}
LLSD undefVal;
removeFromProtectedMap(storage, cred->getGrid(), cred->userID());
cred->setCredentialData(undefVal, undefVal);
_writeProtectedData();
}
// remove item from map of credentials from specific storage
void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey)
{
if (storage == DEFAULT_CREDENTIAL_STORAGE)
{
LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
}
LLSD undefVal;
LLPointer<LLCredential> cred = loadFromCredentialMap(storage, grid, userkey);
removeFromProtectedMap(storage, grid, userkey);
cred->setCredentialData(undefVal, undefVal);
_writeProtectedData();
}
// remove item from map of credentials from specific storage
void LLSecAPIBasicHandler::removeCredentialMap(const std::string& storage, const std::string& grid)
{
deleteProtectedData(storage, grid);
_writeProtectedData();
}
// load the legacy hash for agni, and decrypt it given the
// mac address
std::string LLSecAPIBasicHandler::_legacyLoadPassword()
@ -1656,15 +1828,18 @@ std::string LLSecAPIBasicCredential::userID() const
}
else if ((std::string)mIdentifier["type"] == "agent")
{
return (std::string)mIdentifier["first_name"] + "_" + (std::string)mIdentifier["last_name"];
std::string id = (std::string)mIdentifier["first_name"] + "_" + (std::string)mIdentifier["last_name"];
LLStringUtil::toLower(id);
return id;
}
else if ((std::string)mIdentifier["type"] == "account")
{
return (std::string)mIdentifier["account_name"];
std::string id = (std::string)mIdentifier["account_name"];
LLStringUtil::toLower(id);
return id;
}
return "unknown";
}
// return a printable user identifier

View File

@ -211,8 +211,9 @@ class LLSecAPIBasicCredential : public LLCredential
public:
LLSecAPIBasicCredential(const std::string& grid) : LLCredential(grid) {}
virtual ~LLSecAPIBasicCredential() {}
// return a value representing the user id, (could be guid, name, whatever)
virtual std::string userID() const;
// return a value representing the user id, used for server and voice
// (could be guid, name in format "name_resident", whatever)
virtual std::string userID() const;
// printible string identifying the credential.
virtual std::string asString() const;
@ -246,7 +247,10 @@ public:
// exists, it'll be loaded. If not, one will be created (but not
// persisted)
virtual LLPointer<LLCertificateStore> getCertificateStore(const std::string& store_id);
// protectedData functions technically should be pretected or private,
// they are not because of llsechandler_basic_test imlementation
// persist data in a protected store
virtual void setProtectedData(const std::string& data_type,
const std::string& data_id,
@ -259,19 +263,68 @@ public:
// delete a protected data item from the store
virtual void deleteProtectedData(const std::string& data_type,
const std::string& data_id);
// persist data in a protected store's map
virtual void addToProtectedMap(const std::string& data_type,
const std::string& data_id,
const std::string& map_elem,
const LLSD& data);
// remove data from protected store's map
virtual void removeFromProtectedMap(const std::string& data_type,
const std::string& data_id,
const std::string& map_elem);
// credential management routines
virtual LLPointer<LLCredential> createCredential(const std::string& grid,
const LLSD& identifier,
const LLSD& authenticator);
// load single credencial from default storage
virtual LLPointer<LLCredential> loadCredential(const std::string& grid);
// save credencial to default storage
virtual void saveCredential(LLPointer<LLCredential> cred, bool save_authenticator);
virtual void deleteCredential(LLPointer<LLCredential> cred);
// has map of credentials declared as specific storage
virtual bool hasCredentialMap(const std::string& storage,
const std::string& grid);
// returns true if map is empty or does not exist
virtual bool emptyCredentialMap(const std::string& storage,
const std::string& grid);
// load map of credentials from specific storage
virtual void loadCredentialMap(const std::string& storage,
const std::string& grid,
credential_map_t& credential_map);
// load single username from map of credentials from specific storage
virtual LLPointer<LLCredential> loadFromCredentialMap(const std::string& storage,
const std::string& grid,
const std::string& userid);
// add item to map of credentials from specific storage
virtual void addToCredentialMap(const std::string& storage,
LLPointer<LLCredential> cred,
bool save_authenticator);
// remove item from map of credentials from specific storage
virtual void removeFromCredentialMap(const std::string& storage,
LLPointer<LLCredential> cred);
// remove item from map of credentials from specific storage
virtual void removeFromCredentialMap(const std::string& storage,
const std::string& grid,
const std::string& userid);
virtual void removeCredentialMap(const std::string& storage,
const std::string& grid);
protected:
void _readProtectedData();
void _writeProtectedData();

View File

@ -5426,7 +5426,7 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
}
else
{
if (node->mInventorySerial != inv_serial)
if (node->mInventorySerial != inv_serial && node->getObject())
{
node->getObject()->dirtyInventory();
}

View File

@ -158,6 +158,7 @@
#include "llviewermessage.h"
#include "llviewernetwork.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelaskplay.h"
#include "llviewerparcelmedia.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
@ -236,7 +237,8 @@ LLSLURL LLStartUp::sStartSLURL;
static LLPointer<LLCredential> gUserCredential;
static std::string gDisplayName;
static BOOL gRememberPassword = TRUE;
static bool gRememberPassword = true;
static bool gRememberUser = true;
static U64 gFirstSimHandle = 0;
static LLHost gFirstSim;
@ -350,13 +352,6 @@ bool idle_startup()
gIdleCallbacks.callFunctions();
gViewerWindow->updateUI();
// There is a crash on updateClass, this is an attempt to get more information
if (LLMortician::graveyardCount())
{
std::stringstream log_stream;
LLMortician::logClass(log_stream);
LL_INFOS() << log_stream.str() << LL_ENDL;
}
LLMortician::updateClass();
const std::string delims (" ");
@ -701,19 +696,23 @@ bool idle_startup()
else if (gSavedSettings.getBOOL("AutoLogin"))
{
// Log into last account
gRememberPassword = TRUE;
gSavedSettings.setBOOL("RememberPassword", TRUE);
gRememberPassword = true;
gRememberUser = true;
gSavedSettings.setBOOL("RememberPassword", TRUE);
gSavedSettings.setBOOL("RememberUser", TRUE);
show_connect_box = false;
}
else if (gSavedSettings.getLLSD("UserLoginInfo").size() == 3)
{
// Console provided login&password
gRememberPassword = gSavedSettings.getBOOL("RememberPassword");
gRememberUser = gSavedSettings.getBOOL("RememberUser");
show_connect_box = false;
}
else
{
gRememberPassword = gSavedSettings.getBOOL("RememberPassword");
gRememberUser = gSavedSettings.getBOOL("RememberUser");
show_connect_box = TRUE;
}
@ -781,10 +780,7 @@ bool idle_startup()
// Show the login dialog
login_show();
// connect dialog is already shown, so fill in the names
if (gUserCredential.notNull() && !LLPanelLogin::isCredentialSet())
{
LLPanelLogin::setFields( gUserCredential, gRememberPassword);
}
LLPanelLogin::populateFields( gUserCredential, gRememberUser, gRememberPassword);
LLPanelLogin::giveFocus();
// MAINT-3231 Show first run dialog only for Desura viewer
@ -873,7 +869,7 @@ bool idle_startup()
{
// TODO if not use viewer auth
// Load all the name information out of the login view
LLPanelLogin::getFields(gUserCredential, gRememberPassword);
LLPanelLogin::getFields(gUserCredential, gRememberUser, gRememberPassword);
// end TODO
// HACK: Try to make not jump on login
@ -885,14 +881,21 @@ bool idle_startup()
// STATE_LOGIN_SHOW state if we've gone backwards
mLoginStatePastUI = true;
// save the credentials
std::string userid = "unknown";
if(gUserCredential.notNull())
{
userid = gUserCredential->userID();
gSecAPIHandler->saveCredential(gUserCredential, gRememberPassword);
}
gSavedSettings.setBOOL("RememberPassword", gRememberPassword);
// save the credentials
std::string userid = "unknown";
if (gUserCredential.notNull())
{
userid = gUserCredential->userID();
if (gRememberUser)
{
gSecAPIHandler->addToCredentialMap("login_list", gUserCredential, gRememberPassword);
// Legacy viewers use this method to store user credentials, newer viewers
// reuse it to be compatible and to remember last session
gSecAPIHandler->saveCredential(gUserCredential, gRememberPassword);
}
}
gSavedSettings.setBOOL("RememberPassword", gRememberPassword);
gSavedSettings.setBOOL("RememberUser", gRememberUser);
LL_INFOS("AppInit") << "Attempting login as: " << userid << LL_ENDL;
gDebugInfo["LoginName"] = userid;
@ -1423,6 +1426,10 @@ bool idle_startup()
// create a container's instance for start a controlling conversation windows
// by the voice's events
LLFloaterIMContainer::getInstance();
if (gSavedSettings.getS32("ParcelMediaAutoPlayEnable") == 2)
{
LLViewerParcelAskPlay::getInstance()->loadSettings();
}
// *Note: this is where gWorldMap used to be initialized.
@ -2708,6 +2715,15 @@ std::string& LLStartUp::getInitialOutfitName()
return sInitialOutfit;
}
std::string LLStartUp::getUserId()
{
if (gUserCredential.isNull())
{
return "";
}
return gUserCredential->userID();
}
// Loads a bitmap to display during load
void init_start_screen(S32 location_id)
{

View File

@ -115,6 +115,7 @@ public:
static void saveInitialOutfit();
static std::string& getInitialOutfitName();
static std::string getUserId();
static bool dispatchURL();
// if we have a SLURL or sim string ("Ahern/123/45") that started

View File

@ -34,7 +34,6 @@
#include "llfontgl.h"
#include "lltextbox.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llkeyboard.h"
#include "llfocusmgr.h"
#include "lliconctrl.h"
@ -62,9 +61,8 @@ static const S32 HPAD = 25;
static const S32 BTN_HPAD = 8;
LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal)
: LLToastPanel(notification),
: LLCheckBoxToastPanel(notification),
mDefaultOption( 0 ),
mCheck(NULL),
mCaution(notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH),
mLabel(notification->getName()),
mLineEditor(NULL)
@ -347,20 +345,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
button_left += button_width + BTN_HPAD;
}
std::string ignore_label;
if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE)
{
setCheckBox(LLNotifications::instance().getGlobalString("skipnexttime"), ignore_label);
}
if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY)
{
setCheckBox(LLNotifications::instance().getGlobalString("skipnexttimesessiononly"), ignore_label);
}
else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
{
setCheckBox(LLNotifications::instance().getGlobalString("alwayschoose"), ignore_label);
}
setCheckBoxes(HPAD, VPAD);
// *TODO: check necessity of this code
//gFloaterView->adjustToFitScreen(this, FALSE);
@ -380,46 +365,6 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
LLTransientFloaterMgr::GLOBAL, this);
}
bool LLToastAlertPanel::setCheckBox( const std::string& check_title, const std::string& check_control )
{
mCheck = LLUICtrlFactory::getInstance()->createFromFile<LLCheckBoxCtrl>("alert_check_box.xml", this, LLPanel::child_registry_t::instance());
if(!mCheck)
{
return false;
}
const LLFontGL* font = mCheck->getFont();
const S32 LINE_HEIGHT = font->getLineHeight();
std::vector<std::string> lines;
boost::split(lines, check_title, boost::is_any_of("\n"));
// Extend dialog for "check next time"
S32 max_msg_width = LLToastPanel::getRect().getWidth() - 2 * HPAD;
S32 check_width = S32(font->getWidth(lines[0]) + 0.99f) + 16; // use width of the first line
max_msg_width = llmax(max_msg_width, check_width);
S32 dialog_width = max_msg_width + 2 * HPAD;
S32 dialog_height = LLToastPanel::getRect().getHeight();
dialog_height += LINE_HEIGHT * lines.size();
dialog_height += LINE_HEIGHT / 2;
LLToastPanel::reshape( dialog_width, dialog_height, FALSE );
S32 msg_x = (LLToastPanel::getRect().getWidth() - max_msg_width) / 2;
// set check_box's attributes
LLRect check_rect;
mCheck->setRect(check_rect.setOriginAndSize(msg_x, VPAD+BTN_HEIGHT+LINE_HEIGHT/2, max_msg_width, LINE_HEIGHT*lines.size()));
mCheck->setLabel(check_title);
mCheck->setCommitCallback(boost::bind(&LLToastAlertPanel::onClickIgnore, this, _1));
LLToastPanel::addChild(mCheck);
return true;
}
void LLToastAlertPanel::setVisible( BOOL visible )
{
// only make the "ding" sound if it's newly visible
@ -569,16 +514,3 @@ void LLToastAlertPanel::onButtonPressed( const LLSD& data, S32 button )
mNotification->respond(response); // new notification reponse
}
void LLToastAlertPanel::onClickIgnore(LLUICtrl* ctrl)
{
// checkbox sometimes means "hide and do the default" and
// other times means "warn me again". Yuck. JC
BOOL check = ctrl->getValue().asBoolean();
if (mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
{
// question was "show again" so invert value to get "ignore"
check = !check;
}
mNotification->setIgnored(check);
}

View File

@ -46,7 +46,7 @@ class LLLineEditor;
*/
class LLToastAlertPanel
: public LLToastPanel
: public LLCheckBoxToastPanel
{
LOG_CLASS(LLToastAlertPanel);
public:
@ -61,13 +61,11 @@ public:
virtual void draw();
virtual void setVisible( BOOL visible );
bool setCheckBox( const std::string&, const std::string& );
void setCaution(BOOL val = TRUE) { mCaution = val; }
// If mUnique==TRUE only one copy of this message should exist
void setUnique(BOOL val = TRUE) { mUnique = val; }
void setEditTextArgs(const LLSD& edit_args);
void onClickIgnore(LLUICtrl* ctrl);
void onButtonPressed(const LLSD& data, S32 button);
private:
@ -91,7 +89,6 @@ private:
std::vector<ButtonData> mButtonData;
S32 mDefaultOption;
LLCheckBoxCtrl* mCheck;
BOOL mCaution;
BOOL mUnique;
LLUIString mLabel;

View File

@ -33,6 +33,7 @@
// library includes
#include "lldbstrings.h"
#include "llcheckboxctrl.h"
#include "lllslconstants.h"
#include "llnotifications.h"
#include "lluiconstants.h"
@ -55,7 +56,7 @@ const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL;
LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal;
LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images)
: LLToastPanel(notification),
: LLCheckBoxToastPanel(notification),
LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerReplaceOnCollision>(notification->getID())
{
init(rect, show_images);
@ -162,6 +163,11 @@ void LLToastNotifyPanel::updateButtonsLayout(const std::vector<index_button_pair
{
left = (max_width - btn_rect.getWidth()) / 2;
}
else if (left == 0 && buttons.size() == 2)
{
// Note: this and "size() == 1" shouldn't be inside the cycle, might be good idea to refactor whole placing process
left = (max_width - (btn_rect.getWidth() * 2) - h_pad) / 2;
}
else if (left + btn_rect.getWidth() > max_width)// whether there is still some place for button+h_pad in the mControlPanel
{
// looks like we need to add button to the next row
@ -409,7 +415,20 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
//.xml file intially makes info panel only follow left/right/top. This is so that when control buttons are added the info panel
//can shift upward making room for the buttons inside mControlPanel. After the buttons are added, the info panel can then be set to follow 'all'.
mInfoPanel->setFollowsAll();
snapToMessageHeight(mTextBox, LLToastPanel::MAX_TEXT_LENGTH);
// Add checkbox (one of couple types) if nessesary.
setCheckBoxes(HPAD * 2, 0, mInfoPanel);
if (mCheck)
{
mCheck->setFollows(FOLLOWS_BOTTOM | FOLLOWS_LEFT);
}
// Snap to message, then to checkbox if present
snapToMessageHeight(mTextBox, LLToastPanel::MAX_TEXT_LENGTH);
if (mCheck)
{
S32 new_panel_height = mCheck->getRect().getHeight() + getRect().getHeight() + VPAD;
reshape(getRect().getWidth(), new_panel_height);
}
// reshape the panel to its previous size
if (current_rect.notEmpty())

View File

@ -47,7 +47,7 @@ class LLNotificationForm;
* @deprecated this class will be removed after all toast panel types are
* implemented in separate classes.
*/
class LLToastNotifyPanel: public LLToastPanel, public LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerReplaceOnCollision>
class LLToastNotifyPanel: public LLCheckBoxToastPanel, public LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerReplaceOnCollision>
{
public:
/**

View File

@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "lldbstrings.h"
#include "llcheckboxctrl.h"
#include "llpanelgenerictip.h"
#include "llpanelonlinestatus.h"
#include "llnotifications.h"
@ -34,6 +35,8 @@
#include "lltoastpanel.h"
#include "lltoastscriptquestion.h"
#include <boost/algorithm/string.hpp>
//static
const S32 LLToastPanel::MIN_PANEL_HEIGHT = 40; // VPAD(4)*2 + ICON_HEIGHT(32)
// 'magic numbers', consider initializing (512+20) part from xml/notifications
@ -145,3 +148,108 @@ LLToastPanel* LLToastPanel::buidPanelFromNotification(
return res;
}
LLCheckBoxToastPanel::LLCheckBoxToastPanel(const LLNotificationPtr& p_ntf)
: LLToastPanel(p_ntf),
mCheck(NULL)
{
}
void LLCheckBoxToastPanel::setCheckBoxes(const S32 &h_pad, const S32 &v_pad, LLView *parent_view)
{
std::string ignore_label;
LLNotificationFormPtr form = mNotification->getForm();
if (form->getIgnoreType() == LLNotificationForm::IGNORE_CHECKBOX_ONLY)
{
// Normally text is only used to describe notification in preferences,
// but this one is not displayed in preferences and works on case by case
// basis.
// Display text if present, display 'always chose' if not.
std::string ignore_message = form->getIgnoreMessage();
if (ignore_message.empty())
{
ignore_message = LLNotifications::instance().getGlobalString("alwayschoose");
}
setCheckBox(ignore_message, ignore_label, boost::bind(&LLCheckBoxToastPanel::onCommitCheckbox, this, _1), h_pad, v_pad, parent_view);
}
else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE)
{
setCheckBox(LLNotifications::instance().getGlobalString("skipnexttime"), ignore_label, boost::bind(&LLCheckBoxToastPanel::onCommitCheckbox, this, _1), h_pad, v_pad, parent_view);
}
if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY)
{
setCheckBox(LLNotifications::instance().getGlobalString("skipnexttimesessiononly"), ignore_label, boost::bind(&LLCheckBoxToastPanel::onCommitCheckbox, this, _1), h_pad, v_pad, parent_view);
}
else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
{
setCheckBox(LLNotifications::instance().getGlobalString("alwayschoose"), ignore_label, boost::bind(&LLCheckBoxToastPanel::onCommitCheckbox, this, _1), h_pad, v_pad, parent_view);
}
}
bool LLCheckBoxToastPanel::setCheckBox(const std::string& check_title,
const std::string& check_control,
const commit_signal_t::slot_type& cb,
const S32 &h_pad,
const S32 &v_pad,
LLView *parent_view)
{
mCheck = LLUICtrlFactory::getInstance()->createFromFile<LLCheckBoxCtrl>("alert_check_box.xml", this, LLPanel::child_registry_t::instance());
if (!mCheck)
{
return false;
}
const LLFontGL* font = mCheck->getFont();
const S32 LINE_HEIGHT = font->getLineHeight();
std::vector<std::string> lines;
boost::split(lines, check_title, boost::is_any_of("\n"));
// Extend dialog for "check next time"
S32 max_msg_width = LLToastPanel::getRect().getWidth() - 2 * h_pad;
S32 check_width = S32(font->getWidth(lines[0]) + 0.99f) + 16; // use width of the first line
max_msg_width = llmax(max_msg_width, check_width);
S32 dialog_width = max_msg_width + 2 * h_pad;
S32 dialog_height = LLToastPanel::getRect().getHeight();
dialog_height += LINE_HEIGHT * lines.size();
dialog_height += LINE_HEIGHT / 2;
LLToastPanel::reshape(dialog_width, dialog_height, FALSE);
S32 msg_x = (LLToastPanel::getRect().getWidth() - max_msg_width) / 2;
// set check_box's attributes
LLRect check_rect;
// if we are part of the toast, we need to leave space for buttons
S32 msg_y = v_pad + (parent_view ? 0 : (BTN_HEIGHT + LINE_HEIGHT / 2));
mCheck->setRect(check_rect.setOriginAndSize(msg_x, msg_y, max_msg_width, LINE_HEIGHT*lines.size()));
mCheck->setLabel(check_title);
mCheck->setCommitCallback(cb);
if (parent_view)
{
// assume that width and height autoadjusts to toast
parent_view->addChild(mCheck);
}
else
{
LLToastPanel::addChild(mCheck);
}
return true;
}
void LLCheckBoxToastPanel::onCommitCheckbox(LLUICtrl* ctrl)
{
BOOL check = ctrl->getValue().asBoolean();
if (mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
{
// question was "show again" so invert value to get "ignore"
check = !check;
}
mNotification->setIgnored(check);
}

View File

@ -64,4 +64,23 @@ protected:
S32 computeSnappedToMessageHeight(LLTextBase* message, S32 maxLineCount);
};
class LLCheckBoxCtrl;
// Wrapper with support for 'don't ask again' checkbox
class LLCheckBoxToastPanel : public LLToastPanel
{
public:
LLCheckBoxToastPanel(const LLNotificationPtr& p_ntf);
virtual ~LLCheckBoxToastPanel() {};
// set checkboxes acording to defaults from form
void setCheckBoxes(const S32 &h_pad, const S32 &v_pad, LLView *parent_view = NULL);
// set single checkbox
bool setCheckBox(const std::string&, const std::string&, const commit_signal_t::slot_type& cb, const S32 &h_pad, const S32 &v_pad, LLView *parent_view = NULL);
protected:
void onCommitCheckbox(LLUICtrl* ctrl);
LLCheckBoxCtrl* mCheck;
};
#endif /* LL_TOASTPANEL_H */

View File

@ -115,6 +115,12 @@ BOOL LLTool::handleScrollWheel(S32 x, S32 y, S32 clicks)
return FALSE;
}
BOOL LLTool::handleScrollHWheel(S32 x, S32 y, S32 clicks)
{
// by default, didn't handle it
return FALSE;
}
BOOL LLTool::handleDoubleClick(S32 x,S32 y,MASK mask)
{
// LL_INFOS() << "LLTool::handleDoubleClick" << LL_ENDL;

View File

@ -57,6 +57,7 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);

View File

@ -1728,6 +1728,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
if(gInventory.isObjectDescendentOf(item->getUUID(), outbox_id))
{
// Legacy
return ACCEPT_NO;
}
@ -2154,6 +2155,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory(
const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
if(gInventory.isObjectDescendentOf(category->getUUID(), outbox_id))
{
// Legacy
return ACCEPT_NO;
}

View File

@ -355,7 +355,7 @@ bool LLToolMgr::inBuildMode()
bool LLToolMgr::canAccessMarketplace()
{
return (LLMarketplaceData::instance().getSLMStatus() != MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT) || gSavedSettings.getBOOL("InventoryOutboxDisplayBoth");
return (LLMarketplaceData::instance().getSLMStatus() != MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT);
}
void LLToolMgr::toggleMarketplace(const LLSD& sdname)

View File

@ -208,6 +208,11 @@ BOOL LLToolPie::handleScrollWheel(S32 x, S32 y, S32 clicks)
return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks);
}
BOOL LLToolPie::handleScrollHWheel(S32 x, S32 y, S32 clicks)
{
return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks);
}
// True if you selected an object.
BOOL LLToolPie::handleLeftClickPick()
{

View File

@ -50,6 +50,7 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks);
virtual BOOL handleToolTip(S32 x, S32 y, MASK mask);
virtual void render();

View File

@ -68,6 +68,7 @@
#include "llfloaterexperiencepicker.h"
#include "llfloaterevent.h"
#include "llfloaterfonttest.h"
#include "llfloaterforgetuser.h"
#include "llfloatergesture.h"
#include "llfloatergodtools.h"
#include "llfloatergridstatus.h"
@ -233,6 +234,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("experience_search", "floater_experience_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperiencePicker>);
LLFloaterReg::add("font_test", "floater_font_test.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFontTest>);
LLFloaterReg::add("forget_username", "floater_forget_user.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterForgetUser>);
LLFloaterReg::add("gestures", "floater_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGesture>);
LLFloaterReg::add("god_tools", "floater_god_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGodTools>);

View File

@ -1745,7 +1745,7 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,
{
std::string type_name = userdata.asString();
if (("inbox" == type_name) || ("outbox" == type_name) || ("category" == type_name) || ("current" == type_name) || ("outfit" == type_name) || ("my_otfts" == type_name))
if (("inbox" == type_name) || ("category" == type_name) || ("current" == type_name) || ("outfit" == type_name) || ("my_otfts" == type_name))
{
LLFolderType::EType preferred_type = LLFolderType::lookup(type_name);

View File

@ -57,6 +57,7 @@
#include "llviewercontrol.h"
#include "llviewermenufile.h" // LLFilePickerThread
#include "llviewernetwork.h"
#include "llviewerparcelaskplay.h"
#include "llviewerparcelmedia.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
@ -1018,6 +1019,8 @@ void LLViewerMedia::setAllMediaPaused(bool val)
}
}
LLParcel *agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
// Also do Parcel Media and Parcel Audio
if (!val)
{
@ -1051,6 +1054,12 @@ void LLViewerMedia::setAllMediaPaused(bool val)
LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
}
}
// remove play choice for current parcel
if (agent_parcel && gAgent.getRegion())
{
LLViewerParcelAskPlay::getInstance()->resetSetting(gAgent.getRegion()->getRegionID(), agent_parcel->getLocalID());
}
}
//////////////////////////////////////////////////////////////////////////////////////////
@ -2285,14 +2294,14 @@ void LLViewerMediaImpl::mouseDoubleClick(S32 x, S32 y, MASK mask, S32 button)
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::scrollWheel(S32 x, S32 y, MASK mask)
void LLViewerMediaImpl::scrollWheel(S32 x, S32 y, S32 scroll_x, S32 scroll_y, MASK mask)
{
scaleMouse(&x, &y);
mLastMouseX = x;
mLastMouseY = y;
if (mMediaSource)
{
mMediaSource->scrollEvent(x, y, mask);
mMediaSource->scrollEvent(x, y, scroll_x, scroll_y, mask);
}
}
@ -3754,7 +3763,7 @@ void LLViewerMediaImpl::setTextureID(LLUUID id)
bool LLViewerMediaImpl::isAutoPlayable() const
{
return (mMediaAutoPlay &&
gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
gSavedSettings.getS32("ParcelMediaAutoPlayEnable") != 0 &&
gSavedSettings.getBOOL("MediaTentativeAutoPlay"));
}

View File

@ -79,7 +79,7 @@ class LLViewerMedia: public LLSingleton<LLViewerMedia>
public:
// String to get/set media autoplay in gSavedSettings
static const char* AUTO_PLAY_MEDIA_SETTING;
static const char* AUTO_PLAY_MEDIA_SETTING;
static const char* SHOW_MEDIA_ON_OTHERS_SETTING;
static const char* SHOW_MEDIA_WITHIN_PARCEL_SETTING;
static const char* SHOW_MEDIA_OUTSIDE_PARCEL_SETTING;
@ -235,7 +235,7 @@ public:
void mouseMove(const LLVector2& texture_coords, MASK mask);
void mouseDoubleClick(const LLVector2& texture_coords, MASK mask);
void mouseDoubleClick(S32 x, S32 y, MASK mask, S32 button = 0);
void scrollWheel(S32 x, S32 y, MASK mask);
void scrollWheel(S32 x, S32 y, S32 scroll_x, S32 scroll_y, MASK mask);
void mouseCapture();
void navigateBack();
@ -320,6 +320,7 @@ public:
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask) { return FALSE; };
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) { return FALSE; };
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) { return FALSE; };
/*virtual*/ BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks) { return FALSE; };
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask) { return FALSE; };
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) { return FALSE; };
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask) { return FALSE; };

View File

@ -377,12 +377,7 @@ BOOL LLViewerMediaFocus::handleScrollWheel(S32 x, S32 y, S32 clicks)
LLViewerMediaImpl* media_impl = getFocusedMediaImpl();
if(media_impl && media_impl->hasMedia())
{
// the scrollEvent() API's x and y are not the same as handleScrollWheel's x and y.
// The latter is the position of the mouse at the time of the event
// The former is the 'scroll amount' in x and y, respectively.
// All we have for 'scroll amount' here is 'clicks'.
// We're also not passed the keyboard modifier mask, but we can get that from gKeyboard.
media_impl->getMediaPlugin()->scrollEvent(0, clicks, gKeyboard->currentMask(TRUE));
media_impl->scrollWheel(x, y, 0, clicks, gKeyboard->currentMask(TRUE));
retval = TRUE;
}
return retval;

View File

@ -401,23 +401,20 @@ void set_merchant_SLM_menu()
void check_merchant_status(bool force)
{
if (!gSavedSettings.getBOOL("InventoryOutboxDisplayBoth"))
if (force)
{
if (force)
{
// Reset the SLM status: we actually want to check again, that's the point of calling check_merchant_status()
LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED);
}
// Hide SLM related menu item
gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible(FALSE);
// Also disable the toolbar button for Marketplace Listings
LLCommand* command = LLCommandManager::instance().getCommand("marketplacelistings");
gToolBarView->enableCommand(command->id(), false);
// Launch an SLM test connection to get the merchant status
LLMarketplaceData::instance().initializeSLM(boost::bind(&set_merchant_SLM_menu));
// Reset the SLM status: we actually want to check again, that's the point of calling check_merchant_status()
LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED);
}
// Hide SLM related menu item
gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible(FALSE);
// Also disable the toolbar button for Marketplace Listings
LLCommand* command = LLCommandManager::instance().getCommand("marketplacelistings");
gToolBarView->enableCommand(command->id(), false);
// Launch an SLM test connection to get the merchant status
LLMarketplaceData::instance().initializeSLM(boost::bind(&set_merchant_SLM_menu));
}
void init_menus()

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