Merge Viewer-Bear
commit
5fe09cb64d
|
|
@ -443,6 +443,10 @@ BOOL LLImageBMP::decodeColorMask32( U8* dst, U8* src )
|
|||
mBitfieldMask[2] = 0x000000FF;
|
||||
}
|
||||
|
||||
if (getWidth() * getHeight() * 4 > getDataSize() - mBitmapOffset)
|
||||
{ //here we have situation when data size in src less than actually needed
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
S32 src_row_span = getWidth() * 4;
|
||||
S32 alignment_bytes = (3 * src_row_span) % 4; // round up to nearest multiple of 4
|
||||
|
|
@ -476,6 +480,11 @@ BOOL LLImageBMP::decodeColorTable8( U8* dst, U8* src )
|
|||
S32 src_row_span = getWidth() * 1;
|
||||
S32 alignment_bytes = (3 * src_row_span) % 4; // round up to nearest multiple of 4
|
||||
|
||||
if ((getWidth() * getHeight()) + getHeight() * alignment_bytes > getDataSize() - mBitmapOffset)
|
||||
{ //here we have situation when data size in src less than actually needed
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for( S32 row = 0; row < getHeight(); row++ )
|
||||
{
|
||||
for( S32 col = 0; col < getWidth(); col++ )
|
||||
|
|
@ -501,6 +510,11 @@ BOOL LLImageBMP::decodeTruecolor24( U8* dst, U8* src )
|
|||
S32 src_row_span = getWidth() * 3;
|
||||
S32 alignment_bytes = (3 * src_row_span) % 4; // round up to nearest multiple of 4
|
||||
|
||||
if ((getWidth() * getHeight() * 3) + getHeight() * alignment_bytes > getDataSize() - mBitmapOffset)
|
||||
{ //here we have situation when data size in src less than actually needed
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for( S32 row = 0; row < getHeight(); row++ )
|
||||
{
|
||||
for( S32 col = 0; col < getWidth(); col++ )
|
||||
|
|
|
|||
|
|
@ -447,7 +447,13 @@ BOOL LLImageTGA::decodeTruecolorNonRle( LLImageRaw* raw_image, BOOL &alpha_opaqu
|
|||
// Origin is the bottom left
|
||||
U8* dst = raw_image->getData();
|
||||
U8* src = getData() + mDataOffset;
|
||||
|
||||
S32 pixels = getWidth() * getHeight();
|
||||
|
||||
if (pixels * (mIs15Bit ? 2 : getComponents()) > getDataSize() - mDataOffset)
|
||||
{ //here we have situation when data size in src less than actually needed
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (getComponents() == 4)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -193,8 +193,12 @@ const U8 LL_SCULPT_TYPE_MESH = 5;
|
|||
const U8 LL_SCULPT_TYPE_MASK = LL_SCULPT_TYPE_SPHERE | LL_SCULPT_TYPE_TORUS | LL_SCULPT_TYPE_PLANE |
|
||||
LL_SCULPT_TYPE_CYLINDER | LL_SCULPT_TYPE_MESH;
|
||||
|
||||
// for value checks, assign new value after adding new types
|
||||
const U8 LL_SCULPT_TYPE_MAX = LL_SCULPT_TYPE_MESH;
|
||||
|
||||
const U8 LL_SCULPT_FLAG_INVERT = 64;
|
||||
const U8 LL_SCULPT_FLAG_MIRROR = 128;
|
||||
const U8 LL_SCULPT_FLAG_MASK = LL_SCULPT_FLAG_INVERT | LL_SCULPT_FLAG_MIRROR;
|
||||
|
||||
const S32 LL_SCULPT_MESH_MAX_FACES = 8;
|
||||
|
||||
|
|
|
|||
|
|
@ -146,6 +146,8 @@ void LLPluginClassMedia::reset()
|
|||
mClickTarget.clear();
|
||||
mClickUUID.clear();
|
||||
mStatusCode = 0;
|
||||
|
||||
mClickEnforceTarget = false;
|
||||
|
||||
// media_time class
|
||||
mCurrentTime = 0.0f;
|
||||
|
|
@ -1368,6 +1370,12 @@ void LLPluginClassMedia::addCertificateFilePath(const std::string& path)
|
|||
sendMessage(message);
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::setOverrideClickTarget(const std::string &target)
|
||||
{
|
||||
mClickEnforceTarget = true;
|
||||
mOverrideClickTarget = target;
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::crashPlugin()
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "crash");
|
||||
|
|
|
|||
|
|
@ -249,6 +249,13 @@ public:
|
|||
// This is valid during MEDIA_EVENT_CLICK_LINK_HREF and MEDIA_EVENT_GEOMETRY_CHANGE
|
||||
std::string getClickUUID() const { return mClickUUID; };
|
||||
|
||||
// mClickTarget is received from message and governs how link will be opened
|
||||
// use this to enforce your own way of opening links inside plugins
|
||||
void setOverrideClickTarget(const std::string &target);
|
||||
void resetOverrideClickTarget() { mClickEnforceTarget = false; };
|
||||
bool isOverrideClickTarget() const { return mClickEnforceTarget; }
|
||||
std::string getOverrideClickTarget() const { return mOverrideClickTarget; };
|
||||
|
||||
// These are valid during MEDIA_EVENT_DEBUG_MESSAGE
|
||||
std::string getDebugMessageText() const { return mDebugMessageText; };
|
||||
std::string getDebugMessageLevel() const { return mDebugMessageLevel; };
|
||||
|
|
@ -404,6 +411,8 @@ protected:
|
|||
std::string mClickNavType;
|
||||
std::string mClickTarget;
|
||||
std::string mClickUUID;
|
||||
bool mClickEnforceTarget;
|
||||
std::string mOverrideClickTarget;
|
||||
std::string mDebugMessageText;
|
||||
std::string mDebugMessageLevel;
|
||||
S32 mGeometryX;
|
||||
|
|
|
|||
|
|
@ -328,9 +328,9 @@ S32 LLPrimitive::setTEMaterialID(const U8 index, const LLMaterialID& pMaterialID
|
|||
return mTextureList.setMaterialID(index, pMaterialID);
|
||||
}
|
||||
|
||||
S32 LLPrimitive::setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams)
|
||||
S32 LLPrimitive::setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams, bool isInitFromServer)
|
||||
{
|
||||
return mTextureList.setMaterialParams(index, pMaterialParams);
|
||||
return mTextureList.setMaterialParams(index, pMaterialParams, isInitFromServer);
|
||||
}
|
||||
|
||||
LLMaterialPtr LLPrimitive::getTEMaterialParams(const U8 index)
|
||||
|
|
@ -1880,9 +1880,12 @@ BOOL LLSculptParams::pack(LLDataPacker &dp) const
|
|||
|
||||
BOOL LLSculptParams::unpack(LLDataPacker &dp)
|
||||
{
|
||||
dp.unpackUUID(mSculptTexture, "texture");
|
||||
dp.unpackU8(mSculptType, "type");
|
||||
|
||||
U8 type;
|
||||
LLUUID id;
|
||||
dp.unpackUUID(id, "texture");
|
||||
dp.unpackU8(type, "type");
|
||||
|
||||
setSculptTexture(id, type);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -1907,8 +1910,7 @@ bool LLSculptParams::operator==(const LLNetworkData& data) const
|
|||
void LLSculptParams::copy(const LLNetworkData& data)
|
||||
{
|
||||
const LLSculptParams *param = (LLSculptParams*)&data;
|
||||
mSculptTexture = param->mSculptTexture;
|
||||
mSculptType = param->mSculptType;
|
||||
setSculptTexture(param->mSculptTexture, param->mSculptType);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1926,20 +1928,38 @@ LLSD LLSculptParams::asLLSD() const
|
|||
bool LLSculptParams::fromLLSD(LLSD& sd)
|
||||
{
|
||||
const char *w;
|
||||
w = "texture";
|
||||
if (sd.has(w))
|
||||
{
|
||||
setSculptTexture( sd[w] );
|
||||
} else goto fail;
|
||||
U8 type;
|
||||
w = "type";
|
||||
if (sd.has(w))
|
||||
{
|
||||
setSculptType( (U8)sd[w].asInteger() );
|
||||
} else goto fail;
|
||||
|
||||
type = sd[w].asInteger();
|
||||
}
|
||||
else return false;
|
||||
|
||||
w = "texture";
|
||||
if (sd.has(w))
|
||||
{
|
||||
setSculptTexture(sd[w], type);
|
||||
}
|
||||
else return false;
|
||||
|
||||
return true;
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLSculptParams::setSculptTexture(const LLUUID& texture_id, U8 sculpt_type)
|
||||
{
|
||||
U8 type = sculpt_type & LL_SCULPT_TYPE_MASK;
|
||||
U8 flags = sculpt_type & LL_SCULPT_FLAG_MASK;
|
||||
if (sculpt_type != (type | flags) || type > LL_SCULPT_TYPE_MAX)
|
||||
{
|
||||
mSculptTexture.set(SCULPT_DEFAULT_TEXTURE);
|
||||
mSculptType = LL_SCULPT_TYPE_SPHERE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mSculptTexture = texture_id;
|
||||
mSculptType = sculpt_type;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
|
|
|||
|
|
@ -267,9 +267,8 @@ public:
|
|||
operator LLSD() const { return asLLSD(); }
|
||||
bool fromLLSD(LLSD& sd);
|
||||
|
||||
void setSculptTexture(const LLUUID& id) { mSculptTexture = id; }
|
||||
void setSculptTexture(const LLUUID& texture_id, U8 sculpt_type);
|
||||
LLUUID getSculptTexture() const { return mSculptTexture; }
|
||||
void setSculptType(U8 type) { mSculptType = type; }
|
||||
U8 getSculptType() const { return mSculptType; }
|
||||
};
|
||||
|
||||
|
|
@ -393,7 +392,7 @@ public:
|
|||
virtual S32 setTEMediaFlags(const U8 te, const U8 flags);
|
||||
virtual S32 setTEGlow(const U8 te, const F32 glow);
|
||||
virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
|
||||
virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
|
||||
virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams, bool isInitFromServer);
|
||||
virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed
|
||||
virtual void setTESelected(const U8 te, bool sel);
|
||||
|
||||
|
|
|
|||
|
|
@ -368,11 +368,18 @@ S32 LLPrimTextureList::setMaterialID(const U8 index, const LLMaterialID& pMateri
|
|||
return TEM_CHANGE_NONE;
|
||||
}
|
||||
|
||||
S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams)
|
||||
S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams, bool isInitFromServer)
|
||||
{
|
||||
if (index < mEntryList.size())
|
||||
{
|
||||
return mEntryList[index]->setMaterialParams(pMaterialParams);
|
||||
if (!isInitFromServer && mEntryList[index]->isMatParamsInitFromServer())
|
||||
{
|
||||
return TEM_CHANGE_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mEntryList[index]->setMaterialParams(pMaterialParams);
|
||||
}
|
||||
}
|
||||
return TEM_CHANGE_NONE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ public:
|
|||
S32 setMediaFlags(const U8 index, const U8 media_flags);
|
||||
S32 setGlow(const U8 index, const F32 glow);
|
||||
S32 setMaterialID(const U8 index, const LLMaterialID& pMaterialID);
|
||||
S32 setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
|
||||
S32 setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams, bool isInitFromServer);
|
||||
|
||||
LLMaterialPtr getMaterialParams(const U8 index);
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ LLTextureEntry::LLTextureEntry()
|
|||
: mMediaEntry(NULL)
|
||||
, mSelected(false)
|
||||
, mMaterialUpdatePending(false)
|
||||
, mInitMatParamsFromServer(false)
|
||||
{
|
||||
init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
|
||||
}
|
||||
|
|
@ -71,6 +72,7 @@ LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
|
|||
: mMediaEntry(NULL)
|
||||
, mSelected(false)
|
||||
, mMaterialUpdatePending(false)
|
||||
, mInitMatParamsFromServer(false)
|
||||
{
|
||||
init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
|
||||
}
|
||||
|
|
@ -79,6 +81,7 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
|
|||
: mMediaEntry(NULL)
|
||||
, mSelected(false)
|
||||
, mMaterialUpdatePending(false)
|
||||
, mInitMatParamsFromServer(false)
|
||||
{
|
||||
mID = rhs.mID;
|
||||
mScaleS = rhs.mScaleS;
|
||||
|
|
@ -562,6 +565,7 @@ S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams)
|
|||
mMaterialUpdatePending = true;
|
||||
}
|
||||
mMaterial = pMaterialParams;
|
||||
this->mInitMatParamsFromServer = TRUE;
|
||||
return TEM_CHANGE_TEXTURE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,6 +156,8 @@ public:
|
|||
const LLMaterialID& getMaterialID() const { return mMaterialID; };
|
||||
const LLMaterialPtr getMaterialParams() const { return mMaterial; };
|
||||
|
||||
bool isMatParamsInitFromServer() const { return mInitMatParamsFromServer; };
|
||||
|
||||
// *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.
|
||||
// CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData()
|
||||
// to NOT return NULL.
|
||||
|
|
@ -213,6 +215,8 @@ protected:
|
|||
bool mMaterialUpdatePending;
|
||||
LLMaterialID mMaterialID;
|
||||
LLMaterialPtr mMaterial;
|
||||
bool mInitMatParamsFromServer; // Flag to identification when material paramas initialized from
|
||||
|
||||
|
||||
// Note the media data is not sent via the same message structure as the rest of the TE
|
||||
LLMediaEntry* mMediaEntry; // The media data for the face
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ void LLDockableFloater::setVisible(BOOL visible)
|
|||
mDockControl.get()->repositionDockable();
|
||||
}
|
||||
|
||||
if (visible)
|
||||
if (visible && !isMinimized())
|
||||
{
|
||||
LLFloater::setFrontmost(getAutoFocus());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1581,31 +1581,37 @@ void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection)
|
|||
|
||||
LLFolderView* root = getRoot();
|
||||
|
||||
for (std::vector<LLFolderViewItem*>::iterator it = items_to_select_forward.begin(), end_it = items_to_select_forward.end();
|
||||
BOOL selection_reverse = new_selection->isSelected(); //indication that some elements are being deselected
|
||||
|
||||
// array always go from 'will be selected' to ' will be unselected', iterate
|
||||
// in opposite direction to simplify identification of 'point of origin' in
|
||||
// case it is in the list we are working with
|
||||
for (std::vector<LLFolderViewItem*>::reverse_iterator it = items_to_select_forward.rbegin(), end_it = items_to_select_forward.rend();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
LLFolderViewItem* item = *it;
|
||||
if (item->isSelected())
|
||||
BOOL selected = item->isSelected();
|
||||
if (!selection_reverse && selected)
|
||||
{
|
||||
root->removeFromSelectionList(item);
|
||||
// it is our 'point of origin' where we shift/expand from
|
||||
// don't deselect it
|
||||
selection_reverse = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->selectItem();
|
||||
root->changeSelection(item, !selected);
|
||||
}
|
||||
root->addToSelectionList(item);
|
||||
}
|
||||
|
||||
if (new_selection->isSelected())
|
||||
if (selection_reverse)
|
||||
{
|
||||
root->removeFromSelectionList(new_selection);
|
||||
// at some point we reversed selection, first element should be deselected
|
||||
root->changeSelection(last_selected_item_from_cur, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_selection->selectItem();
|
||||
}
|
||||
root->addToSelectionList(new_selection);
|
||||
|
||||
// element we expand to should always be selected
|
||||
root->changeSelection(new_selection, TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -226,7 +226,6 @@ BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask)
|
|||
|
||||
BOOL LLMenuItemGL::handleHover(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
setHover(TRUE);
|
||||
getWindow()->setCursor(UI_CURSOR_ARROW);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -247,6 +246,18 @@ BOOL LLMenuItemGL::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
|||
return LLUICtrl::handleRightMouseDown(x,y,mask);
|
||||
}
|
||||
|
||||
void LLMenuItemGL::onMouseEnter(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
setHover(TRUE);
|
||||
LLUICtrl::onMouseEnter(x,y,mask);
|
||||
}
|
||||
|
||||
void LLMenuItemGL::onMouseLeave(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
setHover(FALSE);
|
||||
LLUICtrl::onMouseLeave(x,y,mask);
|
||||
}
|
||||
|
||||
//virtual
|
||||
BOOL LLMenuItemGL::handleRightMouseUp(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
|
|
@ -549,9 +560,6 @@ void LLMenuItemGL::draw( void )
|
|||
gl_line_2d(x_begin, (MENU_ITEM_PADDING / 2) + 1, x_end, (MENU_ITEM_PADDING / 2) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// clear got hover every frame
|
||||
setHover(FALSE);
|
||||
}
|
||||
|
||||
BOOL LLMenuItemGL::setLabelArg( const std::string& key, const LLStringExplicit& text )
|
||||
|
|
@ -1059,7 +1067,7 @@ void LLMenuItemBranchGL::onCommit( void )
|
|||
|
||||
// keyboard navigation automatically propagates highlight to sub-menu
|
||||
// to facilitate fast menu control via jump keys
|
||||
if (LLMenuGL::getKeyboardMode() && getBranch()&& !getBranch()->getHighlightedItem())
|
||||
if (LLMenuGL::getKeyboardMode() && getBranch() && !getBranch()->getHighlightedItem())
|
||||
{
|
||||
getBranch()->highlightNextItem(NULL);
|
||||
}
|
||||
|
|
@ -1472,7 +1480,16 @@ BOOL LLMenuItemBranchDownGL::handleMouseDown( S32 x, S32 y, MASK mask )
|
|||
{
|
||||
// switch to mouse control mode
|
||||
LLMenuGL::setKeyboardMode(FALSE);
|
||||
onCommit();
|
||||
|
||||
if (getVisible() && isOpen())
|
||||
{
|
||||
LLMenuGL::sMenuContainer->hideMenus();
|
||||
}
|
||||
else
|
||||
{
|
||||
onCommit();
|
||||
}
|
||||
|
||||
make_ui_sound("UISndClick");
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1604,10 +1621,6 @@ void LLMenuItemBranchDownGL::draw( void )
|
|||
gl_line_2d(x_begin, LABEL_BOTTOM_PAD_PIXELS, x_end, LABEL_BOTTOM_PAD_PIXELS);
|
||||
}
|
||||
}
|
||||
|
||||
// reset every frame so that we only show highlight
|
||||
// when we get hover events on that frame
|
||||
setHover(FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3647,8 +3660,24 @@ BOOL LLMenuHolderGL::handleMouseDown( S32 x, S32 y, MASK mask )
|
|||
BOOL handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL;
|
||||
if (!handled)
|
||||
{
|
||||
// clicked off of menu, hide them all
|
||||
hideMenus();
|
||||
LLMenuGL* visible_menu = (LLMenuGL*)getVisibleMenu();
|
||||
LLMenuItemGL* parent_menu = visible_menu ? visible_menu->getParentMenuItem() : NULL;
|
||||
if (parent_menu && parent_menu->getVisible())
|
||||
{
|
||||
// don't hide menu if parent was hit
|
||||
LLRect parent_rect;
|
||||
parent_menu->localRectToOtherView(parent_menu->getLocalRect(), &parent_rect, this);
|
||||
if (!parent_rect.pointInRect(x, y))
|
||||
{
|
||||
// clicked off of menu and parent, hide them all
|
||||
hideMenus();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no visible parent, clicked off of menu, hide them all
|
||||
hideMenus();
|
||||
}
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,6 +159,10 @@ public:
|
|||
virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
|
||||
virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
|
||||
virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
|
||||
|
||||
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
|
||||
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
|
||||
virtual void draw( void );
|
||||
|
||||
BOOL getHover() const { return mGotHover; }
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "linden_common.h"
|
||||
|
||||
#include "llsearcheditor.h"
|
||||
#include "llkeyboard.h"
|
||||
|
||||
LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)
|
||||
: LLUICtrl(p),
|
||||
|
|
@ -166,4 +167,16 @@ void LLSearchEditor::handleKeystroke()
|
|||
{
|
||||
mKeystrokeCallback(this, getValue());
|
||||
}
|
||||
|
||||
KEY key = gKeyboard->currentKey();
|
||||
if (key == KEY_LEFT ||
|
||||
key == KEY_RIGHT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (mTextChangedCallback)
|
||||
{
|
||||
mTextChangedCallback(this, getValue());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,12 +82,14 @@ public:
|
|||
virtual void setFocus( BOOL b );
|
||||
|
||||
void setKeystrokeCallback( commit_callback_t cb ) { mKeystrokeCallback = cb; }
|
||||
void setTextChangedCallback( commit_callback_t cb ) { mTextChangedCallback = cb; }
|
||||
|
||||
protected:
|
||||
void onClearButtonClick(const LLSD& data);
|
||||
virtual void handleKeystroke();
|
||||
|
||||
commit_callback_t mKeystrokeCallback;
|
||||
commit_callback_t mTextChangedCallback;
|
||||
LLLineEditor* mSearchEditor;
|
||||
LLButton* mSearchButton;
|
||||
LLButton* mClearButton;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "lltextparser.h"
|
||||
#include "lltextutil.h"
|
||||
#include "lltooltip.h"
|
||||
#include "lltrans.h"
|
||||
#include "lluictrl.h"
|
||||
#include "llurlaction.h"
|
||||
#include "llurlregistry.h"
|
||||
|
|
@ -2265,9 +2266,17 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
|
|||
// add icon before url if need
|
||||
// <FS:Ansariel> Optional icon position
|
||||
//LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted());
|
||||
//if ((isContentTrusted() || match.isTrusted()) && !match.getIcon().empty() )
|
||||
//{
|
||||
// setLastSegmentToolTip(LLTrans::getString("TooltipSLIcon"));
|
||||
//}
|
||||
if (mIconPositioning == LLTextBaseEnums::LEFT || match.isTrusted())
|
||||
{
|
||||
LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted());
|
||||
if ((isContentTrusted() || match.isTrusted()) && !match.getIcon().empty() )
|
||||
{
|
||||
setLastSegmentToolTip(LLTrans::getString("TooltipSLIcon"));
|
||||
}
|
||||
}
|
||||
// </FS:Ansariel> Optional icon position
|
||||
|
||||
|
|
@ -2277,48 +2286,34 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
|
|||
appendAndHighlightTextImpl(match.getLabel(), part, link_params,
|
||||
input_params.is_name_slurl ? false : match.underlineOnHoverOnly());
|
||||
// </FS:CR>
|
||||
bool tooltip_required = !match.getTooltip().empty();
|
||||
|
||||
// <FS:Ansariel> Unfail URI display
|
||||
// set the tooltip for the Url label (host part)
|
||||
if (! match.getTooltip().empty())
|
||||
// set the tooltip for the Url label
|
||||
if (tooltip_required)
|
||||
{
|
||||
segment_set_t::iterator it = getSegIterContaining(getLength()-1);
|
||||
if (it != mSegments.end())
|
||||
{
|
||||
LLTextSegmentPtr segment = *it;
|
||||
segment->setToolTip(match.getTooltip());
|
||||
}
|
||||
setLastSegmentToolTip(match.getTooltip());
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
// show query part of url with gray color only for LLUrlEntryHTTP and LLUrlEntryHTTPNoProtocol url entries
|
||||
// show query part of url with gray color only for LLUrlEntryHTTP url entries
|
||||
std::string label = match.getQuery();
|
||||
if (label.size())
|
||||
{
|
||||
// <FS:Ansariel> Custom URI query part color
|
||||
//link_params.color = LLColor4::grey;
|
||||
//link_params.readonly_color = LLColor4::grey;
|
||||
//appendAndHighlightTextImpl(label, part, link_params, match.underlineOnHoverOnly());
|
||||
static LLUIColor query_part_color = LLUIColorTable::getInstance()->getColor("UriQueryPartColor", LLColor4::grey);
|
||||
link_params.color = query_part_color;
|
||||
link_params.readonly_color = query_part_color;
|
||||
// </FS:Ansariel>
|
||||
// <FS:Ansariel> Unfail URI display; add tooltip for query part
|
||||
//appendAndHighlightTextImpl(label, part, link_params, match.underlineOnHoverOnly());
|
||||
appendAndHighlightTextImpl(label, part, link_params, input_params.is_name_slurl ? false : match.underlineOnHoverOnly());
|
||||
//}
|
||||
|
||||
// set the tooltip for the Url label
|
||||
if (! match.getTooltip().empty())
|
||||
{
|
||||
segment_set_t::iterator it = getSegIterContaining(getLength()-1);
|
||||
if (it != mSegments.end())
|
||||
// </FS:Ansariel>
|
||||
|
||||
// set the tooltip for the query part of url
|
||||
if (tooltip_required)
|
||||
{
|
||||
LLTextSegmentPtr segment = *it;
|
||||
segment->setToolTip(match.getTooltip());
|
||||
setLastSegmentToolTip(match.getTooltip());
|
||||
}
|
||||
}
|
||||
// <FS:Ansariel> Unfail URI display
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Optional icon position
|
||||
if (mIconPositioning == LLTextBaseEnums::RIGHT && !match.isTrusted())
|
||||
|
|
@ -2350,6 +2345,16 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
|
|||
}
|
||||
}
|
||||
|
||||
void LLTextBase::setLastSegmentToolTip(const std::string &tooltip)
|
||||
{
|
||||
segment_set_t::iterator it = getSegIterContaining(getLength()-1);
|
||||
if (it != mSegments.end())
|
||||
{
|
||||
LLTextSegmentPtr segment = *it;
|
||||
segment->setToolTip(tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
static LLTrace::BlockTimerStatHandle FTM_APPEND_TEXT("Append Text");
|
||||
|
||||
void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params)
|
||||
|
|
@ -3868,6 +3873,22 @@ S32 LLImageTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
|
|||
return 0;
|
||||
}
|
||||
|
||||
BOOL LLImageTextSegment::handleToolTip(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if (!mTooltip.empty())
|
||||
{
|
||||
LLToolTipMgr::instance().show(mTooltip);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LLImageTextSegment::setToolTip(const std::string& tooltip)
|
||||
{
|
||||
mTooltip = tooltip;
|
||||
}
|
||||
|
||||
F32 LLImageTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
|
||||
{
|
||||
if ( (start >= 0) && (end <= mEnd - mStart))
|
||||
|
|
|
|||
|
|
@ -241,9 +241,15 @@ public:
|
|||
S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
|
||||
F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
|
||||
|
||||
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ void setToolTip(const std::string& tooltip);
|
||||
|
||||
private:
|
||||
class LLTextBase& mEditor;
|
||||
LLStyleConstSP mStyle;
|
||||
|
||||
protected:
|
||||
std::string mTooltip;
|
||||
};
|
||||
|
||||
typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
|
||||
|
|
@ -428,6 +434,8 @@ public:
|
|||
const std::string& getLabel() { return mLabel.getString(); }
|
||||
const LLWString& getWlabel() { return mLabel.getWString();}
|
||||
|
||||
void setLastSegmentToolTip(const std::string &tooltip);
|
||||
|
||||
/**
|
||||
* If label is set, draws text label (which is LLLabelTextSegment)
|
||||
* that is visible when no user text provided
|
||||
|
|
|
|||
|
|
@ -219,10 +219,10 @@ std::string LLUrlEntryBase::urlToGreyQuery(const std::string &url) const
|
|||
LLUriParser up(url);
|
||||
// </FS:Ansariel>
|
||||
|
||||
std::string query;
|
||||
std::string label;
|
||||
up.extractParts();
|
||||
up.glueSecond(query);
|
||||
|
||||
up.glueFirst(label);
|
||||
std::string query = url.substr(label.size());
|
||||
// <FS:Ansariel> Unfail URI display
|
||||
//return query;
|
||||
return unescapeUrl(query);
|
||||
|
|
@ -249,8 +249,8 @@ LLUrlEntryHTTP::LLUrlEntryHTTP()
|
|||
: LLUrlEntryBase()
|
||||
{
|
||||
// <FS:Ansariel> FIRE-1715: Links using FTP protocol are not recognized
|
||||
//mPattern = boost::regex("https?://([-\\w\\.]+)+(:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?/?\\S*",
|
||||
mPattern = boost::regex("(https?|ftp)://([-\\w\\.]+)+(:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?/?\\S*",
|
||||
//mPattern = boost::regex("https?://([-\\w\\.]+)+(:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?\\.[a-z](:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?/?\\S*",
|
||||
mPattern = boost::regex("(https?|ftp)://([-\\w\\.]+)+(:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?\\.[a-z](:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?/?\\S*",
|
||||
// </FS:Ansariel>
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mMenuName = "menu_url_http.xml";
|
||||
|
|
@ -315,51 +315,6 @@ std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string) const
|
|||
return getUrlFromWikiLink(string);
|
||||
}
|
||||
|
||||
//
|
||||
// LLUrlEntryHTTPNoProtocol Describes generic Urls like www.google.com
|
||||
//
|
||||
LLUrlEntryHTTPNoProtocol::LLUrlEntryHTTPNoProtocol()
|
||||
: LLUrlEntryBase()
|
||||
{
|
||||
mPattern = boost::regex("("
|
||||
// <FS:Ansariel> FIRE-1715: Links using FTP protocol are not recognized
|
||||
//"\\bwww\\.\\S+\\.\\S+" // i.e. www.FOO.BAR
|
||||
"\\b(www|ftp)\\.\\S+\\.\\S+" // i.e. www.FOO.BAR
|
||||
// </FS:Ansariel>
|
||||
"|" // or
|
||||
"(?<!@)\\b[^[:space:]:@/>]+\\.(?:com|net|edu|org)([/:][^[:space:]<]*)?\\b" // i.e. FOO.net
|
||||
")",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mMenuName = "menu_url_http.xml";
|
||||
mTooltip = LLTrans::getString("TooltipHttpUrl");
|
||||
}
|
||||
|
||||
std::string LLUrlEntryHTTPNoProtocol::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
|
||||
{
|
||||
return urlToLabelWithGreyQuery(url);
|
||||
}
|
||||
|
||||
std::string LLUrlEntryHTTPNoProtocol::getQuery(const std::string &url) const
|
||||
{
|
||||
return urlToGreyQuery(url);
|
||||
}
|
||||
|
||||
std::string LLUrlEntryHTTPNoProtocol::getUrl(const std::string &string) const
|
||||
{
|
||||
if (string.find("://") == std::string::npos)
|
||||
{
|
||||
return "http://" + escapeUrl(string);
|
||||
}
|
||||
return escapeUrl(string);
|
||||
}
|
||||
|
||||
std::string LLUrlEntryHTTPNoProtocol::getTooltip(const std::string &url) const
|
||||
{
|
||||
// <FS:Ansariel> Unfail URI display
|
||||
//return unescapeUrl(url);
|
||||
return mTooltip;
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
|
||||
LLUrlEntryInvalidSLURL::LLUrlEntryInvalidSLURL()
|
||||
: LLUrlEntryBase()
|
||||
|
|
@ -531,7 +486,7 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
|
|||
//
|
||||
LLUrlEntrySecondlifeURL::LLUrlEntrySecondlifeURL()
|
||||
{
|
||||
mPattern = boost::regex("(https?://)?([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com(:\\d{1,5})?\\/\\S*",
|
||||
mPattern = boost::regex("https?://([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com(:\\d{1,5})?\\/\\S*",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
|
||||
mIcon = "Hand";
|
||||
|
|
@ -572,7 +527,7 @@ std::string LLUrlEntrySecondlifeURL::getTooltip(const std::string &url) const
|
|||
//
|
||||
LLUrlEntrySimpleSecondlifeURL::LLUrlEntrySimpleSecondlifeURL()
|
||||
{
|
||||
mPattern = boost::regex("(https?://)?([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com(?!\\S)",
|
||||
mPattern = boost::regex("https?://([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com(?!\\S)",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
|
||||
mIcon = "Hand";
|
||||
|
|
@ -1546,9 +1501,43 @@ std::string LLUrlEntryJira::getUrl(const std::string &string) const
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// LLUrlEntryEmail Describes a generic mailto: Urls
|
||||
//
|
||||
LLUrlEntryEmail::LLUrlEntryEmail()
|
||||
: LLUrlEntryBase()
|
||||
{
|
||||
mPattern = boost::regex("(mailto:)?[\\w\\.\\-]+@[\\w\\.\\-]+\\.[a-z]{2,6}",
|
||||
boost::regex::perl | boost::regex::icase);
|
||||
mMenuName = "menu_url_email.xml";
|
||||
mTooltip = LLTrans::getString("TooltipEmail");
|
||||
}
|
||||
|
||||
std::string LLUrlEntryEmail::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
|
||||
{
|
||||
int pos = url.find("mailto:");
|
||||
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
return escapeUrl(url);
|
||||
}
|
||||
|
||||
std::string ret = escapeUrl(url.substr(pos + 7, url.length() - pos + 8));
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string LLUrlEntryEmail::getUrl(const std::string &string) const
|
||||
{
|
||||
if (string.find("mailto:") == std::string::npos)
|
||||
{
|
||||
return "mailto:" + escapeUrl(string);
|
||||
}
|
||||
return escapeUrl(string);
|
||||
}
|
||||
|
||||
LLUrlEntryExperienceProfile::LLUrlEntryExperienceProfile()
|
||||
{
|
||||
mPattern = boost::regex(APP_HEADER_REGEX "/experience/[\\da-f-]+/\\w+\\S*",
|
||||
mPattern = boost::regex(APP_HEADER_REGEX "/experience/[\\da-f-]+/profile",
|
||||
boost::regex::perl|boost::regex::icase);
|
||||
mIcon = "Generic_Experience";
|
||||
mMenuName = "menu_url_experience.xml";
|
||||
|
|
|
|||
|
|
@ -157,19 +157,6 @@ public:
|
|||
/*virtual*/ std::string getUrl(const std::string &string) const;
|
||||
};
|
||||
|
||||
///
|
||||
/// LLUrlEntryHTTPNoProtocol Describes generic Urls like www.google.com
|
||||
///
|
||||
class LLUrlEntryHTTPNoProtocol : public LLUrlEntryBase
|
||||
{
|
||||
public:
|
||||
LLUrlEntryHTTPNoProtocol();
|
||||
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
|
||||
/*virtual*/ std::string getQuery(const std::string &url) const;
|
||||
/*virtual*/ std::string getUrl(const std::string &string) const;
|
||||
/*virtual*/ std::string getTooltip(const std::string &url) const;
|
||||
};
|
||||
|
||||
class LLUrlEntryInvalidSLURL : public LLUrlEntryBase
|
||||
{
|
||||
public:
|
||||
|
|
@ -549,6 +536,17 @@ public:
|
|||
/*virtual*/ std::string getIcon(const std::string &url);
|
||||
};
|
||||
|
||||
///
|
||||
/// LLUrlEntryEmail Describes a generic mailto: Urls
|
||||
///
|
||||
class LLUrlEntryEmail : public LLUrlEntryBase
|
||||
{
|
||||
public:
|
||||
LLUrlEntryEmail();
|
||||
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
|
||||
/*virtual*/ std::string getUrl(const std::string &string) const;
|
||||
};
|
||||
|
||||
///
|
||||
/// LLUrlEntryJira Describes Jira issue names -KC
|
||||
///
|
||||
|
|
|
|||
|
|
@ -90,9 +90,7 @@ LLUrlRegistry::LLUrlRegistry()
|
|||
registerUrl(new LLUrlEntrySL());
|
||||
mUrlEntrySLLabel = new LLUrlEntrySLLabel();
|
||||
registerUrl(mUrlEntrySLLabel);
|
||||
// most common pattern is a URL without any protocol,
|
||||
// e.g., "secondlife.com"
|
||||
registerUrl(new LLUrlEntryHTTPNoProtocol());
|
||||
registerUrl(new LLUrlEntryEmail());
|
||||
// parse jira issue names to links -KC
|
||||
registerUrl(new LLUrlEntryJira());
|
||||
}
|
||||
|
|
@ -171,9 +169,6 @@ static bool stringHasUrl(const std::string &text)
|
|||
return (text.find("://") != std::string::npos ||
|
||||
// text.find("www.") != std::string::npos ||
|
||||
// text.find(".com") != std::string::npos ||
|
||||
// text.find(".net") != std::string::npos ||
|
||||
// text.find(".edu") != std::string::npos ||
|
||||
// text.find(".org") != std::string::npos ||
|
||||
// allow ALLCAPS urls -KC
|
||||
boost::ifind_first(text, "www.") ||
|
||||
boost::ifind_first(text, ".com") ||
|
||||
|
|
@ -181,7 +176,8 @@ static bool stringHasUrl(const std::string &text)
|
|||
boost::ifind_first(text, ".edu") ||
|
||||
boost::ifind_first(text, ".org") ||
|
||||
text.find("<nolink>") != std::string::npos ||
|
||||
text.find("<icon") != std::string::npos);
|
||||
text.find("<icon") != std::string::npos ||
|
||||
text.find("@") != std::string::npos);
|
||||
}
|
||||
|
||||
static bool stringHasJira(const std::string &text)
|
||||
|
|
@ -278,9 +274,40 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
|
|||
// did we find a match? if so, return its details in the match object
|
||||
if (match_entry)
|
||||
{
|
||||
|
||||
// Skip if link is an email with an empty username (starting with @). See MAINT-5371.
|
||||
if (match_start > 0 && text.substr(match_start - 1, 1) == "@")
|
||||
return false;
|
||||
|
||||
// fill in the LLUrlMatch object and return it
|
||||
std::string url = text.substr(match_start, match_end - match_start + 1);
|
||||
|
||||
LLUrlEntryBase *stripped_entry = NULL;
|
||||
if(LLStringUtil::containsNonprintable(url))
|
||||
{
|
||||
LLStringUtil::stripNonprintable(url);
|
||||
|
||||
std::vector<LLUrlEntryBase *>::iterator iter;
|
||||
for (iter = mUrlEntry.begin(); iter != mUrlEntry.end(); ++iter)
|
||||
{
|
||||
LLUrlEntryBase *url_entry = *iter;
|
||||
U32 start = 0, end = 0;
|
||||
if (matchRegex(url.c_str(), url_entry->getPattern(), start, end))
|
||||
{
|
||||
if (mLLUrlEntryInvalidSLURL == *iter)
|
||||
{
|
||||
if(url_entry && url_entry->isSLURLvalid(url))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
stripped_entry = url_entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// <FS:Ansariel> Fix the "nolink>" fail; Fix from Alchemy viewer, courtesy of Drake Arconis
|
||||
//if (match_entry == mUrlEntryTrusted)
|
||||
//{
|
||||
|
|
@ -298,10 +325,12 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
|
|||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
std::string url_label = stripped_entry? stripped_entry->getLabel(url, cb) : match_entry->getLabel(url, cb);
|
||||
std::string url_query = stripped_entry? stripped_entry->getQuery(url) : match_entry->getQuery(url);
|
||||
match.setValues(match_start, match_end,
|
||||
match_entry->getUrl(url),
|
||||
match_entry->getLabel(url, cb),
|
||||
match_entry->getQuery(url),
|
||||
url_label,
|
||||
url_query,
|
||||
match_entry->getTooltip(url),
|
||||
match_entry->getIcon(url),
|
||||
match_entry->getStyle(),
|
||||
|
|
|
|||
|
|
@ -651,79 +651,6 @@ namespace tut
|
|||
|
||||
template<> template<>
|
||||
void object::test<11>()
|
||||
{
|
||||
//
|
||||
// test LLUrlEntryHTTPNoProtocol - general URLs without a protocol
|
||||
//
|
||||
LLUrlEntryHTTPNoProtocol url;
|
||||
|
||||
testRegex("naked .com URL", url,
|
||||
"see google.com",
|
||||
"http://google.com");
|
||||
|
||||
testRegex("naked .org URL", url,
|
||||
"see en.wikipedia.org for details",
|
||||
"http://en.wikipedia.org");
|
||||
|
||||
testRegex("naked .net URL", url,
|
||||
"example.net",
|
||||
"http://example.net");
|
||||
|
||||
testRegex("naked .edu URL (2 instances)", url,
|
||||
"MIT web site is at web.mit.edu and also www.mit.edu",
|
||||
"http://web.mit.edu");
|
||||
|
||||
testRegex("don't match e-mail addresses", url,
|
||||
"test@lindenlab.com",
|
||||
"");
|
||||
|
||||
testRegex(".com URL with path", url,
|
||||
"see secondlife.com/status for grid status",
|
||||
"http://secondlife.com/status");
|
||||
|
||||
testRegex(".com URL with port", url,
|
||||
"secondlife.com:80",
|
||||
"http://secondlife.com:80");
|
||||
|
||||
testRegex(".com URL with port and path", url,
|
||||
"see secondlife.com:80/status",
|
||||
"http://secondlife.com:80/status");
|
||||
|
||||
testRegex("www.*.com URL with port and path", url,
|
||||
"see www.secondlife.com:80/status",
|
||||
"http://www.secondlife.com:80/status");
|
||||
|
||||
testRegex("invalid .com URL [1]", url,
|
||||
"..com",
|
||||
"");
|
||||
|
||||
testRegex("invalid .com URL [2]", url,
|
||||
"you.come",
|
||||
"");
|
||||
|
||||
testRegex("invalid .com URL [3]", url,
|
||||
"recommended",
|
||||
"");
|
||||
|
||||
testRegex("invalid .edu URL", url,
|
||||
"hi there scheduled maitenance has begun",
|
||||
"");
|
||||
|
||||
testRegex("invalid .net URL", url,
|
||||
"foo.netty",
|
||||
"");
|
||||
|
||||
testRegex("XML tags around URL [1]", url,
|
||||
"<foo>secondlife.com</foo>",
|
||||
"http://secondlife.com");
|
||||
|
||||
testRegex("XML tags around URL [2]", url,
|
||||
"<foo>secondlife.com/status?bar=1</foo>",
|
||||
"http://secondlife.com/status?bar=1");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<12>()
|
||||
{
|
||||
//
|
||||
// test LLUrlEntryNoLink - turn off hyperlinking
|
||||
|
|
@ -752,7 +679,7 @@ namespace tut
|
|||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<13>()
|
||||
void object::test<12>()
|
||||
{
|
||||
//
|
||||
// test LLUrlEntryRegion - secondlife:///app/region/<location> URLs
|
||||
|
|
@ -860,4 +787,101 @@ namespace tut
|
|||
"secondlife:///app/region/Product%20Engine",
|
||||
"Product Engine");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<13>()
|
||||
{
|
||||
//
|
||||
// test LLUrlEntryemail - general emails
|
||||
//
|
||||
LLUrlEntryEmail url;
|
||||
|
||||
// Regex tests.
|
||||
testRegex("match e-mail addresses", url,
|
||||
"test@lindenlab.com",
|
||||
"mailto:test@lindenlab.com");
|
||||
|
||||
testRegex("match e-mail addresses with mailto: prefix", url,
|
||||
"mailto:test@lindenlab.com",
|
||||
"mailto:test@lindenlab.com");
|
||||
|
||||
testRegex("match e-mail addresses with different domains", url,
|
||||
"test@foo.org.us",
|
||||
"mailto:test@foo.org.us");
|
||||
|
||||
testRegex("match e-mail addresses with different domains", url,
|
||||
"test@foo.bar",
|
||||
"mailto:test@foo.bar");
|
||||
|
||||
testRegex("don't match incorrect e-mail addresses", url,
|
||||
"test @foo.com",
|
||||
"");
|
||||
|
||||
testRegex("don't match incorrect e-mail addresses", url,
|
||||
"test@ foo.com",
|
||||
"");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<14>()
|
||||
{
|
||||
//
|
||||
// test LLUrlEntrySimpleSecondlifeURL - http://*.secondlife.com/* and http://*lindenlab.com/* urls
|
||||
//
|
||||
LLUrlEntrySecondlifeURL url;
|
||||
|
||||
testRegex("match urls with protocol", url,
|
||||
"this url should match http://lindenlab.com/products/second-life",
|
||||
"http://lindenlab.com/products/second-life");
|
||||
|
||||
testRegex("match urls with protocol", url,
|
||||
"search something https://marketplace.secondlife.com/products/search on marketplace and test the https",
|
||||
"https://marketplace.secondlife.com/products/search");
|
||||
|
||||
testRegex("match urls with port", url,
|
||||
"let's specify some port http://secondlife.com:888/status",
|
||||
"http://secondlife.com:888/status");
|
||||
|
||||
testRegex("don't match urls w/o protocol", url,
|
||||
"looks like an url something www.marketplace.secondlife.com/products but no https prefix",
|
||||
"");
|
||||
|
||||
testRegex("but with a protocol www is fine", url,
|
||||
"so let's add a protocol http://www.marketplace.secondlife.com:8888/products",
|
||||
"http://www.marketplace.secondlife.com:8888/products");
|
||||
|
||||
testRegex("don't match urls w/o protocol", url,
|
||||
"and even no www something secondlife.com/status",
|
||||
"");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<15>()
|
||||
{
|
||||
//
|
||||
// test LLUrlEntrySimpleSecondlifeURL - http://*.secondlife.com and http://*lindenlab.com urls
|
||||
//
|
||||
|
||||
LLUrlEntrySimpleSecondlifeURL url;
|
||||
|
||||
testRegex("match urls with a protocol", url,
|
||||
"this url should match http://lindenlab.com",
|
||||
"http://lindenlab.com");
|
||||
|
||||
testRegex("match urls with a protocol", url,
|
||||
"search something https://marketplace.secondlife.com on marketplace and test the https",
|
||||
"https://marketplace.secondlife.com");
|
||||
|
||||
testRegex("don't match urls w/o protocol", url,
|
||||
"looks like an url something www.marketplace.secondlife.com but no https prefix",
|
||||
"");
|
||||
|
||||
testRegex("but with a protocol www is fine", url,
|
||||
"so let's add a protocol http://www.marketplace.secondlife.com",
|
||||
"http://www.marketplace.secondlife.com");
|
||||
|
||||
testRegex("don't match urls w/o protocol", url,
|
||||
"and even no www something lindenlab.com",
|
||||
"");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,14 +50,14 @@ BOOL gDebugClicks = FALSE;
|
|||
BOOL gDebugWindowProc = FALSE;
|
||||
|
||||
// <FS:Zi> Allow file: links to open folders, chat history etc. on Linux systems
|
||||
//const S32 gURLProtocolWhitelistCount = 5;
|
||||
//const std::string gURLProtocolWhitelist[] = { "secondlife:", "http:", "https:", "data:", "mailto:" };
|
||||
#if LL_LINUX
|
||||
const S32 gURLProtocolWhitelistCount = 6;
|
||||
const std::string gURLProtocolWhitelist[] = { "secondlife:", "http:", "https:", "ftp:", "data:", "file:" };
|
||||
const S32 gURLProtocolWhitelistCount = 7;
|
||||
const std::string gURLProtocolWhitelist[] = { "secondlife:", "http:", "https:", "ftp:", "data:", "mailto:", "file:" };
|
||||
#else
|
||||
// </FS:Zi>
|
||||
const S32 gURLProtocolWhitelistCount = 5;
|
||||
const std::string gURLProtocolWhitelist[] = { "secondlife:", "http:", "https:", "ftp:", "data:" };
|
||||
// <FS:Zi> Allow file: links to open folders, chat history etc. on Linux systems
|
||||
const S32 gURLProtocolWhitelistCount = 6;
|
||||
const std::string gURLProtocolWhitelist[] = { "secondlife:", "http:", "https:", "ftp:", "data:", "mailto:" };
|
||||
#endif
|
||||
// </FS:Zi>
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ bool runMainLoop();
|
|||
void initMainLoop();
|
||||
void cleanupViewer();
|
||||
void handleUrl(const char* url);
|
||||
void dispatchUrl(std::string url);
|
||||
|
||||
/* Defined in llwindowmacosx-objc.mm: */
|
||||
int createNSApp(int argc, const char **argv);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ out vec4 frag_data[3];
|
|||
#define frag_data gl_FragData
|
||||
#endif
|
||||
|
||||
uniform float minimum_alpha;
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2D bumpMap;
|
||||
|
||||
|
|
@ -47,16 +48,23 @@ vec2 encode_normal(vec3 n)
|
|||
|
||||
void main()
|
||||
{
|
||||
vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
|
||||
vec3 norm = texture2D(bumpMap, vary_texcoord0.xy).rgb * 2.0 - 1.0;
|
||||
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
|
||||
|
||||
if(col.a < minimum_alpha)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
col *= vertex_color;
|
||||
|
||||
vec3 norm = texture2D(bumpMap, vary_texcoord0.xy).rgb * 2.0 - 1.0;
|
||||
|
||||
vec3 tnorm = vec3(dot(norm,vary_mat0),
|
||||
vec3 tnorm = vec3(dot(norm,vary_mat0),
|
||||
dot(norm,vary_mat1),
|
||||
dot(norm,vary_mat2));
|
||||
|
||||
frag_data[0] = vec4(col, 0.0);
|
||||
frag_data[1] = vertex_color.aaaa; // spec
|
||||
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
vec3 nvn = normalize(tnorm);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
|
||||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vertex_color.aaaa; // spec
|
||||
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
vec3 nvn = normalize(tnorm);
|
||||
frag_data[2] = vec4(encode_normal(nvn), vertex_color.a, 0.0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -420,6 +420,10 @@ public:
|
|||
//mFrom = LLTrans::getString("SECOND_LIFE");
|
||||
//[FIX FIRE-2852] Changed function to find the right Gridname
|
||||
mFrom = LLGridManager::getInstance()->getGridLabel();
|
||||
if(!chat.mFromName.empty() && (mFrom != chat.mFromName))
|
||||
{
|
||||
mFrom += " (" + chat.mFromName + ")";
|
||||
}
|
||||
user_name->setValue(mFrom);
|
||||
updateMinUserNameWidth();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -365,7 +365,7 @@ LLSD FSCommon::populateGroupCount()
|
|||
LLStringUtil::format_map_t args;
|
||||
S32 groupcount = gAgent.mGroups.size();
|
||||
args["[COUNT]"] = llformat("%d", groupcount);
|
||||
args["[REMAINING]"] = llformat("%d", gMaxAgentGroups - groupcount);
|
||||
args["[REMAINING]"] = llformat("%d", gMaxAgentGroups > groupcount ? gMaxAgentGroups - groupcount : 0);
|
||||
LLUIString groupcountstring = LLTrans::getString((gMaxAgentGroups ? "groupcountstring" : "groupcountunlimitedstring"), args);
|
||||
return LLSD(groupcountstring);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -782,7 +782,7 @@ bool FSFloaterImport::processPrimCreated(LLViewerObject* object)
|
|||
LL_DEBUGS("import") << "Setting materials" << LL_ENDL;
|
||||
LLMaterial* mat = new LLMaterial();
|
||||
mat->fromLLSD(*m_itr);
|
||||
object->setTEMaterialParams(te, mat);
|
||||
object->setTEMaterialParams(te, mat, false);
|
||||
++te;
|
||||
}
|
||||
}
|
||||
|
|
@ -796,7 +796,7 @@ bool FSFloaterImport::processPrimCreated(LLViewerObject* object)
|
|||
|
||||
if (mAssetMap[sculpt_params.getSculptTexture()].notNull())
|
||||
{
|
||||
sculpt_params.setSculptTexture(mAssetMap[sculpt_params.getSculptTexture()]);
|
||||
sculpt_params.setSculptTexture(mAssetMap[sculpt_params.getSculptTexture()], sculpt_params.getSculptType());
|
||||
LL_DEBUGS("import") << "Replaced " << prim["sculpt"]["texture"].asUUID().asString() << " with " << sculpt_params.getSculptTexture().asString() << LL_ENDL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -197,7 +197,12 @@ lbl_configure_default_lang:
|
|||
StrCpy $LANGUAGE $0
|
||||
|
||||
# For silent installs, no language prompt, use default
|
||||
# <FS:Ansariel> Disable autorun
|
||||
#IfSilent 0 +3
|
||||
#StrCpy $SKIP_AUTORUN "true"
|
||||
#Goto lbl_return
|
||||
IfSilent lbl_return
|
||||
# </FS:Ansariel>
|
||||
StrCmp $SKIP_DIALOGS "true" lbl_return
|
||||
|
||||
# <FS:Ansariel> Commented out; Warning in build log about not being used
|
||||
|
|
|
|||
|
|
@ -3324,7 +3324,7 @@ BOOL LLAgent::isInGroup(const LLUUID& group_id, BOOL ignore_god_mode /* FALSE */
|
|||
// This implementation should mirror LLAgentInfo::hasPowerInGroup
|
||||
BOOL LLAgent::hasPowerInGroup(const LLUUID& group_id, U64 power) const
|
||||
{
|
||||
if (isGodlike())
|
||||
if (isGodlikeWithoutAdminMenuFakery())
|
||||
return true;
|
||||
|
||||
// GP_NO_POWERS can also mean no power is enough to grant an ability.
|
||||
|
|
|
|||
|
|
@ -31,3 +31,4 @@
|
|||
|
||||
LLUUID gAgentID;
|
||||
LLUUID gAgentSessionID;
|
||||
std::string gAgentUsername;
|
||||
|
|
|
|||
|
|
@ -30,5 +30,6 @@
|
|||
|
||||
extern LLUUID gAgentID;
|
||||
extern LLUUID gAgentSessionID;
|
||||
extern std::string gAgentUsername;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1980,6 +1980,10 @@ bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids)
|
|||
{
|
||||
++n_clothes;
|
||||
}
|
||||
else if (item->getType() == LLAssetType::AT_BODYPART)
|
||||
{
|
||||
return isAgentAvatarValid();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "Unexpected wearable type" << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -3308,10 +3308,12 @@ bool LLAppViewer::initConfiguration()
|
|||
//
|
||||
gWindowTitle = LLVersionInfo::getChannelAndVersion(); // <FS:CR>
|
||||
#if LL_DEBUG
|
||||
gWindowTitle += std::string(" [DEBUG] ") + gArgs;
|
||||
#else
|
||||
gWindowTitle += std::string(" ") + gArgs;
|
||||
gWindowTitle += std::string(" [DEBUG]")
|
||||
#endif
|
||||
if (!gArgs.empty())
|
||||
{
|
||||
gWindowTitle += std::string(" ") + gArgs;
|
||||
}
|
||||
LLStringUtil::truncate(gWindowTitle, 255);
|
||||
|
||||
//RN: if we received a URL, hand it off to the existing instance.
|
||||
|
|
@ -5779,6 +5781,7 @@ void LLAppViewer::idle()
|
|||
|
||||
gIdleCallbacks.callFunctions();
|
||||
gInventory.idleNotifyObservers();
|
||||
LLAvatarTracker::instance().idleNotifyObservers();
|
||||
}
|
||||
|
||||
// Metrics logging (LLViewerAssetStats, etc.)
|
||||
|
|
|
|||
|
|
@ -62,9 +62,10 @@ namespace
|
|||
// They are not used immediately by the app.
|
||||
int gArgC;
|
||||
char** gArgV;
|
||||
LLAppViewerMacOSX* gViewerAppPtr;
|
||||
LLAppViewerMacOSX* gViewerAppPtr = NULL;
|
||||
|
||||
void (*gOldTerminateHandler)() = NULL;
|
||||
std::string gHandleSLURL;
|
||||
}
|
||||
|
||||
static void exceptionTerminateHandler()
|
||||
|
|
@ -107,7 +108,11 @@ bool initViewer()
|
|||
{
|
||||
LL_WARNS() << "Application init failed." << LL_ENDL;
|
||||
}
|
||||
|
||||
else if (!gHandleSLURL.empty())
|
||||
{
|
||||
dispatchUrl(gHandleSLURL);
|
||||
gHandleSLURL = "";
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
|
@ -393,22 +398,31 @@ bool LLAppViewerMacOSX::getMasterSystemAudioMute()
|
|||
|
||||
void handleUrl(const char* url_utf8)
|
||||
{
|
||||
if (url_utf8)
|
||||
if (url_utf8 && gViewerAppPtr)
|
||||
{
|
||||
std::string url = url_utf8;
|
||||
// Safari 3.2 silently mangles secondlife:///app/ URLs into
|
||||
// secondlife:/app/ (only one leading slash).
|
||||
// Fix them up to meet the URL specification. JC
|
||||
const std::string prefix = "secondlife:/app/";
|
||||
std::string test_prefix = url.substr(0, prefix.length());
|
||||
LLStringUtil::toLower(test_prefix);
|
||||
if (test_prefix == prefix)
|
||||
{
|
||||
url.replace(0, prefix.length(), "secondlife:///app/");
|
||||
}
|
||||
|
||||
LLMediaCtrl* web = NULL;
|
||||
const bool trusted_browser = false;
|
||||
LLURLDispatcher::dispatch(url, "", web, trusted_browser);
|
||||
gHandleSLURL = "";
|
||||
dispatchUrl(url_utf8);
|
||||
}
|
||||
else if (url_utf8)
|
||||
{
|
||||
gHandleSLURL = url_utf8;
|
||||
}
|
||||
}
|
||||
|
||||
void dispatchUrl(std::string url)
|
||||
{
|
||||
// Safari 3.2 silently mangles secondlife:///app/ URLs into
|
||||
// secondlife:/app/ (only one leading slash).
|
||||
// Fix them up to meet the URL specification. JC
|
||||
const std::string prefix = "secondlife:/app/";
|
||||
std::string test_prefix = url.substr(0, prefix.length());
|
||||
LLStringUtil::toLower(test_prefix);
|
||||
if (test_prefix == prefix)
|
||||
{
|
||||
url.replace(0, prefix.length(), "secondlife:///app/");
|
||||
}
|
||||
|
||||
LLMediaCtrl* web = NULL;
|
||||
const bool trusted_browser = false;
|
||||
LLURLDispatcher::dispatch(url, "", web, trusted_browser);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,8 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id,
|
|||
LLAvatarTracker::LLAvatarTracker() :
|
||||
mTrackingData(NULL),
|
||||
mTrackedAgentValid(false),
|
||||
mModifyMask(0x0)
|
||||
mModifyMask(0x0),
|
||||
mIsNotifyObservers(FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -280,8 +281,8 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds)
|
|||
<< "]" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
notifyObservers();
|
||||
|
||||
// do not notify observers here - list can be large so let it be done on idle.
|
||||
|
||||
return new_buddy_count;
|
||||
}
|
||||
|
||||
|
|
@ -484,8 +485,25 @@ void LLAvatarTracker::removeObserver(LLFriendObserver* observer)
|
|||
mObservers.end());
|
||||
}
|
||||
|
||||
void LLAvatarTracker::idleNotifyObservers()
|
||||
{
|
||||
if (mModifyMask == LLFriendObserver::NONE && mChangedBuddyIDs.size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
void LLAvatarTracker::notifyObservers()
|
||||
{
|
||||
if (mIsNotifyObservers)
|
||||
{
|
||||
// Don't allow multiple calls.
|
||||
// new masks and ids will be processed later from idle.
|
||||
return;
|
||||
}
|
||||
mIsNotifyObservers = TRUE;
|
||||
|
||||
observer_list_t observers(mObservers);
|
||||
observer_list_t::iterator it = observers.begin();
|
||||
observer_list_t::iterator end = observers.end();
|
||||
|
|
@ -501,6 +519,7 @@ void LLAvatarTracker::notifyObservers()
|
|||
|
||||
mModifyMask = LLFriendObserver::NONE;
|
||||
mChangedBuddyIDs.clear();
|
||||
mIsNotifyObservers = FALSE;
|
||||
}
|
||||
|
||||
void LLAvatarTracker::addParticularFriendObserver(const LLUUID& buddy_id, LLFriendObserver* observer)
|
||||
|
|
@ -604,7 +623,7 @@ void LLAvatarTracker::notifyFriendPermissionObservers(const LLUUID& buddy_id)
|
|||
// store flag for change
|
||||
// and id of object change applies to
|
||||
void LLAvatarTracker::addChangedMask(U32 mask, const LLUUID& referent)
|
||||
{
|
||||
{
|
||||
mModifyMask |= mask;
|
||||
if (referent.notNull())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ public:
|
|||
// observers left behind.
|
||||
void addObserver(LLFriendObserver* observer);
|
||||
void removeObserver(LLFriendObserver* observer);
|
||||
void idleNotifyObservers();
|
||||
void notifyObservers();
|
||||
|
||||
// Observers interested in updates of a particular avatar.
|
||||
|
|
@ -216,6 +217,8 @@ private:
|
|||
LLAvatarTracker(const LLAvatarTracker&);
|
||||
bool operator==(const LLAvatarTracker&);
|
||||
|
||||
BOOL mIsNotifyObservers;
|
||||
|
||||
public:
|
||||
// don't you dare create or delete this object
|
||||
LLAvatarTracker();
|
||||
|
|
|
|||
|
|
@ -393,6 +393,10 @@ public:
|
|||
|| mSourceType == CHAT_SOURCE_SYSTEM)
|
||||
{
|
||||
mFrom = LLTrans::getString("SECOND_LIFE");
|
||||
if(!chat.mFromName.empty() && (mFrom != chat.mFromName))
|
||||
{
|
||||
mFrom += " (" + chat.mFromName + ")";
|
||||
}
|
||||
user_name->setValue(mFrom);
|
||||
updateMinUserNameWidth();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@ public:
|
|||
* file name is conversation.log
|
||||
*/
|
||||
std::string getFileName();
|
||||
LLConversation* findConversation(const LLIMModel::LLIMSession* session);
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -184,7 +185,7 @@ private:
|
|||
void updateConversationName(const LLIMModel::LLIMSession* session, const std::string& name);
|
||||
void updateOfflineIMs(const LLIMModel::LLIMSession* session, BOOL new_messages);
|
||||
|
||||
LLConversation* findConversation(const LLIMModel::LLIMSession* session);
|
||||
|
||||
|
||||
typedef std::vector<LLConversation> conversations_vec_t;
|
||||
std::vector<LLConversation> mConversations;
|
||||
|
|
|
|||
|
|
@ -138,7 +138,24 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32
|
|||
items.push_back(std::string("im"));
|
||||
items.push_back(std::string("offer_teleport"));
|
||||
items.push_back(std::string("request_teleport"));
|
||||
items.push_back(std::string("voice_call"));
|
||||
|
||||
if (getType() != CONV_SESSION_1_ON_1)
|
||||
{
|
||||
items.push_back(std::string("voice_call"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVoiceChannel* voice_channel = LLIMModel::getInstance() ? LLIMModel::getInstance()->getVoiceChannel(this->getUUID()) : NULL;
|
||||
if(voice_channel != LLVoiceChannel::getCurrentVoiceChannel())
|
||||
{
|
||||
items.push_back(std::string("voice_call"));
|
||||
}
|
||||
else
|
||||
{
|
||||
items.push_back(std::string("disconnect_from_voice"));
|
||||
}
|
||||
}
|
||||
|
||||
items.push_back(std::string("chat_history"));
|
||||
items.push_back(std::string("separator_chat_history"));
|
||||
items.push_back(std::string("add_friend"));
|
||||
|
|
|
|||
|
|
@ -875,6 +875,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
|
|||
{
|
||||
LLDrawInfo& params = **i;
|
||||
|
||||
gDeferredBumpProgram.setMinimumAlpha(params.mAlphaMaskCutoff);
|
||||
LLDrawPoolBump::bindBumpMap(params, bump_channel);
|
||||
pushBatch(params, mask, TRUE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llexperienceassociationresponder.h"
|
||||
#include "llexperiencecache.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llagent.h"
|
||||
|
||||
|
|
@ -47,7 +48,13 @@ void ExperienceAssociationResponder::fetchAssociatedExperience( const LLUUID& ob
|
|||
|
||||
void ExperienceAssociationResponder::fetchAssociatedExperience(LLSD& request, callback_t callback)
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
LLViewerObject* object = gObjectList.findObject(request["object-id"]);
|
||||
if (!object)
|
||||
{
|
||||
LL_WARNS() << "Failed to find object with ID " << request["object-id"] << " in fetchAssociatedExperience" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
LLViewerRegion* region = object->getRegion();
|
||||
if (region)
|
||||
{
|
||||
std::string lookup_url=region->getCapability("GetMetadata");
|
||||
|
|
|
|||
|
|
@ -385,9 +385,11 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
|
|||
mShowDragMarker(FALSE),
|
||||
mLandingTab(NULL),
|
||||
mLastTab(NULL),
|
||||
mTabsHighlightEnabled(TRUE)
|
||||
, mUpdateDropDownItems(true)
|
||||
, mRestoreOverflowMenu(false)
|
||||
mTabsHighlightEnabled(TRUE),
|
||||
mUpdateDropDownItems(true),
|
||||
mRestoreOverflowMenu(false),
|
||||
mGetPrevItems(true),
|
||||
mItemsChangedTimer()
|
||||
{
|
||||
// Register callback for menus with current registrar (will be parent panel's registrar)
|
||||
LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Favorites.DoToSelected",
|
||||
|
|
@ -680,6 +682,15 @@ void LLFavoritesBarCtrl::changed(U32 mask)
|
|||
LLFavoritesOrderStorage::instance().getSLURL((*i)->getAssetUUID());
|
||||
}
|
||||
updateButtons();
|
||||
if (!mItemsChangedTimer.getStarted())
|
||||
{
|
||||
mItemsChangedTimer.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
mItemsChangedTimer.reset();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -714,6 +725,21 @@ void LLFavoritesBarCtrl::draw()
|
|||
// Once drawn, mark this false so we won't draw it again (unless we hit the favorite bar again)
|
||||
mShowDragMarker = FALSE;
|
||||
}
|
||||
if (mItemsChangedTimer.getStarted())
|
||||
{
|
||||
if (mItemsChangedTimer.getElapsedTimeF32() > 1.f)
|
||||
{
|
||||
LLFavoritesOrderStorage::instance().saveFavoritesRecord();
|
||||
mItemsChangedTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
if(!mItemsChangedTimer.getStarted() && LLFavoritesOrderStorage::instance().mUpdateRequired)
|
||||
{
|
||||
LLFavoritesOrderStorage::instance().mUpdateRequired = false;
|
||||
mItemsChangedTimer.start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const LLButton::Params& LLFavoritesBarCtrl::getButtonParams()
|
||||
|
|
@ -744,6 +770,12 @@ void LLFavoritesBarCtrl::updateButtons()
|
|||
return;
|
||||
}
|
||||
|
||||
if(mGetPrevItems)
|
||||
{
|
||||
LLFavoritesOrderStorage::instance().mPrevFavorites = mItems;
|
||||
mGetPrevItems = false;
|
||||
}
|
||||
|
||||
const LLButton::Params& button_params = getButtonParams();
|
||||
|
||||
if(mItems.empty())
|
||||
|
|
@ -883,6 +915,7 @@ void LLFavoritesBarCtrl::updateButtons()
|
|||
{
|
||||
mUpdateDropDownItems = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LLButton* LLFavoritesBarCtrl::createButton(const LLPointer<LLViewerInventoryItem> item, const LLButton::Params& button_params, S32 x_offset)
|
||||
|
|
@ -954,9 +987,11 @@ BOOL LLFavoritesBarCtrl::postBuild()
|
|||
|
||||
BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &items)
|
||||
{
|
||||
|
||||
if (mFavoriteFolderId.isNull())
|
||||
return FALSE;
|
||||
|
||||
|
||||
LLInventoryModel::cat_array_t cats;
|
||||
|
||||
LLIsType is_type(LLAssetType::AT_LANDMARK);
|
||||
|
|
@ -1466,6 +1501,7 @@ void LLFavoritesBarCtrl::insertItem(LLInventoryModel::item_array_t& items, const
|
|||
|
||||
const std::string LLFavoritesOrderStorage::SORTING_DATA_FILE_NAME = "landmarks_sorting.xml";
|
||||
const S32 LLFavoritesOrderStorage::NO_INDEX = -1;
|
||||
bool LLFavoritesOrderStorage::mSaveOnExit = false;
|
||||
|
||||
void LLFavoritesOrderStorage::setSortIndex(const LLViewerInventoryItem* inv_item, S32 sort_index)
|
||||
{
|
||||
|
|
@ -1502,19 +1538,23 @@ void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
|
|||
LL_DEBUGS("FavoritesBar") << "landmark for " << asset_id << " already loaded" << LL_ENDL;
|
||||
onLandmarkLoaded(asset_id, lm);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// static
|
||||
std::string LLFavoritesOrderStorage::getStoredFavoritesFilename()
|
||||
{
|
||||
std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
|
||||
// <FS:Ansariel> Favorites are stored in username.grid folder
|
||||
//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()
|
||||
+ ".xml")
|
||||
);
|
||||
// return (user_dir.empty() ? ""
|
||||
// : gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
|
||||
// "stored_favorites_"
|
||||
// + LLGridManager::getInstance()->getGrid()
|
||||
// + ".xml")
|
||||
// );
|
||||
return gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
|
||||
// <FS:Ansariel>
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -1536,15 +1576,19 @@ void LLFavoritesOrderStorage::destroyClass()
|
|||
// LLFile::copy(old_filename,new_filename);
|
||||
// LLFile::remove(old_filename);
|
||||
//}
|
||||
llifstream file;
|
||||
// </FS:Ansariel>
|
||||
|
||||
if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"))
|
||||
std::string filename = getSavedOrderFileName();
|
||||
file.open(filename.c_str());
|
||||
if (file.is_open())
|
||||
{
|
||||
LLFavoritesOrderStorage::instance().saveFavoritesSLURLs();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser();
|
||||
file.close();
|
||||
LLFile::remove(filename);
|
||||
if(mSaveOnExit)
|
||||
{
|
||||
LLFavoritesOrderStorage::instance().saveFavoritesRecord(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1559,124 +1603,66 @@ std::string LLFavoritesOrderStorage::getSavedOrderFileName()
|
|||
|
||||
void LLFavoritesOrderStorage::load()
|
||||
{
|
||||
// load per-resident sorting information
|
||||
std::string filename = getSavedOrderFileName();
|
||||
|
||||
LLSD settings_llsd;
|
||||
llifstream file;
|
||||
file.open(filename.c_str());
|
||||
if (file.is_open())
|
||||
{
|
||||
LLSDSerialize::fromXML(settings_llsd, file);
|
||||
LL_INFOS("FavoritesBar") << "loaded favorites order from '" << filename << "' "
|
||||
<< (settings_llsd.isMap() ? "" : "un") << "successfully"
|
||||
<< LL_ENDL;
|
||||
file.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("FavoritesBar") << "unable to open favorites order file at '" << filename << "'" << LL_ENDL;
|
||||
}
|
||||
LL_INFOS("FavoritesBar") << "loaded favorites order from '" << filename << "' "
|
||||
<< (settings_llsd.isMap() ? "" : "un") << "successfully"
|
||||
<< LL_ENDL;
|
||||
file.close();
|
||||
mSaveOnExit = true;
|
||||
|
||||
for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
|
||||
iter != settings_llsd.endMap(); ++iter)
|
||||
for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
|
||||
iter != settings_llsd.endMap(); ++iter)
|
||||
{
|
||||
mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
|
||||
filename = getStoredFavoritesFilename();
|
||||
if (!filename.empty())
|
||||
{
|
||||
llifstream in_file;
|
||||
in_file.open(filename.c_str());
|
||||
LLSD fav_llsd;
|
||||
LLSD user_llsd;
|
||||
if (in_file.is_open())
|
||||
{
|
||||
LLSDSerialize::fromXML(fav_llsd, in_file);
|
||||
LL_INFOS("FavoritesBar") << "loaded favorites from '" << filename << "' "
|
||||
<< (fav_llsd.isMap() ? "" : "un") << "successfully"
|
||||
<< LL_ENDL;
|
||||
in_file.close();
|
||||
// <FS:Ansariel> FIRE-10122 - User@grid stored_favorites.xml
|
||||
//user_llsd = fav_llsd[gAgentUsername];
|
||||
user_llsd = fav_llsd[gAgentUsername + " @ " + LLGridManager::getInstance()->getGridLabel()];
|
||||
// </FS:Ansariel>
|
||||
|
||||
S32 index = 0;
|
||||
for (LLSD::array_iterator iter = user_llsd.beginArray();
|
||||
iter != user_llsd.endArray(); ++iter)
|
||||
{
|
||||
mSortIndexes.insert(std::make_pair(iter->get("id").asUUID(), index));
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
LL_WARNS("FavoritesBar") << "unable to open favorites from '" << filename << "'" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFavoritesOrderStorage::saveFavoritesSLURLs()
|
||||
{
|
||||
// Do not change the file if we are not logged in yet.
|
||||
if (!LLLoginInstance::getInstance()->authSuccess())
|
||||
{
|
||||
LL_WARNS("FavoritesBar") << "Cannot save favorites: not logged in" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Favorites are stored in username.grid folder
|
||||
// std::string filename = getStoredFavoritesFilename();
|
||||
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
|
||||
// </FS:Ansariel>
|
||||
if (!filename.empty())
|
||||
{
|
||||
llifstream in_file;
|
||||
in_file.open(filename.c_str());
|
||||
LLSD fav_llsd;
|
||||
if (in_file.is_open())
|
||||
{
|
||||
LLSDSerialize::fromXML(fav_llsd, in_file);
|
||||
LL_INFOS("FavoritesBar") << "loaded favorites from '" << filename << "' "
|
||||
<< (fav_llsd.isMap() ? "" : "un") << "successfully"
|
||||
<< LL_ENDL;
|
||||
in_file.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("FavoritesBar") << "unable to open favorites from '" << filename << "'" << LL_ENDL;
|
||||
}
|
||||
|
||||
const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
|
||||
LLInventoryModel::cat_array_t cats;
|
||||
LLInventoryModel::item_array_t items;
|
||||
gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
|
||||
|
||||
LLSD user_llsd;
|
||||
for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)
|
||||
{
|
||||
LLSD value;
|
||||
value["name"] = (*it)->getName();
|
||||
value["asset_id"] = (*it)->getAssetUUID();
|
||||
|
||||
slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]);
|
||||
if (slurl_iter != mSLURLs.end())
|
||||
{
|
||||
LL_DEBUGS("FavoritesBar") << "Saving favorite: idx=" << LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID()) << ", SLURL=" << slurl_iter->second << ", value=" << value << LL_ENDL;
|
||||
value["slurl"] = slurl_iter->second;
|
||||
user_llsd[LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID())] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("FavoritesBar") << "Not saving favorite " << value["name"] << ": no matching SLURL" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
LLAvatarName av_name;
|
||||
LLAvatarNameCache::get( gAgentID, &av_name );
|
||||
// Note : use the "John Doe" and not the "john.doe" version of the name
|
||||
// as we'll compare it with the stored credentials in the login panel.
|
||||
// <FS:CR> FIRE-10122 - User@grid stored_favorites.xml
|
||||
//fav_llsd[av_name.getUserName()] = user_llsd;
|
||||
std::string name = av_name.getUserName() + " @ " + LLGridManager::getInstance()->getGridLabel();
|
||||
LL_DEBUGS("Favorites") << "Saved favorites for " << name << LL_ENDL;
|
||||
fav_llsd[name] = user_llsd;
|
||||
// </FS:CR>
|
||||
|
||||
llofstream file;
|
||||
file.open(filename.c_str());
|
||||
if ( file.is_open() )
|
||||
{
|
||||
LLSDSerialize::toPrettyXML(fav_llsd, file);
|
||||
LL_INFOS("FavoritesBar") << "saved favorites for '" << av_name.getUserName()
|
||||
<< "' to '" << filename << "' "
|
||||
<< LL_ENDL;
|
||||
file.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("FavoritesBar") << "unable to open favorites storage for '" << av_name.getUserName()
|
||||
<< "' at '" << filename << "' "
|
||||
<< LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
|
||||
{
|
||||
// <FS:Ansariel> Favorites are stored in username.grid folder
|
||||
// std::string filename = getStoredFavoritesFilename();
|
||||
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
|
||||
// </FS:Ansariel>
|
||||
std::string filename = getStoredFavoritesFilename();
|
||||
if (!filename.empty())
|
||||
{
|
||||
LLSD fav_llsd;
|
||||
|
|
@ -1691,19 +1677,46 @@ void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
|
|||
LLAvatarNameCache::get( gAgentID, &av_name );
|
||||
// Note : use the "John Doe" and not the "john.doe" version of the name.
|
||||
// See saveFavoritesSLURLs() here above for the reason why.
|
||||
// <FS:CR> FIRE-10122 - User@grid stored_favorites.xml
|
||||
// if (fav_llsd.has(av_name.getUserName()))
|
||||
// <FS:CR> FIRE-10122 - User@grid stored_favorites.xml
|
||||
//if (fav_llsd.has(av_name.getUserName()))
|
||||
//{
|
||||
// LL_INFOS("FavoritesBar") << "Removed favorites for " << av_name.getUserName() << LL_ENDL;
|
||||
// fav_llsd.erase(av_name.getUserName());
|
||||
//}
|
||||
std::string name = av_name.getUserName() + " @ " + LLGridManager::getInstance()->getGridLabel();
|
||||
LL_DEBUGS("Favorites") << "Removed favorites for " << name << LL_ENDL;
|
||||
if (fav_llsd.has(name))
|
||||
{
|
||||
fav_llsd.erase(name);
|
||||
}
|
||||
// </FS:CR>
|
||||
// LLSD user_llsd = fav_llsd[av_name.getUserName()];
|
||||
std::string name = av_name.getUserName() + " @ " + LLGridManager::getInstance()->getGridLabel();
|
||||
if (fav_llsd.has(name))
|
||||
{
|
||||
LLSD user_llsd = fav_llsd[name];
|
||||
// </FS:CR>
|
||||
|
||||
if (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);
|
||||
}
|
||||
// <FS:CR> FIRE-10122 - User@grid stored_favorites.xml
|
||||
//fav_llsd[av_name.getUserName()] = user_llsd;
|
||||
fav_llsd[name] = user_llsd;
|
||||
// </FS:CR> FIRE-10122
|
||||
llofstream file;
|
||||
file.open(filename.c_str());
|
||||
if ( file.is_open() )
|
||||
{
|
||||
LLSDSerialize::toPrettyXML(fav_llsd, file);
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// <FS:CR> FIRE-10122 - User@grid stored_favorites.xml
|
||||
//LL_INFOS("FavoritesBar") << "Removed favorites for " << av_name.getUserName() << LL_ENDL;
|
||||
//fav_llsd.erase(av_name.getUserName());
|
||||
LL_INFOS("FavoritesBar") << "Removed favorites for " << name << LL_ENDL;
|
||||
fav_llsd.erase(name);
|
||||
// </FS:CR> FIRE-10122
|
||||
}
|
||||
}
|
||||
|
||||
llofstream out_file;
|
||||
out_file.open(filename.c_str());
|
||||
|
|
@ -1723,20 +1736,20 @@ void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmar
|
|||
if (landmark)
|
||||
{
|
||||
LL_DEBUGS("FavoritesBar") << "landmark for " << asset_id << " loaded" << LL_ENDL;
|
||||
LLVector3d pos_global;
|
||||
if (!landmark->getGlobalPos(pos_global))
|
||||
{
|
||||
// If global position was unknown on first getGlobalPos() call
|
||||
// it should be set for the subsequent calls.
|
||||
landmark->getGlobalPos(pos_global);
|
||||
}
|
||||
LLVector3d pos_global;
|
||||
if (!landmark->getGlobalPos(pos_global))
|
||||
{
|
||||
// If global position was unknown on first getGlobalPos() call
|
||||
// it should be set for the subsequent calls.
|
||||
landmark->getGlobalPos(pos_global);
|
||||
}
|
||||
|
||||
if (!pos_global.isExactlyZero())
|
||||
{
|
||||
LL_DEBUGS("FavoritesBar") << "requesting slurl for landmark " << asset_id << LL_ENDL;
|
||||
LLLandmarkActions::getSLURLfromPosGlobal(pos_global,
|
||||
if (!pos_global.isExactlyZero())
|
||||
{
|
||||
LL_DEBUGS("FavoritesBar") << "requesting slurl for landmark " << asset_id << LL_ENDL;
|
||||
LLLandmarkActions::getSLURLfromPosGlobal(pos_global,
|
||||
boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1746,41 +1759,6 @@ void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::st
|
|||
mSLURLs[asset_id] = slurl;
|
||||
}
|
||||
|
||||
void LLFavoritesOrderStorage::save()
|
||||
{
|
||||
if (mIsDirty)
|
||||
{
|
||||
// something changed, so save it
|
||||
std::string filename = LLFavoritesOrderStorage::getInstance()->getSavedOrderFileName();
|
||||
if (!filename.empty())
|
||||
{
|
||||
LLSD settings_llsd;
|
||||
|
||||
for(sort_index_map_t::const_iterator iter = mSortIndexes.begin(); iter != mSortIndexes.end(); ++iter)
|
||||
{
|
||||
settings_llsd[iter->first.asString()] = iter->second;
|
||||
}
|
||||
|
||||
llofstream file;
|
||||
file.open(filename.c_str());
|
||||
if ( file.is_open() )
|
||||
{
|
||||
LLSDSerialize::toPrettyXML(settings_llsd, file);
|
||||
LL_INFOS("FavoritesBar") << "saved favorites order to '" << filename << "' " << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("FavoritesBar") << "failed to open favorites order file '" << filename << "' " << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("FavoritesBar") << "no user directory available to store favorites order file" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLFavoritesOrderStorage::cleanup()
|
||||
{
|
||||
// nothing to clean
|
||||
|
|
@ -1795,7 +1773,7 @@ void LLFavoritesOrderStorage::cleanup()
|
|||
|
||||
sort_index_map_t aTempMap;
|
||||
//copy unremoved values from mSortIndexes to aTempMap
|
||||
std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(),
|
||||
std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(),
|
||||
inserter(aTempMap, aTempMap.begin()),
|
||||
is_not_in_fav);
|
||||
|
||||
|
|
@ -1827,8 +1805,8 @@ void LLFavoritesOrderStorage::saveOrder()
|
|||
|
||||
void LLFavoritesOrderStorage::saveItemsOrder( const LLInventoryModel::item_array_t& items )
|
||||
{
|
||||
int sortField = 0;
|
||||
|
||||
int sortField = 0;
|
||||
// current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
|
||||
for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
|
||||
{
|
||||
|
|
@ -1868,6 +1846,115 @@ void LLFavoritesOrderStorage::rearrangeFavoriteLandmarks(const LLUUID& source_it
|
|||
saveItemsOrder(items);
|
||||
}
|
||||
|
||||
BOOL LLFavoritesOrderStorage::saveFavoritesRecord(bool pref_changed)
|
||||
{
|
||||
|
||||
LLUUID favorite_folder= gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
|
||||
if (favorite_folder.isNull())
|
||||
return FALSE;
|
||||
|
||||
LLInventoryModel::item_array_t items;
|
||||
LLInventoryModel::cat_array_t cats;
|
||||
|
||||
LLIsType is_type(LLAssetType::AT_LANDMARK);
|
||||
gInventory.collectDescendentsIf(favorite_folder, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
|
||||
|
||||
std::sort(items.begin(), items.end(), LLFavoritesSort());
|
||||
|
||||
if((items != mPrevFavorites) || pref_changed)
|
||||
{
|
||||
std::string filename = getStoredFavoritesFilename();
|
||||
if (!filename.empty())
|
||||
{
|
||||
llifstream in_file;
|
||||
in_file.open(filename.c_str());
|
||||
LLSD fav_llsd;
|
||||
if (in_file.is_open())
|
||||
{
|
||||
LLSDSerialize::fromXML(fav_llsd, in_file);
|
||||
in_file.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("FavoritesBar") << "unable to open favorites from '" << filename << "'" << LL_ENDL;
|
||||
}
|
||||
|
||||
LLSD user_llsd;
|
||||
S32 fav_iter = 0;
|
||||
for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)
|
||||
{
|
||||
LLSD value;
|
||||
if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"))
|
||||
{
|
||||
value["name"] = (*it)->getName();
|
||||
value["asset_id"] = (*it)->getAssetUUID();
|
||||
value["id"] = (*it)->getUUID();
|
||||
slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]);
|
||||
if (slurl_iter != mSLURLs.end())
|
||||
{
|
||||
value["slurl"] = slurl_iter->second;
|
||||
user_llsd[fav_iter] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
getSLURL((*it)->getAssetUUID());
|
||||
mUpdateRequired = true;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value["id"] = (*it)->getUUID();
|
||||
user_llsd[fav_iter] = value;
|
||||
}
|
||||
|
||||
fav_iter ++;
|
||||
}
|
||||
|
||||
LLAvatarName av_name;
|
||||
LLAvatarNameCache::get( gAgentID, &av_name );
|
||||
// Note : use the "John Doe" and not the "john.doe" version of the name
|
||||
// as we'll compare it with the stored credentials in the login panel.
|
||||
// <FS:CR> FIRE-10122 - User@grid stored_favorites.xml
|
||||
//fav_llsd[av_name.getUserName()] = user_llsd;
|
||||
std::string name = av_name.getUserName() + " @ " + LLGridManager::getInstance()->getGridLabel();
|
||||
LL_DEBUGS("Favorites") << "Saved favorites for " << name << LL_ENDL;
|
||||
fav_llsd[name] = user_llsd;
|
||||
// </FS:CR>
|
||||
llofstream file;
|
||||
file.open(filename.c_str());
|
||||
if ( file.is_open() )
|
||||
{
|
||||
LLSDSerialize::toPrettyXML(fav_llsd, file);
|
||||
file.close();
|
||||
mSaveOnExit = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("FavoritesBar") << "unable to open favorites storage for '" << av_name.getUserName()
|
||||
<< "' at '" << filename << "' " << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
mPrevFavorites = items;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
void LLFavoritesOrderStorage::showFavoritesOnLoginChanged(BOOL show)
|
||||
{
|
||||
if (show)
|
||||
{
|
||||
saveFavoritesRecord(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
removeFavoritesRecordOfUser();
|
||||
}
|
||||
}
|
||||
|
||||
void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)
|
||||
{
|
||||
if (mTargetLandmarkId.isNull()) return;
|
||||
|
|
|
|||
|
|
@ -108,8 +108,10 @@ protected:
|
|||
bool mUpdateDropDownItems;
|
||||
bool mRestoreOverflowMenu;
|
||||
|
||||
LLUUID mSelectedItemID;
|
||||
bool mGetPrevItems;
|
||||
|
||||
LLUUID mSelectedItemID;
|
||||
LLFrameTimer mItemsChangedTimer;
|
||||
LLUIImage* mImageDragIndication;
|
||||
|
||||
private:
|
||||
|
|
@ -211,12 +213,23 @@ public:
|
|||
* @see cleanup()
|
||||
*/
|
||||
static void destroyClass();
|
||||
static std::string getStoredFavoritesFilename();
|
||||
static std::string getSavedOrderFileName();
|
||||
|
||||
BOOL saveFavoritesRecord(bool pref_changed = false);
|
||||
void showFavoritesOnLoginChanged(BOOL show);
|
||||
|
||||
LLInventoryModel::item_array_t mPrevFavorites;
|
||||
|
||||
|
||||
const static S32 NO_INDEX;
|
||||
static bool mSaveOnExit;
|
||||
bool mUpdateRequired;
|
||||
|
||||
private:
|
||||
friend class LLSingleton<LLFavoritesOrderStorage>;
|
||||
LLFavoritesOrderStorage() : mIsDirty(false) { load(); }
|
||||
~LLFavoritesOrderStorage() { save(); }
|
||||
LLFavoritesOrderStorage() : mIsDirty(false), mUpdateRequired(false){ load(); }
|
||||
~LLFavoritesOrderStorage() {}
|
||||
|
||||
/**
|
||||
* Removes sort indexes for items which are not in Favorites bar for now.
|
||||
|
|
@ -224,13 +237,8 @@ private:
|
|||
void cleanup();
|
||||
|
||||
const static std::string SORTING_DATA_FILE_NAME;
|
||||
std::string getSavedOrderFileName();
|
||||
static std::string getStoredFavoritesFilename();
|
||||
|
||||
void load();
|
||||
void save();
|
||||
|
||||
void saveFavoritesSLURLs();
|
||||
void load();
|
||||
|
||||
// Remove record of current user's favorites from file on disk.
|
||||
void removeFavoritesRecordOfUser();
|
||||
|
|
|
|||
|
|
@ -34,10 +34,12 @@
|
|||
// Viewer includes
|
||||
#include "llagent.h"
|
||||
#include "llagentui.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llslurl.h"
|
||||
#include "llvoiceclient.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llupdaterservice.h"
|
||||
#include "llviewertexteditor.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerstats.h"
|
||||
|
|
@ -99,10 +101,24 @@ public:
|
|||
/// separated so that we can programmatically access the same info.
|
||||
static LLSD getInfo();
|
||||
void onClickCopyToClipboard();
|
||||
void onClickUpdateCheck();
|
||||
|
||||
// checks state of updater service and starts a check outside of schedule.
|
||||
// subscribes callback for closest state update
|
||||
static void setUpdateListener();
|
||||
|
||||
// <FS:Ansariel> Release notes link not updating
|
||||
//private:
|
||||
void setSupportText(const std::string& server_release_notes_url);
|
||||
|
||||
// notifications for user requested checks
|
||||
static void showCheckUpdateNotification(S32 state);
|
||||
|
||||
// callback method for manual checks
|
||||
static bool callbackCheckUpdate(LLSD const & event);
|
||||
|
||||
// listener name for update checks
|
||||
static const std::string sCheckUpdateListenerName;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -133,6 +149,11 @@ BOOL LLFloaterAbout::postBuild()
|
|||
getChild<LLUICtrl>("copy_btn")->setCommitCallback(
|
||||
boost::bind(&LLFloaterAbout::onClickCopyToClipboard, this));
|
||||
|
||||
// <FS:Ansariel> Disabled update button
|
||||
//getChild<LLUICtrl>("update_btn")->setCommitCallback(
|
||||
// boost::bind(&LLFloaterAbout::onClickUpdateCheck, this));
|
||||
// </FS:Ansariel>
|
||||
|
||||
static const LLUIColor about_color = LLUIColorTable::instance().getColor("TextFgReadOnlyColor");
|
||||
|
||||
if (gAgent.getRegion())
|
||||
|
|
@ -236,6 +257,11 @@ void LLFloaterAbout::onClickCopyToClipboard()
|
|||
support_widget->deselect();
|
||||
}
|
||||
|
||||
void LLFloaterAbout::onClickUpdateCheck()
|
||||
{
|
||||
setUpdateListener();
|
||||
}
|
||||
|
||||
void LLFloaterAbout::setSupportText(const std::string& server_release_notes_url)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
|
|
@ -256,6 +282,68 @@ void LLFloaterAbout::setSupportText(const std::string& server_release_notes_url)
|
|||
FALSE, LLStyle::Params() .color(about_color));
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Floater About Update-check related functions
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
const std::string LLFloaterAbout::sCheckUpdateListenerName = "LLUpdateNotificationListener";
|
||||
|
||||
void LLFloaterAbout::showCheckUpdateNotification(S32 state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case LLUpdaterService::UP_TO_DATE:
|
||||
LLNotificationsUtil::add("UpdateViewerUpToDate");
|
||||
break;
|
||||
case LLUpdaterService::DOWNLOADING:
|
||||
case LLUpdaterService::INSTALLING:
|
||||
LLNotificationsUtil::add("UpdateDownloadInProgress");
|
||||
break;
|
||||
case LLUpdaterService::TERMINAL:
|
||||
// download complete, user triggered check after download pop-up appeared
|
||||
LLNotificationsUtil::add("UpdateDownloadComplete");
|
||||
break;
|
||||
default:
|
||||
LLNotificationsUtil::add("UpdateCheckError");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLFloaterAbout::callbackCheckUpdate(LLSD const & event)
|
||||
{
|
||||
if (!event.has("payload"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLSD payload = event["payload"];
|
||||
if (payload.has("type") && payload["type"].asInteger() == LLUpdaterService::STATE_CHANGE)
|
||||
{
|
||||
LLEventPumps::instance().obtain("mainlooprepeater").stopListening(sCheckUpdateListenerName);
|
||||
showCheckUpdateNotification(payload["state"].asInteger());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterAbout::setUpdateListener()
|
||||
{
|
||||
LLUpdaterService update_service;
|
||||
S32 service_state = update_service.getState();
|
||||
// Note: Do not set state listener before forceCheck() since it set's new state
|
||||
if (update_service.forceCheck() || service_state == LLUpdaterService::CHECKING_FOR_UPDATE)
|
||||
{
|
||||
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainlooprepeater"));
|
||||
if (mainloop.getListener(sCheckUpdateListenerName) == LLBoundListener()) // dummy listener
|
||||
{
|
||||
mainloop.listen(sCheckUpdateListenerName, boost::bind(&callbackCheckUpdate, _1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
showCheckUpdateNotification(service_state);
|
||||
}
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// LLFloaterAboutUtil
|
||||
///----------------------------------------------------------------------------
|
||||
|
|
@ -266,6 +354,11 @@ void LLFloaterAboutUtil::registerFloater()
|
|||
|
||||
}
|
||||
|
||||
void LLFloaterAboutUtil::checkUpdatesAndNotify()
|
||||
{
|
||||
LLFloaterAbout::setUpdateListener();
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLServerReleaseNotesURLFetcher implementation
|
||||
///----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@
|
|||
namespace LLFloaterAboutUtil
|
||||
{
|
||||
void registerFloater();
|
||||
|
||||
// Support for user initialized update/state checks
|
||||
void checkUpdatesAndNotify();
|
||||
}
|
||||
|
||||
#endif // LL_LLFLOATERABOUT_H
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "llavataractions.h"
|
||||
#include "llfloaterbump.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloaterreporter.h"
|
||||
#include "llmutelist.h"
|
||||
#include "llpanelblockedlist.h"
|
||||
|
|
@ -106,8 +107,10 @@ BOOL LLFloaterBump::postBuild()
|
|||
void LLFloaterBump::onOpen(const LLSD& key)
|
||||
{
|
||||
// <FS:Ansariel> Instant bump list floater update
|
||||
//mNames.clear();
|
||||
//mList->deleteAllItems();
|
||||
//if (gMeanCollisionList.empty())
|
||||
//{
|
||||
// mNames.clear();
|
||||
// mList->deleteAllItems();
|
||||
updateList();
|
||||
}
|
||||
|
||||
|
|
@ -129,10 +132,10 @@ void LLFloaterBump::updateList()
|
|||
return;
|
||||
}
|
||||
mList->deleteAllItems();
|
||||
// </FS:Ansariel>
|
||||
|
||||
if (gMeanCollisionList.empty())
|
||||
{
|
||||
// </FS:Ansariel>
|
||||
std::string none_detected = getString("none_detected");
|
||||
LLSD row;
|
||||
row["columns"][0]["value"] = none_detected;
|
||||
|
|
@ -141,13 +144,26 @@ void LLFloaterBump::updateList()
|
|||
}
|
||||
else
|
||||
{
|
||||
for (mean_collision_list_t::iterator iter = gMeanCollisionList.begin();
|
||||
iter != gMeanCollisionList.end(); ++iter)
|
||||
{
|
||||
LLMeanCollisionData *mcd = *iter;
|
||||
add(mList, mcd);
|
||||
}
|
||||
// <FS:Ansariel> Instant bump list floater update
|
||||
// populateCollisionList();
|
||||
// }
|
||||
//}
|
||||
|
||||
//void LLFloaterBump::populateCollisionList()
|
||||
//{
|
||||
// mNames.clear();
|
||||
// mList->deleteAllItems();
|
||||
// </FS:Ansariel>
|
||||
|
||||
for (mean_collision_list_t::iterator iter = gMeanCollisionList.begin();
|
||||
iter != gMeanCollisionList.end(); ++iter)
|
||||
{
|
||||
LLMeanCollisionData *mcd = *iter;
|
||||
add(mList, mcd);
|
||||
}
|
||||
// <FS:Ansariel> Instant bump list floater update
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
|
||||
void LLFloaterBump::add(LLScrollListCtrl* list, LLMeanCollisionData* mcd)
|
||||
|
|
@ -290,6 +306,11 @@ void LLFloaterBump::inviteToGroup()
|
|||
{
|
||||
LLAvatarActions::inviteToGroup(mItemUUID);
|
||||
}
|
||||
|
||||
LLFloaterBump* LLFloaterBump::getInstance()
|
||||
{
|
||||
return LLFloaterReg::getTypedInstance<LLFloaterBump>("bumps");
|
||||
}
|
||||
#endif
|
||||
// </FS:Ansariel>
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,11 @@ public:
|
|||
/*virtual*/ void draw();
|
||||
void setDirty() { mDirty = true; }
|
||||
|
||||
static LLFloaterBump* getInstance();
|
||||
|
||||
// <FS:Ansariel> Instant bump list floater update
|
||||
//void populateCollisionList();
|
||||
|
||||
void startIM();
|
||||
void startCall();
|
||||
void reportAbuse();
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ const std::string DEFAULT_CHECKIN_ICON_URL = "http://map.secondlife.com.s3.amazo
|
|||
const std::string DEFAULT_CHECKIN_QUERY_PARAMETERS = "?sourceid=slshare_checkin&utm_source=facebook&utm_medium=checkin&utm_campaign=slshare";
|
||||
const std::string DEFAULT_PHOTO_QUERY_PARAMETERS = "?sourceid=slshare_photo&utm_source=facebook&utm_medium=photo&utm_campaign=slshare";
|
||||
|
||||
const S32 MAX_QUALITY = 100; // Max quality value for jpeg images
|
||||
const S32 MIN_QUALITY = 0; // Min quality value for jpeg images
|
||||
const S32 MAX_QUALITY = 100; // Max quality value for jpeg images
|
||||
const S32 MIN_QUALITY = 0; // Min quality value for jpeg images
|
||||
const S32 TARGET_DATA_SIZE = 950000; // Size of the image (compressed) we're trying to send to Facebook
|
||||
|
||||
std::string get_map_url()
|
||||
|
|
|
|||
|
|
@ -262,6 +262,8 @@ BOOL LLFloaterIMContainer::postBuild()
|
|||
|
||||
mInitialized = true;
|
||||
|
||||
mIsFirstOpen = true;
|
||||
|
||||
// Add callbacks:
|
||||
// We'll take care of view updates on idle
|
||||
gIdleCallbacks.addFunction(idle, this);
|
||||
|
|
@ -637,14 +639,16 @@ void LLFloaterIMContainer::setVisible(BOOL visible)
|
|||
{
|
||||
// Make sure we have the Nearby Chat present when showing the conversation container
|
||||
nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
|
||||
if (nearby_chat == NULL)
|
||||
if ((nearby_chat == NULL) || mIsFirstOpen)
|
||||
{
|
||||
mIsFirstOpen = false;
|
||||
// If not found, force the creation of the nearby chat conversation panel
|
||||
// *TODO: find a way to move this to XML as a default panel or something like that
|
||||
LLSD name("nearby_chat");
|
||||
LLFloaterReg::toggleInstanceOrBringToFront(name);
|
||||
selectConversationPair(LLUUID(NULL), false, false);
|
||||
}
|
||||
|
||||
flashConversationItemWidget(mSelectedSession,false);
|
||||
|
||||
LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(mSelectedSession);
|
||||
|
|
@ -1217,7 +1221,22 @@ void LLFloaterIMContainer::doToSelectedConversation(const std::string& command,
|
|||
{
|
||||
if (selectedIDS.size() > 0)
|
||||
{
|
||||
LLAvatarActions::viewChatHistory(selectedIDS.front());
|
||||
if(conversationItem->getType() == LLConversationItem::CONV_SESSION_GROUP)
|
||||
{
|
||||
LLFloaterReg::showInstance("preview_conversation", conversationItem->getUUID(), true);
|
||||
}
|
||||
else if(conversationItem->getType() == LLConversationItem::CONV_SESSION_AD_HOC)
|
||||
{
|
||||
LLConversation* conv = LLConversationLog::instance().findConversation(LLIMModel::getInstance()->findIMSession(conversationItem->getUUID()));
|
||||
if(conv)
|
||||
{
|
||||
LLFloaterReg::showInstance("preview_conversation", conv->getSessionID(), true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLAvatarActions::viewChatHistory(selectedIDS.front());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1317,6 +1336,15 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
|
|||
{
|
||||
return LLLogChat::isNearbyTranscriptExist();
|
||||
}
|
||||
else if (getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_AD_HOC)
|
||||
{
|
||||
const LLConversation* conv = LLConversationLog::instance().findConversation(LLIMModel::getInstance()->findIMSession(uuids.front()));
|
||||
if(conv)
|
||||
{
|
||||
return LLLogChat::isAdHocTranscriptExist(conv->getHistoryFileName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool is_group = (getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_GROUP);
|
||||
|
|
@ -1882,22 +1910,28 @@ bool LLFloaterIMContainer::canBanSelectedMember(const LLUUID& participant_uuid)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!gdatap->mMembers.size())
|
||||
if (gdatap->mPendingBanRequest)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLGroupMgrGroupData::member_list_t::iterator mi = gdatap->mMembers.find((participant_uuid));
|
||||
if (mi == gdatap->mMembers.end())
|
||||
if (gdatap->isRoleMemberDataComplete())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!gdatap->mMembers.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLGroupMemberData* member_data = (*mi).second;
|
||||
// Is the member an owner?
|
||||
if ( member_data && member_data->isInRole(gdatap->mOwnerRole) )
|
||||
{
|
||||
return false;
|
||||
LLGroupMgrGroupData::member_list_t::iterator mi = gdatap->mMembers.find((participant_uuid));
|
||||
if (mi != gdatap->mMembers.end())
|
||||
{
|
||||
LLGroupMemberData* member_data = (*mi).second;
|
||||
// Is the member an owner?
|
||||
if (member_data && member_data->isInRole(gdatap->mOwnerRole))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( gAgent.hasPowerInGroup(group_uuid, GP_ROLE_REMOVE_MEMBER) &&
|
||||
|
|
@ -1925,20 +1959,8 @@ void LLFloaterIMContainer::banSelectedMember(const LLUUID& participant_uuid)
|
|||
LL_WARNS("Groups") << "Unable to get group data for group " << group_uuid << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
std::vector<LLUUID> ids;
|
||||
ids.push_back(participant_uuid);
|
||||
|
||||
LLGroupBanData ban_data;
|
||||
gdatap->createBanEntry(participant_uuid, ban_data);
|
||||
LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, group_uuid, LLGroupMgr::BAN_CREATE, ids);
|
||||
LLGroupMgr::getInstance()->sendGroupMemberEjects(group_uuid, ids);
|
||||
LLGroupMgr::getInstance()->sendGroupMembersRequest(group_uuid);
|
||||
LLSD args;
|
||||
std::string name;
|
||||
gCacheName->getFullName(participant_uuid, name);
|
||||
args["AVATAR_NAME"] = name;
|
||||
args["GROUP_NAME"] = gdatap->mName;
|
||||
LLNotifications::instance().add(LLNotification::Params("EjectAvatarFromGroup").substitutions(args));
|
||||
gdatap->banMemberById(participant_uuid);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -195,6 +195,8 @@ private:
|
|||
bool mInitialized;
|
||||
bool mIsFirstLaunch;
|
||||
|
||||
bool mIsFirstOpen;
|
||||
|
||||
LLUUID mSelectedSession;
|
||||
std::string mGeneralTitle;
|
||||
|
||||
|
|
|
|||
|
|
@ -328,7 +328,21 @@ void LLFloaterJoystick::onClickOK(void *joy_panel)
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloaterJoystick::onClickCloseBtn(bool app_quitting)
|
||||
{
|
||||
cancel();
|
||||
closeFloater(app_quitting);
|
||||
}
|
||||
|
||||
void LLFloaterJoystick::setSNDefaults()
|
||||
{
|
||||
LLViewerJoystick::getInstance()->setSNDefaults();
|
||||
}
|
||||
|
||||
void LLFloaterJoystick::onClose(bool app_quitting)
|
||||
{
|
||||
if (app_quitting)
|
||||
{
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,11 @@ public:
|
|||
virtual void draw();
|
||||
static void setSNDefaults();
|
||||
|
||||
protected:
|
||||
|
||||
void onClose(bool app_quitting);
|
||||
void onClickCloseBtn(bool app_quitting);
|
||||
|
||||
private:
|
||||
|
||||
LLFloaterJoystick(const LLSD& data);
|
||||
|
|
|
|||
|
|
@ -2660,13 +2660,15 @@ void LLPanelLandAccess::refresh()
|
|||
mListAccess->clearSortOrder();
|
||||
mListAccess->deleteAllItems();
|
||||
S32 count = parcel->mAccessList.size();
|
||||
getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count));
|
||||
getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST));
|
||||
// <FS:Ansariel> FIRE-9211: Add counter to parcel ban and access lists
|
||||
//getChild<LLUICtrl>("AllowedText")->setTextArg("[COUNT]", llformat("%d",count));
|
||||
getChild<LLUICtrl>("AllowedText")->setTextArg(LLStringExplicit("[LISTED]"), llformat("%d",count));
|
||||
getChild<LLUICtrl>("AllowedText")->setTextArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST));
|
||||
// </FS:Ansariel>
|
||||
|
||||
getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count));
|
||||
getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST));
|
||||
|
||||
for (LLAccessEntry::map::const_iterator cit = parcel->mAccessList.begin();
|
||||
cit != parcel->mAccessList.end(); ++cit)
|
||||
{
|
||||
|
|
@ -2709,14 +2711,15 @@ void LLPanelLandAccess::refresh()
|
|||
mListBanned->clearSortOrder();
|
||||
mListBanned->deleteAllItems();
|
||||
S32 count = parcel->mBanList.size();
|
||||
|
||||
getChild<LLUICtrl>("BannedList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count));
|
||||
getChild<LLUICtrl>("BannedList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST));
|
||||
// <FS:Ansariel> FIRE-9211: Add counter to parcel ban and access lists
|
||||
//getChild<LLUICtrl>("BanCheck")->setTextArg("[COUNT]", llformat("%d",count));
|
||||
getChild<LLUICtrl>("BanCheck")->setTextArg(LLStringExplicit("[LISTED]"), llformat("%d",count));
|
||||
getChild<LLUICtrl>("BanCheck")->setTextArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST));
|
||||
// </FS:Ansariel>
|
||||
|
||||
getChild<LLUICtrl>("BannedList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count));
|
||||
getChild<LLUICtrl>("BannedList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST));
|
||||
|
||||
for (LLAccessEntry::map::const_iterator cit = parcel->mBanList.begin();
|
||||
cit != parcel->mBanList.end(); ++cit)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2314,10 +2314,15 @@ bool LLModelLoader::loadFromSLM(const std::string& filename)
|
|||
|
||||
for (U32 lod = 0; lod < LLModel::NUM_LODS; ++lod)
|
||||
{
|
||||
if (!model[lod].empty())
|
||||
if (model[lod].size() > idx)
|
||||
{
|
||||
instance_list[i].mLOD[lod] = model[lod][idx];
|
||||
}
|
||||
else if (!model[lod].empty())
|
||||
{
|
||||
// slm load failed - indexes are corrupted
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
instance_list[i].mModel = model[LLModel::LOD_HIGH][idx];
|
||||
|
|
|
|||
|
|
@ -169,61 +169,83 @@ void LLFloaterPermsDefault::onCommitCopy(const LLSD& user_data)
|
|||
xfer->setEnabled(copyable);
|
||||
}
|
||||
|
||||
class LLFloaterPermsResponder : public LLHTTPClient::Responder
|
||||
const int MAX_HTTP_RETRIES = 5;
|
||||
LLFloaterPermsRequester* LLFloaterPermsRequester::sPermsRequester = NULL;
|
||||
|
||||
LLFloaterPermsRequester::LLFloaterPermsRequester(const std::string url, const LLSD report,
|
||||
int maxRetries)
|
||||
: mRetriesCount(0), mMaxRetries(maxRetries), mUrl(url), mReport(report)
|
||||
{}
|
||||
|
||||
//static
|
||||
void LLFloaterPermsRequester::init(const std::string url, const LLSD report, int maxRetries)
|
||||
{
|
||||
public:
|
||||
LLFloaterPermsResponder(): LLHTTPClient::Responder() {}
|
||||
// <FS:Ansariel> Add some retry function
|
||||
static U32 sRetryCount;
|
||||
|
||||
private:
|
||||
static std::string sPreviousReason;
|
||||
|
||||
void httpFailure()
|
||||
if (sPermsRequester == NULL) {
|
||||
sPermsRequester = new LLFloaterPermsRequester(url, report, maxRetries);
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLFloaterPermsRequester::finalize()
|
||||
{
|
||||
if (sPermsRequester != NULL)
|
||||
{
|
||||
delete sPermsRequester;
|
||||
sPermsRequester = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
LLFloaterPermsRequester* LLFloaterPermsRequester::instance()
|
||||
{
|
||||
return sPermsRequester;
|
||||
}
|
||||
|
||||
void LLFloaterPermsRequester::start()
|
||||
{
|
||||
++mRetriesCount;
|
||||
LLHTTPClient::post(mUrl, mReport, new LLFloaterPermsResponder());
|
||||
}
|
||||
|
||||
bool LLFloaterPermsRequester::retry()
|
||||
{
|
||||
if (++mRetriesCount < mMaxRetries)
|
||||
{
|
||||
LLHTTPClient::post(mUrl, mReport, new LLFloaterPermsResponder());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterPermsResponder::httpFailure()
|
||||
{
|
||||
if (!LLFloaterPermsRequester::instance() || !LLFloaterPermsRequester::instance()->retry())
|
||||
{
|
||||
LLFloaterPermsRequester::finalize();
|
||||
const std::string& reason = getReason();
|
||||
// Do not display the same error more than once in a row
|
||||
if (reason != sPreviousReason)
|
||||
{
|
||||
// <FS:Ansariel> Add some retry function
|
||||
if (sRetryCount >= 5)
|
||||
{
|
||||
// </FS:Ansariel>
|
||||
sPreviousReason = reason;
|
||||
LLSD args;
|
||||
args["REASON"] = reason;
|
||||
LLNotificationsUtil::add("DefaultObjectPermissions", args);
|
||||
// <FS:Ansariel> Add some retry function
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("FloaterPermsResponder") << "Sending default permissions to simulator failed. Retrying (attempt " << sRetryCount << ")" << LL_ENDL;
|
||||
sRetryCount++;
|
||||
LLFloaterPermsDefault::sendInitialPerms();
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void httpSuccess()
|
||||
{
|
||||
//const LLSD& content = getContent();
|
||||
//dump_sequential_xml("perms_responder_result.xml", content);
|
||||
void LLFloaterPermsResponder::httpSuccess()
|
||||
{
|
||||
//const LLSD& content = getContent();
|
||||
//dump_sequential_xml("perms_responder_result.xml", content);
|
||||
|
||||
// Since we have had a successful POST call be sure to display the next error message
|
||||
// even if it is the same as a previous one.
|
||||
sPreviousReason = "";
|
||||
// <FS:Ansariel> Add some retry function
|
||||
sRetryCount = 0;
|
||||
LLFloaterPermsDefault::setCapSent(true);
|
||||
LL_INFOS("ObjectPermissionsFloater") << "Default permissions successfully sent to simulator" << LL_ENDL;
|
||||
}
|
||||
};
|
||||
// Since we have had a successful POST call be sure to display the next error message
|
||||
// even if it is the same as a previous one.
|
||||
sPreviousReason = "";
|
||||
LL_INFOS("ObjectPermissionsFloater") << "Default permissions successfully sent to simulator" << LL_ENDL;
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Add some retry function
|
||||
U32 LLFloaterPermsResponder::sRetryCount = 0;
|
||||
|
||||
std::string LLFloaterPermsResponder::sPreviousReason;
|
||||
std::string LLFloaterPermsResponder::sPreviousReason;
|
||||
|
||||
void LLFloaterPermsDefault::sendInitialPerms()
|
||||
{
|
||||
|
|
@ -233,6 +255,7 @@ void LLFloaterPermsDefault::sendInitialPerms()
|
|||
// </FS:Ansariel>
|
||||
{
|
||||
updateCap();
|
||||
setCapSent(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -257,9 +280,8 @@ void LLFloaterPermsDefault::updateCap()
|
|||
LLSDSerialize::toPrettyXML(report, sent_perms_log);
|
||||
LL_CONT << sent_perms_log.str() << LL_ENDL;
|
||||
}
|
||||
|
||||
LLFloaterPermsResponder::sRetryCount++;
|
||||
LLHTTPClient::post(object_url, report, new LLFloaterPermsResponder());
|
||||
LLFloaterPermsRequester::init(object_url, report, MAX_HTTP_RETRIES);
|
||||
LLFloaterPermsRequester::instance()->start();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -277,9 +299,6 @@ void LLFloaterPermsDefault::setCapSent(bool cap_sent)
|
|||
|
||||
void LLFloaterPermsDefault::ok()
|
||||
{
|
||||
// <FS:Ansariel> Add some retry function
|
||||
LLFloaterPermsResponder::sRetryCount = 0;
|
||||
|
||||
// Changes were already applied automatically to saved settings.
|
||||
// Refreshing internal values makes it official.
|
||||
refresh();
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#define LL_LLFLOATERPERMPREFS_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llhttpclient.h"
|
||||
|
||||
class LLFloaterPerms : public LLFloater
|
||||
{
|
||||
|
|
@ -94,4 +95,36 @@ private:
|
|||
static bool sCapSent;
|
||||
};
|
||||
|
||||
class LLFloaterPermsRequester
|
||||
{
|
||||
public:
|
||||
LLFloaterPermsRequester(const std::string url, const LLSD report, int maxRetries);
|
||||
|
||||
static void init(const std::string url, const LLSD report, int maxRetries);
|
||||
static void finalize();
|
||||
static LLFloaterPermsRequester* instance();
|
||||
|
||||
void start();
|
||||
bool retry();
|
||||
|
||||
private:
|
||||
int mRetriesCount;
|
||||
int mMaxRetries;
|
||||
const std::string mUrl;
|
||||
const LLSD mReport;
|
||||
public:
|
||||
static LLFloaterPermsRequester* sPermsRequester;
|
||||
};
|
||||
|
||||
class LLFloaterPermsResponder : public LLHTTPClient::Responder
|
||||
{
|
||||
public:
|
||||
LLFloaterPermsResponder() : LLHTTPClient::Responder() {}
|
||||
private:
|
||||
static std::string sPreviousReason;
|
||||
|
||||
void httpFailure();
|
||||
void httpSuccess();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
//#include "llfirstuse.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloaterabout.h"
|
||||
#include "llfavoritesbar.h"
|
||||
#include "llfloaterhardwaresettings.h"
|
||||
#include "llfloatersidepanelcontainer.h"
|
||||
// <FS:Ansariel> [FS communication UI]
|
||||
|
|
@ -2854,7 +2855,7 @@ BOOL LLPanelPreference::postBuild()
|
|||
}
|
||||
if (hasChild("favorites_on_login_check", TRUE))
|
||||
{
|
||||
getChild<LLCheckBoxCtrl>("favorites_on_login_check")->setCommitCallback(boost::bind(&showFavoritesOnLoginWarning, _1, _2));
|
||||
getChild<LLCheckBoxCtrl>("favorites_on_login_check")->setCommitCallback(boost::bind(&handleFavoritesOnLoginChanged, _1, _2));
|
||||
// <FS:Ansariel> [FS Login Panel]
|
||||
//bool show_favorites_at_login = LLPanelLogin::getShowFavorites();
|
||||
bool show_favorites_at_login = FSPanelLogin::getShowFavorites();
|
||||
|
|
@ -2987,11 +2988,15 @@ void LLPanelPreference::showCustomPortWarning(LLUICtrl* checkbox, const LLSD& va
|
|||
}
|
||||
// [/WoLf]
|
||||
|
||||
void LLPanelPreference::showFavoritesOnLoginWarning(LLUICtrl* checkbox, const LLSD& value)
|
||||
void LLPanelPreference::handleFavoritesOnLoginChanged(LLUICtrl* checkbox, const LLSD& value)
|
||||
{
|
||||
if (checkbox && checkbox->getValue())
|
||||
if (checkbox)
|
||||
{
|
||||
LLNotificationsUtil::add("FavoritesOnLogin");
|
||||
LLFavoritesOrderStorage::instance().showFavoritesOnLoginChanged(checkbox->getValue().asBoolean());
|
||||
if(checkbox->getValue())
|
||||
{
|
||||
LLNotificationsUtil::add("FavoritesOnLogin");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3371,6 +3376,11 @@ void LLFloaterPreferenceProxy::onOpen(const LLSD& key)
|
|||
|
||||
void LLFloaterPreferenceProxy::onClose(bool app_quitting)
|
||||
{
|
||||
if(app_quitting)
|
||||
{
|
||||
cancel();
|
||||
}
|
||||
|
||||
if (mSocksSettingsDirty)
|
||||
{
|
||||
|
||||
|
|
@ -3470,6 +3480,11 @@ void LLFloaterPreferenceProxy::onBtnCancel()
|
|||
cancel();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceProxy::onClickCloseBtn(bool app_quitting)
|
||||
{
|
||||
cancel();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceProxy::cancel()
|
||||
{
|
||||
|
||||
|
|
@ -3480,7 +3495,7 @@ void LLFloaterPreferenceProxy::cancel()
|
|||
LLSD ctrl_value = iter->second;
|
||||
control->set(ctrl_value);
|
||||
}
|
||||
|
||||
mSocksSettingsDirty = false;
|
||||
closeFloater();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ private:
|
|||
static void showCustomPortWarning(LLUICtrl*, const LLSD&); // -WoLf
|
||||
|
||||
//for "Show my Favorite Landmarks at Login"
|
||||
static void showFavoritesOnLoginWarning(LLUICtrl* checkbox, const LLSD& value);
|
||||
static void handleFavoritesOnLoginChanged(LLUICtrl* checkbox, const LLSD& value);
|
||||
|
||||
// <FS:Ansariel> Only enable Growl checkboxes if Growl is usable
|
||||
void onEnableGrowlChanged();
|
||||
|
|
@ -468,6 +468,7 @@ protected:
|
|||
void saveSettings();
|
||||
void onBtnOk();
|
||||
void onBtnCancel();
|
||||
void onClickCloseBtn(bool app_quitting = false);
|
||||
|
||||
void onChangeSocksSettings();
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "llassetstorage.h"
|
||||
#include "llavatarnamecache.h"
|
||||
#include "llcachename.h"
|
||||
#include "llcheckboxctrl.h"
|
||||
#include "llfontgl.h"
|
||||
#include "llimagej2c.h"
|
||||
#include "llinventory.h"
|
||||
|
|
@ -137,6 +138,7 @@ BOOL LLFloaterReporter::postBuild()
|
|||
mOwnerName = LLStringUtil::null;
|
||||
|
||||
getChild<LLUICtrl>("summary_edit")->setFocus(TRUE);
|
||||
getChild<LLCheckBoxCtrl>("screen_check")->set(TRUE);
|
||||
|
||||
mDefaultSummary = getChild<LLUICtrl>("details_edit")->getValue().asString();
|
||||
|
||||
|
|
|
|||
|
|
@ -751,14 +751,20 @@ void LLFloaterSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data)
|
|||
{
|
||||
LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
|
||||
LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
|
||||
LLSnapshotLivePreview* previewp = getPreviewView(view);
|
||||
|
||||
if (!view || !check_box)
|
||||
if (!view || !check_box || !previewp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gSavedSettings.setBOOL("UseFreezeFrame", check_box->get());
|
||||
|
||||
if (check_box->get())
|
||||
{
|
||||
previewp->prepareFreezeFrame();
|
||||
}
|
||||
|
||||
updateLayout(view);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -178,6 +178,12 @@ BOOL LLFloaterTOS::postBuild()
|
|||
// Don't use the start_url parameter for this browser instance -- it may finish loading before we get to add our observer.
|
||||
// Store the URL separately and navigate here instead.
|
||||
web_browser->navigateTo( getString( "loading_url" ) );
|
||||
LLPluginClassMedia* media_plugin = web_browser->getMediaPlugin();
|
||||
if (media_plugin)
|
||||
{
|
||||
// All links from tos_html should be opened in external browser
|
||||
media_plugin->setOverrideClickTarget("_external");
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef OPENSIM
|
||||
|
|
|
|||
|
|
@ -337,12 +337,12 @@ BOOL LLFloaterWorldMap::postBuild()
|
|||
LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo");
|
||||
avatar_combo->selectFirstItem();
|
||||
avatar_combo->setPrearrangeCallback( boost::bind(&LLFloaterWorldMap::onAvatarComboPrearrange, this) );
|
||||
avatar_combo->setTextEntryCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
|
||||
avatar_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
|
||||
mListFriendCombo = dynamic_cast<LLCtrlListInterface *>(avatar_combo);
|
||||
|
||||
LLSearchEditor *location_editor = getChild<LLSearchEditor>("location");
|
||||
location_editor->setFocusChangedCallback(boost::bind(&LLFloaterWorldMap::onLocationFocusChanged, this, _1));
|
||||
location_editor->setKeystrokeCallback( boost::bind(&LLFloaterWorldMap::onSearchTextEntry, this));
|
||||
location_editor->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onSearchTextEntry, this));
|
||||
|
||||
getChild<LLScrollListCtrl>("search_results")->setDoubleClickCallback( boost::bind(&LLFloaterWorldMap::onClickTeleportBtn, this));
|
||||
mListSearchResults = childGetListInterface("search_results");
|
||||
|
|
@ -350,7 +350,7 @@ BOOL LLFloaterWorldMap::postBuild()
|
|||
LLComboBox *landmark_combo = getChild<LLComboBox>( "landmark combo");
|
||||
landmark_combo->selectFirstItem();
|
||||
landmark_combo->setPrearrangeCallback( boost::bind(&LLFloaterWorldMap::onLandmarkComboPrearrange, this) );
|
||||
landmark_combo->setTextEntryCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
|
||||
landmark_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
|
||||
mListLandmarkCombo = dynamic_cast<LLCtrlListInterface *>(landmark_combo);
|
||||
|
||||
mCurZoomVal = log(LLWorldMapView::sMapScale)/log(2.f);
|
||||
|
|
|
|||
|
|
@ -254,7 +254,8 @@ LLGroupMgrGroupData::LLGroupMgrGroupData(const LLUUID& id) :
|
|||
mRoleMemberDataComplete(false),
|
||||
mGroupPropertiesDataComplete(false),
|
||||
mPendingRoleMemberRequest(false),
|
||||
mAccessTime(0.0f)
|
||||
mAccessTime(0.0f),
|
||||
mPendingBanRequest(false)
|
||||
{
|
||||
mMemberVersion.generate();
|
||||
}
|
||||
|
|
@ -776,8 +777,69 @@ void LLGroupMgrGroupData::removeBanEntry(const LLUUID& ban_id)
|
|||
mBanList.erase(ban_id);
|
||||
}
|
||||
|
||||
void LLGroupMgrGroupData::banMemberById(const LLUUID& participant_uuid)
|
||||
{
|
||||
if (!mMemberDataComplete ||
|
||||
!mRoleDataComplete ||
|
||||
!(mRoleMemberDataComplete && mMembers.size()))
|
||||
{
|
||||
LL_WARNS() << "No Role-Member data yet, setting ban request to pending." << LL_ENDL;
|
||||
mPendingBanRequest = true;
|
||||
mPendingBanMemberID = participant_uuid;
|
||||
|
||||
if (!mMemberDataComplete)
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mID);
|
||||
}
|
||||
|
||||
if (!mRoleDataComplete)
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mID);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LLGroupMgrGroupData::member_list_t::iterator mi = mMembers.find((participant_uuid));
|
||||
if (mi == mMembers.end())
|
||||
{
|
||||
if (!mPendingBanRequest)
|
||||
{
|
||||
mPendingBanRequest = true;
|
||||
mPendingBanMemberID = participant_uuid;
|
||||
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mID); // member isn't in members list, request reloading
|
||||
}
|
||||
else
|
||||
{
|
||||
mPendingBanRequest = false;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
mPendingBanRequest = false;
|
||||
|
||||
LLGroupMemberData* member_data = (*mi).second;
|
||||
if (member_data && member_data->isInRole(mOwnerRole))
|
||||
{
|
||||
return; // can't ban group owner
|
||||
}
|
||||
|
||||
std::vector<LLUUID> ids;
|
||||
ids.push_back(participant_uuid);
|
||||
|
||||
LLGroupBanData ban_data;
|
||||
createBanEntry(participant_uuid, ban_data);
|
||||
LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, mID, LLGroupMgr::BAN_CREATE, ids);
|
||||
LLGroupMgr::getInstance()->sendGroupMemberEjects(mID, ids);
|
||||
LLGroupMgr::getInstance()->sendGroupMembersRequest(mID);
|
||||
LLSD args;
|
||||
std::string name;
|
||||
gCacheName->getFullName(participant_uuid, name);
|
||||
args["AVATAR_NAME"] = name;
|
||||
args["GROUP_NAME"] = mName;
|
||||
LLNotifications::instance().add(LLNotification::Params("EjectAvatarFromGroup").substitutions(args));
|
||||
}
|
||||
|
||||
//
|
||||
// LLGroupMgr
|
||||
|
|
@ -1260,6 +1322,11 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
|
|||
|
||||
group_datap->mChanged = TRUE;
|
||||
LLGroupMgr::getInstance()->notifyObservers(GC_ROLE_MEMBER_DATA);
|
||||
|
||||
if (group_datap->mPendingBanRequest)
|
||||
{
|
||||
group_datap->banMemberById(group_datap->mPendingBanMemberID);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -2029,8 +2096,6 @@ void LLGroupMgr::processGroupBanRequest(const LLSD& content)
|
|||
LLGroupMgr::getInstance()->notifyObservers(GC_BANLIST);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Responder class for capability group management
|
||||
class GroupMemberDataResponder : public LLHTTPClient::Responder
|
||||
{
|
||||
|
|
@ -2119,11 +2184,6 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
|
|||
return;
|
||||
}
|
||||
|
||||
// If we have no members, there's no reason to do anything else
|
||||
S32 num_members = content["member_count"];
|
||||
if(num_members < 1)
|
||||
return;
|
||||
|
||||
LLUUID group_id = content["group_id"].asUUID();
|
||||
|
||||
LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id);
|
||||
|
|
@ -2133,6 +2193,18 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
|
|||
return;
|
||||
}
|
||||
|
||||
// If we have no members, there's no reason to do anything else
|
||||
S32 num_members = content["member_count"];
|
||||
if (num_members < 1)
|
||||
{
|
||||
LL_INFOS("GrpMgr") << "Received empty group members list for group id: " << group_id.asString() << LL_ENDL;
|
||||
// Set mMemberDataComplete for correct handling of empty responses. See MAINT-5237
|
||||
group_datap->mMemberDataComplete = true;
|
||||
group_datap->mChanged = TRUE;
|
||||
LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA);
|
||||
return;
|
||||
}
|
||||
|
||||
group_datap->mMemberCount = num_members;
|
||||
|
||||
LLSD member_list = content["members"];
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ public:
|
|||
|
||||
const uuid_vec_t& getRoleMembers() const { return mMemberIDs; }
|
||||
S32 getMembersInRole(uuid_vec_t members, BOOL needs_sort = TRUE);
|
||||
S32 getTotalMembersInRole() { return mMemberIDs.size(); }
|
||||
S32 getTotalMembersInRole() { return mMemberCount ? mMemberCount : mMemberIDs.size(); } //FIXME: Returns 0 for Everyone role when Member list isn't yet loaded, see MAINT-5225
|
||||
|
||||
LLRoleData getRoleData() const { return mRoleData; }
|
||||
void setRoleData(LLRoleData data) { mRoleData = data; }
|
||||
|
|
@ -279,8 +279,8 @@ public:
|
|||
|
||||
void createBanEntry(const LLUUID& ban_id, const LLGroupBanData& ban_data = LLGroupBanData());
|
||||
void removeBanEntry(const LLUUID& ban_id);
|
||||
void banMemberById(const LLUUID& participant_uuid);
|
||||
|
||||
|
||||
public:
|
||||
typedef std::map<LLUUID,LLGroupMemberData*> member_list_t;
|
||||
typedef std::map<LLUUID,LLGroupRoleData*> role_list_t;
|
||||
|
|
@ -312,6 +312,9 @@ public:
|
|||
S32 mMemberCount;
|
||||
S32 mRoleCount;
|
||||
|
||||
bool mPendingBanRequest;
|
||||
LLUUID mPendingBanMemberID;
|
||||
|
||||
protected:
|
||||
void sendRoleChanges();
|
||||
void cancelRoleChanges();
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ bool isAddAction(const std::string& action)
|
|||
|
||||
bool isRemoveAction(const std::string& action)
|
||||
{
|
||||
return ("take_off" == action || "detach" == action || "deactivate" == action);
|
||||
return ("take_off" == action || "detach" == action);
|
||||
}
|
||||
|
||||
bool isMarketplaceCopyAction(const std::string& action)
|
||||
|
|
@ -1038,15 +1038,7 @@ void LLInvFVBridge::addDeleteContextMenuOptions(menuentry_vec_t &items,
|
|||
return;
|
||||
}
|
||||
|
||||
// "Remove link" and "Delete" are the same operation.
|
||||
if (obj && obj->getIsLinkType() && !get_is_item_worn(mUUID))
|
||||
{
|
||||
items.push_back(std::string("Remove Link"));
|
||||
}
|
||||
else
|
||||
{
|
||||
items.push_back(std::string("Delete"));
|
||||
}
|
||||
items.push_back(std::string("Delete"));
|
||||
|
||||
if (!isItemRemovable())
|
||||
{
|
||||
|
|
@ -1994,7 +1986,9 @@ void LLItemBridge::restoreItem()
|
|||
if(item)
|
||||
{
|
||||
LLInventoryModel* model = getInventoryModel();
|
||||
const LLUUID new_parent = model->findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(item->getType()));
|
||||
bool is_snapshot = (item->getInventoryType() == LLInventoryType::IT_SNAPSHOT);
|
||||
|
||||
const LLUUID new_parent = model->findCategoryUUIDForType(is_snapshot? LLFolderType::FT_SNAPSHOT_CATEGORY : LLFolderType::assetTypeToFolderType(item->getType()));
|
||||
// do not restamp on restore.
|
||||
LLInvFVBridge::changeItemParent(model, item, new_parent, FALSE);
|
||||
}
|
||||
|
|
@ -2709,7 +2703,8 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const
|
|||
BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
|
||||
BOOL drop,
|
||||
std::string& tooltip_msg,
|
||||
BOOL user_confirm)
|
||||
BOOL is_link,
|
||||
BOOL user_confirm)
|
||||
{
|
||||
|
||||
LLInventoryModel* model = getInventoryModel();
|
||||
|
|
@ -2759,6 +2754,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
|
|||
const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id);
|
||||
const BOOL move_is_into_my_outfits = (mUUID == my_outifts_id) || model->isObjectDescendentOf(mUUID, my_outifts_id);
|
||||
const BOOL move_is_into_outfit = move_is_into_my_outfits || (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
|
||||
const BOOL move_is_into_current_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_CURRENT_OUTFIT);
|
||||
// <FS:Ansariel> FIRE-1392: Allow dragging all asset types into Landmarks folder
|
||||
//const BOOL move_is_into_landmarks = (mUUID == landmarks_id) || model->isObjectDescendentOf(mUUID, landmarks_id);
|
||||
|
||||
|
|
@ -2806,6 +2802,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
|
|||
is_movable = false;
|
||||
}
|
||||
}
|
||||
if(is_movable && move_is_into_current_outfit && is_link)
|
||||
{
|
||||
is_movable = FALSE;
|
||||
}
|
||||
if (is_movable && (mUUID == model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE)))
|
||||
{
|
||||
is_movable = FALSE;
|
||||
|
|
@ -2999,9 +2999,11 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if target is current outfit folder we use link
|
||||
if (move_is_into_current_outfit &&
|
||||
inv_cat->getPreferredType() == LLFolderType::FT_NONE)
|
||||
(inv_cat->getPreferredType() == LLFolderType::FT_NONE ||
|
||||
inv_cat->getPreferredType() == LLFolderType::FT_OUTFIT))
|
||||
{
|
||||
// traverse category and add all contents to currently worn.
|
||||
BOOL append = true;
|
||||
|
|
@ -4515,7 +4517,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
|
|||
LLInventoryCategory* linked_category = gInventory.getCategory(inv_item->getLinkedUUID());
|
||||
if (linked_category)
|
||||
{
|
||||
accept = dragCategoryIntoFolder((LLInventoryCategory*)linked_category, drop, tooltip_msg);
|
||||
accept = dragCategoryIntoFolder((LLInventoryCategory*)linked_category, drop, tooltip_msg, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -4963,7 +4965,7 @@ void LLFolderBridge::callback_dropCategoryIntoFolder(const LLSD& notification, c
|
|||
if (option == 0) // YES
|
||||
{
|
||||
std::string tooltip_msg;
|
||||
dragCategoryIntoFolder(inv_category, TRUE, tooltip_msg, FALSE);
|
||||
dragCategoryIntoFolder(inv_category, TRUE, tooltip_msg, FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6275,7 +6277,7 @@ void LLGestureBridge::performAction(LLInventoryModel* model, std::string action)
|
|||
gInventory.updateItem(item);
|
||||
gInventory.notifyObservers();
|
||||
}
|
||||
else if (isRemoveAction(action))
|
||||
else if ("deactivate" == action || isRemoveAction(action))
|
||||
{
|
||||
LLGestureMgr::instance().deactivateGesture(mUUID);
|
||||
|
||||
|
|
@ -7052,12 +7054,8 @@ void LLWearableBridge::performAction(LLInventoryModel* model, std::string action
|
|||
|
||||
void LLWearableBridge::openItem()
|
||||
{
|
||||
LLViewerInventoryItem* item = getItem();
|
||||
|
||||
if (item)
|
||||
{
|
||||
LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
|
||||
}
|
||||
performAction(getInventoryModel(),
|
||||
get_is_item_worn(mUUID) ? "take_off" : "wear");
|
||||
}
|
||||
|
||||
void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ public:
|
|||
{}
|
||||
|
||||
BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg, BOOL user_confirm = TRUE);
|
||||
BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg, BOOL user_confirm = TRUE);
|
||||
BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg, BOOL is_link = FALSE, BOOL user_confirm = TRUE);
|
||||
void callback_dropItemIntoFolder(const LLSD& notification, const LLSD& response, LLInventoryItem* inv_item);
|
||||
void callback_dropCategoryIntoFolder(const LLSD& notification, const LLSD& response, LLInventoryCategory* inv_category);
|
||||
|
||||
|
|
|
|||
|
|
@ -2573,7 +2573,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
|
|||
{
|
||||
LLSD args;
|
||||
args["QUESTION"] = LLTrans::getString(root->getSelectedCount() > 1 ? "DeleteItems" : "DeleteItem");
|
||||
LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&onItemsRemovalConfirmation, _1, _2, root->getHandle()));
|
||||
LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root->getHandle()));
|
||||
// Note: marketplace listings will be updated in the callback if delete confirmed
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -485,9 +485,9 @@ struct LLInventoryAction
|
|||
static void removeItemFromDND(LLFolderView* root);
|
||||
|
||||
private:
|
||||
static void buildMarketplaceFolders(LLFolderView* root);
|
||||
static void updateMarketplaceFolders();
|
||||
static std::list<LLUUID> sMarketplaceFolders; // Marketplace folders that will need update once the action is completed
|
||||
static void buildMarketplaceFolders(LLFolderView* root);
|
||||
static void updateMarketplaceFolders();
|
||||
static std::list<LLUUID> sMarketplaceFolders; // Marketplace folders that will need update once the action is completed
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -524,7 +524,7 @@ void LLLocalBitmap::updateUserSculpts(LLUUID old_id, LLUUID new_id)
|
|||
{
|
||||
LLSculptParams* old_params = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
|
||||
LLSculptParams new_params(*old_params);
|
||||
new_params.setSculptTexture(new_id);
|
||||
new_params.setSculptTexture(new_id, (*old_params).getSculptType());
|
||||
object->setParameterEntry(LLNetworkData::PARAMS_SCULPT, new_params, TRUE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -934,19 +934,11 @@ void LLLocationInputCtrl::refreshParcelIcons()
|
|||
#endif // OPENSIM
|
||||
// </FS:CR>
|
||||
|
||||
// <FS:Ansariel> Undo MAIN-23 for now...
|
||||
//bool is_parcel_owner = (gAgent.getID() == current_parcel->getOwnerID());
|
||||
//bool allow_group_modify = (gAgent.isInGroup(current_parcel->getGroupID()) && current_parcel->getAllowGroupModify());
|
||||
// </FS:Ansariel>
|
||||
|
||||
// Most icons are "block this ability"
|
||||
mParcelIcon[VOICE_ICON]->setVisible( !allow_voice );
|
||||
mParcelIcon[FLY_ICON]->setVisible( !allow_fly );
|
||||
mParcelIcon[PUSH_ICON]->setVisible( !allow_push );
|
||||
// <FS:Ansariel> Undo MAIN-23 for now...
|
||||
//mParcelIcon[BUILD_ICON]->setVisible( !allow_build && !is_parcel_owner && !allow_group_modify );
|
||||
mParcelIcon[BUILD_ICON]->setVisible( !allow_build );
|
||||
// </FS:Ansariel>
|
||||
mParcelIcon[SCRIPTS_ICON]->setVisible( !allow_scripts );
|
||||
mParcelIcon[DAMAGE_ICON]->setVisible( allow_damage );
|
||||
mParcelIcon[PATHFINDING_DIRTY_ICON]->setVisible(mIsNavMeshDirty);
|
||||
|
|
|
|||
|
|
@ -886,6 +886,22 @@ bool LLLogChat::isNearbyTranscriptExist()
|
|||
return false;
|
||||
}
|
||||
|
||||
bool LLLogChat::isAdHocTranscriptExist(std::string file_name)
|
||||
{
|
||||
std::vector<std::string> list_of_transcriptions;
|
||||
LLLogChat::getListOfTranscriptFiles(list_of_transcriptions);
|
||||
|
||||
file_name = makeLogFileName(file_name);
|
||||
BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions)
|
||||
{
|
||||
if (transcript_file_name == file_name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//*TODO mark object's names in a special way so that they will be distinguishable form avatar name
|
||||
//which are more strict by its nature (only firstname and secondname)
|
||||
//Example, an object's name can be written like "Object <actual_object's_name>"
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ public:
|
|||
static void deleteTranscripts();
|
||||
static bool isTranscriptExist(const LLUUID& avatar_id, bool is_group=false);
|
||||
static bool isNearbyTranscriptExist();
|
||||
static bool isAdHocTranscriptExist(std::string file_name);
|
||||
|
||||
static bool historyThreadsFinished(LLUUID session_id);
|
||||
static LLLoadHistoryThread* getLoadHistoryThread(LLUUID session_id);
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
|
|||
mStretchToFill( true ),
|
||||
mMaintainAspectRatio ( true ),
|
||||
mDecoupleTextureSize ( false ),
|
||||
mUpdateScrolls( false ),
|
||||
mTextureWidth ( 1024 ),
|
||||
mTextureHeight ( 1024 ),
|
||||
mClearCache(false),
|
||||
|
|
@ -701,7 +702,13 @@ bool LLMediaCtrl::ensureMediaSourceExists()
|
|||
mMediaSource->addObserver( this );
|
||||
mMediaSource->setBackgroundColor( getBackgroundColor() );
|
||||
mMediaSource->setTrustedBrowser(mTrusted);
|
||||
mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] );
|
||||
|
||||
F32 scale_factor = LLUI::getScaleFactor().mV[ VX ];
|
||||
if (scale_factor != mMediaSource->getPageZoomFactor())
|
||||
{
|
||||
mMediaSource->setPageZoomFactor( scale_factor );
|
||||
mUpdateScrolls = true;
|
||||
}
|
||||
|
||||
if(mClearCache)
|
||||
{
|
||||
|
|
@ -739,10 +746,11 @@ void LLMediaCtrl::draw()
|
|||
{
|
||||
F32 alpha = getDrawContext().mAlpha;
|
||||
|
||||
if ( gRestoreGL == 1 )
|
||||
if ( gRestoreGL == 1 || mUpdateScrolls)
|
||||
{
|
||||
LLRect r = getRect();
|
||||
reshape( r.getWidth(), r.getHeight(), FALSE );
|
||||
mUpdateScrolls = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -784,7 +792,12 @@ void LLMediaCtrl::draw()
|
|||
{
|
||||
gGL.pushUIMatrix();
|
||||
{
|
||||
mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] );
|
||||
F32 scale_factor = LLUI::getScaleFactor().mV[ VX ];
|
||||
if (scale_factor != mMediaSource->getPageZoomFactor())
|
||||
{
|
||||
mMediaSource->setPageZoomFactor( scale_factor );
|
||||
mUpdateScrolls = true;
|
||||
}
|
||||
|
||||
// scale texture to fit the space using texture coords
|
||||
gGL.getTexUnit(0)->bind(media_texture);
|
||||
|
|
@ -989,11 +1002,11 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
|
|||
|
||||
case MEDIA_EVENT_CLICK_LINK_HREF:
|
||||
{
|
||||
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << self->getClickTarget() << "\", uri is " << self->getClickURL() << LL_ENDL;
|
||||
// retrieve the event parameters
|
||||
std::string url = self->getClickURL();
|
||||
std::string target = self->getClickTarget();
|
||||
std::string target = self->isOverrideClickTarget() ? self->getOverrideClickTarget() : self->getClickTarget();
|
||||
std::string uuid = self->getClickUUID();
|
||||
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << target << "\", uri is " << url << LL_ENDL;
|
||||
|
||||
LLNotification::Params notify_params;
|
||||
notify_params.name = "PopupAttempt";
|
||||
|
|
|
|||
|
|
@ -193,7 +193,8 @@ public:
|
|||
mHidingInitialLoad,
|
||||
mClearCache,
|
||||
mHoverTextChanged,
|
||||
mDecoupleTextureSize;
|
||||
mDecoupleTextureSize,
|
||||
mUpdateScrolls;
|
||||
|
||||
std::string mHomePageUrl,
|
||||
mHomePageMimeType,
|
||||
|
|
|
|||
|
|
@ -309,7 +309,15 @@ void LLFloaterMove::onFlyButtonClick()
|
|||
void LLFloaterMove::setMovementMode(const EMovementMode mode)
|
||||
{
|
||||
mCurrentMode = mode;
|
||||
gAgent.setFlying(MM_FLY == mode);
|
||||
|
||||
if(MM_FLY == mode)
|
||||
{
|
||||
LLAgent::toggleFlying();
|
||||
}
|
||||
else
|
||||
{
|
||||
gAgent.setFlying(FALSE);
|
||||
}
|
||||
|
||||
// attempts to set avatar flying can not set it real flying in some cases.
|
||||
// For ex. when avatar fell down & is standing up.
|
||||
|
|
|
|||
|
|
@ -134,8 +134,14 @@ BOOL LLNameListCtrl::handleDragAndDrop(
|
|||
return handled;
|
||||
}
|
||||
|
||||
void LLNameListCtrl::showInspector(const LLUUID& avatar_id, bool is_group)
|
||||
void LLNameListCtrl::showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience)
|
||||
{
|
||||
if(is_experience)
|
||||
{
|
||||
LLFloaterReg::showInstance("experience_profile", avatar_id, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_group)
|
||||
LLFloaterReg::showInstance("inspect_group", LLSD().with("group_id", avatar_id));
|
||||
else
|
||||
|
|
@ -234,10 +240,11 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
|
|||
|
||||
// Should we show a group or an avatar inspector?
|
||||
bool is_group = hit_item->isGroup();
|
||||
bool is_experience = hit_item->isExperience();
|
||||
|
||||
LLToolTip::Params params;
|
||||
params.background_visible( false );
|
||||
params.click_callback( boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group) );
|
||||
params.click_callback( boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group, is_experience) );
|
||||
params.delay_time(0.0f); // spawn instantly on hover
|
||||
params.image( icon );
|
||||
params.message("");
|
||||
|
|
@ -305,7 +312,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
|
|||
const std::string& prefix)
|
||||
{
|
||||
LLUUID id = name_item.value().asUUID();
|
||||
LLNameListItem* item = new LLNameListItem(name_item,name_item.target() == GROUP);
|
||||
LLNameListItem* item = new LLNameListItem(name_item,name_item.target() == GROUP, name_item.target() == EXPERIENCE);
|
||||
|
||||
if (!item) return NULL;
|
||||
|
||||
|
|
@ -365,6 +372,8 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
|
|||
}
|
||||
break;
|
||||
}
|
||||
case EXPERIENCE:
|
||||
// just use supplied name
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,22 +50,30 @@ class LLNameListItem : public LLScrollListItem, public LLHandleProvider<LLNameLi
|
|||
public:
|
||||
bool isGroup() const { return mIsGroup; }
|
||||
void setIsGroup(bool is_group) { mIsGroup = is_group; }
|
||||
bool isExperience() const { return mIsExperience; }
|
||||
void setIsExperience(bool is_experience) { mIsExperience = is_experience; }
|
||||
|
||||
protected:
|
||||
friend class LLNameListCtrl;
|
||||
|
||||
LLNameListItem( const LLScrollListItem::Params& p )
|
||||
: LLScrollListItem(p), mIsGroup(false)
|
||||
: LLScrollListItem(p), mIsGroup(false), mIsExperience(false)
|
||||
{
|
||||
}
|
||||
|
||||
LLNameListItem( const LLScrollListItem::Params& p, bool is_group )
|
||||
: LLScrollListItem(p), mIsGroup(is_group)
|
||||
: LLScrollListItem(p), mIsGroup(is_group), mIsExperience(false)
|
||||
{
|
||||
}
|
||||
|
||||
LLNameListItem( const LLScrollListItem::Params& p, bool is_group, bool is_experience )
|
||||
: LLScrollListItem(p), mIsGroup(is_group), mIsExperience(is_experience)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
bool mIsGroup;
|
||||
bool mIsExperience;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -82,7 +90,8 @@ public:
|
|||
{
|
||||
INDIVIDUAL,
|
||||
GROUP,
|
||||
SPECIAL
|
||||
SPECIAL,
|
||||
EXPERIENCE
|
||||
} ENameType;
|
||||
|
||||
// provide names for enums
|
||||
|
|
@ -172,7 +181,7 @@ public:
|
|||
|
||||
/*virtual*/ void mouseOverHighlightNthItem( S32 index );
|
||||
private:
|
||||
void showInspector(const LLUUID& avatar_id, bool is_group);
|
||||
void showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience = false);
|
||||
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, LLHandle<LLNameListItem> item);
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -1192,6 +1192,8 @@ void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, BOOL show, BO
|
|||
|
||||
targetPanel->setVisible(show);
|
||||
toggleTypeSpecificControls(type);
|
||||
// Update type controls here
|
||||
updateTypeSpecificControls(type);
|
||||
|
||||
if (show)
|
||||
{
|
||||
|
|
@ -1203,7 +1205,6 @@ void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, BOOL show, BO
|
|||
mNameEditor->setText(mWearableItem->getName());
|
||||
|
||||
updatePanelPickerControls(type);
|
||||
updateTypeSpecificControls(type);
|
||||
|
||||
// clear and rebuild visual param list
|
||||
U8 num_subparts = wearable_entry->mSubparts.size();
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "llfloaterexperiencepicker.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llhandle.h"
|
||||
#include "llnamelistctrl.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llagent.h"
|
||||
|
|
@ -54,7 +55,7 @@ LLPanelExperienceListEditor::LLPanelExperienceListEditor()
|
|||
|
||||
BOOL LLPanelExperienceListEditor::postBuild()
|
||||
{
|
||||
mItems = getChild<LLScrollListCtrl>("experience_list");
|
||||
mItems = getChild<LLNameListCtrl>("experience_list");
|
||||
mAdd = getChild<LLButton>("btn_add");
|
||||
mRemove = getChild<LLButton>("btn_remove");
|
||||
mProfile = getChild<LLButton>("btn_profile");
|
||||
|
|
@ -186,12 +187,13 @@ void LLPanelExperienceListEditor::onItems()
|
|||
{
|
||||
const LLUUID& experience = *it;
|
||||
item["id"]=experience;
|
||||
item["target"] = LLNameListCtrl::EXPERIENCE;
|
||||
LLSD& columns = item["columns"];
|
||||
columns[0]["column"] = "experience_name";
|
||||
columns[0]["value"] = getString("loading");
|
||||
mItems->addElement(item);
|
||||
|
||||
LLExperienceCache::get(experience, boost::bind(&LLPanelExperienceListEditor::experienceDetailsCallback,
|
||||
LLExperienceCache::get(experience, boost::bind(&LLPanelExperienceListEditor::experienceDetailsCallback,
|
||||
getDerivedHandle<LLPanelExperienceListEditor>(), _1));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "lluuid.h"
|
||||
#include <set>
|
||||
|
||||
class LLNameListCtrl;
|
||||
class LLScrollListCtrl;
|
||||
class LLButton;
|
||||
class LLFloaterExperiencePicker;
|
||||
|
|
@ -82,7 +83,7 @@ private:
|
|||
uuid_list_t mExperienceIds;
|
||||
|
||||
|
||||
LLScrollListCtrl* mItems;
|
||||
LLNameListCtrl* mItems;
|
||||
filter_list mFilters;
|
||||
LLButton* mAdd;
|
||||
LLButton* mRemove;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "llviewercontrol.h"
|
||||
#include "llfloater.h"
|
||||
#include "lltrans.h"
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
#define BTN_FIND "find"
|
||||
#define BTN_OK "ok_btn"
|
||||
|
|
@ -148,6 +149,46 @@ void LLPanelExperiencePicker::editKeystroke( class LLLineEditor* caller, void* u
|
|||
void LLPanelExperiencePicker::onBtnFind()
|
||||
{
|
||||
mCurrentPage=1;
|
||||
boost::cmatch what;
|
||||
std::string text = getChild<LLUICtrl>(TEXT_EDIT)->getValue().asString();
|
||||
const boost::regex expression("secondlife:///app/experience/[\\da-f-]+/profile");
|
||||
if (boost::regex_match(text.c_str(), what, expression))
|
||||
{
|
||||
LLURI uri(text);
|
||||
LLSD path_array = uri.pathArray();
|
||||
if (path_array.size() == 4)
|
||||
{
|
||||
std::string exp_id = path_array.get(2).asString();
|
||||
LLUUID experience_id(exp_id);
|
||||
if (!experience_id.isNull())
|
||||
{
|
||||
const LLSD& experience_details = LLExperienceCache::get(experience_id);
|
||||
if(!experience_details.isUndefined())
|
||||
{
|
||||
std::string experience_name_string = experience_details[LLExperienceCache::NAME].asString();
|
||||
if(!experience_name_string.empty())
|
||||
{
|
||||
getChild<LLUICtrl>(TEXT_EDIT)->setValue(experience_name_string);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLScrollListCtrl>(LIST_RESULTS)->deleteAllItems();
|
||||
getChild<LLScrollListCtrl>(LIST_RESULTS)->setCommentText(getString("searching"));
|
||||
|
||||
getChildView(BTN_OK)->setEnabled(FALSE);
|
||||
getChildView(BTN_PROFILE)->setEnabled(FALSE);
|
||||
|
||||
getChildView(BTN_RIGHT)->setEnabled(FALSE);
|
||||
getChildView(BTN_LEFT)->setEnabled(FALSE);
|
||||
LLExperienceCache::get(experience_id, boost::bind(&LLPanelExperiencePicker::onBtnFind, this));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
find();
|
||||
}
|
||||
|
||||
|
|
@ -184,7 +225,6 @@ void LLPanelExperiencePicker::find()
|
|||
getChildView(BTN_LEFT)->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
|
||||
bool LLPanelExperiencePicker::isSelectButtonEnabled()
|
||||
{
|
||||
LLScrollListCtrl* list=getChild<LLScrollListCtrl>(LIST_RESULTS);
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@ private:
|
|||
LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material);
|
||||
}
|
||||
|
||||
object->setTEMaterialParams(face, new_material);
|
||||
object->setTEMaterialParams(face, new_material, TRUE);
|
||||
return new_material;
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -367,7 +367,7 @@ void LLPanelGroup::update(LLGroupChange gc)
|
|||
// </FS:Ansariel>
|
||||
|
||||
LLGroupData agent_gdatap;
|
||||
bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlike();
|
||||
bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlikeWithoutAdminMenuFakery();
|
||||
bool join_btn_visible = !is_member && gdatap->mOpenEnrollment;
|
||||
|
||||
mButtonJoin->setVisible(join_btn_visible);
|
||||
|
|
@ -499,7 +499,7 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
|
|||
}
|
||||
|
||||
LLGroupData agent_gdatap;
|
||||
bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlike();
|
||||
bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlikeWithoutAdminMenuFakery();
|
||||
|
||||
tab_roles->setVisible(is_member);
|
||||
tab_notices->setVisible(is_member);
|
||||
|
|
|
|||
|
|
@ -243,56 +243,59 @@ void LLPanelGroupInvite::impl::addRoleNames(LLGroupMgrGroupData* gdatap)
|
|||
LLGroupMgrGroupData::member_list_t::iterator agent_iter =
|
||||
gdatap->mMembers.find(gAgent.getID());
|
||||
|
||||
//get the member data for the agent if it exists
|
||||
if ( agent_iter != gdatap->mMembers.end() )
|
||||
{
|
||||
LLGroupMemberData* member_data = (*agent_iter).second;
|
||||
|
||||
//loop over the agent's roles in the group
|
||||
//then add those roles to the list of roles that the agent
|
||||
//can invite people to be
|
||||
if ( member_data && mRoleNames)
|
||||
{
|
||||
//if the user is the owner then we add
|
||||
//all of the roles in the group
|
||||
//else if they have the add to roles power
|
||||
//we add every role but owner,
|
||||
//else if they have the limited add to roles power
|
||||
//we add every role the user is in
|
||||
//else we just add to everyone
|
||||
bool is_owner = member_data->isOwner();
|
||||
bool can_assign_any = gAgent.hasPowerInGroup(mGroupID,
|
||||
//loop over the agent's roles in the group
|
||||
//then add those roles to the list of roles that the agent
|
||||
//can invite people to be.
|
||||
//if the user is the owner then we add
|
||||
//all of the roles in the group,
|
||||
//else if they have the add to roles power
|
||||
//we add every role but owner,
|
||||
//else if they have the limited add to roles power
|
||||
//we add every role the user is in,
|
||||
//else we just add to everyone
|
||||
bool is_owner = FALSE;
|
||||
bool can_assign_any = gAgent.hasPowerInGroup(mGroupID,
|
||||
GP_ROLE_ASSIGN_MEMBER);
|
||||
bool can_assign_limited = gAgent.hasPowerInGroup(mGroupID,
|
||||
GP_ROLE_ASSIGN_MEMBER_LIMITED);
|
||||
|
||||
LLGroupMgrGroupData::role_list_t::iterator rit = gdatap->mRoles.begin();
|
||||
LLGroupMgrGroupData::role_list_t::iterator end = gdatap->mRoles.end();
|
||||
|
||||
//populate the role list
|
||||
for ( ; rit != end; ++rit)
|
||||
{
|
||||
LLUUID role_id = (*rit).first;
|
||||
LLRoleData rd;
|
||||
if ( gdatap->getRoleData(role_id,rd) )
|
||||
{
|
||||
// Owners can add any role.
|
||||
if ( is_owner
|
||||
// Even 'can_assign_any' can't add owner role.
|
||||
|| (can_assign_any && role_id != gdatap->mOwnerRole)
|
||||
// Add all roles user is in
|
||||
|| (can_assign_limited && member_data->isInRole(role_id))
|
||||
// Everyone role.
|
||||
|| role_id == LLUUID::null )
|
||||
{
|
||||
mRoleNames->add(rd.mRoleName,
|
||||
role_id,
|
||||
ADD_BOTTOM);
|
||||
}
|
||||
}
|
||||
}
|
||||
bool can_assign_limited = gAgent.hasPowerInGroup(mGroupID,
|
||||
GP_ROLE_ASSIGN_MEMBER_LIMITED);
|
||||
LLGroupMemberData* member_data = NULL;
|
||||
//get the member data for the agent if it exists
|
||||
if (agent_iter != gdatap->mMembers.end())
|
||||
{
|
||||
member_data = (*agent_iter).second;
|
||||
if (member_data && mRoleNames)
|
||||
{
|
||||
is_owner = member_data->isOwner();
|
||||
}//end if member data is not null
|
||||
}//end if agent is in the group
|
||||
|
||||
|
||||
|
||||
LLGroupMgrGroupData::role_list_t::iterator rit = gdatap->mRoles.begin();
|
||||
LLGroupMgrGroupData::role_list_t::iterator end = gdatap->mRoles.end();
|
||||
|
||||
//populate the role list:
|
||||
for ( ; rit != end; ++rit)
|
||||
{
|
||||
LLUUID role_id = (*rit).first;
|
||||
LLRoleData rd;
|
||||
if ( gdatap->getRoleData(role_id,rd) )
|
||||
{
|
||||
// Owners can add any role.
|
||||
if ( is_owner
|
||||
// Even 'can_assign_any' can't add owner role.
|
||||
|| (can_assign_any && role_id != gdatap->mOwnerRole)
|
||||
// Add all roles user is in
|
||||
|| (can_assign_limited && member_data && member_data->isInRole(role_id))
|
||||
// Everyone role.
|
||||
|| role_id == LLUUID::null )
|
||||
{
|
||||
mRoleNames->add(rd.mRoleName,
|
||||
role_id,
|
||||
ADD_BOTTOM);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -581,7 +584,8 @@ void LLPanelGroupInvite::updateLists()
|
|||
{
|
||||
waiting = true;
|
||||
}
|
||||
if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete() && gdatap->isRoleMemberDataComplete())
|
||||
if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete()
|
||||
&& (gdatap->isRoleMemberDataComplete() || !gdatap->mMembers.size())) // MAINT-5270: large groups receives an empty members list without some powers, so RoleMemberData wouldn't be complete for them
|
||||
{
|
||||
if ( mImplementation->mRoleNames )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -354,12 +354,10 @@ void LLPanelGroupRoles::update(LLGroupChange gc)
|
|||
|
||||
void LLPanelGroupRoles::activate()
|
||||
{
|
||||
if (!gAgent.isInGroup(mGroupID)) return;
|
||||
|
||||
// Start requesting member and role data if needed.
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
|
||||
if (!gdatap || !gdatap->isMemberDataComplete() )
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
|
||||
}
|
||||
|
||||
if (!gdatap || !gdatap->isRoleDataComplete() )
|
||||
{
|
||||
|
|
@ -368,13 +366,7 @@ void LLPanelGroupRoles::activate()
|
|||
|
||||
LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID);
|
||||
}
|
||||
|
||||
// Check role-member mapping data.
|
||||
if (!gdatap || !gdatap->isRoleMemberDataComplete() )
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID);
|
||||
}
|
||||
|
||||
|
||||
// Need this to get base group member powers
|
||||
if (!gdatap || !gdatap->isGroupPropertiesDataComplete() )
|
||||
{
|
||||
|
|
@ -1182,7 +1174,37 @@ void LLPanelGroupMembersSubTab::onEjectMembers(void *userdata)
|
|||
|
||||
if ( selfp )
|
||||
{
|
||||
selfp->handleEjectMembers();
|
||||
selfp->confirmEjectMembers();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelGroupMembersSubTab::confirmEjectMembers()
|
||||
{
|
||||
std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected();
|
||||
if (selection.empty()) return;
|
||||
|
||||
S32 selection_count = selection.size();
|
||||
if (selection_count == 1)
|
||||
{
|
||||
LLSD args;
|
||||
std::string fullname;
|
||||
gCacheName->getFullName(mMembersList->getValue(), fullname);
|
||||
args["AVATAR_NAME"] = fullname;
|
||||
LLSD payload;
|
||||
LLNotificationsUtil::add("EjectGroupMemberWarning",
|
||||
args,
|
||||
payload,
|
||||
boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2));
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSD args;
|
||||
args["COUNT"] = llformat("%d", selection_count);
|
||||
LLSD payload;
|
||||
LLNotificationsUtil::add("EjectGroupMembersWarning",
|
||||
args,
|
||||
payload,
|
||||
boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1209,6 +1231,16 @@ void LLPanelGroupMembersSubTab::handleEjectMembers()
|
|||
LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID, selected_members);
|
||||
}
|
||||
|
||||
bool LLPanelGroupMembersSubTab::handleEjectCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (0 == option) // Eject button
|
||||
{
|
||||
handleEjectMembers();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLPanelGroupMembersSubTab::sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members)
|
||||
{
|
||||
LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(group_id);
|
||||
|
|
@ -1348,15 +1380,26 @@ void LLPanelGroupMembersSubTab::handleMemberDoubleClick()
|
|||
|
||||
void LLPanelGroupMembersSubTab::activate()
|
||||
{
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
|
||||
|
||||
LLPanelGroupSubTab::activate();
|
||||
if(!mActivated)
|
||||
{
|
||||
if (!gdatap || !gdatap->isMemberDataComplete())
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
|
||||
}
|
||||
|
||||
if (!gdatap || !gdatap->isRoleMemberDataComplete())
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID);
|
||||
}
|
||||
|
||||
update(GC_ALL);
|
||||
mActivated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
|
||||
// Members can be removed outside of this tab, checking changes
|
||||
if (!gdatap || (gdatap->isMemberDataComplete() && gdatap->mMembers.size() != mMembersList->getItemCount()))
|
||||
{
|
||||
|
|
@ -1657,7 +1700,13 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc)
|
|||
{
|
||||
// Build a string with info on retrieval progress.
|
||||
std::ostringstream retrieved;
|
||||
if ( !gdatap->isMemberDataComplete() )
|
||||
|
||||
if ( gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete() && !gdatap->mMembers.size() )
|
||||
{
|
||||
// MAINT-5237
|
||||
retrieved << "Member list not available.";
|
||||
}
|
||||
else if ( !gdatap->isMemberDataComplete() )
|
||||
{
|
||||
// Still busy retreiving member list.
|
||||
retrieved << "Retrieving member list (" << gdatap->mMembers.size()
|
||||
|
|
@ -1821,7 +1870,7 @@ void LLPanelGroupMembersSubTab::updateMembers()
|
|||
{
|
||||
mMembersList->setEnabled(TRUE);
|
||||
}
|
||||
else
|
||||
else if (gdatap->mMembers.size())
|
||||
{
|
||||
mMembersList->setEnabled(FALSE);
|
||||
mMembersList->setCommentText(std::string("No match."));
|
||||
|
|
@ -1839,7 +1888,47 @@ void LLPanelGroupMembersSubTab::updateMembers()
|
|||
void LLPanelGroupMembersSubTab::onBanMember(void* user_data)
|
||||
{
|
||||
LLPanelGroupMembersSubTab* self = static_cast<LLPanelGroupMembersSubTab*>(user_data);
|
||||
self->handleBanMember();
|
||||
self->confirmBanMembers();
|
||||
}
|
||||
|
||||
void LLPanelGroupMembersSubTab::confirmBanMembers()
|
||||
{
|
||||
std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected();
|
||||
if (selection.empty()) return;
|
||||
|
||||
S32 selection_count = selection.size();
|
||||
if (selection_count == 1)
|
||||
{
|
||||
LLSD args;
|
||||
std::string fullname;
|
||||
gCacheName->getFullName(mMembersList->getValue(), fullname);
|
||||
args["AVATAR_NAME"] = fullname;
|
||||
LLSD payload;
|
||||
LLNotificationsUtil::add("BanGroupMemberWarning",
|
||||
args,
|
||||
payload,
|
||||
boost::bind(&LLPanelGroupMembersSubTab::handleBanCallback, this, _1, _2));
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSD args;
|
||||
args["COUNT"] = llformat("%d", selection_count);
|
||||
LLSD payload;
|
||||
LLNotificationsUtil::add("BanGroupMembersWarning",
|
||||
args,
|
||||
payload,
|
||||
boost::bind(&LLPanelGroupMembersSubTab::handleBanCallback, this, _1, _2));
|
||||
}
|
||||
}
|
||||
|
||||
bool LLPanelGroupMembersSubTab::handleBanCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (0 == option) // Eject button
|
||||
{
|
||||
handleBanMember();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// [FS:CR] FIRE-12276
|
||||
|
|
@ -2189,20 +2278,7 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc)
|
|||
mDeleteRoleButton->setEnabled(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if(!mFirstOpen)
|
||||
{
|
||||
if (!gdatap || !gdatap->isMemberDataComplete())
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
|
||||
}
|
||||
|
||||
if (!gdatap || !gdatap->isRoleMemberDataComplete())
|
||||
{
|
||||
LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((GC_ROLE_MEMBER_DATA == gc || GC_MEMBER_DATA == gc)
|
||||
&& gdatap
|
||||
&& gdatap->isMemberDataComplete()
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ public:
|
|||
void handleEjectMembers();
|
||||
void sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members);
|
||||
bool handleEjectCallback(const LLSD& notification, const LLSD& response);
|
||||
void confirmEjectMembers();
|
||||
|
||||
static void onRoleCheck(LLUICtrl* check, void* user_data);
|
||||
void handleRoleCheck(const LLUUID& role_id,
|
||||
|
|
@ -178,6 +179,8 @@ public:
|
|||
|
||||
static void onBanMember(void* user_data);
|
||||
void handleBanMember();
|
||||
bool handleBanCallback(const LLSD& notification, const LLSD& response);
|
||||
void confirmBanMembers();
|
||||
|
||||
|
||||
void applyMemberChanges();
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
|
|||
}
|
||||
else
|
||||
{
|
||||
LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_NORMAL, agent_pos);
|
||||
region_name = desc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -920,7 +920,7 @@ void LLPanelMainInventory::updateItemcountText()
|
|||
}
|
||||
else
|
||||
{
|
||||
text = getString("ItemcountUnknown");
|
||||
text = getString("ItemcountUnknown", string_args);
|
||||
}
|
||||
|
||||
mCounterCtrl->setValue(text);
|
||||
|
|
|
|||
|
|
@ -319,6 +319,10 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& _media
|
|||
// Helper to set media control to media URL as required
|
||||
void LLPanelMediaSettingsGeneral::updateMediaPreview()
|
||||
{
|
||||
if(LLTrans::getString("Multiple Media") == mHomeURL->getValue().asString())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( mHomeURL->getValue().asString().length() > 0 )
|
||||
{
|
||||
if(mPreviewMedia->getCurrentNavUrl() != mHomeURL->getValue().asString())
|
||||
|
|
|
|||
|
|
@ -2153,9 +2153,10 @@ void LLPanelObject::sendSculpt()
|
|||
return;
|
||||
|
||||
LLSculptParams sculpt_params;
|
||||
LLUUID sculpt_id = LLUUID::null;
|
||||
|
||||
if (mCtrlSculptTexture)
|
||||
sculpt_params.setSculptTexture(mCtrlSculptTexture->getImageAssetID());
|
||||
sculpt_id = mCtrlSculptTexture->getImageAssetID();
|
||||
|
||||
U8 sculpt_type = 0;
|
||||
|
||||
|
|
@ -2179,7 +2180,7 @@ void LLPanelObject::sendSculpt()
|
|||
if ((mCtrlSculptInvert) && (mCtrlSculptInvert->get()))
|
||||
sculpt_type |= LL_SCULPT_FLAG_INVERT;
|
||||
|
||||
sculpt_params.setSculptType(sculpt_type);
|
||||
sculpt_params.setSculptTexture(sculpt_id, sculpt_type);
|
||||
mObject->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE);
|
||||
}
|
||||
|
||||
|
|
@ -2416,7 +2417,11 @@ void LLPanelObject::onCancelSculpt(const LLSD& data)
|
|||
LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
|
||||
if(!mTextureCtrl)
|
||||
return;
|
||||
|
||||
|
||||
if(mSculptTextureRevert == LLUUID::null)
|
||||
{
|
||||
mSculptTextureRevert = LLUUID(SCULPT_DEFAULT_TEXTURE);
|
||||
}
|
||||
mTextureCtrl->setImageAssetID(mSculptTextureRevert);
|
||||
|
||||
sendSculpt();
|
||||
|
|
@ -2744,10 +2749,7 @@ void LLPanelObject::onPasteParams(const LLSD& data)
|
|||
LLSculptParams sculpt_params;
|
||||
|
||||
if (mPramsClipboard.has("sculptid"))
|
||||
sculpt_params.setSculptTexture(mPramsClipboard["sculptid"].asUUID());
|
||||
|
||||
if (mPramsClipboard.has("sculptid"))
|
||||
sculpt_params.setSculptType((U8)mPramsClipboard["sculpt_type"].asInteger());
|
||||
sculpt_params.setSculptTexture(mPramsClipboard["sculptid"].asUUID(), (U8)mPramsClipboard["sculpt_type"].asInteger());
|
||||
|
||||
objectp->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,9 @@ static const std::string BLOCKED_TAB_NAME = "blocked_panel"; // blocked avatars
|
|||
static const std::string CONTACT_SETS_TAB_NAME = "contact_sets_panel"; // [FS:CR] Contact sets
|
||||
static const std::string COLLAPSED_BY_USER = "collapsed_by_user";
|
||||
|
||||
const S32 BASE_MAX_AGENT_GROUPS = 42;
|
||||
const S32 PREMIUM_MAX_AGENT_GROUPS = 60;
|
||||
|
||||
// [FS] FIRE-12229
|
||||
//extern S32 gMaxAgentGroups;
|
||||
|
||||
|
|
@ -631,6 +634,7 @@ BOOL LLPanelPeople::postBuild()
|
|||
getChild<LLFilterEditor>("groups_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
|
||||
getChild<LLFilterEditor>("recent_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
|
||||
//getChild<LLFilterEditor>("fbc_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); // <FS:Ansariel> Doesn't exist anymore
|
||||
getChild<LLTextBox>("groupcount")->setURLClickedCallback(boost::bind(&LLPanelPeople::onGroupLimitInfo, this));
|
||||
|
||||
mTabContainer = getChild<LLTabContainer>("tabs");
|
||||
mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2));
|
||||
|
|
@ -1018,9 +1022,12 @@ void LLPanelPeople::updateButtons()
|
|||
|
||||
LLPanel* groups_panel = mTabContainer->getCurrentPanel();
|
||||
groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); // a real group selected
|
||||
|
||||
// [CR] FIRE-12229
|
||||
//groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.size()));
|
||||
//groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[REMAINING]", llformat("%d",(gMaxAgentGroups-gAgent.mGroups.size())));
|
||||
//U32 groups_count = gAgent.mGroups.size();
|
||||
//U32 groups_ramaining = gMaxAgentGroups > groups_count ? gMaxAgentGroups - groups_count : 0;
|
||||
//groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d", groups_count));
|
||||
//groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[REMAINING]", llformat("%d", groups_ramaining));
|
||||
getChild<LLUICtrl>("groupcount")->setValue(FSCommon::populateGroupCount());
|
||||
// [/CR]
|
||||
}
|
||||
|
|
@ -1261,6 +1268,14 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string)
|
|||
}
|
||||
}
|
||||
|
||||
void LLPanelPeople::onGroupLimitInfo()
|
||||
{
|
||||
LLSD args;
|
||||
args["MAX_BASIC"] = BASE_MAX_AGENT_GROUPS;
|
||||
args["MAX_PREMIUM"] = PREMIUM_MAX_AGENT_GROUPS;
|
||||
LLNotificationsUtil::add("GroupLimitInfo", args);
|
||||
}
|
||||
|
||||
void LLPanelPeople::onTabSelected(const LLSD& param)
|
||||
{
|
||||
std::string tab_name = getChild<LLPanel>(param.asString())->getName();
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ private:
|
|||
|
||||
// UI callbacks
|
||||
void onFilterEdit(const std::string& search_string);
|
||||
void onGroupLimitInfo();
|
||||
void onTabSelected(const LLSD& param);
|
||||
void onAddFriendButtonClicked();
|
||||
void onAddFriendWizButtonClicked();
|
||||
|
|
|
|||
|
|
@ -450,7 +450,7 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
|
|||
|
||||
mNoPicks = !mPicksList->size();
|
||||
}
|
||||
else if(APT_CLASSIFIEDS == type)
|
||||
else if((APT_CLASSIFIEDS == type) || (APT_CLASSIFIED_INFO == type))
|
||||
{
|
||||
LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data);
|
||||
if(c_info && getAvatarId() == c_info->target_id)
|
||||
|
|
|
|||
|
|
@ -963,7 +963,12 @@ void LLPanelPlaces::onBackButtonClicked()
|
|||
void LLPanelPlaces::togglePickPanel(BOOL visible)
|
||||
{
|
||||
if (mPickPanel)
|
||||
{
|
||||
mPickPanel->setVisible(visible);
|
||||
mPlaceProfile->setVisible(!visible);
|
||||
updateVerbs();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
|
||||
|
|
@ -1183,16 +1188,21 @@ void LLPanelPlaces::updateVerbs()
|
|||
|
||||
bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE;
|
||||
bool is_create_landmark_visible = mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE;
|
||||
bool is_pick_panel_visible = false;
|
||||
if(mPickPanel)
|
||||
{
|
||||
is_pick_panel_visible = mPickPanel->isInVisibleChain();
|
||||
}
|
||||
bool have_3d_pos = ! mPosGlobal.isExactlyZero();
|
||||
|
||||
mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
|
||||
mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
|
||||
mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
|
||||
mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
|
||||
mOverflowBtn->setVisible(is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn);
|
||||
mEditBtn->setVisible(mPlaceInfoType == LANDMARK_INFO_TYPE && !isLandmarkEditModeOn);
|
||||
mSaveBtn->setVisible(isLandmarkEditModeOn);
|
||||
mCancelBtn->setVisible(isLandmarkEditModeOn);
|
||||
mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn);
|
||||
mPlaceInfoBtn->setVisible(!is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn);
|
||||
mPlaceInfoBtn->setVisible(!is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
|
||||
|
||||
mPlaceInfoBtn->setEnabled(!is_create_landmark_visible && !isLandmarkEditModeOn && have_3d_pos);
|
||||
|
||||
|
|
|
|||
|
|
@ -328,19 +328,11 @@ void LLPanelTopInfoBar::updateParcelIcons()
|
|||
bool allow_damage = vpm->allowAgentDamage(agent_region, current_parcel);
|
||||
bool see_avs = current_parcel->getSeeAVs();
|
||||
|
||||
// <FS:Ansariel> Undo MAIN-23 for now...
|
||||
//bool is_parcel_owner = (gAgent.getID() == current_parcel->getOwnerID());
|
||||
//bool allow_group_modify = (gAgent.isInGroup(current_parcel->getGroupID()) && current_parcel->getAllowGroupModify());
|
||||
// </FS:Ansariel>
|
||||
|
||||
// Most icons are "block this ability"
|
||||
mParcelIcon[VOICE_ICON]->setVisible( !allow_voice );
|
||||
mParcelIcon[FLY_ICON]->setVisible( !allow_fly );
|
||||
mParcelIcon[PUSH_ICON]->setVisible( !allow_push );
|
||||
// <FS:Ansariel> Undo MAIN-23 for now...
|
||||
//mParcelIcon[BUILD_ICON]->setVisible( !allow_build && !is_parcel_owner && !allow_group_modify );
|
||||
mParcelIcon[BUILD_ICON]->setVisible( !allow_build );
|
||||
// </FS:Ansariel>
|
||||
mParcelIcon[SCRIPTS_ICON]->setVisible( !allow_scripts );
|
||||
mParcelIcon[DAMAGE_ICON]->setVisible( allow_damage );
|
||||
mDamageText->setVisible(allow_damage);
|
||||
|
|
|
|||
|
|
@ -1751,6 +1751,8 @@ void LLLiveLSLEditor::buildExperienceList()
|
|||
else
|
||||
{
|
||||
mExperiences->setEnabled(TRUE);
|
||||
mExperiences->sortByName(TRUE);
|
||||
mExperiences->setCurrentByIndex(mExperiences->getCurrentIndex());
|
||||
getChild<LLButton>("view_profile")->setVisible(TRUE);
|
||||
}
|
||||
}
|
||||
|
|
@ -3243,12 +3245,16 @@ void LLLiveLSLEditor::onSave(void* userdata, BOOL close_after_save, bool sync)
|
|||
// </FS:Ansariel>
|
||||
{
|
||||
LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata;
|
||||
|
||||
self->mCloseAfterSave = close_after_save;
|
||||
// <FS:Ansariel> FIRE-7514: Script in external editor needs to be saved twice
|
||||
//self->saveIfNeeded();
|
||||
self->saveIfNeeded(sync);
|
||||
// </FS:Ansariel>
|
||||
if(self)
|
||||
{
|
||||
self->mCloseAfterSave = close_after_save;
|
||||
// <FS:Ansariel> Commented out because we fixed errors differently
|
||||
//self->mScriptEd->mErrorList->setCommentText("");
|
||||
// <FS:Ansariel> FIRE-7514: Script in external editor needs to be saved twice
|
||||
//self->saveIfNeeded();
|
||||
self->saveIfNeeded(sync);
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1076,4 +1076,5 @@ void LLPreviewTexture::setObjectID(const LLUUID& object_id)
|
|||
mAssetStatus = PREVIEW_ASSET_UNLOADED;
|
||||
loadAsset();
|
||||
}
|
||||
refreshFromItem();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2204,7 +2204,7 @@ void LLSelectMgr::selectionRemoveMaterial()
|
|||
{
|
||||
LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL;
|
||||
LLMaterialMgr::getInstance()->remove(object->getID(),face);
|
||||
object->setTEMaterialParams(face, NULL);
|
||||
object->setTEMaterialParams(face, NULL, FALSE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -5119,6 +5119,7 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name,
|
|||
ESendType send_type)
|
||||
{
|
||||
LLSelectNode* node;
|
||||
LLSelectNode* linkset_root = NULL;
|
||||
LLViewerRegion* last_region;
|
||||
LLViewerRegion* current_region;
|
||||
|
||||
|
|
@ -5126,6 +5127,8 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name,
|
|||
S32 packets_sent = 0;
|
||||
S32 objects_in_this_packet = 0;
|
||||
|
||||
bool link_operation = message_name == "ObjectLink";
|
||||
|
||||
//clear update override data (allow next update through)
|
||||
struct f : public LLSelectedNodeFunctor
|
||||
{
|
||||
|
|
@ -5234,6 +5237,12 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name,
|
|||
&& (! gMessageSystem->isSendFull(NULL))
|
||||
&& (objects_in_this_packet < MAX_OBJECTS_PER_PACKET))
|
||||
{
|
||||
if (link_operation && linkset_root == NULL)
|
||||
{
|
||||
// linksets over 254 will be split into multiple messages,
|
||||
// but we need to provide same root for all messages or we will get separate linksets
|
||||
linkset_root = node;
|
||||
}
|
||||
// add another instance of the body of the data
|
||||
(*pack_body)(node, user_data);
|
||||
// do any related logging
|
||||
|
|
@ -5262,6 +5271,22 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name,
|
|||
gMessageSystem->newMessage(message_name.c_str());
|
||||
(*pack_header)(user_data);
|
||||
|
||||
if (linkset_root != NULL)
|
||||
{
|
||||
if (current_region != last_region)
|
||||
{
|
||||
// root should be in one region with the child, reset it
|
||||
linkset_root = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// add root instance into new message
|
||||
(*pack_body)(linkset_root, user_data);
|
||||
++objects_sent;
|
||||
++objects_in_this_packet;
|
||||
}
|
||||
}
|
||||
|
||||
// don't move to the next object, we still need to add the
|
||||
// body data.
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue