Merge branch master (DRTVWR-483) into DRTVWR-559
# Conflicts: # indra/newview/lllocalbitmaps.cpp # indra/newview/lllocalbitmaps.h # indra/newview/llviewerregion.cpp # lllocalgltfmaterials.* were modified to match lllocalbitmaps*master
|
|
@ -223,6 +223,7 @@ Ansariel Hiller
|
|||
MAINT-8723
|
||||
SL-10385
|
||||
SL-10891
|
||||
SL-10675
|
||||
SL-13364
|
||||
SL-13858
|
||||
SL-13697
|
||||
|
|
@ -820,6 +821,7 @@ Jonathan Yap
|
|||
Kadah Coba
|
||||
STORM-1060
|
||||
STORM-1843
|
||||
SL-10675
|
||||
Jondan Lundquist
|
||||
Joosten Briebers
|
||||
MAINT-7074
|
||||
|
|
|
|||
|
|
@ -259,6 +259,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
|
|||
mMinHeight(p.min_height),
|
||||
mHeaderHeight(p.header_height),
|
||||
mLegacyHeaderHeight(p.legacy_header_height),
|
||||
mDefaultRectForGroup(true),
|
||||
mMinimized(FALSE),
|
||||
mForeground(FALSE),
|
||||
mFirstLook(TRUE),
|
||||
|
|
@ -906,7 +907,10 @@ bool LLFloater::applyRectControl()
|
|||
if (last_in_group && last_in_group != this)
|
||||
{
|
||||
// other floaters in our group, position ourselves relative to them and don't save the rect
|
||||
mRectControl.clear();
|
||||
if (mDefaultRectForGroup)
|
||||
{
|
||||
mRectControl.clear();
|
||||
}
|
||||
mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP;
|
||||
}
|
||||
else
|
||||
|
|
@ -3481,8 +3485,15 @@ void LLFloater::stackWith(LLFloater& other)
|
|||
}
|
||||
next_rect.translate(floater_offset, -floater_offset);
|
||||
|
||||
next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
|
||||
|
||||
const LLRect& rect = getControlGroup()->getRect(mRectControl);
|
||||
if (rect.notEmpty() && !mDefaultRectForGroup && mResizable)
|
||||
{
|
||||
next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
|
||||
}
|
||||
else
|
||||
{
|
||||
next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
|
||||
}
|
||||
setShape(next_rect);
|
||||
|
||||
if (!other.getHost())
|
||||
|
|
|
|||
|
|
@ -454,6 +454,7 @@ public:
|
|||
|
||||
protected:
|
||||
bool mSaveRect;
|
||||
bool mDefaultRectForGroup;
|
||||
std::string mRectControl;
|
||||
std::string mPosXControl;
|
||||
std::string mPosYControl;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "llui.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "lluiimage.h"
|
||||
#include "llwindow.h"
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLIconCtrl> r("icon");
|
||||
|
||||
|
|
@ -42,6 +43,7 @@ LLIconCtrl::Params::Params()
|
|||
: image("image_name"),
|
||||
color("color"),
|
||||
use_draw_context_alpha("use_draw_context_alpha", true),
|
||||
interactable("interactable", false),
|
||||
scale_image("scale_image"),
|
||||
min_width("min_width", 0),
|
||||
min_height("min_height", 0)
|
||||
|
|
@ -52,6 +54,7 @@ LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p)
|
|||
mColor(p.color()),
|
||||
mImagep(p.image),
|
||||
mUseDrawContextAlpha(p.use_draw_context_alpha),
|
||||
mInteractable(p.interactable),
|
||||
mPriority(0),
|
||||
mMinWidth(p.min_width),
|
||||
mMinHeight(p.min_height),
|
||||
|
|
@ -81,6 +84,16 @@ void LLIconCtrl::draw()
|
|||
LLUICtrl::draw();
|
||||
}
|
||||
|
||||
BOOL LLIconCtrl::handleHover(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if (mInteractable && getEnabled())
|
||||
{
|
||||
getWindow()->setCursor(UI_CURSOR_HAND);
|
||||
return TRUE;
|
||||
}
|
||||
return LLUICtrl::handleHover(x, y, mask);
|
||||
}
|
||||
|
||||
// virtual
|
||||
// value might be a string or a UUID
|
||||
void LLIconCtrl::setValue(const LLSD& value)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ public:
|
|||
{
|
||||
Optional<LLUIImage*> image;
|
||||
Optional<LLUIColor> color;
|
||||
Optional<bool> use_draw_context_alpha;
|
||||
Optional<bool> use_draw_context_alpha,
|
||||
interactable;
|
||||
Optional<S32> min_width,
|
||||
min_height;
|
||||
Ignored scale_image;
|
||||
|
|
@ -67,6 +68,9 @@ public:
|
|||
// llview overrides
|
||||
virtual void draw();
|
||||
|
||||
// llview overrides
|
||||
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
|
||||
// lluictrl overrides
|
||||
virtual void setValue(const LLSD& value );
|
||||
|
||||
|
|
@ -88,6 +92,7 @@ protected:
|
|||
// If set to true (default), use the draw context transparency.
|
||||
// If false, will use transparency returned by getCurrentTransparency(). See STORM-698.
|
||||
bool mUseDrawContextAlpha;
|
||||
bool mInteractable;
|
||||
|
||||
private:
|
||||
LLUIColor mColor;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ void LLMenuButton::MenuPositions::declareValues()
|
|||
declare("topleft", MP_TOP_LEFT);
|
||||
declare("topright", MP_TOP_RIGHT);
|
||||
declare("bottomleft", MP_BOTTOM_LEFT);
|
||||
declare("bottomright", MP_BOTTOM_RIGHT);
|
||||
}
|
||||
|
||||
LLMenuButton::Params::Params()
|
||||
|
|
@ -212,6 +213,13 @@ void LLMenuButton::updateMenuOrigin()
|
|||
mY = rect.mBottom;
|
||||
break;
|
||||
}
|
||||
case MP_BOTTOM_RIGHT:
|
||||
{
|
||||
const LLRect& menu_rect = menu->getRect();
|
||||
mX = rect.mRight - menu_rect.getWidth();
|
||||
mY = rect.mBottom;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ public:
|
|||
{
|
||||
MP_TOP_LEFT,
|
||||
MP_TOP_RIGHT,
|
||||
MP_BOTTOM_LEFT
|
||||
MP_BOTTOM_LEFT,
|
||||
MP_BOTTOM_RIGHT
|
||||
} EMenuPosition;
|
||||
|
||||
struct MenuPositions
|
||||
|
|
|
|||
|
|
@ -402,9 +402,13 @@ void LLTabContainer::draw()
|
|||
S32 cur_scroll_pos = getScrollPos();
|
||||
if (cur_scroll_pos > 0)
|
||||
{
|
||||
S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
|
||||
if (!mIsVertical)
|
||||
if (mIsVertical)
|
||||
{
|
||||
target_pixel_scroll = cur_scroll_pos * (BTN_HEIGHT + tabcntrv_pad);
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
|
||||
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
|
||||
{
|
||||
if (cur_scroll_pos == 0)
|
||||
|
|
@ -1189,13 +1193,15 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
|
|||
sendChildToFront(mNextArrowBtn);
|
||||
sendChildToFront(mJumpPrevArrowBtn);
|
||||
sendChildToFront(mJumpNextArrowBtn);
|
||||
|
||||
|
||||
updateMaxScrollPos();
|
||||
|
||||
if( select )
|
||||
{
|
||||
selectLastTab();
|
||||
mScrollPos = mMaxScrollPos;
|
||||
}
|
||||
|
||||
updateMaxScrollPos();
|
||||
}
|
||||
|
||||
void LLTabContainer::addPlaceholder(LLPanel* child, const std::string& label)
|
||||
|
|
@ -2079,9 +2085,9 @@ void LLTabContainer::updateMaxScrollPos()
|
|||
if( tab_total_height > available_height )
|
||||
{
|
||||
static LLUICachedControl<S32> tabcntrv_arrow_btn_size ("UITabCntrvArrowBtnSize", 0);
|
||||
S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad);
|
||||
S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad) - mNextArrowBtn->getRect().mBottom;
|
||||
S32 additional_needed = tab_total_height - available_height_with_arrows;
|
||||
setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT) ) );
|
||||
setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT + tabcntrv_pad) ) );
|
||||
no_scroll = FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ LLTextBase::Params::Params()
|
|||
font_shadow("font_shadow"),
|
||||
wrap("wrap"),
|
||||
trusted_content("trusted_content", true),
|
||||
always_show_icons("always_show_icons", false),
|
||||
use_ellipses("use_ellipses", false),
|
||||
parse_urls("parse_urls", false),
|
||||
force_urls_external("force_urls_external", false),
|
||||
|
|
@ -212,6 +213,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
|
|||
mClip(p.clip),
|
||||
mClipPartial(p.clip_partial && !p.allow_scroll),
|
||||
mTrustedContent(p.trusted_content),
|
||||
mAlwaysShowIcons(p.always_show_icons),
|
||||
mTrackEnd( p.track_end ),
|
||||
mScrollIndex(-1),
|
||||
mSelectionStart( 0 ),
|
||||
|
|
@ -448,8 +450,48 @@ void LLTextBase::drawSelectionBackground()
|
|||
++rect_it)
|
||||
{
|
||||
LLRect selection_rect = *rect_it;
|
||||
selection_rect = *rect_it;
|
||||
selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
|
||||
if (mScroller)
|
||||
{
|
||||
// If scroller is On content_display_rect has correct rect and safe to use as is
|
||||
// Note: we might need to account for border
|
||||
selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If scroller is Off content_display_rect will have rect from document, adjusted to text width, heigh and position
|
||||
// and we have to acount for offset depending on position
|
||||
S32 v_delta = 0;
|
||||
S32 h_delta = 0;
|
||||
switch (mVAlign)
|
||||
{
|
||||
case LLFontGL::TOP:
|
||||
v_delta = mVisibleTextRect.mTop - content_display_rect.mTop - mVPad;
|
||||
break;
|
||||
case LLFontGL::VCENTER:
|
||||
v_delta = (llmax(mVisibleTextRect.getHeight() - content_display_rect.mTop, -content_display_rect.mBottom) + (mVisibleTextRect.mBottom - content_display_rect.mBottom)) / 2;
|
||||
break;
|
||||
case LLFontGL::BOTTOM:
|
||||
v_delta = mVisibleTextRect.mBottom - content_display_rect.mBottom;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (mHAlign)
|
||||
{
|
||||
case LLFontGL::LEFT:
|
||||
h_delta = mVisibleTextRect.mLeft - content_display_rect.mLeft + mHPad;
|
||||
break;
|
||||
case LLFontGL::HCENTER:
|
||||
h_delta = (llmax(mVisibleTextRect.getWidth() - content_display_rect.mLeft, -content_display_rect.mRight) + (mVisibleTextRect.mRight - content_display_rect.mRight)) / 2;
|
||||
break;
|
||||
case LLFontGL::RIGHT:
|
||||
h_delta = mVisibleTextRect.mRight - content_display_rect.mRight;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
selection_rect.translate(h_delta, v_delta);
|
||||
}
|
||||
gl_rect_2d(selection_rect, selection_color);
|
||||
}
|
||||
}
|
||||
|
|
@ -2116,7 +2158,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
|
|||
LLUrlMatch match;
|
||||
std::string text = new_text;
|
||||
while ( LLUrlRegistry::instance().findUrl(text, match,
|
||||
boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted()))
|
||||
boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted() || mAlwaysShowIcons))
|
||||
{
|
||||
start = match.getStart();
|
||||
end = match.getEnd()+1;
|
||||
|
|
@ -2141,7 +2183,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
|
|||
}
|
||||
|
||||
// add icon before url if need
|
||||
LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted());
|
||||
LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted() || mAlwaysShowIcons);
|
||||
if ((isContentTrusted() || match.isTrusted()) && !match.getIcon().empty() )
|
||||
{
|
||||
setLastSegmentToolTip(LLTrans::getString("TooltipSLIcon"));
|
||||
|
|
|
|||
|
|
@ -321,7 +321,8 @@ public:
|
|||
parse_highlights,
|
||||
clip,
|
||||
clip_partial,
|
||||
trusted_content;
|
||||
trusted_content,
|
||||
always_show_icons;
|
||||
|
||||
Optional<S32> v_pad,
|
||||
h_pad;
|
||||
|
|
@ -369,6 +370,8 @@ public:
|
|||
virtual void onFocusReceived();
|
||||
virtual void onFocusLost();
|
||||
|
||||
void setParseHTML(bool parse_html) { mParseHTML = parse_html; }
|
||||
|
||||
// LLSpellCheckMenuHandler overrides
|
||||
/*virtual*/ bool getSpellCheck() const;
|
||||
|
||||
|
|
@ -702,6 +705,8 @@ protected:
|
|||
bool mAutoIndent;
|
||||
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
|
||||
bool mSkipTripleClick;
|
||||
bool mAlwaysShowIcons;
|
||||
|
||||
bool mSkipLinkUnderline;
|
||||
|
||||
// support widgets
|
||||
|
|
|
|||
|
|
@ -236,12 +236,14 @@ set(viewer_SOURCE_FILES
|
|||
llfloatercamera.cpp
|
||||
llfloatercamerapresets.cpp
|
||||
llfloaterchatvoicevolume.cpp
|
||||
llfloaterclassified.cpp
|
||||
llfloatercolorpicker.cpp
|
||||
llfloaterconversationlog.cpp
|
||||
llfloaterconversationpreview.cpp
|
||||
llfloatercreatelandmark.cpp
|
||||
llfloaterdeleteprefpreset.cpp
|
||||
llfloaterdestinations.cpp
|
||||
llfloaterdisplayname.cpp
|
||||
llfloatereditenvironmentbase.cpp
|
||||
llfloatereditextdaycycle.cpp
|
||||
llfloaterenvironmentadjust.cpp
|
||||
|
|
@ -297,9 +299,11 @@ set(viewer_SOURCE_FILES
|
|||
llfloaterpay.cpp
|
||||
llfloaterperms.cpp
|
||||
llfloaterpostprocess.cpp
|
||||
llfloaterprofile.cpp
|
||||
llfloaterpreference.cpp
|
||||
llfloaterpreferenceviewadvanced.cpp
|
||||
llfloaterpreviewtrash.cpp
|
||||
llfloaterprofiletexture.cpp
|
||||
llfloaterproperties.cpp
|
||||
llfloaterregiondebugconsole.cpp
|
||||
llfloaterregioninfo.cpp
|
||||
|
|
@ -331,7 +335,6 @@ set(viewer_SOURCE_FILES
|
|||
llfloatervoiceeffect.cpp
|
||||
llfloatervoicevolume.cpp
|
||||
llfloaterwebcontent.cpp
|
||||
llfloaterwebprofile.cpp
|
||||
llfloaterwhitelistentry.cpp
|
||||
llfloaterwindowsize.cpp
|
||||
llfloaterworldmap.cpp
|
||||
|
|
@ -480,7 +483,6 @@ set(viewer_SOURCE_FILES
|
|||
llpanelmediasettingsgeneral.cpp
|
||||
llpanelmediasettingspermissions.cpp
|
||||
llpanelmediasettingssecurity.cpp
|
||||
llpanelme.cpp
|
||||
llpanelnearbymedia.cpp
|
||||
llpanelobject.cpp
|
||||
llpanelobjectinventory.cpp
|
||||
|
|
@ -490,8 +492,6 @@ set(viewer_SOURCE_FILES
|
|||
llpanelpeople.cpp
|
||||
llpanelpeoplemenus.cpp
|
||||
llpanelpermissions.cpp
|
||||
llpanelpick.cpp
|
||||
llpanelpicks.cpp
|
||||
llpanelplaceinfo.cpp
|
||||
llpanelplaceprofile.cpp
|
||||
llpanelplaces.cpp
|
||||
|
|
@ -500,6 +500,8 @@ set(viewer_SOURCE_FILES
|
|||
llpanelpresetspulldown.cpp
|
||||
llpanelprimmediacontrols.cpp
|
||||
llpanelprofile.cpp
|
||||
llpanelprofileclassifieds.cpp
|
||||
llpanelprofilepicks.cpp
|
||||
llpanelsnapshot.cpp
|
||||
llpanelsnapshotinventory.cpp
|
||||
llpanelsnapshotlocal.cpp
|
||||
|
|
@ -664,6 +666,7 @@ set(viewer_SOURCE_FILES
|
|||
llviewercontrol.cpp
|
||||
llviewercontrollistener.cpp
|
||||
llviewerdisplay.cpp
|
||||
llviewerdisplayname.cpp
|
||||
llviewerfloaterreg.cpp
|
||||
llviewerfoldertype.cpp
|
||||
llviewergenericmessage.cpp
|
||||
|
|
@ -878,12 +881,14 @@ set(viewer_HEADER_FILES
|
|||
llfloatercamerapresets.h
|
||||
llfloatercamera.h
|
||||
llfloaterchatvoicevolume.h
|
||||
llfloaterclassified.h
|
||||
llfloatercolorpicker.h
|
||||
llfloaterconversationlog.h
|
||||
llfloaterconversationpreview.h
|
||||
llfloatercreatelandmark.h
|
||||
llfloaterdeleteprefpreset.h
|
||||
llfloaterdestinations.h
|
||||
llfloaterdisplayname.h
|
||||
llfloatereditenvironmentbase.h
|
||||
llfloatereditextdaycycle.h
|
||||
llfloaterenvironmentadjust.h
|
||||
|
|
@ -942,9 +947,11 @@ set(viewer_HEADER_FILES
|
|||
llfloaterpay.h
|
||||
llfloaterperms.h
|
||||
llfloaterpostprocess.h
|
||||
llfloaterprofile.h
|
||||
llfloaterpreference.h
|
||||
llfloaterpreferenceviewadvanced.h
|
||||
llfloaterpreviewtrash.h
|
||||
llfloaterprofiletexture.h
|
||||
llfloaterproperties.h
|
||||
llfloaterregiondebugconsole.h
|
||||
llfloaterregioninfo.h
|
||||
|
|
@ -976,7 +983,6 @@ set(viewer_HEADER_FILES
|
|||
llfloatervoiceeffect.h
|
||||
llfloatervoicevolume.h
|
||||
llfloaterwebcontent.h
|
||||
llfloaterwebprofile.h
|
||||
llfloaterwhitelistentry.h
|
||||
llfloaterwindowsize.h
|
||||
llfloaterworldmap.h
|
||||
|
|
@ -1115,7 +1121,6 @@ set(viewer_HEADER_FILES
|
|||
llpanelmediasettingsgeneral.h
|
||||
llpanelmediasettingspermissions.h
|
||||
llpanelmediasettingssecurity.h
|
||||
llpanelme.h
|
||||
llpanelnearbymedia.h
|
||||
llpanelobject.h
|
||||
llpanelobjectinventory.h
|
||||
|
|
@ -1125,8 +1130,6 @@ set(viewer_HEADER_FILES
|
|||
llpanelpeople.h
|
||||
llpanelpeoplemenus.h
|
||||
llpanelpermissions.h
|
||||
llpanelpick.h
|
||||
llpanelpicks.h
|
||||
llpanelplaceinfo.h
|
||||
llpanelplaceprofile.h
|
||||
llpanelplaces.h
|
||||
|
|
@ -1135,6 +1138,8 @@ set(viewer_HEADER_FILES
|
|||
llpanelpresetspulldown.h
|
||||
llpanelprimmediacontrols.h
|
||||
llpanelprofile.h
|
||||
llpanelprofileclassifieds.h
|
||||
llpanelprofilepicks.h
|
||||
llpanelsnapshot.h
|
||||
llpanelteleporthistory.h
|
||||
llpaneltiptoast.h
|
||||
|
|
@ -1300,6 +1305,7 @@ set(viewer_HEADER_FILES
|
|||
llviewercontrol.h
|
||||
llviewercontrollistener.h
|
||||
llviewerdisplay.h
|
||||
llviewerdisplayname.h
|
||||
llviewerfloaterreg.h
|
||||
llviewerfoldertype.h
|
||||
llviewergenericmessage.h
|
||||
|
|
|
|||
|
|
@ -167,10 +167,8 @@
|
|||
icon="Command_Picks_Icon"
|
||||
label_ref="Command_Picks_Label"
|
||||
tooltip_ref="Command_Picks_Tooltip"
|
||||
execute_function="Floater.ToggleOrBringToFront"
|
||||
execute_parameters="picks"
|
||||
is_running_function="Floater.IsOpen"
|
||||
is_running_parameters="picks"
|
||||
execute_function="Avatar.TogglePicks"
|
||||
is_running_function="Avatar.IsPicksTabOpen"
|
||||
/>
|
||||
<command name="places"
|
||||
available_in_toybox="true"
|
||||
|
|
|
|||
|
|
@ -74,10 +74,10 @@ public:
|
|||
|
||||
void decrementNumberOfPicks() { --mNumberOfPicks; }
|
||||
|
||||
private:
|
||||
|
||||
void onServerRespond(LLAvatarPicks* picks);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Sets number of Picks.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include "llfloatergroups.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloaterpay.h"
|
||||
#include "llfloaterprofile.h"
|
||||
#include "llfloatersidepanelcontainer.h"
|
||||
#include "llfloaterwebcontent.h"
|
||||
#include "llfloaterworldmap.h"
|
||||
|
|
@ -62,11 +63,14 @@
|
|||
#include "llnotificationsutil.h" // for LLNotificationsUtil
|
||||
#include "llpaneloutfitedit.h"
|
||||
#include "llpanelprofile.h"
|
||||
#include "llparcel.h"
|
||||
#include "llrecentpeople.h"
|
||||
#include "lltrans.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llviewermessage.h" // for handle_lure
|
||||
#include "llviewernetwork.h" //LLGridManager
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "lltrans.h"
|
||||
#include "llcallingcard.h"
|
||||
|
|
@ -81,6 +85,19 @@ const U32 KICK_FLAGS_FREEZE = 1 << 0;
|
|||
const U32 KICK_FLAGS_UNFREEZE = 1 << 1;
|
||||
|
||||
|
||||
std::string getProfileURL(const std::string& agent_name, bool feed_only)
|
||||
{
|
||||
std::string url = "[WEB_PROFILE_URL][AGENT_NAME][FEED_ONLY]";
|
||||
LLSD subs;
|
||||
subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL();
|
||||
subs["AGENT_NAME"] = agent_name;
|
||||
subs["FEED_ONLY"] = feed_only ? "/?feed_only=true" : "";
|
||||
url = LLWeb::expandURLSubstitutions(url, subs);
|
||||
LLStringUtil::toLower(url);
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
|
||||
{
|
||||
|
|
@ -316,57 +333,144 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& float
|
|||
make_ui_sound("UISndStartIM");
|
||||
}
|
||||
|
||||
static const char* get_profile_floater_name(const LLUUID& avatar_id)
|
||||
{
|
||||
// Use different floater XML for our profile to be able to save its rect.
|
||||
return avatar_id == gAgentID ? "my_profile" : "profile";
|
||||
}
|
||||
|
||||
static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarName& av_name)
|
||||
{
|
||||
std::string url = getProfileURL(av_name.getAccountName());
|
||||
|
||||
// PROFILES: open in webkit window
|
||||
LLFloaterWebContent::Params p;
|
||||
p.url(url).id(agent_id.asString());
|
||||
LLFloaterReg::showInstance(get_profile_floater_name(agent_id), p);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLAvatarActions::showProfile(const LLUUID& id)
|
||||
void LLAvatarActions::showProfile(const LLUUID& avatar_id)
|
||||
{
|
||||
if (id.notNull())
|
||||
if (avatar_id.notNull())
|
||||
{
|
||||
LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_show_profile, _1, _2));
|
||||
LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id));
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLAvatarActions::showPicks(const LLUUID& avatar_id)
|
||||
{
|
||||
if (avatar_id.notNull())
|
||||
{
|
||||
LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
|
||||
if (profilefloater)
|
||||
{
|
||||
profilefloater->showPick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLAvatarActions::showPick(const LLUUID& avatar_id, const LLUUID& pick_id)
|
||||
{
|
||||
if (avatar_id.notNull())
|
||||
{
|
||||
LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
|
||||
if (profilefloater)
|
||||
{
|
||||
profilefloater->showPick(pick_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLAvatarActions::createPick()
|
||||
{
|
||||
LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (profilefloater && region)
|
||||
{
|
||||
LLPickData data;
|
||||
data.pos_global = gAgent.getPositionGlobal();
|
||||
data.sim_name = region->getName();
|
||||
|
||||
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
||||
if (parcel)
|
||||
{
|
||||
data.name = parcel->getName();
|
||||
data.desc = parcel->getDesc();
|
||||
data.snapshot_id = parcel->getSnapshotID();
|
||||
data.parcel_id = parcel->getID();
|
||||
}
|
||||
else
|
||||
{
|
||||
data.name = region->getName();
|
||||
}
|
||||
|
||||
profilefloater->createPick(data);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLAvatarActions::isPickTabSelected(const LLUUID& avatar_id)
|
||||
{
|
||||
if (avatar_id.notNull())
|
||||
{
|
||||
LLFloaterProfile* profilefloater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
|
||||
if (profilefloater)
|
||||
{
|
||||
return profilefloater->isPickTabSelected();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLAvatarActions::showClassifieds(const LLUUID& avatar_id)
|
||||
{
|
||||
if (avatar_id.notNull())
|
||||
{
|
||||
LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
|
||||
if (profilefloater)
|
||||
{
|
||||
profilefloater->showClassified();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLAvatarActions::showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit)
|
||||
{
|
||||
if (avatar_id.notNull())
|
||||
{
|
||||
LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
|
||||
if (profilefloater)
|
||||
{
|
||||
profilefloater->showClassified(classified_id, edit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLAvatarActions::createClassified()
|
||||
{
|
||||
LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
|
||||
if (profilefloater)
|
||||
{
|
||||
profilefloater->createClassified();
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
bool LLAvatarActions::profileVisible(const LLUUID& id)
|
||||
bool LLAvatarActions::profileVisible(const LLUUID& avatar_id)
|
||||
{
|
||||
LLSD sd;
|
||||
sd["id"] = id;
|
||||
LLFloater* browser = getProfileFloater(id);
|
||||
return browser && browser->isShown();
|
||||
sd["id"] = avatar_id;
|
||||
LLFloater* floater = getProfileFloater(avatar_id);
|
||||
return floater && floater->isShown();
|
||||
}
|
||||
|
||||
//static
|
||||
LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& id)
|
||||
LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& avatar_id)
|
||||
{
|
||||
LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*>
|
||||
(LLFloaterReg::findInstance(get_profile_floater_name(id), LLSD().with("id", id)));
|
||||
return browser;
|
||||
LLFloaterProfile* floater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
|
||||
return floater;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLAvatarActions::hideProfile(const LLUUID& id)
|
||||
void LLAvatarActions::hideProfile(const LLUUID& avatar_id)
|
||||
{
|
||||
LLSD sd;
|
||||
sd["id"] = id;
|
||||
LLFloater* browser = getProfileFloater(id);
|
||||
if (browser)
|
||||
sd["id"] = avatar_id;
|
||||
LLFloater* floater = getProfileFloater(avatar_id);
|
||||
if (floater)
|
||||
{
|
||||
browser->closeFloater();
|
||||
floater->closeFloater();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -990,7 +1094,7 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
|
|||
}
|
||||
|
||||
// static
|
||||
void LLAvatarActions::toggleBlock(const LLUUID& id)
|
||||
bool LLAvatarActions::toggleBlock(const LLUUID& id)
|
||||
{
|
||||
LLAvatarName av_name;
|
||||
LLAvatarNameCache::get(id, &av_name);
|
||||
|
|
@ -1000,10 +1104,12 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
|
|||
if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))
|
||||
{
|
||||
LLMuteList::getInstance()->remove(mute);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLMuteList::getInstance()->add(mute);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ class LLInventoryPanel;
|
|||
class LLFloater;
|
||||
class LLView;
|
||||
|
||||
std::string getProfileURL(const std::string& agent_name, bool feed_only = false);
|
||||
|
||||
/**
|
||||
* Friend-related actions (add, remove, offer teleport, etc)
|
||||
*/
|
||||
|
|
@ -91,13 +93,20 @@ public:
|
|||
*/
|
||||
static void startConference(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null);
|
||||
|
||||
/**
|
||||
* Show avatar profile.
|
||||
*/
|
||||
static void showProfile(const LLUUID& id);
|
||||
static void hideProfile(const LLUUID& id);
|
||||
static bool profileVisible(const LLUUID& id);
|
||||
static LLFloater* getProfileFloater(const LLUUID& id);
|
||||
/**
|
||||
* Show avatar profile.
|
||||
*/
|
||||
static void showProfile(const LLUUID& avatar_id);
|
||||
static void showPicks(const LLUUID& avatar_id);
|
||||
static void showPick(const LLUUID& avatar_id, const LLUUID& pick_id);
|
||||
static void createPick();
|
||||
static void showClassifieds(const LLUUID& avatar_id);
|
||||
static void showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit = false);
|
||||
static void createClassified();
|
||||
static void hideProfile(const LLUUID& avatar_id);
|
||||
static bool profileVisible(const LLUUID& avatar_id);
|
||||
static bool isPickTabSelected(const LLUUID& avatar_id);
|
||||
static LLFloater* getProfileFloater(const LLUUID& avatar_id);
|
||||
|
||||
/**
|
||||
* Show avatar on world map.
|
||||
|
|
@ -126,9 +135,10 @@ public:
|
|||
static void shareWithAvatars(LLView * panel);
|
||||
|
||||
/**
|
||||
* Block/unblock the avatar.
|
||||
* Block/unblock the avatar by id.
|
||||
* Returns true if blocked, returns false if unblocked
|
||||
*/
|
||||
static void toggleBlock(const LLUUID& id);
|
||||
static bool toggleBlock(const LLUUID& id);
|
||||
|
||||
/**
|
||||
* Mute/unmute avatar.
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "llstartup.h"
|
||||
|
||||
// Linden library includes
|
||||
#include "llavataractions.h" // for getProfileUrl
|
||||
#include "lldate.h"
|
||||
#include "lltrans.h"
|
||||
#include "llui.h" // LLUI::getLanguage()
|
||||
|
|
@ -94,54 +95,98 @@ void LLAvatarPropertiesProcessor::removeObserver(const LLUUID& avatar_id, LLAvat
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method)
|
||||
void LLAvatarPropertiesProcessor::sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method)
|
||||
{
|
||||
// this is the startup state when send_complete_agent_movement() message is sent.
|
||||
// Before this messages won't work so don't bother trying
|
||||
if (LLStartUp::getStartupState() <= STATE_AGENT_SEND)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (avatar_id.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Suppress duplicate requests while waiting for a response from the network
|
||||
if (isPendingRequest(avatar_id, type))
|
||||
{
|
||||
// waiting for a response, don't re-request
|
||||
return;
|
||||
}
|
||||
// indicate we're going to make a request
|
||||
addPendingRequest(avatar_id, type);
|
||||
|
||||
std::vector<std::string> strings;
|
||||
strings.push_back( avatar_id.asString() );
|
||||
send_generic_message(method, strings);
|
||||
std::string cap;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case APT_PROPERTIES:
|
||||
// indicate we're going to make a request
|
||||
sendAvatarPropertiesRequestMessage(avatar_id);
|
||||
// can use getRegionCapability("AgentProfile"), but it is heavy
|
||||
// initAgentProfileCapRequest(avatar_id, cap);
|
||||
break;
|
||||
case APT_PICKS:
|
||||
case APT_GROUPS:
|
||||
case APT_NOTES:
|
||||
if (cap.empty())
|
||||
{
|
||||
// indicate we're going to make a request
|
||||
sendGenericRequest(avatar_id, type, method);
|
||||
}
|
||||
else
|
||||
{
|
||||
initAgentProfileCapRequest(avatar_id, cap);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sendGenericRequest(avatar_id, type, method);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method)
|
||||
{
|
||||
// indicate we're going to make a request
|
||||
addPendingRequest(avatar_id, type);
|
||||
|
||||
std::vector<std::string> strings;
|
||||
strings.push_back(avatar_id.asString());
|
||||
send_generic_message(method, strings);
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id)
|
||||
{
|
||||
addPendingRequest(avatar_id, APT_PROPERTIES);
|
||||
|
||||
LLMessageSystem *msg = gMessageSystem;
|
||||
|
||||
msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->addUUIDFast(_PREHASH_AvatarID, avatar_id);
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url)
|
||||
{
|
||||
addPendingRequest(avatar_id, APT_PROPERTIES);
|
||||
addPendingRequest(avatar_id, APT_PICKS);
|
||||
addPendingRequest(avatar_id, APT_GROUPS);
|
||||
addPendingRequest(avatar_id, APT_NOTES);
|
||||
LLCoros::instance().launch("requestAgentUserInfoCoro",
|
||||
boost::bind(requestAvatarPropertiesCoro, cap_url, avatar_id));
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
|
||||
{
|
||||
// this is the startup state when send_complete_agent_movement() message is sent.
|
||||
// Before this, the AvatarPropertiesRequest message
|
||||
// won't work so don't bother trying
|
||||
if (LLStartUp::getStartupState() <= STATE_AGENT_SEND)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPendingRequest(avatar_id, APT_PROPERTIES))
|
||||
{
|
||||
// waiting for a response, don't re-request
|
||||
return;
|
||||
}
|
||||
// indicate we're going to make a request
|
||||
addPendingRequest(avatar_id, APT_PROPERTIES);
|
||||
|
||||
LLMessageSystem *msg = gMessageSystem;
|
||||
|
||||
msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
|
||||
msg->nextBlockFast( _PREHASH_AgentData);
|
||||
msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
msg->addUUIDFast( _PREHASH_AvatarID, avatar_id);
|
||||
gAgent.sendReliableMessage();
|
||||
sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest");
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id)
|
||||
{
|
||||
sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
|
||||
sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendAvatarNotesRequest(const LLUUID& avatar_id)
|
||||
|
|
@ -174,7 +219,7 @@ void LLAvatarPropertiesProcessor::sendAvatarPropertiesUpdate(const LLAvatarData*
|
|||
return;
|
||||
}
|
||||
|
||||
LL_INFOS() << "Sending avatarinfo update" << LL_ENDL;
|
||||
LL_WARNS() << "Sending avatarinfo update. This trims profile descriptions!!!" << LL_ENDL;
|
||||
|
||||
// This value is required by sendAvatarPropertiesUpdate method.
|
||||
//A profile should never be mature. (From the original code)
|
||||
|
|
@ -266,6 +311,113 @@ bool LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(const LLAvatarData* avata
|
|||
return ((avatar_data->flags & AVATAR_TRANSACTED) || (avatar_data->flags & AVATAR_IDENTIFIED));
|
||||
}
|
||||
|
||||
// static
|
||||
void LLAvatarPropertiesProcessor::requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id)
|
||||
{
|
||||
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
|
||||
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestAvatarPropertiesCoro", httpPolicy));
|
||||
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
|
||||
LLCore::HttpHeaders::ptr_t httpHeaders;
|
||||
|
||||
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
|
||||
httpOpts->setFollowRedirects(true);
|
||||
|
||||
std::string finalUrl = cap_url + "/" + agent_id.asString();
|
||||
|
||||
LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders);
|
||||
|
||||
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
|
||||
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
|
||||
|
||||
if (!status
|
||||
|| !result.has("id")
|
||||
|| agent_id != result["id"].asUUID())
|
||||
{
|
||||
LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL;
|
||||
LLAvatarPropertiesProcessor* self = getInstance();
|
||||
self->removePendingRequest(agent_id, APT_PROPERTIES);
|
||||
self->removePendingRequest(agent_id, APT_PICKS);
|
||||
self->removePendingRequest(agent_id, APT_GROUPS);
|
||||
self->removePendingRequest(agent_id, APT_NOTES);
|
||||
return;
|
||||
}
|
||||
|
||||
// Avatar Data
|
||||
|
||||
LLAvatarData avatar_data;
|
||||
std::string birth_date;
|
||||
|
||||
avatar_data.agent_id = agent_id;
|
||||
avatar_data.avatar_id = agent_id;
|
||||
avatar_data.image_id = result["sl_image_id"].asUUID();
|
||||
avatar_data.fl_image_id = result["fl_image_id"].asUUID();
|
||||
avatar_data.partner_id = result["partner_id"].asUUID();
|
||||
avatar_data.about_text = result["sl_about_text"].asString();
|
||||
avatar_data.fl_about_text = result["fl_about_text"].asString();
|
||||
avatar_data.born_on = result["member_since"].asDate();
|
||||
avatar_data.profile_url = getProfileURL(agent_id.asString());
|
||||
|
||||
avatar_data.flags = 0;
|
||||
avatar_data.caption_index = 0;
|
||||
|
||||
LLAvatarPropertiesProcessor* self = getInstance();
|
||||
// Request processed, no longer pending
|
||||
self->removePendingRequest(agent_id, APT_PROPERTIES);
|
||||
self->notifyObservers(agent_id, &avatar_data, APT_PROPERTIES);
|
||||
|
||||
// Picks
|
||||
|
||||
LLSD picks_array = result["picks"];
|
||||
LLAvatarPicks avatar_picks;
|
||||
avatar_picks.agent_id = agent_id; // Not in use?
|
||||
avatar_picks.target_id = agent_id;
|
||||
|
||||
for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it)
|
||||
{
|
||||
const LLSD& pick_data = *it;
|
||||
avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString());
|
||||
}
|
||||
|
||||
// Request processed, no longer pending
|
||||
self->removePendingRequest(agent_id, APT_PICKS);
|
||||
self->notifyObservers(agent_id, &avatar_picks, APT_PICKS);
|
||||
|
||||
// Groups
|
||||
|
||||
LLSD groups_array = result["groups"];
|
||||
LLAvatarGroups avatar_groups;
|
||||
avatar_groups.agent_id = agent_id; // Not in use?
|
||||
avatar_groups.avatar_id = agent_id; // target_id
|
||||
|
||||
for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it)
|
||||
{
|
||||
const LLSD& group_info = *it;
|
||||
LLAvatarGroups::LLGroupData group_data;
|
||||
group_data.group_powers = 0; // Not in use?
|
||||
group_data.group_title = group_info["name"].asString(); // Missing data, not in use?
|
||||
group_data.group_id = group_info["id"].asUUID();
|
||||
group_data.group_name = group_info["name"].asString();
|
||||
group_data.group_insignia_id = group_info["image_id"].asUUID();
|
||||
|
||||
avatar_groups.group_list.push_back(group_data);
|
||||
}
|
||||
|
||||
self->removePendingRequest(agent_id, APT_GROUPS);
|
||||
self->notifyObservers(agent_id, &avatar_groups, APT_GROUPS);
|
||||
|
||||
// Notes
|
||||
LLAvatarNotes avatar_notes;
|
||||
|
||||
avatar_notes.agent_id = agent_id;
|
||||
avatar_notes.target_id = agent_id;
|
||||
avatar_notes.notes = result["notes"].asString();
|
||||
|
||||
// Request processed, no longer pending
|
||||
self->removePendingRequest(agent_id, APT_NOTES);
|
||||
self->notifyObservers(agent_id, &avatar_notes, APT_NOTES);
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**)
|
||||
{
|
||||
LLAvatarData avatar_data;
|
||||
|
|
@ -312,6 +464,21 @@ void LLAvatarPropertiesProcessor::processAvatarInterestsReply(LLMessageSystem* m
|
|||
That will suppress the warnings and be compatible with old server versions.
|
||||
WARNING: LLTemplateMessageReader::decodeData: Message from 216.82.37.237:13000 with no handler function received: AvatarInterestsReply
|
||||
*/
|
||||
|
||||
LLInterestsData interests_data;
|
||||
|
||||
msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, interests_data.agent_id );
|
||||
msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AvatarID, interests_data.avatar_id );
|
||||
msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_WantToMask, interests_data.want_to_mask );
|
||||
msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_WantToText, interests_data.want_to_text );
|
||||
msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_SkillsMask, interests_data.skills_mask );
|
||||
msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_SkillsText, interests_data.skills_text );
|
||||
msg->getString( _PREHASH_PropertiesData, _PREHASH_LanguagesText, interests_data.languages_text );
|
||||
|
||||
LLAvatarPropertiesProcessor* self = getInstance();
|
||||
// Request processed, no longer pending
|
||||
self->removePendingRequest(interests_data.avatar_id, APT_INTERESTS_INFO);
|
||||
self->notifyObservers(interests_data.avatar_id, &interests_data, APT_INTERESTS_INFO);
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem* msg, void**)
|
||||
|
|
@ -385,7 +552,7 @@ void LLAvatarPropertiesProcessor::processAvatarNotesReply(LLMessageSystem* msg,
|
|||
void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg, void**)
|
||||
{
|
||||
LLAvatarPicks avatar_picks;
|
||||
msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.target_id);
|
||||
msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.agent_id);
|
||||
msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id);
|
||||
|
||||
S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
|
||||
|
|
@ -551,6 +718,29 @@ void LLAvatarPropertiesProcessor::sendClassifiedDelete(const LLUUID& classified_
|
|||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendInterestsInfoUpdate(const LLInterestsData* interests_data)
|
||||
{
|
||||
if(!interests_data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
||||
msg->newMessage(_PREHASH_AvatarInterestsUpdate);
|
||||
msg->nextBlockFast( _PREHASH_AgentData);
|
||||
msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
|
||||
msg->addUUIDFast( _PREHASH_SessionID, gAgent.getSessionID() );
|
||||
msg->nextBlockFast( _PREHASH_PropertiesData);
|
||||
msg->addU32Fast( _PREHASH_WantToMask, interests_data->want_to_mask);
|
||||
msg->addStringFast( _PREHASH_WantToText, interests_data->want_to_text);
|
||||
msg->addU32Fast( _PREHASH_SkillsMask, interests_data->skills_mask);
|
||||
msg->addStringFast( _PREHASH_SkillsText, interests_data->skills_text);
|
||||
msg->addString( _PREHASH_LanguagesText, interests_data->languages_text);
|
||||
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick)
|
||||
{
|
||||
if (!new_pick) return;
|
||||
|
|
|
|||
|
|
@ -56,10 +56,22 @@ enum EAvatarProcessorType
|
|||
APT_PICKS,
|
||||
APT_PICK_INFO,
|
||||
APT_TEXTURES,
|
||||
APT_INTERESTS_INFO,
|
||||
APT_CLASSIFIEDS,
|
||||
APT_CLASSIFIED_INFO
|
||||
};
|
||||
|
||||
struct LLInterestsData
|
||||
{
|
||||
LLUUID agent_id;
|
||||
LLUUID avatar_id; //target id
|
||||
U32 want_to_mask;
|
||||
std::string want_to_text;
|
||||
U32 skills_mask;
|
||||
std::string skills_text;
|
||||
std::string languages_text;
|
||||
};
|
||||
|
||||
struct LLAvatarData
|
||||
{
|
||||
LLUUID agent_id;
|
||||
|
|
@ -223,6 +235,8 @@ public:
|
|||
|
||||
void sendClassifiedDelete(const LLUUID& classified_id);
|
||||
|
||||
void sendInterestsInfoUpdate(const LLInterestsData* interests_data);
|
||||
|
||||
// Returns translated, human readable string for account type, such
|
||||
// as "Resident" or "Linden Employee". Used for profiles, inspectors.
|
||||
static std::string accountType(const LLAvatarData* avatar_data);
|
||||
|
|
@ -234,6 +248,8 @@ public:
|
|||
|
||||
static bool hasPaymentInfoOnFile(const LLAvatarData* avatar_data);
|
||||
|
||||
static void requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id);
|
||||
|
||||
static void processAvatarPropertiesReply(LLMessageSystem* msg, void**);
|
||||
|
||||
static void processAvatarInterestsReply(LLMessageSystem* msg, void**);
|
||||
|
|
@ -252,7 +268,10 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method);
|
||||
void sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
|
||||
void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
|
||||
void sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id);
|
||||
void initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url);
|
||||
|
||||
void notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type);
|
||||
|
||||
|
|
|
|||
|
|
@ -640,6 +640,7 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
|
|||
if(mBuddyInfo.find(agent_related) != mBuddyInfo.end())
|
||||
{
|
||||
(mBuddyInfo[agent_related])->setRightsTo(new_rights);
|
||||
mChangedBuddyIDs.insert(agent_related);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ LLFloaterChatVoiceVolume::LLFloaterChatVoiceVolume(const LLSD& key)
|
|||
void LLFloaterChatVoiceVolume::onOpen(const LLSD& key)
|
||||
{
|
||||
LLInspect::onOpen(key);
|
||||
LLUI::getInstance()->positionViewNearMouse(this);
|
||||
LLInspect::repositionInspector(key);
|
||||
}
|
||||
|
||||
LLFloaterChatVoiceVolume::~LLFloaterChatVoiceVolume()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* @file llfloaterclassified.cpp
|
||||
* @brief LLFloaterClassified for displaying classifieds.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llfloaterclassified.h"
|
||||
|
||||
LLFloaterClassified::LLFloaterClassified(const LLSD& key)
|
||||
: LLFloater(key)
|
||||
{
|
||||
}
|
||||
|
||||
LLFloaterClassified::~LLFloaterClassified()
|
||||
{
|
||||
}
|
||||
|
||||
void LLFloaterClassified::onOpen(const LLSD& key)
|
||||
{
|
||||
LLPanel* panel = findChild<LLPanel>("main_panel", true);
|
||||
if (panel)
|
||||
{
|
||||
panel->onOpen(key);
|
||||
}
|
||||
if (key.has("classified_name"))
|
||||
{
|
||||
setTitle(key["classified_name"].asString());
|
||||
}
|
||||
LLFloater::onOpen(key);
|
||||
}
|
||||
|
||||
BOOL LLFloaterClassified::postBuild()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
bool LLFloaterClassified::matchesKey(const LLSD& key)
|
||||
{
|
||||
bool is_mkey_valid = mKey.has("classified_id");
|
||||
bool is_key_valid = key.has("classified_id");
|
||||
if (is_mkey_valid && is_key_valid)
|
||||
{
|
||||
return key["classified_id"].asUUID() == mKey["classified_id"].asUUID();
|
||||
}
|
||||
return is_mkey_valid == is_key_valid;
|
||||
}
|
||||
|
||||
// eof
|
||||
|
|
@ -1,59 +1,45 @@
|
|||
/**
|
||||
* @file llfloaterwebprofile.h
|
||||
* @brief Avatar profile floater.
|
||||
/**
|
||||
* @file llfloaterclassified.h
|
||||
* @brief LLFloaterClassified for displaying classifieds.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* Copyright (C) 2022, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFLOATERWEBPROFILE_H
|
||||
#define LL_LLFLOATERWEBPROFILE_H
|
||||
#ifndef LL_LLFLOATERCLASSIFIED_H
|
||||
#define LL_LLFLOATERCLASSIFIED_H
|
||||
|
||||
#include "llfloaterwebcontent.h"
|
||||
#include "llviewermediaobserver.h"
|
||||
#include "llfloater.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class LLMediaCtrl;
|
||||
|
||||
/**
|
||||
* Displays avatar profile web page.
|
||||
*/
|
||||
class LLFloaterWebProfile
|
||||
: public LLFloaterWebContent
|
||||
class LLFloaterClassified : public LLFloater
|
||||
{
|
||||
LOG_CLASS(LLFloaterWebProfile);
|
||||
LOG_CLASS(LLFloaterClassified);
|
||||
public:
|
||||
typedef LLFloaterWebContent::Params Params;
|
||||
LLFloaterClassified(const LLSD& key);
|
||||
virtual ~LLFloaterClassified();
|
||||
|
||||
LLFloaterWebProfile(const Params& key);
|
||||
void onOpen(const LLSD& key) override;
|
||||
BOOL postBuild() override;
|
||||
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
/*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
|
||||
|
||||
static LLFloater* create(const LLSD& key);
|
||||
|
||||
private:
|
||||
void applyPreferredRect();
|
||||
bool matchesKey(const LLSD& key) override;
|
||||
};
|
||||
|
||||
#endif // LL_LLFLOATERWEBPROFILE_H
|
||||
|
||||
#endif // LL_LLFLOATERCLASSIFIED_H
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
/**
|
||||
* @file llfloaterdisplayname.cpp
|
||||
* @author Leyla Farazha
|
||||
* @brief Implementation of the LLFloaterDisplayName class.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloater.h"
|
||||
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llviewerdisplayname.h"
|
||||
|
||||
#include "llnotifications.h"
|
||||
#include "llfloaterdisplayname.h"
|
||||
#include "llavatarnamecache.h"
|
||||
|
||||
#include "llagent.h"
|
||||
|
||||
|
||||
class LLFloaterDisplayName : public LLFloater
|
||||
{
|
||||
public:
|
||||
LLFloaterDisplayName(const LLSD& key);
|
||||
virtual ~LLFloaterDisplayName() { }
|
||||
/*virtual*/ BOOL postBuild();
|
||||
void onSave();
|
||||
void onCancel();
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
|
||||
private:
|
||||
|
||||
void onCacheSetName(bool success,
|
||||
const std::string& reason,
|
||||
const LLSD& content);
|
||||
};
|
||||
|
||||
LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) :
|
||||
LLFloater(key)
|
||||
{
|
||||
}
|
||||
|
||||
void LLFloaterDisplayName::onOpen(const LLSD& key)
|
||||
{
|
||||
getChild<LLUICtrl>("display_name_editor")->clear();
|
||||
getChild<LLUICtrl>("display_name_confirm")->clear();
|
||||
|
||||
LLAvatarName av_name;
|
||||
LLAvatarNameCache::get(gAgent.getID(), &av_name);
|
||||
|
||||
F64 now_secs = LLDate::now().secondsSinceEpoch();
|
||||
|
||||
if (now_secs < av_name.mNextUpdate)
|
||||
{
|
||||
// ...can't update until some time in the future
|
||||
F64 next_update_local_secs =
|
||||
av_name.mNextUpdate - LLStringOps::getLocalTimeOffset();
|
||||
LLDate next_update_local(next_update_local_secs);
|
||||
// display as "July 18 12:17 PM"
|
||||
std::string next_update_string =
|
||||
next_update_local.toHTTPDateString("%B %d %I:%M %p");
|
||||
getChild<LLUICtrl>("lockout_text")->setTextArg("[TIME]", next_update_string);
|
||||
getChild<LLUICtrl>("lockout_text")->setVisible(true);
|
||||
getChild<LLUICtrl>("save_btn")->setEnabled(false);
|
||||
getChild<LLUICtrl>("display_name_editor")->setEnabled(false);
|
||||
getChild<LLUICtrl>("display_name_confirm")->setEnabled(false);
|
||||
getChild<LLUICtrl>("cancel_btn")->setFocus(TRUE);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("lockout_text")->setVisible(false);
|
||||
getChild<LLUICtrl>("save_btn")->setEnabled(true);
|
||||
getChild<LLUICtrl>("display_name_editor")->setEnabled(true);
|
||||
getChild<LLUICtrl>("display_name_confirm")->setEnabled(true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLFloaterDisplayName::postBuild()
|
||||
{
|
||||
getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onCancel, this));
|
||||
getChild<LLUICtrl>("save_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onSave, this));
|
||||
|
||||
center();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterDisplayName::onCacheSetName(bool success,
|
||||
const std::string& reason,
|
||||
const LLSD& content)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
// Inform the user that the change took place, but will take a while
|
||||
// to percolate.
|
||||
LLSD args;
|
||||
args["DISPLAY_NAME"] = content["display_name"];
|
||||
LLNotificationsUtil::add("SetDisplayNameSuccess", args);
|
||||
return;
|
||||
}
|
||||
|
||||
// Request failed, notify the user
|
||||
std::string error_tag = content["error_tag"].asString();
|
||||
LL_INFOS() << "set name failure error_tag " << error_tag << LL_ENDL;
|
||||
|
||||
// We might have a localized string for this message
|
||||
// error_args will usually be empty from the server.
|
||||
if (!error_tag.empty()
|
||||
&& LLNotifications::getInstance()->templateExists(error_tag))
|
||||
{
|
||||
LLNotificationsUtil::add(error_tag);
|
||||
return;
|
||||
}
|
||||
|
||||
// The server error might have a localized message for us
|
||||
std::string lang_code = LLUI::getLanguage();
|
||||
LLSD error_desc = content["error_description"];
|
||||
if (error_desc.has( lang_code ))
|
||||
{
|
||||
LLSD args;
|
||||
args["MESSAGE"] = error_desc[lang_code].asString();
|
||||
LLNotificationsUtil::add("GenericAlert", args);
|
||||
return;
|
||||
}
|
||||
|
||||
// No specific error, throw a generic one
|
||||
LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
|
||||
}
|
||||
|
||||
void LLFloaterDisplayName::onCancel()
|
||||
{
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
void LLFloaterDisplayName::onSave()
|
||||
{
|
||||
std::string display_name_utf8 = getChild<LLUICtrl>("display_name_editor")->getValue().asString();
|
||||
std::string display_name_confirm = getChild<LLUICtrl>("display_name_confirm")->getValue().asString();
|
||||
|
||||
if (display_name_utf8.compare(display_name_confirm))
|
||||
{
|
||||
LLNotificationsUtil::add("SetDisplayNameMismatch");
|
||||
return;
|
||||
}
|
||||
|
||||
const U32 DISPLAY_NAME_MAX_LENGTH = 31; // characters, not bytes
|
||||
LLWString display_name_wstr = utf8string_to_wstring(display_name_utf8);
|
||||
if (display_name_wstr.size() > DISPLAY_NAME_MAX_LENGTH)
|
||||
{
|
||||
LLSD args;
|
||||
args["LENGTH"] = llformat("%d", DISPLAY_NAME_MAX_LENGTH);
|
||||
LLNotificationsUtil::add("SetDisplayNameFailedLength", args);
|
||||
return;
|
||||
}
|
||||
|
||||
if (LLAvatarNameCache::getInstance()->hasNameLookupURL())
|
||||
{
|
||||
LLViewerDisplayName::set(display_name_utf8,boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
|
||||
}
|
||||
else
|
||||
{
|
||||
LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
|
||||
}
|
||||
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// LLInspectObjectUtil
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void LLFloaterDisplayNameUtil::registerFloater()
|
||||
{
|
||||
LLFloaterReg::add("display_name", "floater_display_name.xml",
|
||||
&LLFloaterReg::build<LLFloaterDisplayName>);
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
/**
|
||||
* @file llpanelme.h
|
||||
* @brief Side tray "Me" (My Profile) panel
|
||||
* @file llfloaterdisplayname.h
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
|
|
@ -24,27 +23,16 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLPANELMEPROFILE_H
|
||||
#define LL_LLPANELMEPROFILE_H
|
||||
#ifndef LLFLOATERDISPLAYNAME_H
|
||||
#define LLFLOATERDISPLAYNAME_H
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "llpanelprofile.h"
|
||||
|
||||
/**
|
||||
* Panel for displaying Agent's Picks and Classifieds panel.
|
||||
* LLPanelMe allows user to edit his picks and classifieds.
|
||||
*/
|
||||
class LLPanelMe : public LLPanelProfile
|
||||
namespace LLFloaterDisplayNameUtil
|
||||
{
|
||||
LOG_CLASS(LLPanelMe);
|
||||
// Register with LLFloaterReg
|
||||
void registerFloater();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
LLPanelMe();
|
||||
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELMEPROFILE_H
|
||||
#endif
|
||||
|
|
@ -122,7 +122,7 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key)
|
|||
mObserver = new LLFloaterGestureObserver(this);
|
||||
LLGestureMgr::instance().addObserver(mObserver);
|
||||
|
||||
mCommitCallbackRegistrar.add("Gesture.Action.ToogleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
|
||||
mCommitCallbackRegistrar.add("Gesture.Action.ToggleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
|
||||
mCommitCallbackRegistrar.add("Gesture.Action.ShowPreview", boost::bind(&LLFloaterGesture::onClickEdit, this));
|
||||
mCommitCallbackRegistrar.add("Gesture.Action.CopyPaste", boost::bind(&LLFloaterGesture::onCopyPasteAction, this, _2));
|
||||
mCommitCallbackRegistrar.add("Gesture.Action.SaveToCOF", boost::bind(&LLFloaterGesture::addToCurrentOutFit, this));
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@
|
|||
#include "llviewercontrol.h"
|
||||
#include "lltoolfocus.h"
|
||||
#include "lltoolmgr.h"
|
||||
#include "llwebprofile.h"
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function declarations, constants, enums, and typedefs
|
||||
|
|
|
|||
|
|
@ -333,60 +333,59 @@ void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType t
|
|||
const LLAvatarData* pAvatarData = static_cast<const LLAvatarData*>( pData );
|
||||
if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id != LLUUID::null))
|
||||
{
|
||||
storeAvatarProperties( pAvatarData );
|
||||
processProfileProperties( pAvatarData );
|
||||
mAllowPublish = (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH);
|
||||
mAvatarDataInitialized = true;
|
||||
getChild<LLUICtrl>("online_searchresults")->setValue(mAllowPublish);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterPreference::storeAvatarProperties( const LLAvatarData* pAvatarData )
|
||||
{
|
||||
if (LLStartUp::getStartupState() == STATE_STARTED)
|
||||
{
|
||||
mAvatarProperties.avatar_id = pAvatarData->avatar_id;
|
||||
mAvatarProperties.image_id = pAvatarData->image_id;
|
||||
mAvatarProperties.fl_image_id = pAvatarData->fl_image_id;
|
||||
mAvatarProperties.about_text = pAvatarData->about_text;
|
||||
mAvatarProperties.fl_about_text = pAvatarData->fl_about_text;
|
||||
mAvatarProperties.profile_url = pAvatarData->profile_url;
|
||||
mAvatarProperties.flags = pAvatarData->flags;
|
||||
mAvatarProperties.allow_publish = pAvatarData->flags & AVATAR_ALLOW_PUBLISH;
|
||||
|
||||
mAvatarDataInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterPreference::processProfileProperties(const LLAvatarData* pAvatarData )
|
||||
{
|
||||
getChild<LLUICtrl>("online_searchresults")->setValue( (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH) );
|
||||
}
|
||||
|
||||
void LLFloaterPreference::saveAvatarProperties( void )
|
||||
{
|
||||
const BOOL allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue();
|
||||
const bool allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue();
|
||||
|
||||
if (allowPublish)
|
||||
{
|
||||
mAvatarProperties.flags |= AVATAR_ALLOW_PUBLISH;
|
||||
}
|
||||
if ((LLStartUp::getStartupState() == STATE_STARTED)
|
||||
&& mAvatarDataInitialized
|
||||
&& (allowPublish != mAllowPublish))
|
||||
{
|
||||
std::string cap_url = gAgent.getRegionCapability("AgentProfile");
|
||||
if (!cap_url.empty())
|
||||
{
|
||||
mAllowPublish = allowPublish;
|
||||
|
||||
//
|
||||
// NOTE: We really don't want to send the avatar properties unless we absolutely
|
||||
// need to so we can avoid the accidental profile reset bug, so, if we're
|
||||
// logged in, the avatar data has been initialized and we have a state change
|
||||
// for the "allow publish" flag, then set the flag to its new value and send
|
||||
// the properties update.
|
||||
//
|
||||
// NOTE: The only reason we can not remove this update altogether is because of the
|
||||
// "allow publish" flag, the last remaining profile setting in the viewer
|
||||
// that doesn't exist in the web profile.
|
||||
//
|
||||
if ((LLStartUp::getStartupState() == STATE_STARTED) && mAvatarDataInitialized && (allowPublish != mAvatarProperties.allow_publish))
|
||||
{
|
||||
mAvatarProperties.allow_publish = allowPublish;
|
||||
LLCoros::instance().launch("requestAgentUserInfoCoro",
|
||||
boost::bind(saveAvatarPropertiesCoro, cap_url, allowPublish));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate( &mAvatarProperties );
|
||||
}
|
||||
void LLFloaterPreference::saveAvatarPropertiesCoro(const std::string cap_url, bool allow_publish)
|
||||
{
|
||||
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
|
||||
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy));
|
||||
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
|
||||
LLCore::HttpHeaders::ptr_t httpHeaders;
|
||||
|
||||
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
|
||||
httpOpts->setFollowRedirects(true);
|
||||
|
||||
std::string finalUrl = cap_url + "/" + gAgentID.asString();
|
||||
LLSD data;
|
||||
data["allow_publish"] = allow_publish;
|
||||
|
||||
LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders);
|
||||
|
||||
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
|
||||
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
LL_WARNS("Preferences") << "Failed to put agent information " << data << " for id " << gAgentID << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LL_DEBUGS("Preferences") << "Agent id: " << gAgentID << " Data: " << data << " Result: " << httpResults << LL_ENDL;
|
||||
}
|
||||
|
||||
BOOL LLFloaterPreference::postBuild()
|
||||
|
|
@ -938,7 +937,7 @@ void LLFloaterPreference::onBtnOK(const LLSD& userdata)
|
|||
else
|
||||
{
|
||||
// Show beep, pop up dialog, etc.
|
||||
LL_INFOS() << "Can't close preferences!" << LL_ENDL;
|
||||
LL_INFOS("Preferences") << "Can't close preferences!" << LL_ENDL;
|
||||
}
|
||||
|
||||
LLPanelLogin::updateLocationSelectorsVisibility();
|
||||
|
|
@ -1678,13 +1677,13 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
|
|||
|
||||
if (!LLXMLNode::parseFile(filename, root, NULL))
|
||||
{
|
||||
LL_WARNS() << "Unable to parse file " << filename << LL_ENDL;
|
||||
LL_WARNS("Preferences") << "Unable to parse file " << filename << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!root->hasName("labels"))
|
||||
{
|
||||
LL_WARNS() << filename << " is not a valid definition file" << LL_ENDL;
|
||||
LL_WARNS("Preferences") << filename << " is not a valid definition file" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1704,7 +1703,7 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
|
|||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << filename << " failed to load" << LL_ENDL;
|
||||
LL_WARNS("Preferences") << filename << " failed to load" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2610,7 +2609,7 @@ bool LLPanelPreferenceControls::addControlTableColumns(const std::string &filena
|
|||
LLScrollListCtrl::Contents contents;
|
||||
if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
|
||||
{
|
||||
LL_WARNS() << "Failed to load " << filename << LL_ENDL;
|
||||
LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
LLXUIParser parser;
|
||||
|
|
@ -2637,7 +2636,7 @@ bool LLPanelPreferenceControls::addControlTableRows(const std::string &filename)
|
|||
LLScrollListCtrl::Contents contents;
|
||||
if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
|
||||
{
|
||||
LL_WARNS() << "Failed to load " << filename << LL_ENDL;
|
||||
LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
LLXUIParser parser;
|
||||
|
|
@ -2743,7 +2742,7 @@ void LLPanelPreferenceControls::populateControlTable()
|
|||
{
|
||||
// Either unknown mode or MODE_SAVED_SETTINGS
|
||||
// It doesn't have UI or actual settings yet
|
||||
LL_WARNS() << "Unimplemented mode" << LL_ENDL;
|
||||
LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
|
||||
|
||||
// Searchable columns were removed, mark searchables for an update
|
||||
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
|
||||
|
|
@ -2783,7 +2782,7 @@ void LLPanelPreferenceControls::populateControlTable()
|
|||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "Unimplemented mode" << LL_ENDL;
|
||||
LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
|
||||
}
|
||||
|
||||
// explicit update to make sure table is ready for llsearchableui
|
||||
|
|
|
|||
|
|
@ -100,9 +100,8 @@ public:
|
|||
static void updateShowFavoritesCheckbox(bool val);
|
||||
|
||||
void processProperties( void* pData, EAvatarProcessorType type );
|
||||
void processProfileProperties(const LLAvatarData* pAvatarData );
|
||||
void storeAvatarProperties( const LLAvatarData* pAvatarData );
|
||||
void saveAvatarProperties( void );
|
||||
static void saveAvatarPropertiesCoro(const std::string url, bool allow_publish);
|
||||
void selectPrivacyPanel();
|
||||
void selectChatPanel();
|
||||
void getControlNames(std::vector<std::string>& names);
|
||||
|
|
@ -213,7 +212,7 @@ private:
|
|||
bool mOriginalHideOnlineStatus;
|
||||
std::string mDirectoryVisibility;
|
||||
|
||||
LLAvatarData mAvatarProperties;
|
||||
bool mAllowPublish; // Allow showing agent in search
|
||||
std::string mSavedCameraPreset;
|
||||
std::string mSavedGraphicsPreset;
|
||||
LOG_CLASS(LLFloaterPreference);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,170 @@
|
|||
/**
|
||||
* @file llfloaterprofile.cpp
|
||||
* @brief Avatar profile floater.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llfloaterprofile.h"
|
||||
|
||||
#include "llagent.h" //gAgent
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llpanelavatar.h"
|
||||
#include "llpanelprofile.h"
|
||||
|
||||
static const std::string PANEL_PROFILE_VIEW = "panel_profile_view";
|
||||
|
||||
LLFloaterProfile::LLFloaterProfile(const LLSD& key)
|
||||
: LLFloater(key),
|
||||
mAvatarId(key["id"].asUUID()),
|
||||
mNameCallbackConnection()
|
||||
{
|
||||
mDefaultRectForGroup = false;
|
||||
}
|
||||
|
||||
LLFloaterProfile::~LLFloaterProfile()
|
||||
{
|
||||
if (mNameCallbackConnection.connected())
|
||||
{
|
||||
mNameCallbackConnection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterProfile::onOpen(const LLSD& key)
|
||||
{
|
||||
mPanelProfile->onOpen(key);
|
||||
|
||||
// Update the avatar name.
|
||||
mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2));
|
||||
}
|
||||
|
||||
BOOL LLFloaterProfile::postBuild()
|
||||
{
|
||||
mPanelProfile = findChild<LLPanelProfile>(PANEL_PROFILE_VIEW);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterProfile::onClickCloseBtn(bool app_quitting)
|
||||
{
|
||||
if (!app_quitting)
|
||||
{
|
||||
if (mPanelProfile->hasUnpublishedClassifieds())
|
||||
{
|
||||
LLNotificationsUtil::add("ProfileUnpublishedClassified", LLSD(), LLSD(),
|
||||
boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, false));
|
||||
}
|
||||
else if (mPanelProfile->hasUnsavedChanges())
|
||||
{
|
||||
LLNotificationsUtil::add("ProfileUnsavedChanges", LLSD(), LLSD(),
|
||||
boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
closeFloater();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
closeFloater();
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterProfile::onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (can_save)
|
||||
{
|
||||
// savable content
|
||||
|
||||
if (option == 0) // Save
|
||||
{
|
||||
mPanelProfile->commitUnsavedChanges();
|
||||
closeFloater();
|
||||
}
|
||||
if (option == 1) // Discard
|
||||
{
|
||||
closeFloater();
|
||||
}
|
||||
// else cancel
|
||||
}
|
||||
else
|
||||
{
|
||||
// classifieds
|
||||
|
||||
if (option == 0) // Ok
|
||||
{
|
||||
closeFloater();
|
||||
}
|
||||
// else cancel
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLFloaterProfile::createPick(const LLPickData &data)
|
||||
{
|
||||
mPanelProfile->createPick(data);
|
||||
}
|
||||
|
||||
void LLFloaterProfile::showPick(const LLUUID& pick_id)
|
||||
{
|
||||
mPanelProfile->showPick(pick_id);
|
||||
}
|
||||
|
||||
bool LLFloaterProfile::isPickTabSelected()
|
||||
{
|
||||
return mPanelProfile->isPickTabSelected();
|
||||
}
|
||||
|
||||
void LLFloaterProfile::refreshName()
|
||||
{
|
||||
if (!mNameCallbackConnection.connected())
|
||||
{
|
||||
mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2));
|
||||
}
|
||||
|
||||
LLPanelProfileSecondLife *panel = findChild<LLPanelProfileSecondLife>("panel_profile_secondlife");
|
||||
if (panel)
|
||||
{
|
||||
panel->refreshName();
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterProfile::showClassified(const LLUUID& classified_id, bool edit)
|
||||
{
|
||||
mPanelProfile->showClassified(classified_id, edit);
|
||||
}
|
||||
|
||||
void LLFloaterProfile::createClassified()
|
||||
{
|
||||
mPanelProfile->createClassified();
|
||||
}
|
||||
|
||||
void LLFloaterProfile::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
|
||||
{
|
||||
mNameCallbackConnection.disconnect();
|
||||
setTitle(av_name.getCompleteName());
|
||||
}
|
||||
|
||||
// eof
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* @file llfloaterprofile.h
|
||||
* @brief Avatar profile floater.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFLOATERPROFILE_H
|
||||
#define LL_LLFLOATERPROFILE_H
|
||||
|
||||
#include "llavatarnamecache.h"
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
#include "llfloater.h"
|
||||
|
||||
class LLPanelProfile;
|
||||
|
||||
class LLFloaterProfile : public LLFloater
|
||||
{
|
||||
LOG_CLASS(LLFloaterProfile);
|
||||
public:
|
||||
LLFloaterProfile(const LLSD& key);
|
||||
virtual ~LLFloaterProfile();
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void onOpen(const LLSD& key) override;
|
||||
void onClickCloseBtn(bool app_quitting = false) override;
|
||||
void onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save);
|
||||
|
||||
void createPick(const LLPickData &data);
|
||||
void showPick(const LLUUID& pick_id = LLUUID::null);
|
||||
bool isPickTabSelected();
|
||||
void refreshName();
|
||||
|
||||
void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false);
|
||||
void createClassified();
|
||||
|
||||
private:
|
||||
LLAvatarNameCache::callback_connection_t mNameCallbackConnection;
|
||||
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
|
||||
|
||||
LLPanelProfile* mPanelProfile;
|
||||
|
||||
LLUUID mAvatarId;
|
||||
};
|
||||
|
||||
#endif // LL_LLFLOATERPROFILE_H
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
/**
|
||||
* @file llfloaterprofiletexture.cpp
|
||||
* @brief LLFloaterProfileTexture class implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llfloaterprofiletexture.h"
|
||||
|
||||
#include "llbutton.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llpreview.h" // fors constants
|
||||
#include "lltrans.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "lltextureview.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "llviewertexturelist.h"
|
||||
|
||||
|
||||
|
||||
LLFloaterProfileTexture::LLFloaterProfileTexture(LLView* owner)
|
||||
: LLFloater(LLSD())
|
||||
, mUpdateDimensions(TRUE)
|
||||
, mLastHeight(0)
|
||||
, mLastWidth(0)
|
||||
, mImage(NULL)
|
||||
, mImageOldBoostLevel(LLGLTexture::BOOST_NONE)
|
||||
, mOwnerHandle(owner->getHandle())
|
||||
{
|
||||
buildFromFile("floater_profile_texture.xml");
|
||||
}
|
||||
|
||||
LLFloaterProfileTexture::~LLFloaterProfileTexture()
|
||||
{
|
||||
if (mImage.notNull())
|
||||
{
|
||||
mImage->setBoostLevel(mImageOldBoostLevel);
|
||||
mImage = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLFloaterProfileTexture::postBuild()
|
||||
{
|
||||
mProfileIcon = getChild<LLIconCtrl>("profile_pic");
|
||||
|
||||
mCloseButton = getChild<LLButton>("close_btn");
|
||||
mCloseButton->setCommitCallback([this](LLUICtrl*, void*) { closeFloater(); }, nullptr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLFloaterProfileTexture::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
LLFloater::reshape(width, height, called_from_parent);
|
||||
}
|
||||
|
||||
// It takes a while until we get height and width information.
|
||||
// When we receive it, reshape the window accordingly.
|
||||
void LLFloaterProfileTexture::updateDimensions()
|
||||
{
|
||||
if (mImage.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
S32 img_width = mImage->getFullWidth();
|
||||
S32 img_height = mImage->getFullHeight();
|
||||
|
||||
if (mAssetStatus != LLPreview::PREVIEW_ASSET_LOADED
|
||||
|| mLastWidth != img_width
|
||||
|| mLastHeight != img_height)
|
||||
{
|
||||
mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
|
||||
// Asset has been fully loaded
|
||||
mUpdateDimensions = TRUE;
|
||||
}
|
||||
|
||||
mLastHeight = img_height;
|
||||
mLastWidth = img_width;
|
||||
|
||||
// Reshape the floater only when required
|
||||
if (mUpdateDimensions)
|
||||
{
|
||||
mUpdateDimensions = FALSE;
|
||||
|
||||
LLRect old_floater_rect = getRect();
|
||||
LLRect old_image_rect = mProfileIcon->getRect();
|
||||
S32 width = old_floater_rect.getWidth() - old_image_rect.getWidth() + mLastWidth;
|
||||
S32 height = old_floater_rect.getHeight() - old_image_rect.getHeight() + mLastHeight;
|
||||
|
||||
const F32 MAX_DIMENTIONS = 512; // most profiles are supposed to be 256x256
|
||||
|
||||
S32 biggest_dim = llmax(width, height);
|
||||
if (biggest_dim > MAX_DIMENTIONS)
|
||||
{
|
||||
F32 scale_down = MAX_DIMENTIONS / (F32)biggest_dim;
|
||||
width *= scale_down;
|
||||
height *= scale_down;
|
||||
}
|
||||
|
||||
//reshape floater
|
||||
reshape(width, height);
|
||||
|
||||
gFloaterView->adjustToFitScreen(this, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterProfileTexture::draw()
|
||||
{
|
||||
// drawFrustum
|
||||
LLView *owner = mOwnerHandle.get();
|
||||
static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
|
||||
drawConeToOwner(mContextConeOpacity, max_opacity, owner);
|
||||
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
||||
void LLFloaterProfileTexture::onOpen(const LLSD& key)
|
||||
{
|
||||
mCloseButton->setFocus(true);
|
||||
}
|
||||
|
||||
void LLFloaterProfileTexture::resetAsset()
|
||||
{
|
||||
mProfileIcon->setValue("Generic_Person_Large");
|
||||
mImageID = LLUUID::null;
|
||||
if (mImage.notNull())
|
||||
{
|
||||
mImage->setBoostLevel(mImageOldBoostLevel);
|
||||
mImage = NULL;
|
||||
}
|
||||
}
|
||||
void LLFloaterProfileTexture::loadAsset(const LLUUID &image_id)
|
||||
{
|
||||
if (mImageID != image_id)
|
||||
{
|
||||
if (mImage.notNull())
|
||||
{
|
||||
mImage->setBoostLevel(mImageOldBoostLevel);
|
||||
mImage = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mProfileIcon->setValue(image_id);
|
||||
mImageID = image_id;
|
||||
mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
|
||||
mImageOldBoostLevel = mImage->getBoostLevel();
|
||||
|
||||
if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
|
||||
{
|
||||
mImage->setLoadedCallback(LLFloaterProfileTexture::onTextureLoaded,
|
||||
0, TRUE, FALSE, new LLHandle<LLFloater>(getHandle()), &mCallbackTextureList);
|
||||
|
||||
mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
|
||||
mAssetStatus = LLPreview::PREVIEW_ASSET_LOADING;
|
||||
}
|
||||
else
|
||||
{
|
||||
mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
|
||||
}
|
||||
|
||||
mUpdateDimensions = TRUE;
|
||||
updateDimensions();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterProfileTexture::onTextureLoaded(
|
||||
BOOL success,
|
||||
LLViewerFetchedTexture *src_vi,
|
||||
LLImageRaw* src,
|
||||
LLImageRaw* aux_src,
|
||||
S32 discard_level,
|
||||
BOOL final,
|
||||
void* userdata)
|
||||
{
|
||||
LLHandle<LLFloater>* handle = (LLHandle<LLFloater>*)userdata;
|
||||
|
||||
if (!handle->isDead())
|
||||
{
|
||||
LLFloaterProfileTexture* floater = static_cast<LLFloaterProfileTexture*>(handle->get());
|
||||
if (floater && success)
|
||||
{
|
||||
floater->mUpdateDimensions = TRUE;
|
||||
floater->updateDimensions();
|
||||
}
|
||||
}
|
||||
|
||||
if (final || !success)
|
||||
{
|
||||
delete handle;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* @file llfloaterprofiletexture.h
|
||||
* @brief LLFloaterProfileTexture class definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFLOATERPROFILETEXTURE_H
|
||||
#define LL_LLFLOATERPROFILETEXTURE_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llviewertexture.h"
|
||||
|
||||
class LLButton;
|
||||
class LLImageRaw;
|
||||
class LLIconCtrl;
|
||||
|
||||
class LLFloaterProfileTexture : public LLFloater
|
||||
{
|
||||
public:
|
||||
LLFloaterProfileTexture(LLView* owner);
|
||||
~LLFloaterProfileTexture();
|
||||
|
||||
void draw() override;
|
||||
void onOpen(const LLSD& key) override;
|
||||
|
||||
void resetAsset();
|
||||
void loadAsset(const LLUUID &image_id);
|
||||
|
||||
|
||||
static void onTextureLoaded(
|
||||
BOOL success,
|
||||
LLViewerFetchedTexture *src_vi,
|
||||
LLImageRaw* src,
|
||||
LLImageRaw* aux_src,
|
||||
S32 discard_level,
|
||||
BOOL final,
|
||||
void* userdata);
|
||||
|
||||
void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
|
||||
protected:
|
||||
BOOL postBuild() override;
|
||||
|
||||
private:
|
||||
void updateDimensions();
|
||||
|
||||
LLUUID mImageID;
|
||||
LLPointer<LLViewerFetchedTexture> mImage;
|
||||
S32 mImageOldBoostLevel;
|
||||
S32 mAssetStatus;
|
||||
F32 mContextConeOpacity;
|
||||
S32 mLastHeight;
|
||||
S32 mLastWidth;
|
||||
BOOL mUpdateDimensions;
|
||||
|
||||
LLHandle<LLView> mOwnerHandle;
|
||||
LLIconCtrl* mProfileIcon;
|
||||
LLButton* mCloseButton;
|
||||
|
||||
LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList;
|
||||
};
|
||||
#endif // LL_LLFLOATERPROFILETEXTURE_H
|
||||
|
|
@ -127,7 +127,7 @@ void LLFloaterVoiceVolume::onOpen(const LLSD& data)
|
|||
// Extract appropriate avatar id
|
||||
mAvatarID = data["avatar_id"];
|
||||
|
||||
LLUI::getInstance()->positionViewNearMouse(this);
|
||||
LLInspect::repositionInspector(data);
|
||||
|
||||
getChild<LLUICtrl>("avatar_name")->setValue("");
|
||||
updateVolumeControls();
|
||||
|
|
|
|||
|
|
@ -1,81 +0,0 @@
|
|||
/**
|
||||
* @file llfloaterwebprofile.cpp
|
||||
* @brief Avatar profile floater.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llfloaterwebprofile.h"
|
||||
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
LLFloaterWebProfile::LLFloaterWebProfile(const Params& key) :
|
||||
LLFloaterWebContent(key)
|
||||
{
|
||||
}
|
||||
|
||||
void LLFloaterWebProfile::onOpen(const LLSD& key)
|
||||
{
|
||||
Params p(key);
|
||||
p.show_chrome(true);
|
||||
p.window_class("profile");
|
||||
p.allow_address_entry(false);
|
||||
p.trusted_content(true);
|
||||
LLFloaterWebContent::onOpen(p);
|
||||
applyPreferredRect();
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLFloaterWebProfile::handleReshape(const LLRect& new_rect, bool by_user)
|
||||
{
|
||||
LL_DEBUGS() << "handleReshape: " << new_rect << LL_ENDL;
|
||||
|
||||
if (by_user && !isMinimized())
|
||||
{
|
||||
LL_DEBUGS() << "Storing new rect" << LL_ENDL;
|
||||
gSavedSettings.setRect("WebProfileFloaterRect", new_rect);
|
||||
}
|
||||
|
||||
LLFloaterWebContent::handleReshape(new_rect, by_user);
|
||||
}
|
||||
|
||||
LLFloater* LLFloaterWebProfile::create(const LLSD& key)
|
||||
{
|
||||
LLFloaterWebContent::Params p(key);
|
||||
preCreate(p);
|
||||
return new LLFloaterWebProfile(p);
|
||||
}
|
||||
|
||||
void LLFloaterWebProfile::applyPreferredRect()
|
||||
{
|
||||
const LLRect preferred_rect = gSavedSettings.getRect("WebProfileFloaterRect");
|
||||
LL_DEBUGS() << "Applying preferred rect: " << preferred_rect << LL_ENDL;
|
||||
|
||||
// Don't override position that may have been set by floater stacking code.
|
||||
LLRect new_rect = getRect();
|
||||
new_rect.setLeftTopAndSize(
|
||||
new_rect.mLeft, new_rect.mTop,
|
||||
preferred_rect.getWidth(), preferred_rect.getHeight());
|
||||
setShape(new_rect);
|
||||
}
|
||||
|
|
@ -45,7 +45,6 @@
|
|||
#include "llvoiceclient.h"
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
|
||||
S32 LLGroupListItem::sIconWidth = 0;
|
||||
|
||||
class LLGroupComparator : public LLFlatListView::ItemComparator
|
||||
{
|
||||
|
|
@ -65,21 +64,81 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
static const LLGroupComparator GROUP_COMPARATOR;
|
||||
class LLSharedGroupComparator : public LLFlatListView::ItemComparator
|
||||
{
|
||||
public:
|
||||
LLSharedGroupComparator() {};
|
||||
|
||||
/*virtual*/ bool compare(const LLPanel* item1, const LLPanel* item2) const
|
||||
{
|
||||
const LLGroupListItem* group_item1 = static_cast<const LLGroupListItem*>(item1);
|
||||
std::string name1 = group_item1->getGroupName();
|
||||
bool item1_shared = gAgent.isInGroup(group_item1->getGroupID(), true);
|
||||
|
||||
const LLGroupListItem* group_item2 = static_cast<const LLGroupListItem*>(item2);
|
||||
std::string name2 = group_item2->getGroupName();
|
||||
bool item2_shared = gAgent.isInGroup(group_item2->getGroupID(), true);
|
||||
|
||||
if (item2_shared != item1_shared)
|
||||
{
|
||||
return item1_shared;
|
||||
}
|
||||
|
||||
LLStringUtil::toUpper(name1);
|
||||
LLStringUtil::toUpper(name2);
|
||||
|
||||
return name1 < name2;
|
||||
}
|
||||
};
|
||||
|
||||
static LLGroupComparator GROUP_COMPARATOR;
|
||||
static LLSharedGroupComparator SHARED_GROUP_COMPARATOR;
|
||||
|
||||
LLGroupList::Params::Params()
|
||||
: for_agent("for_agent", true)
|
||||
{
|
||||
}
|
||||
|
||||
LLGroupList::LLGroupList(const Params& p)
|
||||
: LLFlatListViewEx(p)
|
||||
, mForAgent(p.for_agent)
|
||||
, mDirty(true) // to force initial update
|
||||
, mShowIcons(false)
|
||||
, mShowNone(true)
|
||||
{
|
||||
// Listen for agent group changes.
|
||||
gAgent.addListener(this, "new group");
|
||||
|
||||
mShowIcons = gSavedSettings.getBOOL("GroupListShowIcons");
|
||||
setCommitOnSelectionChange(true);
|
||||
|
||||
// Set default sort order.
|
||||
setComparator(&GROUP_COMPARATOR);
|
||||
if (mForAgent)
|
||||
{
|
||||
setComparator(&GROUP_COMPARATOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
// shared groups first
|
||||
setComparator(&SHARED_GROUP_COMPARATOR);
|
||||
}
|
||||
|
||||
if (mForAgent)
|
||||
{
|
||||
enableForAgent(true);
|
||||
}
|
||||
}
|
||||
|
||||
LLGroupList::~LLGroupList()
|
||||
{
|
||||
if (mForAgent) gAgent.removeListener(this);
|
||||
if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
|
||||
}
|
||||
|
||||
void LLGroupList::enableForAgent(bool show_icons)
|
||||
{
|
||||
mForAgent = true;
|
||||
|
||||
mShowIcons = mForAgent && gSavedSettings.getBOOL("GroupListShowIcons") && show_icons;
|
||||
|
||||
// Listen for agent group changes.
|
||||
gAgent.addListener(this, "new group");
|
||||
|
||||
// Set up context menu.
|
||||
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
|
||||
|
|
@ -94,12 +153,6 @@ LLGroupList::LLGroupList(const Params& p)
|
|||
mContextMenuHandle = context_menu->getHandle();
|
||||
}
|
||||
|
||||
LLGroupList::~LLGroupList()
|
||||
{
|
||||
gAgent.removeListener(this);
|
||||
if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLGroupList::draw()
|
||||
{
|
||||
|
|
@ -114,12 +167,15 @@ BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
|||
{
|
||||
BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
|
||||
|
||||
LLToggleableMenu* context_menu = mContextMenuHandle.get();
|
||||
if (context_menu && size() > 0)
|
||||
{
|
||||
context_menu->buildDrawLabels();
|
||||
context_menu->updateParent(LLMenuGL::sMenuContainer);
|
||||
LLMenuGL::showPopup(this, context_menu, x, y);
|
||||
if (mForAgent)
|
||||
{
|
||||
LLToggleableMenu* context_menu = mContextMenuHandle.get();
|
||||
if (context_menu && size() > 0)
|
||||
{
|
||||
context_menu->buildDrawLabels();
|
||||
context_menu->updateParent(LLMenuGL::sMenuContainer);
|
||||
LLMenuGL::showPopup(this, context_menu, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
|
|
@ -132,7 +188,7 @@ BOOL LLGroupList::handleDoubleClick(S32 x, S32 y, MASK mask)
|
|||
// Handle double click only for the selected item in the list, skip clicks on empty space.
|
||||
if (handled)
|
||||
{
|
||||
if (mDoubleClickSignal)
|
||||
if (mDoubleClickSignal && getItemsRect().pointInRect(x, y))
|
||||
{
|
||||
(*mDoubleClickSignal)(this, x, y, mask);
|
||||
}
|
||||
|
|
@ -164,34 +220,49 @@ static bool findInsensitive(std::string haystack, const std::string& needle_uppe
|
|||
|
||||
void LLGroupList::refresh()
|
||||
{
|
||||
const LLUUID& highlight_id = gAgent.getGroupID();
|
||||
S32 count = gAgent.mGroups.size();
|
||||
LLUUID id;
|
||||
bool have_filter = !mNameFilter.empty();
|
||||
if (mForAgent)
|
||||
{
|
||||
const LLUUID& highlight_id = gAgent.getGroupID();
|
||||
S32 count = gAgent.mGroups.size();
|
||||
LLUUID id;
|
||||
bool have_filter = !mNameFilter.empty();
|
||||
|
||||
clear();
|
||||
clear();
|
||||
|
||||
for(S32 i = 0; i < count; ++i)
|
||||
{
|
||||
id = gAgent.mGroups.at(i).mID;
|
||||
const LLGroupData& group_data = gAgent.mGroups.at(i);
|
||||
if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
|
||||
continue;
|
||||
addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM);
|
||||
}
|
||||
for(S32 i = 0; i < count; ++i)
|
||||
{
|
||||
id = gAgent.mGroups.at(i).mID;
|
||||
const LLGroupData& group_data = gAgent.mGroups.at(i);
|
||||
if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
|
||||
continue;
|
||||
addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM, group_data.mListInProfile);
|
||||
}
|
||||
|
||||
// Sort the list.
|
||||
sort();
|
||||
// Sort the list.
|
||||
sort();
|
||||
|
||||
// Add "none" to list at top if filter not set (what's the point of filtering "none"?).
|
||||
// but only if some real groups exists. EXT-4838
|
||||
if (!have_filter && count > 0)
|
||||
{
|
||||
std::string loc_none = LLTrans::getString("GroupsNone");
|
||||
addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP);
|
||||
}
|
||||
// Add "none" to list at top if filter not set (what's the point of filtering "none"?).
|
||||
// but only if some real groups exists. EXT-4838
|
||||
if (!have_filter && count > 0 && mShowNone)
|
||||
{
|
||||
std::string loc_none = LLTrans::getString("GroupsNone");
|
||||
addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP);
|
||||
}
|
||||
|
||||
selectItemByUUID(highlight_id);
|
||||
selectItemByUUID(highlight_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
clear();
|
||||
|
||||
for (group_map_t::iterator it = mGroups.begin(); it != mGroups.end(); ++it)
|
||||
{
|
||||
addNewItem(it->second, it->first, LLUUID::null, ADD_BOTTOM);
|
||||
}
|
||||
|
||||
// Sort the list.
|
||||
sort();
|
||||
}
|
||||
|
||||
setDirty(false);
|
||||
onCommit();
|
||||
|
|
@ -212,13 +283,19 @@ void LLGroupList::toggleIcons()
|
|||
}
|
||||
}
|
||||
|
||||
void LLGroupList::setGroups(const std::map< std::string,LLUUID> group_list)
|
||||
{
|
||||
mGroups = group_list;
|
||||
setDirty(true);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PRIVATE Section
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos)
|
||||
void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos, bool visible_in_profile)
|
||||
{
|
||||
LLGroupListItem* item = new LLGroupListItem();
|
||||
LLGroupListItem* item = new LLGroupListItem(mForAgent, mShowIcons);
|
||||
|
||||
item->setGroupID(id);
|
||||
item->setName(name, mNameFilter);
|
||||
|
|
@ -227,7 +304,10 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
|
|||
item->getChildView("info_btn")->setVisible( false);
|
||||
item->getChildView("profile_btn")->setVisible( false);
|
||||
item->setGroupIconVisible(mShowIcons);
|
||||
|
||||
if (!mShowIcons)
|
||||
{
|
||||
item->setVisibleInProfile(visible_in_profile);
|
||||
}
|
||||
addItem(item, id, pos);
|
||||
|
||||
// setCommentVisible(false);
|
||||
|
|
@ -243,6 +323,29 @@ bool LLGroupList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD&
|
|||
return true;
|
||||
}
|
||||
|
||||
if (event->desc() == "value_changed")
|
||||
{
|
||||
LLSD data = event->getValue();
|
||||
if (data.has("group_id") && data.has("visible"))
|
||||
{
|
||||
LLUUID group_id = data["group_id"].asUUID();
|
||||
bool visible = data["visible"].asBoolean();
|
||||
|
||||
std::vector<LLPanel*> items;
|
||||
getItems(items);
|
||||
for (std::vector<LLPanel*>::iterator it = items.begin(); it != items.end(); ++it)
|
||||
{
|
||||
LLGroupListItem* item = dynamic_cast<LLGroupListItem*>(*it);
|
||||
if (item && item->getGroupID() == group_id)
|
||||
{
|
||||
item->setVisibleInProfile(visible);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -294,21 +397,25 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)
|
|||
/* LLGroupListItem implementation */
|
||||
/************************************************************************/
|
||||
|
||||
LLGroupListItem::LLGroupListItem()
|
||||
LLGroupListItem::LLGroupListItem(bool for_agent, bool show_icons)
|
||||
: LLPanel(),
|
||||
mGroupIcon(NULL),
|
||||
mGroupNameBox(NULL),
|
||||
mInfoBtn(NULL),
|
||||
mGroupID(LLUUID::null)
|
||||
mProfileBtn(NULL),
|
||||
mVisibilityHideBtn(NULL),
|
||||
mVisibilityShowBtn(NULL),
|
||||
mGroupID(LLUUID::null),
|
||||
mForAgent(for_agent)
|
||||
{
|
||||
buildFromFile( "panel_group_list_item.xml");
|
||||
|
||||
// Remember group icon width including its padding from the name text box,
|
||||
// so that we can hide and show the icon again later.
|
||||
if (!sIconWidth)
|
||||
{
|
||||
sIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft;
|
||||
}
|
||||
if (show_icons)
|
||||
{
|
||||
buildFromFile( "panel_group_list_item.xml");
|
||||
}
|
||||
else
|
||||
{
|
||||
buildFromFile( "panel_group_list_item_short.xml");
|
||||
}
|
||||
}
|
||||
|
||||
LLGroupListItem::~LLGroupListItem()
|
||||
|
|
@ -325,7 +432,25 @@ BOOL LLGroupListItem::postBuild()
|
|||
mInfoBtn = getChild<LLButton>("info_btn");
|
||||
mInfoBtn->setClickedCallback(boost::bind(&LLGroupListItem::onInfoBtnClick, this));
|
||||
|
||||
childSetAction("profile_btn", boost::bind(&LLGroupListItem::onProfileBtnClick, this));
|
||||
mProfileBtn = getChild<LLButton>("profile_btn");
|
||||
mProfileBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onProfileBtnClick(); });
|
||||
|
||||
mVisibilityHideBtn = findChild<LLButton>("visibility_hide_btn");
|
||||
if (mVisibilityHideBtn)
|
||||
{
|
||||
mVisibilityHideBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onVisibilityBtnClick(false); });
|
||||
}
|
||||
mVisibilityShowBtn = findChild<LLButton>("visibility_show_btn");
|
||||
if (mVisibilityShowBtn)
|
||||
{
|
||||
mVisibilityShowBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onVisibilityBtnClick(true); });
|
||||
}
|
||||
|
||||
// Remember group icon width including its padding from the name text box,
|
||||
// so that we can hide and show the icon again later.
|
||||
// Also note that panel_group_list_item and panel_group_list_item_short
|
||||
// have icons of different sizes so we need to figure it per file.
|
||||
mIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -344,7 +469,16 @@ void LLGroupListItem::onMouseEnter(S32 x, S32 y, MASK mask)
|
|||
if (mGroupID.notNull()) // don't show the info button for the "none" group
|
||||
{
|
||||
mInfoBtn->setVisible(true);
|
||||
getChildView("profile_btn")->setVisible( true);
|
||||
mProfileBtn->setVisible(true);
|
||||
if (mForAgent && mVisibilityHideBtn)
|
||||
{
|
||||
LLGroupData agent_gdatap;
|
||||
if (gAgent.getGroupData(mGroupID, agent_gdatap))
|
||||
{
|
||||
mVisibilityHideBtn->setVisible(agent_gdatap.mListInProfile);
|
||||
mVisibilityShowBtn->setVisible(!agent_gdatap.mListInProfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLPanel::onMouseEnter(x, y, mask);
|
||||
|
|
@ -354,7 +488,12 @@ void LLGroupListItem::onMouseLeave(S32 x, S32 y, MASK mask)
|
|||
{
|
||||
getChildView("hovered_icon")->setVisible( false);
|
||||
mInfoBtn->setVisible(false);
|
||||
getChildView("profile_btn")->setVisible( false);
|
||||
mProfileBtn->setVisible(false);
|
||||
if (mVisibilityHideBtn)
|
||||
{
|
||||
mVisibilityHideBtn->setVisible(false);
|
||||
mVisibilityShowBtn->setVisible(false);
|
||||
}
|
||||
|
||||
LLPanel::onMouseLeave(x, y, mask);
|
||||
}
|
||||
|
|
@ -372,7 +511,17 @@ void LLGroupListItem::setGroupID(const LLUUID& group_id)
|
|||
|
||||
mID = group_id;
|
||||
mGroupID = group_id;
|
||||
setActive(group_id == gAgent.getGroupID());
|
||||
|
||||
if (mForAgent)
|
||||
{
|
||||
// Active group should be bold.
|
||||
setBold(group_id == gAgent.getGroupID());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Groups shared with the agent should be bold
|
||||
setBold(gAgent.isInGroup(group_id, true));
|
||||
}
|
||||
|
||||
LLGroupMgr::getInstance()->addObserver(this);
|
||||
}
|
||||
|
|
@ -393,24 +542,28 @@ void LLGroupListItem::setGroupIconVisible(bool visible)
|
|||
|
||||
// Move the group name horizontally by icon size + its distance from the group name.
|
||||
LLRect name_rect = mGroupNameBox->getRect();
|
||||
name_rect.mLeft += visible ? sIconWidth : -sIconWidth;
|
||||
name_rect.mLeft += visible ? mIconWidth : -mIconWidth;
|
||||
mGroupNameBox->setRect(name_rect);
|
||||
}
|
||||
|
||||
void LLGroupListItem::setVisibleInProfile(bool visible)
|
||||
{
|
||||
mGroupNameBox->setColor(LLUIColorTable::instance().getColor((visible ? "GroupVisibleInProfile" : "GroupHiddenInProfile"), LLColor4::red).get());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Private Section
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void LLGroupListItem::setActive(bool active)
|
||||
void LLGroupListItem::setBold(bool bold)
|
||||
{
|
||||
// *BUG: setName() overrides the style params.
|
||||
|
||||
// Active group should be bold.
|
||||
LLFontDescriptor new_desc(mGroupNameBox->getFont()->getFontDesc());
|
||||
|
||||
// *NOTE dzaporozhan
|
||||
// On Windows LLFontGL::NORMAL will not remove LLFontGL::BOLD if font
|
||||
// is predefined as bold (SansSerifSmallBold, for example)
|
||||
new_desc.setStyle(active ? LLFontGL::BOLD : LLFontGL::NORMAL);
|
||||
new_desc.setStyle(bold ? LLFontGL::BOLD : LLFontGL::NORMAL);
|
||||
LLFontGL* new_font = LLFontGL::getFont(new_desc);
|
||||
mGroupNameStyle.font = new_font;
|
||||
|
||||
|
|
@ -430,11 +583,25 @@ void LLGroupListItem::onProfileBtnClick()
|
|||
LLGroupActions::show(mGroupID);
|
||||
}
|
||||
|
||||
void LLGroupListItem::onVisibilityBtnClick(bool new_visibility)
|
||||
{
|
||||
LLGroupData agent_gdatap;
|
||||
if (gAgent.getGroupData(mGroupID, agent_gdatap))
|
||||
{
|
||||
gAgent.setUserGroupFlags(mGroupID, agent_gdatap.mAcceptNotices, new_visibility);
|
||||
setVisibleInProfile(new_visibility);
|
||||
mVisibilityHideBtn->setVisible(new_visibility);
|
||||
mVisibilityShowBtn->setVisible(!new_visibility);
|
||||
}
|
||||
}
|
||||
|
||||
void LLGroupListItem::changed(LLGroupChange gc)
|
||||
{
|
||||
LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mID);
|
||||
if(group_data)
|
||||
setGroupIconID(group_data->mInsigniaID);
|
||||
if ((gc == GC_ALL || gc == GC_PROPERTIES) && group_data)
|
||||
{
|
||||
setGroupIconID(group_data->mInsigniaID);
|
||||
}
|
||||
}
|
||||
|
||||
//EOF
|
||||
|
|
|
|||
|
|
@ -50,12 +50,15 @@ class LLGroupList: public LLFlatListViewEx, public LLOldEvents::LLSimpleListener
|
|||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
|
||||
{
|
||||
Params(){};
|
||||
Optional<bool> for_agent;
|
||||
Params();
|
||||
};
|
||||
|
||||
LLGroupList(const Params& p);
|
||||
virtual ~LLGroupList();
|
||||
|
||||
void enableForAgent(bool show_icons);
|
||||
|
||||
virtual void draw(); // from LLView
|
||||
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); // from LLView
|
||||
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); // from LLView
|
||||
|
|
@ -63,13 +66,16 @@ public:
|
|||
void setNameFilter(const std::string& filter);
|
||||
void toggleIcons();
|
||||
bool getIconsVisible() const { return mShowIcons; }
|
||||
void setIconsVisible(bool show_icons) { mShowIcons = show_icons; }
|
||||
void setShowNone(bool show_none) { mShowNone = show_none; }
|
||||
void setGroups(const std::map< std::string,LLUUID> group_list);
|
||||
|
||||
LLToggleableMenu* getContextMenu() const { return mContextMenuHandle.get(); }
|
||||
|
||||
private:
|
||||
void setDirty(bool val = true) { mDirty = val; }
|
||||
void refresh();
|
||||
void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos = ADD_BOTTOM);
|
||||
void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos = ADD_BOTTOM, bool visible_in_profile = true);
|
||||
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); // called on agent group list changes
|
||||
|
||||
bool onContextMenuItemClick(const LLSD& userdata);
|
||||
|
|
@ -80,6 +86,11 @@ private:
|
|||
bool mShowIcons;
|
||||
bool mDirty;
|
||||
std::string mNameFilter;
|
||||
|
||||
bool mForAgent;
|
||||
bool mShowNone;
|
||||
typedef std::map< std::string,LLUUID> group_map_t;
|
||||
group_map_t mGroups;
|
||||
};
|
||||
|
||||
class LLButton;
|
||||
|
|
@ -90,7 +101,7 @@ class LLGroupListItem : public LLPanel
|
|||
, public LLGroupMgrObserver
|
||||
{
|
||||
public:
|
||||
LLGroupListItem();
|
||||
LLGroupListItem(bool for_agent, bool show_icons);
|
||||
~LLGroupListItem();
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void setValue(const LLSD& value);
|
||||
|
|
@ -106,19 +117,26 @@ public:
|
|||
void setGroupIconVisible(bool visible);
|
||||
|
||||
virtual void changed(LLGroupChange gc);
|
||||
|
||||
void setVisibleInProfile(bool visible);
|
||||
private:
|
||||
void setActive(bool active);
|
||||
void setBold(bool bold);
|
||||
void onInfoBtnClick();
|
||||
void onProfileBtnClick();
|
||||
void onVisibilityBtnClick(bool new_visibility);
|
||||
|
||||
LLTextBox* mGroupNameBox;
|
||||
LLUUID mGroupID;
|
||||
LLGroupIconCtrl* mGroupIcon;
|
||||
LLButton* mInfoBtn;
|
||||
LLButton* mInfoBtn;
|
||||
LLButton* mProfileBtn;
|
||||
LLButton* mVisibilityHideBtn;
|
||||
LLButton* mVisibilityShowBtn;
|
||||
|
||||
std::string mGroupName;
|
||||
bool mForAgent;
|
||||
LLStyle::Params mGroupNameStyle;
|
||||
|
||||
static S32 sIconWidth; // icon width + padding
|
||||
S32 mIconWidth;
|
||||
};
|
||||
#endif // LL_LLGROUPLIST_H
|
||||
|
|
|
|||
|
|
@ -147,3 +147,19 @@ bool LLInspect::childHasVisiblePopupMenu()
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLInspect::repositionInspector(const LLSD& data)
|
||||
{
|
||||
// Position the inspector relative to the mouse cursor
|
||||
// Similar to how tooltips are positioned
|
||||
// See LLToolTipMgr::createToolTip
|
||||
if (data.has("pos"))
|
||||
{
|
||||
LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
|
||||
}
|
||||
else
|
||||
{
|
||||
LLUI::getInstance()->positionViewNearMouse(this);
|
||||
}
|
||||
applyRectControl();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ public:
|
|||
|
||||
/// Inspectors close themselves when they lose focus
|
||||
/*virtual*/ void onFocusLost();
|
||||
|
||||
void repositionInspector(const LLSD& data);
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@
|
|||
#include "llfloater.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "lltextbox.h"
|
||||
#include "lltooltip.h" // positionViewNearMouse()
|
||||
#include "lltrans.h"
|
||||
|
||||
class LLFetchAvatarData;
|
||||
|
|
@ -202,17 +201,7 @@ void LLInspectAvatar::onOpen(const LLSD& data)
|
|||
// Extract appropriate avatar id
|
||||
mAvatarID = data["avatar_id"];
|
||||
|
||||
// Position the inspector relative to the mouse cursor
|
||||
// Similar to how tooltips are positioned
|
||||
// See LLToolTipMgr::createToolTip
|
||||
if (data.has("pos"))
|
||||
{
|
||||
LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
|
||||
}
|
||||
else
|
||||
{
|
||||
LLUI::getInstance()->positionViewNearMouse(this);
|
||||
}
|
||||
LLInspect::repositionInspector(data);
|
||||
|
||||
// Generate link to avatar profile.
|
||||
LLTextBase* avatar_profile_link = getChild<LLTextBase>("avatar_profile_link");
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@
|
|||
#include "llfloater.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llresmgr.h" // getMonetaryString()
|
||||
#include "lltooltip.h" // positionViewNearMouse()
|
||||
#include "lltrans.h"
|
||||
#include "lluictrl.h"
|
||||
#include "llgroupiconctrl.h"
|
||||
|
|
@ -124,17 +123,7 @@ void LLInspectGroup::onOpen(const LLSD& data)
|
|||
|
||||
setGroupID(data["group_id"]);
|
||||
|
||||
// Position the inspector relative to the mouse cursor
|
||||
// Similar to how tooltips are positioned
|
||||
// See LLToolTipMgr::createToolTip
|
||||
if (data.has("pos"))
|
||||
{
|
||||
LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
|
||||
}
|
||||
else
|
||||
{
|
||||
LLUI::getInstance()->positionViewNearMouse(this);
|
||||
}
|
||||
LLInspect::repositionInspector(data);
|
||||
|
||||
// can't call from constructor as widgets are not built yet
|
||||
requestUpdate();
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@
|
|||
#include "lltextbox.h" // for description truncation
|
||||
#include "lltoggleablemenu.h"
|
||||
#include "lltrans.h"
|
||||
#include "llui.h" // positionViewNearMouse()
|
||||
#include "lluictrl.h"
|
||||
|
||||
class LLViewerObject;
|
||||
|
|
@ -198,17 +197,8 @@ void LLInspectObject::onOpen(const LLSD& data)
|
|||
{
|
||||
mObjectFace = data["object_face"];
|
||||
}
|
||||
// Position the inspector relative to the mouse cursor
|
||||
// Similar to how tooltips are positioned
|
||||
// See LLToolTipMgr::createToolTip
|
||||
if (data.has("pos"))
|
||||
{
|
||||
LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
|
||||
}
|
||||
else
|
||||
{
|
||||
LLUI::getInstance()->positionViewNearMouse(this);
|
||||
}
|
||||
|
||||
LLInspect::repositionInspector(data);
|
||||
|
||||
// Promote hovered object to a complete selection, which will also force
|
||||
// a request for selected object data off the network
|
||||
|
|
|
|||
|
|
@ -111,17 +111,7 @@ void LLInspectRemoteObject::onOpen(const LLSD& data)
|
|||
// update the inspector with the current object state
|
||||
update();
|
||||
|
||||
// Position the inspector relative to the mouse cursor
|
||||
// Similar to how tooltips are positioned
|
||||
// See LLToolTipMgr::createToolTip
|
||||
if (data.has("pos"))
|
||||
{
|
||||
LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
|
||||
}
|
||||
else
|
||||
{
|
||||
LLUI::getInstance()->positionViewNearMouse(this);
|
||||
}
|
||||
LLInspect::repositionInspector(data);
|
||||
}
|
||||
|
||||
void LLInspectRemoteObject::onClickMap()
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ void LLInspectToast::onOpen(const LLSD& notification_id)
|
|||
panel_rect = panel->getRect();
|
||||
reshape(panel_rect.getWidth(), panel_rect.getHeight());
|
||||
|
||||
LLUI::getInstance()->positionViewNearMouse(this);
|
||||
LLInspect::repositionInspector(notification_id);
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
|
|
|||
|
|
@ -925,20 +925,20 @@ bool LLLocalBitmapMgr::addUnit(const std::vector<std::string>& filenames)
|
|||
std::vector<std::string>::const_iterator iter = filenames.begin();
|
||||
while (iter != filenames.end())
|
||||
{
|
||||
if (!iter->empty())
|
||||
if (!iter->empty() && addUnit(*iter).notNull())
|
||||
{
|
||||
add_successful |= addUnit(*iter);
|
||||
add_successful = true;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
return add_successful;
|
||||
}
|
||||
|
||||
bool LLLocalBitmapMgr::addUnit(const std::string& filename)
|
||||
LLUUID LLLocalBitmapMgr::addUnit(const std::string& filename)
|
||||
{
|
||||
if (!checkTextureDimensions(filename))
|
||||
{
|
||||
return false;
|
||||
return LLUUID::null;
|
||||
}
|
||||
|
||||
LLLocalBitmap* unit = new LLLocalBitmap(filename);
|
||||
|
|
@ -946,7 +946,7 @@ bool LLLocalBitmapMgr::addUnit(const std::string& filename)
|
|||
if (unit->getValid())
|
||||
{
|
||||
mBitmapList.push_back(unit);
|
||||
return true;
|
||||
return unit->getTrackingID();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -959,8 +959,9 @@ bool LLLocalBitmapMgr::addUnit(const std::string& filename)
|
|||
|
||||
delete unit;
|
||||
unit = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
return LLUUID::null;
|
||||
}
|
||||
|
||||
bool LLLocalBitmapMgr::checkTextureDimensions(std::string filename)
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ class LLLocalBitmapMgr : public LLSingleton<LLLocalBitmapMgr>
|
|||
~LLLocalBitmapMgr();
|
||||
public:
|
||||
bool addUnit(const std::vector<std::string>& filenames);
|
||||
bool addUnit(const std::string& filename);
|
||||
LLUUID addUnit(const std::string& filename);
|
||||
void delUnit(LLUUID tracking_id);
|
||||
bool checkTextureDimensions(std::string filename);
|
||||
|
||||
|
|
|
|||
|
|
@ -368,23 +368,23 @@ bool LLLocalGLTFMaterialMgr::addUnit(const std::vector<std::string>& filenames)
|
|||
std::vector<std::string>::const_iterator iter = filenames.begin();
|
||||
while (iter != filenames.end())
|
||||
{
|
||||
if (!iter->empty())
|
||||
if (!iter->empty() && addUnit(*iter).notNull())
|
||||
{
|
||||
add_successful |= addUnit(*iter);
|
||||
add_successful = true;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
return add_successful;
|
||||
}
|
||||
|
||||
bool LLLocalGLTFMaterialMgr::addUnit(const std::string& filename)
|
||||
LLUUID LLLocalGLTFMaterialMgr::addUnit(const std::string& filename)
|
||||
{
|
||||
LLLocalGLTFMaterial* unit = new LLLocalGLTFMaterial(filename);
|
||||
|
||||
if (unit->getValid())
|
||||
{
|
||||
mMaterialList.push_back(unit);
|
||||
return true;
|
||||
return unit->getTrackingID();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -397,9 +397,9 @@ bool LLLocalGLTFMaterialMgr::addUnit(const std::string& filename)
|
|||
|
||||
delete unit;
|
||||
unit = NULL;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return LLUUID::null;
|
||||
}
|
||||
|
||||
void LLLocalGLTFMaterialMgr::delUnit(LLUUID tracking_id)
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ class LLLocalGLTFMaterialMgr : public LLSingleton<LLLocalGLTFMaterialMgr>
|
|||
~LLLocalGLTFMaterialMgr();
|
||||
public:
|
||||
bool addUnit(const std::vector<std::string>& filenames);
|
||||
bool addUnit(const std::string& filename);
|
||||
LLUUID addUnit(const std::string& filename);
|
||||
void delUnit(LLUUID tracking_id);
|
||||
|
||||
LLUUID getWorldID(LLUUID tracking_id);
|
||||
|
|
|
|||
|
|
@ -1374,6 +1374,7 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id)
|
|||
texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLOutfitGallery::onTexturePickerCommit, this, _1, _2));
|
||||
texture_floaterp->setOnUpdateImageStatsCallback(boost::bind(&LLOutfitGallery::onTexturePickerUpdateImageStats, this, _1));
|
||||
texture_floaterp->setLocalTextureEnabled(FALSE);
|
||||
texture_floaterp->setBakeTextureEnabled(FALSE);
|
||||
texture_floaterp->setCanApply(false, true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
/**
|
||||
/**
|
||||
* @file llpanelavatar.cpp
|
||||
* @brief LLPanelAvatar and related class implementations
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
|
@ -28,173 +28,127 @@
|
|||
#include "llpanelavatar.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llavataractions.h"
|
||||
#include "llcallingcard.h"
|
||||
#include "llcombobox.h"
|
||||
#include "lldateutil.h" // ageFromDate()
|
||||
#include "llimview.h"
|
||||
#include "llmenubutton.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llslurl.h"
|
||||
#include "lltexteditor.h"
|
||||
#include "lltexturectrl.h"
|
||||
#include "lltoggleablemenu.h"
|
||||
#include "llloadingindicator.h"
|
||||
#include "lltooldraganddrop.h"
|
||||
#include "llscrollcontainer.h"
|
||||
#include "llavatariconctrl.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llviewermenu.h" // is_agent_mappable
|
||||
#include "llvoiceclient.h"
|
||||
#include "lltextbox.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLDropTarget
|
||||
//
|
||||
// This handy class is a simple way to drop something on another
|
||||
// view. It handles drop events, always setting itself to the size of
|
||||
// its parent.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// LLProfileDropTarget
|
||||
|
||||
class LLDropTarget : public LLView
|
||||
{
|
||||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLView::Params>
|
||||
{
|
||||
Optional<LLUUID> agent_id;
|
||||
Params()
|
||||
: agent_id("agent_id")
|
||||
{
|
||||
changeDefault(mouse_opaque, false);
|
||||
changeDefault(follows.flags, FOLLOWS_ALL);
|
||||
}
|
||||
};
|
||||
|
||||
LLDropTarget(const Params&);
|
||||
~LLDropTarget();
|
||||
|
||||
void doDrop(EDragAndDropType cargo_type, void* cargo_data);
|
||||
|
||||
//
|
||||
// LLView functionality
|
||||
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
void setAgentID(const LLUUID &agent_id) { mAgentID = agent_id; }
|
||||
protected:
|
||||
LLUUID mAgentID;
|
||||
};
|
||||
|
||||
LLDropTarget::LLDropTarget(const LLDropTarget::Params& p)
|
||||
: LLView(p),
|
||||
mAgentID(p.agent_id)
|
||||
LLProfileDropTarget::LLProfileDropTarget(const LLProfileDropTarget::Params& p)
|
||||
: LLView(p),
|
||||
mAgentID(p.agent_id)
|
||||
{}
|
||||
|
||||
LLDropTarget::~LLDropTarget()
|
||||
{}
|
||||
|
||||
void LLDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
|
||||
void LLProfileDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
|
||||
{
|
||||
LL_INFOS() << "LLDropTarget::doDrop()" << LL_ENDL;
|
||||
LL_INFOS() << "LLProfileDropTarget::doDrop()" << LL_ENDL;
|
||||
}
|
||||
|
||||
BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg)
|
||||
BOOL LLProfileDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg)
|
||||
{
|
||||
if(getParent())
|
||||
{
|
||||
LLToolDragAndDrop::handleGiveDragAndDrop(mAgentID, LLUUID::null, drop,
|
||||
cargo_type, cargo_data, accept);
|
||||
if (getParent())
|
||||
{
|
||||
LLToolDragAndDrop::handleGiveDragAndDrop(mAgentID, LLUUID::null, drop,
|
||||
cargo_type, cargo_data, accept);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLDropTarget> r("drop_target");
|
||||
static LLDefaultChildRegistry::Register<LLProfileDropTarget> r("profile_drop_target");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// LLPanelProfileTab
|
||||
|
||||
LLPanelProfileTab::LLPanelProfileTab()
|
||||
: LLPanel()
|
||||
, mAvatarId(LLUUID::null)
|
||||
, mLoadingState(PROFILE_INIT)
|
||||
, mSelfProfile(false)
|
||||
{
|
||||
}
|
||||
|
||||
LLPanelProfileTab::~LLPanelProfileTab()
|
||||
{
|
||||
if(getAvatarId().notNull())
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfileTab::setAvatarId(const LLUUID& id)
|
||||
void LLPanelProfileTab::setAvatarId(const LLUUID& avatar_id)
|
||||
{
|
||||
if(id.notNull())
|
||||
{
|
||||
if(getAvatarId().notNull())
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId,this);
|
||||
}
|
||||
mAvatarId = id;
|
||||
LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(),this);
|
||||
}
|
||||
if (avatar_id.notNull())
|
||||
{
|
||||
mAvatarId = avatar_id;
|
||||
mSelfProfile = (getAvatarId() == gAgentID);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfileTab::onOpen(const LLSD& key)
|
||||
{
|
||||
// Don't reset panel if we are opening it for same avatar.
|
||||
if(getAvatarId() != key.asUUID())
|
||||
{
|
||||
resetControls();
|
||||
resetData();
|
||||
// Update data even if we are viewing same avatar profile as some data might been changed.
|
||||
setAvatarId(key.asUUID());
|
||||
|
||||
scrollToTop();
|
||||
}
|
||||
|
||||
// Update data even if we are viewing same avatar profile as some data might been changed.
|
||||
setAvatarId(key.asUUID());
|
||||
updateData();
|
||||
updateButtons();
|
||||
setApplyProgress(true);
|
||||
}
|
||||
|
||||
void LLPanelProfileTab::scrollToTop()
|
||||
void LLPanelProfileTab::setLoaded()
|
||||
{
|
||||
LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll");
|
||||
if (scrollContainer)
|
||||
scrollContainer->goToTop();
|
||||
setApplyProgress(false);
|
||||
|
||||
mLoadingState = PROFILE_LOADED;
|
||||
}
|
||||
|
||||
void LLPanelProfileTab::onMapButtonClick()
|
||||
void LLPanelProfileTab::setApplyProgress(bool started)
|
||||
{
|
||||
LLAvatarActions::showOnMap(getAvatarId());
|
||||
LLLoadingIndicator* indicator = findChild<LLLoadingIndicator>("progress_indicator");
|
||||
|
||||
if (indicator)
|
||||
{
|
||||
indicator->setVisible(started);
|
||||
|
||||
if (started)
|
||||
{
|
||||
indicator->start();
|
||||
}
|
||||
else
|
||||
{
|
||||
indicator->stop();
|
||||
}
|
||||
}
|
||||
|
||||
LLPanel* panel = findChild<LLPanel>("indicator_stack");
|
||||
if (panel)
|
||||
{
|
||||
panel->setVisible(started);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfileTab::updateButtons()
|
||||
LLPanelProfilePropertiesProcessorTab::LLPanelProfilePropertiesProcessorTab()
|
||||
: LLPanelProfileTab()
|
||||
{
|
||||
bool is_buddy_online = LLAvatarTracker::instance().isBuddyOnline(getAvatarId());
|
||||
|
||||
if(LLAvatarActions::isFriend(getAvatarId()))
|
||||
{
|
||||
getChildView("teleport")->setEnabled(is_buddy_online);
|
||||
}
|
||||
else
|
||||
{
|
||||
getChildView("teleport")->setEnabled(true);
|
||||
}
|
||||
|
||||
bool enable_map_btn = (is_buddy_online &&
|
||||
is_agent_mappable(getAvatarId()))
|
||||
|| gAgent.isGodlike();
|
||||
getChildView("show_on_map_btn")->setEnabled(enable_map_btn);
|
||||
}
|
||||
|
||||
LLPanelProfilePropertiesProcessorTab::~LLPanelProfilePropertiesProcessorTab()
|
||||
{
|
||||
if (getAvatarId().notNull())
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfilePropertiesProcessorTab::setAvatarId(const LLUUID & avatar_id)
|
||||
{
|
||||
if (avatar_id.notNull())
|
||||
{
|
||||
if (getAvatarId().notNull())
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
|
||||
}
|
||||
LLPanelProfileTab::setAvatarId(avatar_id);
|
||||
LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
/**
|
||||
/**
|
||||
* @file llpanelavatar.h
|
||||
* @brief LLPanelAvatar and related class definitions
|
||||
* @brief Legacy profile panel base class
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* $LicenseInfo:firstyear=2019&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* Copyright (C) 2019, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
|
@ -29,80 +29,141 @@
|
|||
|
||||
#include "llpanel.h"
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
#include "llcallingcard.h"
|
||||
#include "llvoiceclient.h"
|
||||
#include "llavatarnamecache.h"
|
||||
|
||||
class LLComboBox;
|
||||
class LLLineEditor;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLProfileDropTarget
|
||||
//
|
||||
// This handy class is a simple way to drop something on another
|
||||
// view. It handles drop events, always setting itself to the size of
|
||||
// its parent.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
class LLProfileDropTarget : public LLView
|
||||
{
|
||||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLView::Params>
|
||||
{
|
||||
Optional<LLUUID> agent_id;
|
||||
Params()
|
||||
: agent_id("agent_id")
|
||||
{
|
||||
changeDefault(mouse_opaque, false);
|
||||
changeDefault(follows.flags, FOLLOWS_ALL);
|
||||
}
|
||||
};
|
||||
|
||||
LLProfileDropTarget(const Params&);
|
||||
~LLProfileDropTarget() {}
|
||||
|
||||
void doDrop(EDragAndDropType cargo_type, void* cargo_data);
|
||||
|
||||
//
|
||||
// LLView functionality
|
||||
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
|
||||
void setAgentID(const LLUUID &agent_id) { mAgentID = agent_id; }
|
||||
|
||||
protected:
|
||||
LLUUID mAgentID;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Base class for any Profile View.
|
||||
*/
|
||||
class LLPanelProfileTab
|
||||
: public LLPanel
|
||||
, public LLAvatarPropertiesObserver
|
||||
: public LLPanel
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Sets avatar ID, sets panel as observer of avatar related info replies from server.
|
||||
*/
|
||||
virtual void setAvatarId(const LLUUID& id);
|
||||
/**
|
||||
* Sets avatar ID, sets panel as observer of avatar related info replies from server.
|
||||
*/
|
||||
virtual void setAvatarId(const LLUUID& avatar_id);
|
||||
|
||||
/**
|
||||
* Returns avatar ID.
|
||||
*/
|
||||
virtual const LLUUID& getAvatarId() { return mAvatarId; }
|
||||
/**
|
||||
* Returns avatar ID.
|
||||
*/
|
||||
virtual const LLUUID& getAvatarId() { return mAvatarId; }
|
||||
|
||||
/**
|
||||
* Sends update data request to server.
|
||||
*/
|
||||
virtual void updateData() = 0;
|
||||
/**
|
||||
* Sends update data request to server.
|
||||
*/
|
||||
virtual void updateData() {};
|
||||
|
||||
/**
|
||||
* Clears panel data if viewing avatar info for first time and sends update data request.
|
||||
*/
|
||||
virtual void onOpen(const LLSD& key);
|
||||
/**
|
||||
* Clears panel data if viewing avatar info for first time and sends update data request.
|
||||
*/
|
||||
virtual void onOpen(const LLSD& key);
|
||||
|
||||
/**
|
||||
* Profile tabs should close any opened panels here.
|
||||
*
|
||||
* Called from LLPanelProfile::onOpen() before opening new profile.
|
||||
* See LLPanelPicks::onClosePanel for example. LLPanelPicks closes picture info panel
|
||||
* before new profile is displayed, otherwise new profile will
|
||||
* be hidden behind picture info panel.
|
||||
*/
|
||||
virtual void onClosePanel() {}
|
||||
/**
|
||||
* Clears all data received from server.
|
||||
*/
|
||||
virtual void resetData(){};
|
||||
|
||||
/**
|
||||
* Resets controls visibility, state, etc.
|
||||
*/
|
||||
virtual void resetControls(){};
|
||||
|
||||
/**
|
||||
* Clears all data received from server.
|
||||
*/
|
||||
virtual void resetData(){};
|
||||
|
||||
/*virtual*/ ~LLPanelProfileTab();
|
||||
/*virtual*/ ~LLPanelProfileTab();
|
||||
|
||||
protected:
|
||||
|
||||
LLPanelProfileTab();
|
||||
LLPanelProfileTab();
|
||||
|
||||
/**
|
||||
* Scrolls panel to top when viewing avatar info for first time.
|
||||
*/
|
||||
void scrollToTop();
|
||||
enum ELoadingState
|
||||
{
|
||||
PROFILE_INIT,
|
||||
PROFILE_LOADING,
|
||||
PROFILE_LOADED,
|
||||
};
|
||||
|
||||
virtual void onMapButtonClick();
|
||||
|
||||
virtual void updateButtons();
|
||||
// mLoading: false: Initial state, can request
|
||||
// true: Data requested, skip duplicate requests (happens due to LLUI's habit of repeated callbacks)
|
||||
// mLoaded: false: Initial state, show loading indicator
|
||||
// true: Data recieved, which comes in a single message, hide indicator
|
||||
ELoadingState getLoadingState() { return mLoadingState; }
|
||||
virtual void setLoaded();
|
||||
void setApplyProgress(bool started);
|
||||
|
||||
const bool getSelfProfile() const { return mSelfProfile; }
|
||||
|
||||
public:
|
||||
void setIsLoading() { mLoadingState = PROFILE_LOADING; }
|
||||
void resetLoading() { mLoadingState = PROFILE_INIT; }
|
||||
|
||||
bool getStarted() { return mLoadingState != PROFILE_INIT; }
|
||||
bool getIsLoaded() { return mLoadingState == PROFILE_LOADED; }
|
||||
|
||||
virtual bool hasUnsavedChanges() { return false; }
|
||||
virtual void commitUnsavedChanges() {}
|
||||
|
||||
private:
|
||||
|
||||
LLUUID mAvatarId;
|
||||
LLUUID mAvatarId;
|
||||
ELoadingState mLoadingState;
|
||||
bool mSelfProfile;
|
||||
};
|
||||
|
||||
class LLPanelProfilePropertiesProcessorTab
|
||||
: public LLPanelProfileTab
|
||||
, public LLAvatarPropertiesObserver
|
||||
{
|
||||
public:
|
||||
LLPanelProfilePropertiesProcessorTab();
|
||||
~LLPanelProfilePropertiesProcessorTab();
|
||||
|
||||
/*virtual*/ void setAvatarId(const LLUUID& avatar_id);
|
||||
|
||||
/**
|
||||
* Processes data received from server via LLAvatarPropertiesObserver.
|
||||
*/
|
||||
virtual void processProperties(void* data, EAvatarProcessorType type) = 0;
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELAVATAR_H
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
/**
|
||||
* @file llpanelclassified.cpp
|
||||
* @brief LLPanelClassified class implementation
|
||||
* @brief LLPanelClassifiedInfo class implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
|
||||
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
* Copyright (C) 2021, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -34,33 +34,21 @@
|
|||
|
||||
#include "lldispatcher.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llparcel.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llclassifiedflags.h"
|
||||
#include "llcommandhandler.h" // for classified HTML detail page click tracking
|
||||
#include "lliconctrl.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llcombobox.h"
|
||||
#include "lltexturectrl.h"
|
||||
#include "lltexteditor.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llfloaterworldmap.h"
|
||||
#include "llviewergenericmessage.h" // send_generic_message
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "lltrans.h"
|
||||
#include "llscrollcontainer.h"
|
||||
#include "llstatusbar.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "llcorehttputil.h"
|
||||
|
||||
const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
|
||||
|
||||
//static
|
||||
LLPanelClassifiedInfo::panel_list_t LLPanelClassifiedInfo::sAllPanels;
|
||||
static LLPanelInjector<LLPanelClassifiedInfo> t_panel_panel_classified_info("panel_classified_info");
|
||||
|
||||
// "classifiedclickthrough"
|
||||
// strings[0] = classified_id
|
||||
|
|
@ -118,17 +106,8 @@ LLPanelClassifiedInfo::~LLPanelClassifiedInfo()
|
|||
sAllPanels.remove(this);
|
||||
}
|
||||
|
||||
// static
|
||||
LLPanelClassifiedInfo* LLPanelClassifiedInfo::create()
|
||||
{
|
||||
LLPanelClassifiedInfo* panel = new LLPanelClassifiedInfo();
|
||||
panel->buildFromFile("panel_classified_info.xml");
|
||||
return panel;
|
||||
}
|
||||
|
||||
BOOL LLPanelClassifiedInfo::postBuild()
|
||||
{
|
||||
childSetAction("back_btn", boost::bind(&LLPanelClassifiedInfo::onExit, this));
|
||||
childSetAction("show_on_map_btn", boost::bind(&LLPanelClassifiedInfo::onMapClick, this));
|
||||
childSetAction("teleport_btn", boost::bind(&LLPanelClassifiedInfo::onTeleportClick, this));
|
||||
|
||||
|
|
@ -144,16 +123,6 @@ BOOL LLPanelClassifiedInfo::postBuild()
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelClassifiedInfo::setExitCallback(const commit_callback_t& cb)
|
||||
{
|
||||
getChild<LLButton>("back_btn")->setClickedCallback(cb);
|
||||
}
|
||||
|
||||
void LLPanelClassifiedInfo::setEditClassifiedCallback(const commit_callback_t& cb)
|
||||
{
|
||||
getChild<LLButton>("edit_btn")->setClickedCallback(cb);
|
||||
}
|
||||
|
||||
void LLPanelClassifiedInfo::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
|
||||
{
|
||||
LLPanel::reshape(width, height, called_from_parent);
|
||||
|
|
@ -286,6 +255,8 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t
|
|||
getChild<LLUICtrl>("creation_date")->setValue(date_str);
|
||||
|
||||
setInfoLoaded(true);
|
||||
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -590,588 +561,4 @@ void LLPanelClassifiedInfo::onTeleportClick()
|
|||
}
|
||||
}
|
||||
|
||||
void LLPanelClassifiedInfo::onExit()
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
|
||||
gGenericDispatcher.addHandler("classifiedclickthrough", NULL); // deregister our handler
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const S32 CB_ITEM_MATURE = 0;
|
||||
static const S32 CB_ITEM_PG = 1;
|
||||
|
||||
LLPanelClassifiedEdit::LLPanelClassifiedEdit()
|
||||
: LLPanelClassifiedInfo()
|
||||
, mIsNew(false)
|
||||
, mIsNewWithErrors(false)
|
||||
, mCanClose(false)
|
||||
, mPublishFloater(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LLPanelClassifiedEdit::~LLPanelClassifiedEdit()
|
||||
{
|
||||
}
|
||||
|
||||
//static
|
||||
LLPanelClassifiedEdit* LLPanelClassifiedEdit::create()
|
||||
{
|
||||
LLPanelClassifiedEdit* panel = new LLPanelClassifiedEdit();
|
||||
panel->buildFromFile("panel_edit_classified.xml");
|
||||
return panel;
|
||||
}
|
||||
|
||||
BOOL LLPanelClassifiedEdit::postBuild()
|
||||
{
|
||||
LLPanelClassifiedInfo::postBuild();
|
||||
|
||||
LLUICtrl* edit_icon = getChild<LLUICtrl>("edit_icon");
|
||||
mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseEnter, this, edit_icon));
|
||||
mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseLeave, this, edit_icon));
|
||||
edit_icon->setVisible(false);
|
||||
|
||||
LLLineEditor* line_edit = getChild<LLLineEditor>("classified_name");
|
||||
line_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
|
||||
|
||||
LLTextEditor* text_edit = getChild<LLTextEditor>("classified_desc");
|
||||
text_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
|
||||
|
||||
LLComboBox* combobox = getChild<LLComboBox>( "category");
|
||||
LLClassifiedInfo::cat_map::iterator iter;
|
||||
for (iter = LLClassifiedInfo::sCategories.begin();
|
||||
iter != LLClassifiedInfo::sCategories.end();
|
||||
iter++)
|
||||
{
|
||||
combobox->add(LLTrans::getString(iter->second));
|
||||
}
|
||||
|
||||
combobox->setCommitCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
|
||||
|
||||
childSetCommitCallback("content_type", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
|
||||
childSetCommitCallback("price_for_listing", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
|
||||
childSetCommitCallback("auto_renew", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
|
||||
|
||||
childSetAction("save_changes_btn", boost::bind(&LLPanelClassifiedEdit::onSaveClick, this));
|
||||
childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelClassifiedEdit::onSetLocationClick, this));
|
||||
|
||||
mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelClassifiedEdit::onTextureSelected, this));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::fillIn(const LLSD& key)
|
||||
{
|
||||
setAvatarId(gAgent.getID());
|
||||
|
||||
if(key.isUndefined())
|
||||
{
|
||||
setPosGlobal(gAgent.getPositionGlobal());
|
||||
|
||||
LLUUID snapshot_id = LLUUID::null;
|
||||
std::string desc;
|
||||
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
||||
|
||||
if(parcel)
|
||||
{
|
||||
desc = parcel->getDesc();
|
||||
snapshot_id = parcel->getSnapshotID();
|
||||
}
|
||||
|
||||
std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region)
|
||||
{
|
||||
region_name = region->getName();
|
||||
}
|
||||
|
||||
getChild<LLUICtrl>("classified_name")->setValue(makeClassifiedName());
|
||||
getChild<LLUICtrl>("classified_desc")->setValue(desc);
|
||||
setSnapshotId(snapshot_id);
|
||||
setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
|
||||
// server will set valid parcel id
|
||||
setParcelId(LLUUID::null);
|
||||
}
|
||||
else
|
||||
{
|
||||
setClassifiedId(key["classified_id"]);
|
||||
setClassifiedName(key["name"]);
|
||||
setDescription(key["desc"]);
|
||||
setSnapshotId(key["snapshot_id"]);
|
||||
setCategory((U32)key["category"].asInteger());
|
||||
setContentType((U32)key["content_type"].asInteger());
|
||||
setClassifiedLocation(key["location_text"]);
|
||||
getChild<LLUICtrl>("auto_renew")->setValue(key["auto_renew"]);
|
||||
getChild<LLUICtrl>("price_for_listing")->setValue(key["price_for_listing"].asInteger());
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::onOpen(const LLSD& key)
|
||||
{
|
||||
mIsNew = key.isUndefined();
|
||||
|
||||
scrollToTop();
|
||||
|
||||
// classified is not created yet
|
||||
bool is_new = isNew() || isNewWithErrors();
|
||||
|
||||
if(is_new)
|
||||
{
|
||||
resetData();
|
||||
resetControls();
|
||||
|
||||
fillIn(key);
|
||||
|
||||
if(isNew())
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLPanelClassifiedInfo::onOpen(key);
|
||||
}
|
||||
|
||||
std::string save_btn_label = is_new ? getString("publish_label") : getString("save_label");
|
||||
getChild<LLUICtrl>("save_changes_btn")->setLabelArg("[LABEL]", save_btn_label);
|
||||
|
||||
enableVerbs(is_new);
|
||||
enableEditing(is_new);
|
||||
showEditing(!is_new);
|
||||
resetDirty();
|
||||
setInfoLoaded(false);
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::processProperties(void* data, EAvatarProcessorType type)
|
||||
{
|
||||
if(APT_CLASSIFIED_INFO == type)
|
||||
{
|
||||
LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
|
||||
if(c_info && getClassifiedId() == c_info->classified_id)
|
||||
{
|
||||
// see LLPanelClassifiedEdit::sendUpdate() for notes
|
||||
mIsNewWithErrors = false;
|
||||
// for just created classified - panel will probably be closed when we get here.
|
||||
if(!getVisible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
enableEditing(true);
|
||||
|
||||
setClassifiedName(c_info->name);
|
||||
setDescription(c_info->description);
|
||||
setSnapshotId(c_info->snapshot_id);
|
||||
setParcelId(c_info->parcel_id);
|
||||
setPosGlobal(c_info->pos_global);
|
||||
|
||||
setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global));
|
||||
// *HACK see LLPanelClassifiedEdit::sendUpdate()
|
||||
setCategory(c_info->category - 1);
|
||||
|
||||
bool mature = is_cf_mature(c_info->flags);
|
||||
bool auto_renew = is_cf_auto_renew(c_info->flags);
|
||||
|
||||
setContentType(mature ? CB_ITEM_MATURE : CB_ITEM_PG);
|
||||
getChild<LLUICtrl>("auto_renew")->setValue(auto_renew);
|
||||
getChild<LLUICtrl>("price_for_listing")->setValue(c_info->price_for_listing);
|
||||
getChildView("price_for_listing")->setEnabled(isNew());
|
||||
|
||||
resetDirty();
|
||||
setInfoLoaded(true);
|
||||
enableVerbs(false);
|
||||
|
||||
// for just created classified - in case user opened edit panel before processProperties() callback
|
||||
getChild<LLUICtrl>("save_changes_btn")->setLabelArg("[LABEL]", getString("save_label"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLPanelClassifiedEdit::isDirty() const
|
||||
{
|
||||
if(mIsNew)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL dirty = false;
|
||||
|
||||
dirty |= LLPanelClassifiedInfo::isDirty();
|
||||
dirty |= getChild<LLUICtrl>("classified_snapshot")->isDirty();
|
||||
dirty |= getChild<LLUICtrl>("classified_name")->isDirty();
|
||||
dirty |= getChild<LLUICtrl>("classified_desc")->isDirty();
|
||||
dirty |= getChild<LLUICtrl>("category")->isDirty();
|
||||
dirty |= getChild<LLUICtrl>("content_type")->isDirty();
|
||||
dirty |= getChild<LLUICtrl>("auto_renew")->isDirty();
|
||||
dirty |= getChild<LLUICtrl>("price_for_listing")->isDirty();
|
||||
|
||||
return dirty;
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::resetDirty()
|
||||
{
|
||||
LLPanelClassifiedInfo::resetDirty();
|
||||
getChild<LLUICtrl>("classified_snapshot")->resetDirty();
|
||||
getChild<LLUICtrl>("classified_name")->resetDirty();
|
||||
|
||||
LLTextEditor* desc = getChild<LLTextEditor>("classified_desc");
|
||||
// call blockUndo() to really reset dirty(and make isDirty work as intended)
|
||||
desc->blockUndo();
|
||||
desc->resetDirty();
|
||||
|
||||
getChild<LLUICtrl>("category")->resetDirty();
|
||||
getChild<LLUICtrl>("content_type")->resetDirty();
|
||||
getChild<LLUICtrl>("auto_renew")->resetDirty();
|
||||
getChild<LLUICtrl>("price_for_listing")->resetDirty();
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::setSaveCallback(const commit_signal_t::slot_type& cb)
|
||||
{
|
||||
mSaveButtonClickedSignal.connect(cb);
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::setCancelCallback(const commit_signal_t::slot_type& cb)
|
||||
{
|
||||
getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::resetControls()
|
||||
{
|
||||
LLPanelClassifiedInfo::resetControls();
|
||||
|
||||
getChild<LLComboBox>("category")->setCurrentByIndex(0);
|
||||
getChild<LLComboBox>("content_type")->setCurrentByIndex(0);
|
||||
getChild<LLUICtrl>("auto_renew")->setValue(false);
|
||||
getChild<LLUICtrl>("price_for_listing")->setValue(MINIMUM_PRICE_FOR_LISTING);
|
||||
getChildView("price_for_listing")->setEnabled(TRUE);
|
||||
}
|
||||
|
||||
bool LLPanelClassifiedEdit::canClose()
|
||||
{
|
||||
return mCanClose;
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::draw()
|
||||
{
|
||||
LLPanel::draw();
|
||||
|
||||
// Need to re-stretch on every draw because LLTextureCtrl::onSelectCallback
|
||||
// does not trigger callbacks when user navigates through images.
|
||||
stretchSnapshot();
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::stretchSnapshot()
|
||||
{
|
||||
LLPanelClassifiedInfo::stretchSnapshot();
|
||||
|
||||
getChild<LLUICtrl>("edit_icon")->setShape(mSnapshotCtrl->getRect());
|
||||
}
|
||||
|
||||
U32 LLPanelClassifiedEdit::getContentType()
|
||||
{
|
||||
LLComboBox* ct_cb = getChild<LLComboBox>("content_type");
|
||||
return ct_cb->getCurrentIndex();
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::setContentType(U32 content_type)
|
||||
{
|
||||
LLComboBox* ct_cb = getChild<LLComboBox>("content_type");
|
||||
ct_cb->setCurrentByIndex(content_type);
|
||||
ct_cb->resetDirty();
|
||||
}
|
||||
|
||||
bool LLPanelClassifiedEdit::getAutoRenew()
|
||||
{
|
||||
return getChild<LLUICtrl>("auto_renew")->getValue().asBoolean();
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::sendUpdate()
|
||||
{
|
||||
LLAvatarClassifiedInfo c_data;
|
||||
|
||||
if(getClassifiedId().isNull())
|
||||
{
|
||||
setClassifiedId(LLUUID::generateNewID());
|
||||
}
|
||||
|
||||
c_data.agent_id = gAgent.getID();
|
||||
c_data.classified_id = getClassifiedId();
|
||||
// *HACK
|
||||
// Categories on server start with 1 while combo-box index starts with 0
|
||||
c_data.category = getCategory() + 1;
|
||||
c_data.name = getClassifiedName();
|
||||
c_data.description = getDescription();
|
||||
c_data.parcel_id = getParcelId();
|
||||
c_data.snapshot_id = getSnapshotId();
|
||||
c_data.pos_global = getPosGlobal();
|
||||
c_data.flags = getFlags();
|
||||
c_data.price_for_listing = getPriceForListing();
|
||||
|
||||
LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data);
|
||||
|
||||
if(isNew())
|
||||
{
|
||||
// Lets assume there will be some error.
|
||||
// Successful sendClassifiedInfoUpdate will trigger processProperties and
|
||||
// let us know there was no error.
|
||||
mIsNewWithErrors = true;
|
||||
}
|
||||
}
|
||||
|
||||
U32 LLPanelClassifiedEdit::getCategory()
|
||||
{
|
||||
LLComboBox* cat_cb = getChild<LLComboBox>("category");
|
||||
return cat_cb->getCurrentIndex();
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::setCategory(U32 category)
|
||||
{
|
||||
LLComboBox* cat_cb = getChild<LLComboBox>("category");
|
||||
cat_cb->setCurrentByIndex(category);
|
||||
cat_cb->resetDirty();
|
||||
}
|
||||
|
||||
U8 LLPanelClassifiedEdit::getFlags()
|
||||
{
|
||||
bool auto_renew = getChild<LLUICtrl>("auto_renew")->getValue().asBoolean();
|
||||
|
||||
LLComboBox* content_cb = getChild<LLComboBox>("content_type");
|
||||
bool mature = content_cb->getCurrentIndex() == CB_ITEM_MATURE;
|
||||
|
||||
return pack_classified_flags_request(auto_renew, false, mature, false);
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::enableVerbs(bool enable)
|
||||
{
|
||||
getChildView("save_changes_btn")->setEnabled(enable);
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::enableEditing(bool enable)
|
||||
{
|
||||
getChildView("classified_snapshot")->setEnabled(enable);
|
||||
getChildView("classified_name")->setEnabled(enable);
|
||||
getChildView("classified_desc")->setEnabled(enable);
|
||||
getChildView("set_to_curr_location_btn")->setEnabled(enable);
|
||||
getChildView("category")->setEnabled(enable);
|
||||
getChildView("content_type")->setEnabled(enable);
|
||||
getChildView("price_for_listing")->setEnabled(enable);
|
||||
getChildView("auto_renew")->setEnabled(enable);
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::showEditing(bool show)
|
||||
{
|
||||
getChildView("price_for_listing_label")->setVisible( show);
|
||||
getChildView("price_for_listing")->setVisible( show);
|
||||
}
|
||||
|
||||
std::string LLPanelClassifiedEdit::makeClassifiedName()
|
||||
{
|
||||
std::string name;
|
||||
|
||||
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
||||
if(parcel)
|
||||
{
|
||||
name = parcel->getName();
|
||||
}
|
||||
|
||||
if(!name.empty())
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if(region)
|
||||
{
|
||||
name = region->getName();
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
S32 LLPanelClassifiedEdit::getPriceForListing()
|
||||
{
|
||||
return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::setPriceForListing(S32 price)
|
||||
{
|
||||
getChild<LLUICtrl>("price_for_listing")->setValue(price);
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::onSetLocationClick()
|
||||
{
|
||||
setPosGlobal(gAgent.getPositionGlobal());
|
||||
setParcelId(LLUUID::null);
|
||||
|
||||
std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region)
|
||||
{
|
||||
region_name = region->getName();
|
||||
}
|
||||
|
||||
setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
|
||||
|
||||
// mark classified as dirty
|
||||
setValue(LLSD());
|
||||
|
||||
onChange();
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::onChange()
|
||||
{
|
||||
enableVerbs(isDirty());
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::onSaveClick()
|
||||
{
|
||||
mCanClose = false;
|
||||
|
||||
if(!isValidName())
|
||||
{
|
||||
notifyInvalidName();
|
||||
return;
|
||||
}
|
||||
if(isNew() || isNewWithErrors())
|
||||
{
|
||||
if(gStatusBar->getBalance() < getPriceForListing())
|
||||
{
|
||||
LLNotificationsUtil::add("ClassifiedInsufficientFunds");
|
||||
return;
|
||||
}
|
||||
|
||||
mPublishFloater = LLFloaterReg::findTypedInstance<LLPublishClassifiedFloater>(
|
||||
"publish_classified", LLSD());
|
||||
|
||||
if(!mPublishFloater)
|
||||
{
|
||||
mPublishFloater = LLFloaterReg::getTypedInstance<LLPublishClassifiedFloater>(
|
||||
"publish_classified", LLSD());
|
||||
|
||||
mPublishFloater->setPublishClickedCallback(boost::bind
|
||||
(&LLPanelClassifiedEdit::onPublishFloaterPublishClicked, this));
|
||||
}
|
||||
|
||||
// set spinner value before it has focus or value wont be set
|
||||
mPublishFloater->setPrice(getPriceForListing());
|
||||
mPublishFloater->openFloater(mPublishFloater->getKey());
|
||||
mPublishFloater->center();
|
||||
}
|
||||
else
|
||||
{
|
||||
doSave();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::doSave()
|
||||
{
|
||||
mCanClose = true;
|
||||
sendUpdate();
|
||||
resetDirty();
|
||||
|
||||
mSaveButtonClickedSignal(this, LLSD());
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::onPublishFloaterPublishClicked()
|
||||
{
|
||||
setPriceForListing(mPublishFloater->getPrice());
|
||||
|
||||
doSave();
|
||||
}
|
||||
|
||||
std::string LLPanelClassifiedEdit::getLocationNotice()
|
||||
{
|
||||
static std::string location_notice = getString("location_notice");
|
||||
return location_notice;
|
||||
}
|
||||
|
||||
bool LLPanelClassifiedEdit::isValidName()
|
||||
{
|
||||
std::string name = getClassifiedName();
|
||||
if (name.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!isalnum(name[0]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::notifyInvalidName()
|
||||
{
|
||||
std::string name = getClassifiedName();
|
||||
if (name.empty())
|
||||
{
|
||||
LLNotificationsUtil::add("BlankClassifiedName");
|
||||
}
|
||||
else if (!isalnum(name[0]))
|
||||
{
|
||||
LLNotificationsUtil::add("ClassifiedMustBeAlphanumeric");
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
|
||||
{
|
||||
ctrl->setVisible(TRUE);
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
|
||||
{
|
||||
ctrl->setVisible(FALSE);
|
||||
}
|
||||
|
||||
void LLPanelClassifiedEdit::onTextureSelected()
|
||||
{
|
||||
setSnapshotId(mSnapshotCtrl->getValue().asUUID());
|
||||
onChange();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLPublishClassifiedFloater::LLPublishClassifiedFloater(const LLSD& key)
|
||||
: LLFloater(key)
|
||||
{
|
||||
}
|
||||
|
||||
LLPublishClassifiedFloater::~LLPublishClassifiedFloater()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLPublishClassifiedFloater::postBuild()
|
||||
{
|
||||
LLFloater::postBuild();
|
||||
|
||||
childSetAction("publish_btn", boost::bind(&LLFloater::closeFloater, this, false));
|
||||
childSetAction("cancel_btn", boost::bind(&LLFloater::closeFloater, this, false));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPublishClassifiedFloater::setPrice(S32 price)
|
||||
{
|
||||
getChild<LLUICtrl>("price_for_listing")->setValue(price);
|
||||
}
|
||||
|
||||
S32 LLPublishClassifiedFloater::getPrice()
|
||||
{
|
||||
return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
|
||||
}
|
||||
|
||||
void LLPublishClassifiedFloater::setPublishClickedCallback(const commit_signal_t::slot_type& cb)
|
||||
{
|
||||
getChild<LLButton>("publish_btn")->setClickedCallback(cb);
|
||||
}
|
||||
|
||||
void LLPublishClassifiedFloater::setCancelClickedCallback(const commit_signal_t::slot_type& cb)
|
||||
{
|
||||
getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
|
||||
}
|
||||
|
||||
//EOF
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
/**
|
||||
* @file llpanelclassified.h
|
||||
* @brief LLPanelClassified class definition
|
||||
* @brief LLPanelClassifiedInfo class definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
|
||||
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
* Copyright (C) 2021, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -35,39 +35,16 @@
|
|||
#include "llfloater.h"
|
||||
#include "llpanel.h"
|
||||
#include "llrect.h"
|
||||
#include "lluuid.h"
|
||||
#include "v3dmath.h"
|
||||
#include "llcoros.h"
|
||||
#include "lleventcoro.h"
|
||||
|
||||
class LLScrollContainer;
|
||||
class LLTextureCtrl;
|
||||
class LLUICtrl;
|
||||
|
||||
class LLPublishClassifiedFloater : public LLFloater
|
||||
{
|
||||
public:
|
||||
LLPublishClassifiedFloater(const LLSD& key);
|
||||
virtual ~LLPublishClassifiedFloater();
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
void setPrice(S32 price);
|
||||
S32 getPrice();
|
||||
|
||||
void setPublishClickedCallback(const commit_signal_t::slot_type& cb);
|
||||
void setCancelClickedCallback(const commit_signal_t::slot_type& cb);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver
|
||||
{
|
||||
LOG_CLASS(LLPanelClassifiedInfo);
|
||||
public:
|
||||
|
||||
static LLPanelClassifiedInfo* create();
|
||||
|
||||
LLPanelClassifiedInfo();
|
||||
virtual ~LLPanelClassifiedInfo();
|
||||
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
|
|
@ -135,18 +112,12 @@ public:
|
|||
const LLVector3d& global_pos,
|
||||
const std::string& sim_name);
|
||||
|
||||
void setExitCallback(const commit_callback_t& cb);
|
||||
|
||||
void setEditClassifiedCallback(const commit_callback_t& cb);
|
||||
|
||||
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
|
||||
/*virtual*/ void draw();
|
||||
|
||||
protected:
|
||||
|
||||
LLPanelClassifiedInfo();
|
||||
|
||||
virtual void resetData();
|
||||
|
||||
virtual void resetControls();
|
||||
|
|
@ -165,7 +136,6 @@ protected:
|
|||
|
||||
void onMapClick();
|
||||
void onTeleportClick();
|
||||
void onExit();
|
||||
|
||||
bool mSnapshotStreched;
|
||||
LLRect mSnapshotRect;
|
||||
|
|
@ -202,100 +172,4 @@ private:
|
|||
static panel_list_t sAllPanels;
|
||||
};
|
||||
|
||||
class LLPanelClassifiedEdit : public LLPanelClassifiedInfo
|
||||
{
|
||||
LOG_CLASS(LLPanelClassifiedEdit);
|
||||
public:
|
||||
|
||||
static LLPanelClassifiedEdit* create();
|
||||
|
||||
virtual ~LLPanelClassifiedEdit();
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
void fillIn(const LLSD& key);
|
||||
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
|
||||
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
|
||||
|
||||
/*virtual*/ BOOL isDirty() const;
|
||||
|
||||
/*virtual*/ void resetDirty();
|
||||
|
||||
void setSaveCallback(const commit_signal_t::slot_type& cb);
|
||||
|
||||
void setCancelCallback(const commit_signal_t::slot_type& cb);
|
||||
|
||||
/*virtual*/ void resetControls();
|
||||
|
||||
bool isNew() { return mIsNew; }
|
||||
|
||||
bool isNewWithErrors() { return mIsNewWithErrors; }
|
||||
|
||||
bool canClose();
|
||||
|
||||
void draw();
|
||||
|
||||
void stretchSnapshot();
|
||||
|
||||
U32 getCategory();
|
||||
|
||||
void setCategory(U32 category);
|
||||
|
||||
U32 getContentType();
|
||||
|
||||
void setContentType(U32 content_type);
|
||||
|
||||
bool getAutoRenew();
|
||||
|
||||
S32 getPriceForListing();
|
||||
|
||||
protected:
|
||||
|
||||
LLPanelClassifiedEdit();
|
||||
|
||||
void sendUpdate();
|
||||
|
||||
void enableVerbs(bool enable);
|
||||
|
||||
void enableEditing(bool enable);
|
||||
|
||||
void showEditing(bool show);
|
||||
|
||||
std::string makeClassifiedName();
|
||||
|
||||
void setPriceForListing(S32 price);
|
||||
|
||||
U8 getFlags();
|
||||
|
||||
std::string getLocationNotice();
|
||||
|
||||
bool isValidName();
|
||||
|
||||
void notifyInvalidName();
|
||||
|
||||
void onSetLocationClick();
|
||||
void onChange();
|
||||
void onSaveClick();
|
||||
|
||||
void doSave();
|
||||
|
||||
void onPublishFloaterPublishClicked();
|
||||
|
||||
void onTexturePickerMouseEnter(LLUICtrl* ctrl);
|
||||
void onTexturePickerMouseLeave(LLUICtrl* ctrl);
|
||||
|
||||
void onTextureSelected();
|
||||
|
||||
private:
|
||||
bool mIsNew;
|
||||
bool mIsNewWithErrors;
|
||||
bool mCanClose;
|
||||
|
||||
LLPublishClassifiedFloater* mPublishFloater;
|
||||
|
||||
commit_signal_t mSaveButtonClickedSignal;
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELCLASSIFIED_H
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
#include "llaccordionctrltab.h"
|
||||
#include "llflatlistview.h"
|
||||
#include "llpanelavatar.h"
|
||||
|
||||
class LLExperienceItem;
|
||||
class LLPanelProfile;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* @file llpanelavatar.cpp
|
||||
* @brief LLPanelAvatar and related class implementations
|
||||
* @file llpanelimcontrolpanel.cpp
|
||||
* @brief LLPanelIMControlPanel and related class implementations
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "llpanellandmarks.h"
|
||||
|
||||
#include "llbutton.h"
|
||||
#include "llfloaterprofile.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llsdutil.h"
|
||||
|
|
@ -1003,17 +1004,6 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
|
|||
return can_be_modified;
|
||||
}
|
||||
|
||||
void LLLandmarksPanel::onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params)
|
||||
{
|
||||
pick_panel->setVisible(FALSE);
|
||||
owner->removeChild(pick_panel);
|
||||
//we need remove observer to avoid processParcelInfo in the future.
|
||||
LLRemoteParcelInfoProcessor::getInstance()->removeObserver(params["parcel_id"].asUUID(), this);
|
||||
|
||||
delete pick_panel;
|
||||
pick_panel = NULL;
|
||||
}
|
||||
|
||||
bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data , EAcceptance* accept)
|
||||
{
|
||||
*accept = ACCEPT_NO;
|
||||
|
|
@ -1080,49 +1070,21 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,
|
|||
LLInventoryItem* inv_item,
|
||||
const LLParcelData& parcel_data)
|
||||
{
|
||||
LLPanelPickEdit* panel_pick = LLPanelPickEdit::create();
|
||||
LLVector3d landmark_global_pos;
|
||||
landmark->getGlobalPos(landmark_global_pos);
|
||||
|
||||
// let's toggle pick panel into panel places
|
||||
LLPanel* panel_places = NULL;
|
||||
LLFloaterSidePanelContainer* floaterp = LLFloaterReg::getTypedInstance<LLFloaterSidePanelContainer>("places");
|
||||
if (floaterp)
|
||||
{
|
||||
panel_places = floaterp->findChild<LLPanel>("main_panel");
|
||||
}
|
||||
|
||||
if (!panel_places)
|
||||
{
|
||||
llassert(NULL != panel_places);
|
||||
return;
|
||||
}
|
||||
panel_places->addChild(panel_pick);
|
||||
LLRect paren_rect(panel_places->getRect());
|
||||
panel_pick->reshape(paren_rect.getWidth(),paren_rect.getHeight(), TRUE);
|
||||
panel_pick->setRect(paren_rect);
|
||||
panel_pick->onOpen(LLSD());
|
||||
|
||||
LLPickData data;
|
||||
data.pos_global = landmark_global_pos;
|
||||
data.name = inv_item->getName();
|
||||
data.desc = inv_item->getDescription();
|
||||
data.snapshot_id = parcel_data.snapshot_id;
|
||||
data.parcel_id = parcel_data.parcel_id;
|
||||
panel_pick->setPickData(&data);
|
||||
|
||||
LLSD params;
|
||||
params["parcel_id"] = parcel_data.parcel_id;
|
||||
/* set exit callback to get back onto panel places
|
||||
in callback we will make cleaning up( delete pick_panel instance,
|
||||
remove landmark panel from observer list
|
||||
*/
|
||||
panel_pick->setExitCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
|
||||
panel_pick, panel_places,params));
|
||||
panel_pick->setSaveCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
|
||||
panel_pick, panel_places,params));
|
||||
panel_pick->setCancelCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
|
||||
panel_pick, panel_places,params));
|
||||
LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID)));
|
||||
if (profile_floater)
|
||||
{
|
||||
profile_floater->createPick(data);
|
||||
}
|
||||
}
|
||||
|
||||
void LLLandmarksPanel::doCreatePick(LLLandmark* landmark, const LLUUID &item_id)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@
|
|||
#include "llinventorymodel.h"
|
||||
#include "lllandmarklist.h"
|
||||
#include "llpanelplacestab.h"
|
||||
#include "llpanelpick.h"
|
||||
#include "llremoteparcelrequest.h"
|
||||
|
||||
class LLAccordionCtrlTab;
|
||||
|
|
@ -136,7 +135,6 @@ private:
|
|||
* For now it checks cut/rename/delete/paste actions.
|
||||
*/
|
||||
bool canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const;
|
||||
void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params);
|
||||
|
||||
/**
|
||||
* Landmark actions callbacks. Fire when a landmark is loaded from the list.
|
||||
|
|
|
|||
|
|
@ -1,67 +0,0 @@
|
|||
/**
|
||||
* @file llpanelme.cpp
|
||||
* @brief Side tray "Me" (My Profile) panel
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llpanelme.h"
|
||||
|
||||
// Viewer includes
|
||||
#include "llpanelprofile.h"
|
||||
#include "llagent.h"
|
||||
#include "llagentcamera.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llfirstuse.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llhints.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
// Linden libraries
|
||||
#include "llavatarnamecache.h" // IDEVO
|
||||
#include "lliconctrl.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llnotificationsutil.h" // IDEVO
|
||||
#include "lltabcontainer.h"
|
||||
#include "lltexturectrl.h"
|
||||
|
||||
static LLPanelInjector<LLPanelMe> t_panel_me_profile("panel_me");
|
||||
|
||||
LLPanelMe::LLPanelMe(void)
|
||||
: LLPanelProfile()
|
||||
{
|
||||
setAvatarId(gAgent.getID());
|
||||
}
|
||||
|
||||
BOOL LLPanelMe::postBuild()
|
||||
{
|
||||
LLPanelProfile::postBuild();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelMe::onOpen(const LLSD& key)
|
||||
{
|
||||
LLPanelProfile::onOpen(key);
|
||||
}
|
||||
|
|
@ -1,620 +0,0 @@
|
|||
/**
|
||||
* @file llpanelpick.cpp
|
||||
* @brief LLPanelPick class implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// Display of a "Top Pick" used both for the global top picks in the
|
||||
// Find directory, and also for each individual user's picks in their
|
||||
// profile.
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llpanelpick.h"
|
||||
|
||||
#include "message.h"
|
||||
|
||||
#include "llparcel.h"
|
||||
|
||||
#include "llbutton.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "lliconctrl.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llpanel.h"
|
||||
#include "llscrollcontainer.h"
|
||||
#include "lltexteditor.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llagentpicksinfo.h"
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
#include "llfloaterworldmap.h"
|
||||
#include "lltexturectrl.h"
|
||||
#include "lluiconstants.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llworldmap.h"
|
||||
|
||||
|
||||
#define XML_PANEL_EDIT_PICK "panel_edit_pick.xml"
|
||||
#define XML_PANEL_PICK_INFO "panel_pick_info.xml"
|
||||
|
||||
#define XML_NAME "pick_name"
|
||||
#define XML_DESC "pick_desc"
|
||||
#define XML_SNAPSHOT "pick_snapshot"
|
||||
#define XML_LOCATION "pick_location"
|
||||
|
||||
#define XML_BTN_ON_TXTR "edit_icon"
|
||||
#define XML_BTN_SAVE "save_changes_btn"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//static
|
||||
LLPanelPickInfo* LLPanelPickInfo::create()
|
||||
{
|
||||
LLPanelPickInfo* panel = new LLPanelPickInfo();
|
||||
panel->buildFromFile(XML_PANEL_PICK_INFO);
|
||||
return panel;
|
||||
}
|
||||
|
||||
LLPanelPickInfo::LLPanelPickInfo()
|
||||
: LLPanel()
|
||||
, LLAvatarPropertiesObserver()
|
||||
, LLRemoteParcelInfoObserver()
|
||||
, mAvatarId(LLUUID::null)
|
||||
, mSnapshotCtrl(NULL)
|
||||
, mPickId(LLUUID::null)
|
||||
, mParcelId(LLUUID::null)
|
||||
, mRequestedId(LLUUID::null)
|
||||
, mScrollingPanelMinHeight(0)
|
||||
, mScrollingPanelWidth(0)
|
||||
, mScrollingPanel(NULL)
|
||||
, mScrollContainer(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LLPanelPickInfo::~LLPanelPickInfo()
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
|
||||
|
||||
if (mParcelId.notNull())
|
||||
{
|
||||
LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPickInfo::onOpen(const LLSD& key)
|
||||
{
|
||||
LLUUID avatar_id = key["avatar_id"];
|
||||
if(avatar_id.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(getAvatarId().notNull())
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(
|
||||
getAvatarId(), this);
|
||||
}
|
||||
|
||||
setAvatarId(avatar_id);
|
||||
|
||||
resetData();
|
||||
resetControls();
|
||||
|
||||
setPickId(key["pick_id"]);
|
||||
setPickName(key["pick_name"]);
|
||||
setPickDesc(key["pick_desc"]);
|
||||
setSnapshotId(key["snapshot_id"]);
|
||||
|
||||
LLAvatarPropertiesProcessor::getInstance()->addObserver(
|
||||
getAvatarId(), this);
|
||||
LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(
|
||||
getAvatarId(), getPickId());
|
||||
}
|
||||
|
||||
BOOL LLPanelPickInfo::postBuild()
|
||||
{
|
||||
mSnapshotCtrl = getChild<LLTextureCtrl>(XML_SNAPSHOT);
|
||||
|
||||
childSetAction("teleport_btn", boost::bind(&LLPanelPickInfo::onClickTeleport, this));
|
||||
childSetAction("show_on_map_btn", boost::bind(&LLPanelPickInfo::onClickMap, this));
|
||||
childSetAction("back_btn", boost::bind(&LLPanelPickInfo::onClickBack, this));
|
||||
|
||||
mScrollingPanel = getChild<LLPanel>("scroll_content_panel");
|
||||
mScrollContainer = getChild<LLScrollContainer>("profile_scroll");
|
||||
|
||||
mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight();
|
||||
mScrollingPanelWidth = mScrollingPanel->getRect().getWidth();
|
||||
|
||||
LLTextEditor* text_desc = getChild<LLTextEditor>(XML_DESC);
|
||||
text_desc->setContentTrusted(false);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelPickInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
LLPanel::reshape(width, height, called_from_parent);
|
||||
|
||||
if (!mScrollContainer || !mScrollingPanel)
|
||||
return;
|
||||
|
||||
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
|
||||
|
||||
S32 scroll_height = mScrollContainer->getRect().getHeight();
|
||||
if (mScrollingPanelMinHeight >= scroll_height)
|
||||
{
|
||||
mScrollingPanel->reshape(mScrollingPanelWidth, mScrollingPanelMinHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
mScrollingPanel->reshape(mScrollingPanelWidth + scrollbar_size, scroll_height);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPickInfo::processProperties(void* data, EAvatarProcessorType type)
|
||||
{
|
||||
if(APT_PICK_INFO != type)
|
||||
{
|
||||
return;
|
||||
}
|
||||
LLPickData* pick_info = static_cast<LLPickData*>(data);
|
||||
if(!pick_info
|
||||
|| pick_info->creator_id != getAvatarId()
|
||||
|| pick_info->pick_id != getPickId())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mParcelId = pick_info->parcel_id;
|
||||
setSnapshotId(pick_info->snapshot_id);
|
||||
setPickName(pick_info->name);
|
||||
setPickDesc(pick_info->desc);
|
||||
setPosGlobal(pick_info->pos_global);
|
||||
|
||||
// Send remote parcel info request to get parcel name and sim (region) name.
|
||||
sendParcelInfoRequest();
|
||||
|
||||
// *NOTE dzaporozhan
|
||||
// We want to keep listening to APT_PICK_INFO because user may
|
||||
// edit the Pick and we have to update Pick info panel.
|
||||
// revomeObserver is called from onClickBack
|
||||
}
|
||||
|
||||
void LLPanelPickInfo::sendParcelInfoRequest()
|
||||
{
|
||||
if (mParcelId != mRequestedId)
|
||||
{
|
||||
LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this);
|
||||
LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId);
|
||||
|
||||
mRequestedId = mParcelId;
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPickInfo::setExitCallback(const commit_callback_t& cb)
|
||||
{
|
||||
getChild<LLButton>("back_btn")->setClickedCallback(cb);
|
||||
}
|
||||
|
||||
void LLPanelPickInfo::processParcelInfo(const LLParcelData& parcel_data)
|
||||
{
|
||||
setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name,
|
||||
parcel_data.sim_name, getPosGlobal()));
|
||||
|
||||
// We have received parcel info for the requested ID so clear it now.
|
||||
mRequestedId.setNull();
|
||||
|
||||
if (mParcelId.notNull())
|
||||
{
|
||||
LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPickInfo::setEditPickCallback(const commit_callback_t& cb)
|
||||
{
|
||||
getChild<LLButton>("edit_btn")->setClickedCallback(cb);
|
||||
}
|
||||
|
||||
// PROTECTED AREA
|
||||
|
||||
void LLPanelPickInfo::resetControls()
|
||||
{
|
||||
if(getAvatarId() == gAgent.getID())
|
||||
{
|
||||
getChildView("edit_btn")->setEnabled(TRUE);
|
||||
getChildView("edit_btn")->setVisible( TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
getChildView("edit_btn")->setEnabled(FALSE);
|
||||
getChildView("edit_btn")->setVisible( FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPickInfo::resetData()
|
||||
{
|
||||
setPickName(LLStringUtil::null);
|
||||
setPickDesc(LLStringUtil::null);
|
||||
setPickLocation(LLStringUtil::null);
|
||||
setPickId(LLUUID::null);
|
||||
setSnapshotId(LLUUID::null);
|
||||
mPosGlobal.clearVec();
|
||||
mParcelId.setNull();
|
||||
mRequestedId.setNull();
|
||||
}
|
||||
|
||||
// static
|
||||
std::string LLPanelPickInfo::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global)
|
||||
{
|
||||
std::string location_text;
|
||||
location_text.append(owner_name);
|
||||
if (!original_name.empty())
|
||||
{
|
||||
if (!location_text.empty()) location_text.append(", ");
|
||||
location_text.append(original_name);
|
||||
|
||||
}
|
||||
if (!sim_name.empty())
|
||||
{
|
||||
if (!location_text.empty()) location_text.append(", ");
|
||||
location_text.append(sim_name);
|
||||
}
|
||||
|
||||
if (!location_text.empty()) location_text.append(" ");
|
||||
|
||||
if (!pos_global.isNull())
|
||||
{
|
||||
S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
|
||||
S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
|
||||
S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
|
||||
location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
|
||||
}
|
||||
return location_text;
|
||||
}
|
||||
|
||||
void LLPanelPickInfo::setSnapshotId(const LLUUID& id)
|
||||
{
|
||||
mSnapshotCtrl->setImageAssetID(id);
|
||||
mSnapshotCtrl->setValid(TRUE);
|
||||
}
|
||||
|
||||
void LLPanelPickInfo::setPickName(const std::string& name)
|
||||
{
|
||||
getChild<LLUICtrl>(XML_NAME)->setValue(name);
|
||||
}
|
||||
|
||||
void LLPanelPickInfo::setPickDesc(const std::string& desc)
|
||||
{
|
||||
getChild<LLUICtrl>(XML_DESC)->setValue(desc);
|
||||
}
|
||||
|
||||
void LLPanelPickInfo::setPickLocation(const std::string& location)
|
||||
{
|
||||
getChild<LLUICtrl>(XML_LOCATION)->setValue(location);
|
||||
}
|
||||
|
||||
void LLPanelPickInfo::onClickMap()
|
||||
{
|
||||
LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
|
||||
LLFloaterReg::showInstance("world_map", "center");
|
||||
}
|
||||
|
||||
void LLPanelPickInfo::onClickTeleport()
|
||||
{
|
||||
if (!getPosGlobal().isExactlyZero())
|
||||
{
|
||||
gAgent.teleportViaLocation(getPosGlobal());
|
||||
LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPickInfo::onClickBack()
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//static
|
||||
LLPanelPickEdit* LLPanelPickEdit::create()
|
||||
{
|
||||
LLPanelPickEdit* panel = new LLPanelPickEdit();
|
||||
panel->buildFromFile(XML_PANEL_EDIT_PICK);
|
||||
return panel;
|
||||
}
|
||||
|
||||
LLPanelPickEdit::LLPanelPickEdit()
|
||||
: LLPanelPickInfo()
|
||||
, mLocationChanged(false)
|
||||
, mNeedData(true)
|
||||
, mNewPick(false)
|
||||
{
|
||||
}
|
||||
|
||||
LLPanelPickEdit::~LLPanelPickEdit()
|
||||
{
|
||||
}
|
||||
|
||||
void LLPanelPickEdit::onOpen(const LLSD& key)
|
||||
{
|
||||
LLUUID pick_id = key["pick_id"];
|
||||
mNeedData = true;
|
||||
|
||||
// creating new Pick
|
||||
if(pick_id.isNull())
|
||||
{
|
||||
mNewPick = true;
|
||||
|
||||
setAvatarId(gAgent.getID());
|
||||
|
||||
resetData();
|
||||
resetControls();
|
||||
|
||||
setPosGlobal(gAgent.getPositionGlobal());
|
||||
|
||||
LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null;
|
||||
std::string pick_name, pick_desc, region_name;
|
||||
|
||||
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
||||
if(parcel)
|
||||
{
|
||||
parcel_id = parcel->getID();
|
||||
pick_name = parcel->getName();
|
||||
pick_desc = parcel->getDesc();
|
||||
snapshot_id = parcel->getSnapshotID();
|
||||
}
|
||||
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if(region)
|
||||
{
|
||||
region_name = region->getName();
|
||||
}
|
||||
|
||||
setParcelID(parcel_id);
|
||||
getChild<LLUICtrl>("pick_name")->setValue(pick_name.empty() ? region_name : pick_name);
|
||||
getChild<LLUICtrl>("pick_desc")->setValue(pick_desc);
|
||||
setSnapshotId(snapshot_id);
|
||||
setPickLocation(createLocationText(getLocationNotice(), pick_name, region_name, getPosGlobal()));
|
||||
|
||||
enableSaveButton(true);
|
||||
}
|
||||
// editing existing pick
|
||||
else
|
||||
{
|
||||
mNewPick = false;
|
||||
LLPanelPickInfo::onOpen(key);
|
||||
|
||||
enableSaveButton(false);
|
||||
}
|
||||
|
||||
resetDirty();
|
||||
}
|
||||
|
||||
void LLPanelPickEdit::setPickData(const LLPickData* pick_data)
|
||||
{
|
||||
if(!pick_data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mNeedData = false;
|
||||
|
||||
setParcelID(pick_data->parcel_id);
|
||||
getChild<LLUICtrl>("pick_name")->setValue(pick_data->name);
|
||||
getChild<LLUICtrl>("pick_desc")->setValue(pick_data->desc);
|
||||
setSnapshotId(pick_data->snapshot_id);
|
||||
setPosGlobal(pick_data->pos_global);
|
||||
setPickLocation(createLocationText(LLStringUtil::null, pick_data->name,
|
||||
pick_data->sim_name, pick_data->pos_global));
|
||||
}
|
||||
|
||||
BOOL LLPanelPickEdit::postBuild()
|
||||
{
|
||||
LLPanelPickInfo::postBuild();
|
||||
|
||||
mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelPickEdit::onSnapshotChanged, this));
|
||||
|
||||
LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name");
|
||||
line_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1), NULL);
|
||||
|
||||
LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc");
|
||||
text_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1));
|
||||
|
||||
childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPickEdit::onClickSave, this));
|
||||
childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPickEdit::onClickSetLocation, this));
|
||||
|
||||
initTexturePickerMouseEvents();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelPickEdit::setSaveCallback(const commit_callback_t& cb)
|
||||
{
|
||||
getChild<LLButton>("save_changes_btn")->setClickedCallback(cb);
|
||||
}
|
||||
|
||||
void LLPanelPickEdit::setCancelCallback(const commit_callback_t& cb)
|
||||
{
|
||||
getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
|
||||
}
|
||||
|
||||
void LLPanelPickEdit::resetDirty()
|
||||
{
|
||||
LLPanelPickInfo::resetDirty();
|
||||
|
||||
getChild<LLLineEditor>("pick_name")->resetDirty();
|
||||
getChild<LLTextEditor>("pick_desc")->resetDirty();
|
||||
mSnapshotCtrl->resetDirty();
|
||||
mLocationChanged = false;
|
||||
}
|
||||
|
||||
BOOL LLPanelPickEdit::isDirty() const
|
||||
{
|
||||
if( mNewPick
|
||||
|| LLPanelPickInfo::isDirty()
|
||||
|| mLocationChanged
|
||||
|| mSnapshotCtrl->isDirty()
|
||||
|| getChild<LLLineEditor>("pick_name")->isDirty()
|
||||
|| getChild<LLTextEditor>("pick_desc")->isDirty())
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// PROTECTED AREA
|
||||
|
||||
void LLPanelPickEdit::sendUpdate()
|
||||
{
|
||||
LLPickData pick_data;
|
||||
|
||||
// If we don't have a pick id yet, we'll need to generate one,
|
||||
// otherwise we'll keep overwriting pick_id 00000 in the database.
|
||||
if (getPickId().isNull())
|
||||
{
|
||||
getPickId().generate();
|
||||
}
|
||||
|
||||
pick_data.agent_id = gAgent.getID();
|
||||
pick_data.session_id = gAgent.getSessionID();
|
||||
pick_data.pick_id = getPickId();
|
||||
pick_data.creator_id = gAgent.getID();;
|
||||
|
||||
//legacy var need to be deleted
|
||||
pick_data.top_pick = FALSE;
|
||||
pick_data.parcel_id = mParcelId;
|
||||
pick_data.name = getChild<LLUICtrl>(XML_NAME)->getValue().asString();
|
||||
pick_data.desc = getChild<LLUICtrl>(XML_DESC)->getValue().asString();
|
||||
pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
|
||||
pick_data.pos_global = getPosGlobal();
|
||||
pick_data.sort_order = 0;
|
||||
pick_data.enabled = TRUE;
|
||||
|
||||
LLAvatarPropertiesProcessor::instance().sendPickInfoUpdate(&pick_data);
|
||||
|
||||
if(mNewPick)
|
||||
{
|
||||
// Assume a successful create pick operation, make new number of picks
|
||||
// available immediately. Actual number of picks will be requested in
|
||||
// LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond.
|
||||
LLAgentPicksInfo::getInstance()->incrementNumberOfPicks();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPickEdit::onSnapshotChanged()
|
||||
{
|
||||
enableSaveButton(true);
|
||||
}
|
||||
|
||||
void LLPanelPickEdit::onPickChanged(LLUICtrl* ctrl)
|
||||
{
|
||||
enableSaveButton(isDirty());
|
||||
}
|
||||
|
||||
void LLPanelPickEdit::resetData()
|
||||
{
|
||||
LLPanelPickInfo::resetData();
|
||||
mLocationChanged = false;
|
||||
}
|
||||
|
||||
void LLPanelPickEdit::enableSaveButton(bool enable)
|
||||
{
|
||||
getChildView(XML_BTN_SAVE)->setEnabled(enable);
|
||||
}
|
||||
|
||||
void LLPanelPickEdit::onClickSetLocation()
|
||||
{
|
||||
// Save location for later use.
|
||||
setPosGlobal(gAgent.getPositionGlobal());
|
||||
|
||||
std::string parcel_name, region_name;
|
||||
|
||||
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
||||
if (parcel)
|
||||
{
|
||||
mParcelId = parcel->getID();
|
||||
parcel_name = parcel->getName();
|
||||
}
|
||||
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if(region)
|
||||
{
|
||||
region_name = region->getName();
|
||||
}
|
||||
|
||||
setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal()));
|
||||
|
||||
mLocationChanged = true;
|
||||
enableSaveButton(TRUE);
|
||||
}
|
||||
|
||||
void LLPanelPickEdit::onClickSave()
|
||||
{
|
||||
sendUpdate();
|
||||
|
||||
mLocationChanged = false;
|
||||
|
||||
LLSD params;
|
||||
params["action"] = "save_new_pick";
|
||||
notifyParent(params);
|
||||
}
|
||||
|
||||
std::string LLPanelPickEdit::getLocationNotice()
|
||||
{
|
||||
static std::string notice = getString("location_notice");
|
||||
return notice;
|
||||
}
|
||||
|
||||
void LLPanelPickEdit::processProperties(void* data, EAvatarProcessorType type)
|
||||
{
|
||||
if(mNeedData)
|
||||
{
|
||||
LLPanelPickInfo::processProperties(data, type);
|
||||
}
|
||||
}
|
||||
|
||||
// PRIVATE AREA
|
||||
|
||||
void LLPanelPickEdit::initTexturePickerMouseEvents()
|
||||
{
|
||||
text_icon = getChild<LLIconCtrl>(XML_BTN_ON_TXTR);
|
||||
mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseEnter, this, _1));
|
||||
mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseLeave, this, _1));
|
||||
|
||||
text_icon->setVisible(FALSE);
|
||||
}
|
||||
|
||||
void LLPanelPickEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
|
||||
{
|
||||
text_icon->setVisible(TRUE);
|
||||
}
|
||||
|
||||
void LLPanelPickEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
|
||||
{
|
||||
text_icon->setVisible(FALSE);
|
||||
}
|
||||
|
|
@ -1,264 +0,0 @@
|
|||
/**
|
||||
* @file llpanelpick.h
|
||||
* @brief LLPanelPick class definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// Display of a "Top Pick" used both for the global top picks in the
|
||||
// Find directory, and also for each individual user's picks in their
|
||||
// profile.
|
||||
|
||||
#ifndef LL_LLPANELPICK_H
|
||||
#define LL_LLPANELPICK_H
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "llremoteparcelrequest.h"
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
|
||||
class LLIconCtrl;
|
||||
class LLTextureCtrl;
|
||||
class LLScrollContainer;
|
||||
class LLMessageSystem;
|
||||
class LLAvatarPropertiesObserver;
|
||||
|
||||
/**
|
||||
* Panel for displaying Pick Information - snapshot, name, description, etc.
|
||||
*/
|
||||
class LLPanelPickInfo : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteParcelInfoObserver
|
||||
{
|
||||
LOG_CLASS(LLPanelPickInfo);
|
||||
public:
|
||||
|
||||
// Creates new panel
|
||||
static LLPanelPickInfo* create();
|
||||
|
||||
virtual ~LLPanelPickInfo();
|
||||
|
||||
/**
|
||||
* Initializes panel properties
|
||||
*
|
||||
* By default Pick will be created for current Agent location.
|
||||
* Use setPickData to change Pick properties.
|
||||
*/
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
|
||||
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
|
||||
|
||||
/**
|
||||
* Sends remote parcel info request to resolve parcel name from its ID.
|
||||
*/
|
||||
void sendParcelInfoRequest();
|
||||
|
||||
/**
|
||||
* Sets "Back" button click callback
|
||||
*/
|
||||
virtual void setExitCallback(const commit_callback_t& cb);
|
||||
|
||||
/**
|
||||
* Sets "Edit" button click callback
|
||||
*/
|
||||
virtual void setEditPickCallback(const commit_callback_t& cb);
|
||||
|
||||
//This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing
|
||||
/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
|
||||
/*virtual*/ void setParcelID(const LLUUID& parcel_id) { mParcelId = parcel_id; }
|
||||
/*virtual*/ void setErrorStatus(S32 status, const std::string& reason) {};
|
||||
|
||||
protected:
|
||||
|
||||
LLPanelPickInfo();
|
||||
|
||||
/**
|
||||
* Resets Pick information
|
||||
*/
|
||||
virtual void resetData();
|
||||
|
||||
/**
|
||||
* Resets UI controls (visibility, values)
|
||||
*/
|
||||
virtual void resetControls();
|
||||
|
||||
/**
|
||||
* "Location text" is actually the owner name, the original
|
||||
* name that owner gave the parcel, and the location.
|
||||
*/
|
||||
static std::string createLocationText(
|
||||
const std::string& owner_name,
|
||||
const std::string& original_name,
|
||||
const std::string& sim_name,
|
||||
const LLVector3d& pos_global);
|
||||
|
||||
virtual void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
|
||||
virtual LLUUID& getAvatarId() { return mAvatarId; }
|
||||
|
||||
/**
|
||||
* Sets snapshot id.
|
||||
*
|
||||
* Will mark snapshot control as valid if id is not null.
|
||||
* Will mark snapshot control as invalid if id is null. If null id is a valid value,
|
||||
* you have to manually mark snapshot is valid.
|
||||
*/
|
||||
virtual void setSnapshotId(const LLUUID& id);
|
||||
|
||||
virtual void setPickId(const LLUUID& id) { mPickId = id; }
|
||||
virtual LLUUID& getPickId() { return mPickId; }
|
||||
|
||||
virtual void setPickName(const std::string& name);
|
||||
|
||||
virtual void setPickDesc(const std::string& desc);
|
||||
|
||||
virtual void setPickLocation(const std::string& location);
|
||||
|
||||
virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
|
||||
virtual LLVector3d& getPosGlobal() { return mPosGlobal; }
|
||||
|
||||
/**
|
||||
* Callback for "Map" button, opens Map
|
||||
*/
|
||||
void onClickMap();
|
||||
|
||||
/**
|
||||
* Callback for "Teleport" button, teleports user to Pick location.
|
||||
*/
|
||||
void onClickTeleport();
|
||||
|
||||
void onClickBack();
|
||||
|
||||
protected:
|
||||
|
||||
S32 mScrollingPanelMinHeight;
|
||||
S32 mScrollingPanelWidth;
|
||||
LLScrollContainer* mScrollContainer;
|
||||
LLPanel* mScrollingPanel;
|
||||
LLTextureCtrl* mSnapshotCtrl;
|
||||
|
||||
LLUUID mAvatarId;
|
||||
LLVector3d mPosGlobal;
|
||||
LLUUID mParcelId;
|
||||
LLUUID mPickId;
|
||||
LLUUID mRequestedId;
|
||||
};
|
||||
|
||||
/**
|
||||
* Panel for creating/editing Pick.
|
||||
*/
|
||||
class LLPanelPickEdit : public LLPanelPickInfo
|
||||
{
|
||||
LOG_CLASS(LLPanelPickEdit);
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates new panel
|
||||
*/
|
||||
static LLPanelPickEdit* create();
|
||||
|
||||
/*virtual*/ ~LLPanelPickEdit();
|
||||
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
|
||||
virtual void setPickData(const LLPickData* pick_data);
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
/**
|
||||
* Sets "Save" button click callback
|
||||
*/
|
||||
virtual void setSaveCallback(const commit_callback_t& cb);
|
||||
|
||||
/**
|
||||
* Sets "Cancel" button click callback
|
||||
*/
|
||||
virtual void setCancelCallback(const commit_callback_t& cb);
|
||||
|
||||
/**
|
||||
* Resets panel and all cantrols to unedited state
|
||||
*/
|
||||
/*virtual*/ void resetDirty();
|
||||
|
||||
/**
|
||||
* Returns true if any of Pick properties was changed by user.
|
||||
*/
|
||||
/*virtual*/ BOOL isDirty() const;
|
||||
|
||||
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
|
||||
|
||||
protected:
|
||||
|
||||
LLPanelPickEdit();
|
||||
|
||||
/**
|
||||
* Sends Pick properties to server.
|
||||
*/
|
||||
void sendUpdate();
|
||||
|
||||
/**
|
||||
* Called when snapshot image changes.
|
||||
*/
|
||||
void onSnapshotChanged();
|
||||
|
||||
/**
|
||||
* Callback for Pick snapshot, name and description changed event.
|
||||
*/
|
||||
void onPickChanged(LLUICtrl* ctrl);
|
||||
|
||||
/*virtual*/ void resetData();
|
||||
|
||||
/**
|
||||
* Enables/disables "Save" button
|
||||
*/
|
||||
void enableSaveButton(bool enable);
|
||||
|
||||
/**
|
||||
* Callback for "Set Location" button click
|
||||
*/
|
||||
void onClickSetLocation();
|
||||
|
||||
/**
|
||||
* Callback for "Save" button click
|
||||
*/
|
||||
void onClickSave();
|
||||
|
||||
std::string getLocationNotice();
|
||||
|
||||
protected:
|
||||
|
||||
bool mLocationChanged;
|
||||
bool mNeedData;
|
||||
bool mNewPick;
|
||||
|
||||
private:
|
||||
|
||||
void initTexturePickerMouseEvents();
|
||||
void onTexturePickerMouseEnter(LLUICtrl* ctrl);
|
||||
void onTexturePickerMouseLeave(LLUICtrl* ctrl);
|
||||
|
||||
private:
|
||||
|
||||
LLIconCtrl* text_icon;
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELPICK_H
|
||||
|
|
@ -1,315 +0,0 @@
|
|||
/**
|
||||
* @file llpanelpicks.h
|
||||
* @brief LLPanelPicks and related class definitions
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLPANELPICKS_H
|
||||
#define LL_LLPANELPICKS_H
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "v3dmath.h"
|
||||
#include "lluuid.h"
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
#include "llpanelavatar.h"
|
||||
#include "llregistry.h"
|
||||
|
||||
class LLAccordionCtrlTab;
|
||||
class LLPanelProfile;
|
||||
class LLMessageSystem;
|
||||
class LLVector3d;
|
||||
class LLPanelProfileTab;
|
||||
class LLAgent;
|
||||
class LLMenuGL;
|
||||
class LLPickItem;
|
||||
class LLClassifiedItem;
|
||||
class LLFlatListView;
|
||||
class LLPanelPickInfo;
|
||||
class LLPanelPickEdit;
|
||||
class LLToggleableMenu;
|
||||
class LLPanelClassifiedInfo;
|
||||
class LLPanelClassifiedEdit;
|
||||
|
||||
// *TODO
|
||||
// Panel Picks has been consolidated with Classifieds (EXT-2095), give LLPanelPicks
|
||||
// and corresponding files (cpp, h, xml) a new name. (new name is TBD at the moment)
|
||||
|
||||
class LLPanelPicks
|
||||
: public LLPanelProfileTab
|
||||
{
|
||||
public:
|
||||
LLPanelPicks();
|
||||
~LLPanelPicks();
|
||||
|
||||
static void* create(void* data);
|
||||
|
||||
/*virtual*/ BOOL postBuild(void);
|
||||
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
|
||||
/*virtual*/ void onClosePanel();
|
||||
|
||||
void processProperties(void* data, EAvatarProcessorType type);
|
||||
|
||||
void updateData();
|
||||
|
||||
// returns the selected pick item
|
||||
LLPickItem* getSelectedPickItem();
|
||||
LLClassifiedItem* getSelectedClassifiedItem();
|
||||
LLClassifiedItem* findClassifiedById(const LLUUID& classified_id);
|
||||
|
||||
//*NOTE top down approch when panel toggling is done only by
|
||||
// parent panels failed to work (picks related code was in my profile panel)
|
||||
void setProfilePanel(LLPanelProfile* profile_panel);
|
||||
|
||||
void createNewPick();
|
||||
void createNewClassified();
|
||||
|
||||
protected:
|
||||
/*virtual*/void updateButtons();
|
||||
void updateNoItemsLabel();
|
||||
|
||||
private:
|
||||
void onClickDelete();
|
||||
void onClickTeleport();
|
||||
void onClickMap();
|
||||
|
||||
void onPlusMenuItemClicked(const LLSD& param);
|
||||
bool isActionEnabled(const LLSD& userdata) const;
|
||||
|
||||
bool isClassifiedPublished(LLClassifiedItem* c_item);
|
||||
|
||||
void onListCommit(const LLFlatListView* f_list);
|
||||
void onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab);
|
||||
|
||||
//------------------------------------------------
|
||||
// Callbacks which require panel toggling
|
||||
//------------------------------------------------
|
||||
void onClickPlusBtn();
|
||||
void onClickInfo();
|
||||
void onPanelPickClose(LLPanel* panel);
|
||||
void onPanelPickSave(LLPanel* panel);
|
||||
void onPanelClassifiedSave(LLPanelClassifiedEdit* panel);
|
||||
void onPanelClassifiedClose(LLPanelClassifiedInfo* panel);
|
||||
void openPickEdit(const LLSD& params);
|
||||
void onPanelPickEdit();
|
||||
void onPanelClassifiedEdit();
|
||||
void editClassified(const LLUUID& classified_id);
|
||||
void onClickMenuEdit();
|
||||
|
||||
bool onEnableMenuItem(const LLSD& user_data);
|
||||
|
||||
void openPickInfo();
|
||||
void openClassifiedInfo();
|
||||
void openClassifiedInfo(const LLSD& params);
|
||||
void openClassifiedEdit(const LLSD& params);
|
||||
friend class LLPanelProfile;
|
||||
|
||||
void showAccordion(const std::string& name, bool show);
|
||||
|
||||
void buildPickPanel();
|
||||
|
||||
bool callbackDeletePick(const LLSD& notification, const LLSD& response);
|
||||
bool callbackDeleteClassified(const LLSD& notification, const LLSD& response);
|
||||
bool callbackTeleport(const LLSD& notification, const LLSD& response);
|
||||
|
||||
|
||||
virtual void onDoubleClickPickItem(LLUICtrl* item);
|
||||
virtual void onDoubleClickClassifiedItem(LLUICtrl* item);
|
||||
virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
|
||||
|
||||
LLPanelProfile* getProfilePanel();
|
||||
|
||||
void createPickInfoPanel();
|
||||
void createPickEditPanel();
|
||||
void createClassifiedInfoPanel();
|
||||
void createClassifiedEditPanel(LLPanelClassifiedEdit** panel);
|
||||
|
||||
LLMenuGL* mPopupMenu;
|
||||
LLPanelProfile* mProfilePanel;
|
||||
LLPanelPickInfo* mPickPanel;
|
||||
LLFlatListView* mPicksList;
|
||||
LLFlatListView* mClassifiedsList;
|
||||
LLPanelPickInfo* mPanelPickInfo;
|
||||
LLPanelClassifiedInfo* mPanelClassifiedInfo;
|
||||
LLPanelPickEdit* mPanelPickEdit;
|
||||
LLToggleableMenu* mPlusMenu;
|
||||
LLUICtrl* mNoItemsLabel;
|
||||
|
||||
// <classified_id, edit_panel>
|
||||
typedef std::map<LLUUID, LLPanelClassifiedEdit*> panel_classified_edit_map_t;
|
||||
|
||||
// This map is needed for newly created classifieds. The purpose of panel is to
|
||||
// sit in this map and listen to LLPanelClassifiedEdit::processProperties callback.
|
||||
panel_classified_edit_map_t mEditClassifiedPanels;
|
||||
|
||||
LLAccordionCtrlTab* mPicksAccTab;
|
||||
LLAccordionCtrlTab* mClassifiedsAccTab;
|
||||
|
||||
//true if picks list is empty after processing picks
|
||||
bool mNoPicks;
|
||||
//true if classifieds list is empty after processing classifieds
|
||||
bool mNoClassifieds;
|
||||
};
|
||||
|
||||
class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver
|
||||
{
|
||||
public:
|
||||
|
||||
LLPickItem();
|
||||
|
||||
static LLPickItem* create();
|
||||
|
||||
void init(LLPickData* pick_data);
|
||||
|
||||
void setPickName(const std::string& name);
|
||||
|
||||
void setPickDesc(const std::string& descr);
|
||||
|
||||
void setPickId(const LLUUID& id);
|
||||
|
||||
void setCreatorId(const LLUUID& id) {mCreatorID = id;};
|
||||
|
||||
void setSnapshotId(const LLUUID& id) {mSnapshotID = id;};
|
||||
|
||||
void setNeedData(bool need){mNeedData = need;};
|
||||
|
||||
const LLUUID& getPickId();
|
||||
|
||||
const std::string& getPickName();
|
||||
|
||||
const LLUUID& getCreatorId();
|
||||
|
||||
const LLUUID& getSnapshotId();
|
||||
|
||||
const LLVector3d& getPosGlobal();
|
||||
|
||||
const std::string getDescription();
|
||||
|
||||
const std::string& getSimName() { return mSimName; }
|
||||
|
||||
const std::string& getUserName() { return mUserName; }
|
||||
|
||||
const std::string& getOriginalName() { return mOriginalName; }
|
||||
|
||||
const std::string& getPickDesc() { return mPickDescription; }
|
||||
|
||||
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
|
||||
|
||||
void update();
|
||||
|
||||
~LLPickItem();
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
/** setting on/off background icon to indicate selected state */
|
||||
/*virtual*/ void setValue(const LLSD& value);
|
||||
|
||||
protected:
|
||||
|
||||
LLUUID mPickID;
|
||||
LLUUID mCreatorID;
|
||||
LLUUID mParcelID;
|
||||
LLUUID mSnapshotID;
|
||||
LLVector3d mPosGlobal;
|
||||
bool mNeedData;
|
||||
|
||||
std::string mPickName;
|
||||
std::string mUserName;
|
||||
std::string mOriginalName;
|
||||
std::string mPickDescription;
|
||||
std::string mSimName;
|
||||
};
|
||||
|
||||
class LLClassifiedItem : public LLPanel, public LLAvatarPropertiesObserver
|
||||
{
|
||||
public:
|
||||
|
||||
LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id);
|
||||
|
||||
virtual ~LLClassifiedItem();
|
||||
|
||||
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
/*virtual*/ void setValue(const LLSD& value);
|
||||
|
||||
void fillIn(LLPanelClassifiedEdit* panel);
|
||||
|
||||
LLUUID getAvatarId() {return mAvatarId;}
|
||||
|
||||
void setAvatarId(const LLUUID& avatar_id) {mAvatarId = avatar_id;}
|
||||
|
||||
LLUUID getClassifiedId() {return mClassifiedId;}
|
||||
|
||||
void setClassifiedId(const LLUUID& classified_id) {mClassifiedId = classified_id;}
|
||||
|
||||
void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
|
||||
|
||||
const LLVector3d getPosGlobal() { return mPosGlobal; }
|
||||
|
||||
void setLocationText(const std::string location) { mLocationText = location; }
|
||||
|
||||
std::string getLocationText() { return mLocationText; }
|
||||
|
||||
void setClassifiedName (const std::string& name);
|
||||
|
||||
std::string getClassifiedName() { return getChild<LLUICtrl>("name")->getValue().asString(); }
|
||||
|
||||
void setDescription(const std::string& desc);
|
||||
|
||||
std::string getDescription() { return getChild<LLUICtrl>("description")->getValue().asString(); }
|
||||
|
||||
void setSnapshotId(const LLUUID& snapshot_id);
|
||||
|
||||
LLUUID getSnapshotId();
|
||||
|
||||
void setCategory(U32 cat) { mCategory = cat; }
|
||||
|
||||
U32 getCategory() { return mCategory; }
|
||||
|
||||
void setContentType(U32 ct) { mContentType = ct; }
|
||||
|
||||
U32 getContentType() { return mContentType; }
|
||||
|
||||
void setAutoRenew(U32 renew) { mAutoRenew = renew; }
|
||||
|
||||
bool getAutoRenew() { return mAutoRenew; }
|
||||
|
||||
void setPriceForListing(S32 price) { mPriceForListing = price; }
|
||||
|
||||
S32 getPriceForListing() { return mPriceForListing; }
|
||||
|
||||
private:
|
||||
LLUUID mAvatarId;
|
||||
LLUUID mClassifiedId;
|
||||
LLVector3d mPosGlobal;
|
||||
std::string mLocationText;
|
||||
U32 mCategory;
|
||||
U32 mContentType;
|
||||
bool mAutoRenew;
|
||||
S32 mPriceForListing;
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELPICKS_H
|
||||
|
|
@ -27,6 +27,8 @@
|
|||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llpanelplaceinfo.h"
|
||||
#include "llfloaterprofile.h"
|
||||
#include "llfloaterreg.h"
|
||||
|
||||
#include "llavatarname.h"
|
||||
#include "llsdutil.h"
|
||||
|
|
@ -42,7 +44,6 @@
|
|||
|
||||
#include "llagent.h"
|
||||
#include "llexpandabletextbox.h"
|
||||
#include "llpanelpick.h"
|
||||
#include "llslurl.h"
|
||||
#include "lltexturectrl.h"
|
||||
#include "llviewerregion.h"
|
||||
|
|
@ -287,7 +288,7 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
|
|||
}
|
||||
}
|
||||
|
||||
void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel)
|
||||
void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global)
|
||||
{
|
||||
LLPickData data;
|
||||
data.pos_global = pos_global;
|
||||
|
|
@ -296,7 +297,12 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit*
|
|||
data.desc = mDescEditor->getText();
|
||||
data.snapshot_id = mSnapshotCtrl->getImageAssetID();
|
||||
data.parcel_id = mParcelID;
|
||||
pick_panel->setPickData(&data);
|
||||
|
||||
LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID)));
|
||||
if (profile_floater)
|
||||
{
|
||||
profile_floater->createPick(data);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ class LLAvatarName;
|
|||
class LLExpandableTextBox;
|
||||
class LLIconCtrl;
|
||||
class LLInventoryItem;
|
||||
class LLPanelPickEdit;
|
||||
class LLParcel;
|
||||
class LLScrollContainer;
|
||||
class LLTextBox;
|
||||
|
|
@ -94,7 +93,7 @@ public:
|
|||
|
||||
// Create a pick for the location specified
|
||||
// by global_pos.
|
||||
void createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel);
|
||||
void createPick(const LLVector3d& pos_global);
|
||||
|
||||
protected:
|
||||
static void onNameCache(LLTextBox* text, const std::string& full_name);
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@
|
|||
#include "lllayoutstack.h"
|
||||
#include "llpanellandmarkinfo.h"
|
||||
#include "llpanellandmarks.h"
|
||||
#include "llpanelpick.h"
|
||||
#include "llpanelplaceprofile.h"
|
||||
#include "llpanelteleporthistory.h"
|
||||
#include "llremoteparcelrequest.h"
|
||||
|
|
@ -238,7 +237,6 @@ LLPanelPlaces::LLPanelPlaces()
|
|||
mFilterEditor(NULL),
|
||||
mPlaceProfile(NULL),
|
||||
mLandmarkInfo(NULL),
|
||||
mPickPanel(NULL),
|
||||
mItem(NULL),
|
||||
mPlaceMenu(NULL),
|
||||
mLandmarkMenu(NULL),
|
||||
|
|
@ -952,28 +950,11 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
|
|||
}
|
||||
else if (item == "pick")
|
||||
{
|
||||
if (mPickPanel == NULL)
|
||||
{
|
||||
mPickPanel = LLPanelPickEdit::create();
|
||||
addChild(mPickPanel);
|
||||
|
||||
mPickPanel->setExitCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
|
||||
mPickPanel->setCancelCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
|
||||
mPickPanel->setSaveCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
|
||||
}
|
||||
|
||||
togglePickPanel(TRUE);
|
||||
mPickPanel->onOpen(LLSD());
|
||||
|
||||
LLPanelPlaceInfo* panel = getCurrentInfoPanel();
|
||||
if (panel)
|
||||
{
|
||||
panel->createPick(mPosGlobal, mPickPanel);
|
||||
panel->createPick(mPosGlobal);
|
||||
}
|
||||
|
||||
LLRect rect = getRect();
|
||||
mPickPanel->reshape(rect.getWidth(), rect.getHeight());
|
||||
mPickPanel->setRect(rect);
|
||||
}
|
||||
else if (item == "add_to_favbar")
|
||||
{
|
||||
|
|
@ -1050,17 +1031,6 @@ bool LLPanelPlaces::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_t
|
|||
return false;
|
||||
}
|
||||
|
||||
void LLPanelPlaces::togglePickPanel(BOOL visible)
|
||||
{
|
||||
if (mPickPanel)
|
||||
{
|
||||
mPickPanel->setVisible(visible);
|
||||
mPlaceProfile->setVisible(!visible);
|
||||
updateVerbs();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
|
||||
{
|
||||
if (!mPlaceProfile || !mLandmarkInfo)
|
||||
|
|
@ -1309,15 +1279,11 @@ 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 && !is_pick_panel_visible);
|
||||
mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
|
||||
mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
|
||||
mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
|
||||
mSaveBtn->setVisible(isLandmarkEditModeOn);
|
||||
mCancelBtn->setVisible(isLandmarkEditModeOn);
|
||||
mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ class LLLandmark;
|
|||
class LLPanelLandmarkInfo;
|
||||
class LLPanelPlaceProfile;
|
||||
|
||||
class LLPanelPickEdit;
|
||||
class LLPanelPlaceInfo;
|
||||
class LLPanelPlacesTab;
|
||||
class LLParcelSelection;
|
||||
|
|
@ -95,7 +94,6 @@ private:
|
|||
void onOverflowButtonClicked();
|
||||
void onOverflowMenuItemClicked(const LLSD& param);
|
||||
bool onOverflowMenuItemEnable(const LLSD& param);
|
||||
void onCreateLandmarkButtonClicked(const LLUUID& folder_id);
|
||||
void onBackButtonClicked();
|
||||
void onGearMenuClick();
|
||||
void onSortingMenuClick();
|
||||
|
|
@ -103,9 +101,6 @@ private:
|
|||
void onRemoveButtonClicked();
|
||||
bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept);
|
||||
|
||||
|
||||
void toggleMediaPanel();
|
||||
void togglePickPanel(BOOL visible);
|
||||
void togglePlaceInfoPanel(BOOL visible);
|
||||
|
||||
/*virtual*/ void onVisibilityChange(BOOL new_visibility);
|
||||
|
|
@ -122,7 +117,6 @@ private:
|
|||
LLPanelPlaceProfile* mPlaceProfile;
|
||||
LLPanelLandmarkInfo* mLandmarkInfo;
|
||||
|
||||
LLPanelPickEdit* mPickPanel;
|
||||
LLToggleableMenu* mPlaceMenu;
|
||||
LLToggleableMenu* mLandmarkMenu;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
/**
|
||||
/**
|
||||
* @file llpanelprofile.h
|
||||
* @brief Profile panel
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* Copyright (C) 2022, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
|
@ -27,76 +27,384 @@
|
|||
#ifndef LL_LLPANELPROFILE_H
|
||||
#define LL_LLPANELPROFILE_H
|
||||
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
#include "llcallingcard.h"
|
||||
#include "llfloater.h"
|
||||
#include "llpanel.h"
|
||||
#include "llpanelavatar.h"
|
||||
#include "llmediactrl.h"
|
||||
#include "llvoiceclient.h"
|
||||
|
||||
// class LLPanelProfileClassifieds;
|
||||
// class LLTabContainer;
|
||||
|
||||
// class LLPanelProfileSecondLife;
|
||||
// class LLPanelProfileWeb;
|
||||
// class LLPanelProfilePicks;
|
||||
// class LLPanelProfileFirstLife;
|
||||
// class LLPanelProfileNotes;
|
||||
|
||||
class LLAvatarName;
|
||||
class LLButton;
|
||||
class LLCheckBoxCtrl;
|
||||
class LLComboBox;
|
||||
class LLIconCtrl;
|
||||
class LLTabContainer;
|
||||
class LLTextBox;
|
||||
class LLTextureCtrl;
|
||||
class LLMediaCtrl;
|
||||
class LLGroupList;
|
||||
class LLTextBase;
|
||||
class LLMenuButton;
|
||||
class LLLineEditor;
|
||||
class LLTextEditor;
|
||||
class LLPanelProfileClassifieds;
|
||||
class LLPanelProfilePicks;
|
||||
class LLViewerFetchedTexture;
|
||||
|
||||
std::string getProfileURL(const std::string& agent_name);
|
||||
|
||||
/**
|
||||
* Base class for Profile View and My Profile.
|
||||
* Panel for displaying Avatar's second life related info.
|
||||
*/
|
||||
class LLPanelProfile : public LLPanel
|
||||
class LLPanelProfileSecondLife
|
||||
: public LLPanelProfileTab
|
||||
, public LLFriendObserver
|
||||
, public LLVoiceClientStatusObserver
|
||||
{
|
||||
LOG_CLASS(LLPanelProfile);
|
||||
|
||||
public:
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
LLPanelProfileSecondLife();
|
||||
/*virtual*/ ~LLPanelProfileSecondLife();
|
||||
|
||||
virtual void openPanel(LLPanel* panel, const LLSD& params);
|
||||
void onOpen(const LLSD& key) override;
|
||||
|
||||
virtual void closePanel(LLPanel* panel);
|
||||
/**
|
||||
* LLFriendObserver trigger
|
||||
*/
|
||||
void changed(U32 mask) override;
|
||||
|
||||
S32 notifyParent(const LLSD& info);
|
||||
// Implements LLVoiceClientStatusObserver::onChange() to enable the call
|
||||
// button when voice is available
|
||||
void onChange(EStatusType status, const std::string &channelURI, bool proximal) override;
|
||||
|
||||
void setAvatarId(const LLUUID& avatar_id) override;
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void resetData() override;
|
||||
|
||||
/**
|
||||
* Sends update data request to server.
|
||||
*/
|
||||
void updateData() override;
|
||||
void refreshName();
|
||||
|
||||
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
|
||||
|
||||
void setProfileImageUploading(bool loading);
|
||||
void setProfileImageUploaded(const LLUUID &image_asset_id);
|
||||
|
||||
bool hasUnsavedChanges() override;
|
||||
void commitUnsavedChanges() override;
|
||||
|
||||
friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Process profile related data received from server.
|
||||
*/
|
||||
void processProfileProperties(const LLAvatarData* avatar_data);
|
||||
|
||||
LLPanelProfile();
|
||||
/**
|
||||
* Processes group related data received from server.
|
||||
*/
|
||||
void processGroupProperties(const LLAvatarGroups* avatar_groups);
|
||||
|
||||
virtual void onTabSelected(const LLSD& param);
|
||||
/**
|
||||
* Fills common for Avatar profile and My Profile fields.
|
||||
*/
|
||||
void fillCommonData(const LLAvatarData* avatar_data);
|
||||
|
||||
const LLUUID& getAvatarId() { return mAvatarId; }
|
||||
/**
|
||||
* Fills partner data.
|
||||
*/
|
||||
void fillPartnerData(const LLAvatarData* avatar_data);
|
||||
|
||||
void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
|
||||
/**
|
||||
* Fills account status.
|
||||
*/
|
||||
void fillAccountStatus(const LLAvatarData* avatar_data);
|
||||
|
||||
typedef std::map<std::string, LLPanelProfileTab*> profile_tabs_t;
|
||||
/**
|
||||
* Sets permissions specific icon
|
||||
*/
|
||||
void fillRightsData();
|
||||
|
||||
profile_tabs_t& getTabContainer() { return mTabContainer; }
|
||||
/**
|
||||
* Fills user name, display name, age.
|
||||
*/
|
||||
void fillAgeData(const LLDate &born_on);
|
||||
|
||||
void onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep);
|
||||
static void onImageLoaded(BOOL success,
|
||||
LLViewerFetchedTexture *src_vi,
|
||||
LLImageRaw* src,
|
||||
LLImageRaw* aux_src,
|
||||
S32 discard_level,
|
||||
BOOL final,
|
||||
void* userdata);
|
||||
|
||||
/**
|
||||
* Displays avatar's online status if possible.
|
||||
*
|
||||
* Requirements from EXT-3880:
|
||||
* For friends:
|
||||
* - Online when online and privacy settings allow to show
|
||||
* - Offline when offline and privacy settings allow to show
|
||||
* - Else: nothing
|
||||
* For other avatars:
|
||||
* - Online when online and was not set in Preferences/"Only Friends & Groups can see when I am online"
|
||||
* - Else: Offline
|
||||
*/
|
||||
void updateOnlineStatus();
|
||||
void processOnlineStatus(bool is_friend, bool show_online, bool online);
|
||||
|
||||
private:
|
||||
void setLoaded() override;
|
||||
void onCommitMenu(const LLSD& userdata);
|
||||
bool onEnableMenu(const LLSD& userdata);
|
||||
bool onCheckMenu(const LLSD& userdata);
|
||||
void onAvatarNameCacheSetName(const LLUUID& id, const LLAvatarName& av_name);
|
||||
|
||||
//-- ChildStack begins ----------------------------------------------------
|
||||
class ChildStack
|
||||
{
|
||||
LOG_CLASS(LLPanelProfile::ChildStack);
|
||||
public:
|
||||
ChildStack();
|
||||
~ChildStack();
|
||||
void setParent(LLPanel* parent);
|
||||
void setDescriptionText(const std::string &text);
|
||||
void onSetDescriptionDirty();
|
||||
void onShowInSearchCallback();
|
||||
void onSaveDescriptionChanges();
|
||||
void onDiscardDescriptionChanges();
|
||||
void onShowAgentPermissionsDialog();
|
||||
void onShowAgentProfileTexture();
|
||||
void onShowTexturePicker();
|
||||
void onCommitProfileImage(const LLUUID& id);
|
||||
void onOpenNotes();
|
||||
|
||||
bool push();
|
||||
bool pop();
|
||||
void preParentReshape();
|
||||
void postParentReshape();
|
||||
private:
|
||||
typedef std::map<std::string, LLUUID> group_map_t;
|
||||
group_map_t mGroups;
|
||||
void openGroupProfile();
|
||||
|
||||
private:
|
||||
void dump();
|
||||
LLGroupList* mGroupList;
|
||||
LLComboBox* mShowInSearchCombo;
|
||||
LLIconCtrl* mSecondLifePic;
|
||||
LLPanel* mSecondLifePicLayout;
|
||||
LLTextEditor* mDescriptionEdit;
|
||||
LLMenuButton* mAgentActionMenuButton;
|
||||
LLButton* mSaveDescriptionChanges;
|
||||
LLButton* mDiscardDescriptionChanges;
|
||||
LLIconCtrl* mCanSeeOnlineIcon;
|
||||
LLIconCtrl* mCantSeeOnlineIcon;
|
||||
LLIconCtrl* mCanSeeOnMapIcon;
|
||||
LLIconCtrl* mCantSeeOnMapIcon;
|
||||
LLIconCtrl* mCanEditObjectsIcon;
|
||||
LLIconCtrl* mCantEditObjectsIcon;
|
||||
|
||||
typedef LLView::child_list_t view_list_t;
|
||||
typedef std::list<view_list_t> stack_t;
|
||||
LLHandle<LLFloater> mFloaterPermissionsHandle;
|
||||
LLHandle<LLFloater> mFloaterProfileTextureHandle;
|
||||
LLHandle<LLFloater> mFloaterTexturePickerHandle;
|
||||
|
||||
stack_t mStack;
|
||||
stack_t mSavedStack;
|
||||
LLPanel* mParent;
|
||||
};
|
||||
//-- ChildStack ends ------------------------------------------------------
|
||||
bool mHasUnsavedDescriptionChanges;
|
||||
bool mVoiceStatus;
|
||||
bool mWaitingForImageUpload;
|
||||
bool mAllowPublish;
|
||||
std::string mDescriptionText;
|
||||
LLUUID mImageId;
|
||||
|
||||
profile_tabs_t mTabContainer;
|
||||
ChildStack mChildStack;
|
||||
LLUUID mAvatarId;
|
||||
boost::signals2::connection mAvatarNameCacheConnection;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Panel for displaying Avatar's web profile and home page.
|
||||
*/
|
||||
class LLPanelProfileWeb
|
||||
: public LLPanelProfileTab
|
||||
, public LLViewerMediaObserver
|
||||
{
|
||||
public:
|
||||
LLPanelProfileWeb();
|
||||
/*virtual*/ ~LLPanelProfileWeb();
|
||||
|
||||
void onOpen(const LLSD& key) override;
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void resetData() override;
|
||||
|
||||
/**
|
||||
* Loads web profile.
|
||||
*/
|
||||
void updateData() override;
|
||||
|
||||
void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override;
|
||||
|
||||
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
|
||||
|
||||
friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
|
||||
|
||||
protected:
|
||||
void onCommitLoad(LLUICtrl* ctrl);
|
||||
|
||||
private:
|
||||
std::string mURLHome;
|
||||
std::string mURLWebProfile;
|
||||
LLMediaCtrl* mWebBrowser;
|
||||
|
||||
LLFrameTimer mPerformanceTimer;
|
||||
bool mFirstNavigate;
|
||||
|
||||
boost::signals2::connection mAvatarNameCacheConnection;
|
||||
};
|
||||
|
||||
/**
|
||||
* Panel for displaying Avatar's first life related info.
|
||||
*/
|
||||
class LLPanelProfileFirstLife
|
||||
: public LLPanelProfileTab
|
||||
{
|
||||
public:
|
||||
LLPanelProfileFirstLife();
|
||||
/*virtual*/ ~LLPanelProfileFirstLife();
|
||||
|
||||
void onOpen(const LLSD& key) override;
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void processProperties(const LLAvatarData* avatar_data);
|
||||
|
||||
void resetData() override;
|
||||
|
||||
void setProfileImageUploading(bool loading);
|
||||
void setProfileImageUploaded(const LLUUID &image_asset_id);
|
||||
|
||||
bool hasUnsavedChanges() override { return mHasUnsavedChanges; }
|
||||
void commitUnsavedChanges() override;
|
||||
|
||||
friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
|
||||
|
||||
protected:
|
||||
void setLoaded() override;
|
||||
|
||||
void onUploadPhoto();
|
||||
void onChangePhoto();
|
||||
void onRemovePhoto();
|
||||
void onCommitPhoto(const LLUUID& id);
|
||||
void setDescriptionText(const std::string &text);
|
||||
void onSetDescriptionDirty();
|
||||
void onSaveDescriptionChanges();
|
||||
void onDiscardDescriptionChanges();
|
||||
|
||||
LLTextEditor* mDescriptionEdit;
|
||||
LLIconCtrl* mPicture;
|
||||
LLButton* mUploadPhoto;
|
||||
LLButton* mChangePhoto;
|
||||
LLButton* mRemovePhoto;
|
||||
LLButton* mSaveChanges;
|
||||
LLButton* mDiscardChanges;
|
||||
|
||||
LLHandle<LLFloater> mFloaterTexturePickerHandle;
|
||||
|
||||
std::string mCurrentDescription;
|
||||
LLUUID mImageId;
|
||||
bool mHasUnsavedChanges;
|
||||
};
|
||||
|
||||
/**
|
||||
* Panel for displaying Avatar's notes and modifying friend's rights.
|
||||
*/
|
||||
class LLPanelProfileNotes
|
||||
: public LLPanelProfileTab
|
||||
{
|
||||
public:
|
||||
LLPanelProfileNotes();
|
||||
/*virtual*/ ~LLPanelProfileNotes();
|
||||
|
||||
void setAvatarId(const LLUUID& avatar_id) override;
|
||||
|
||||
void onOpen(const LLSD& key) override;
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void processProperties(LLAvatarNotes* avatar_notes);
|
||||
|
||||
void resetData() override;
|
||||
|
||||
void updateData() override;
|
||||
|
||||
bool hasUnsavedChanges() override { return mHasUnsavedChanges; }
|
||||
void commitUnsavedChanges() override;
|
||||
|
||||
protected:
|
||||
void setNotesText(const std::string &text);
|
||||
void onSetNotesDirty();
|
||||
void onSaveNotesChanges();
|
||||
void onDiscardNotesChanges();
|
||||
|
||||
LLTextEditor* mNotesEditor;
|
||||
LLButton* mSaveChanges;
|
||||
LLButton* mDiscardChanges;
|
||||
|
||||
std::string mCurrentNotes;
|
||||
bool mHasUnsavedChanges;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Container panel for the profile tabs
|
||||
*/
|
||||
class LLPanelProfile
|
||||
: public LLPanelProfileTab
|
||||
{
|
||||
public:
|
||||
LLPanelProfile();
|
||||
/*virtual*/ ~LLPanelProfile();
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void updateData() override;
|
||||
void refreshName();
|
||||
|
||||
void onOpen(const LLSD& key) override;
|
||||
|
||||
void createPick(const LLPickData &data);
|
||||
void showPick(const LLUUID& pick_id = LLUUID::null);
|
||||
bool isPickTabSelected();
|
||||
bool isNotesTabSelected();
|
||||
bool hasUnsavedChanges() override;
|
||||
bool hasUnpublishedClassifieds();
|
||||
void commitUnsavedChanges() override;
|
||||
|
||||
void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false);
|
||||
void createClassified();
|
||||
|
||||
LLAvatarData getAvatarData() { return mAvatarData; };
|
||||
|
||||
friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
|
||||
|
||||
private:
|
||||
void onTabChange();
|
||||
|
||||
LLPanelProfileSecondLife* mPanelSecondlife;
|
||||
LLPanelProfileWeb* mPanelWeb;
|
||||
LLPanelProfilePicks* mPanelPicks;
|
||||
LLPanelProfileClassifieds* mPanelClassifieds;
|
||||
LLPanelProfileFirstLife* mPanelFirstlife;
|
||||
LLPanelProfileNotes* mPanelNotes;
|
||||
LLTabContainer* mTabContainer;
|
||||
|
||||
// Todo: due to server taking minutes to update this needs a more long term storage
|
||||
// to reuse recently saved values if user opens floater again
|
||||
// Storage implementation depends onto how a cap will be implemented, if cap will be
|
||||
// enought to fully update LLAvatarPropertiesProcessor, then this storage can be
|
||||
// implemented there.
|
||||
LLAvatarData mAvatarData;
|
||||
};
|
||||
|
||||
#endif //LL_LLPANELPROFILE_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,340 @@
|
|||
/**
|
||||
* @file llpanelprofileclassifieds.h
|
||||
* @brief LLPanelProfileClassifieds and related class implementations
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_PANELPROFILECLASSIFIEDS_H
|
||||
#define LL_PANELPROFILECLASSIFIEDS_H
|
||||
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
#include "llclassifiedinfo.h"
|
||||
#include "llfloater.h"
|
||||
#include "llpanel.h"
|
||||
#include "llpanelavatar.h"
|
||||
#include "llrect.h"
|
||||
#include "lluuid.h"
|
||||
#include "v3dmath.h"
|
||||
#include "llcoros.h"
|
||||
#include "lleventcoro.h"
|
||||
|
||||
class LLCheckBoxCtrl;
|
||||
class LLLineEditor;
|
||||
class LLMediaCtrl;
|
||||
class LLScrollContainer;
|
||||
class LLTabContainer;
|
||||
class LLTextEditor;
|
||||
class LLTextureCtrl;
|
||||
class LLUICtrl;
|
||||
|
||||
|
||||
class LLPublishClassifiedFloater : public LLFloater
|
||||
{
|
||||
public:
|
||||
LLPublishClassifiedFloater(const LLSD& key);
|
||||
virtual ~LLPublishClassifiedFloater();
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void setPrice(S32 price);
|
||||
S32 getPrice();
|
||||
|
||||
void setPublishClickedCallback(const commit_signal_t::slot_type& cb);
|
||||
void setCancelClickedCallback(const commit_signal_t::slot_type& cb);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Panel for displaying Avatar's picks.
|
||||
*/
|
||||
class LLPanelProfileClassifieds
|
||||
: public LLPanelProfilePropertiesProcessorTab
|
||||
{
|
||||
public:
|
||||
LLPanelProfileClassifieds();
|
||||
/*virtual*/ ~LLPanelProfileClassifieds();
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void onOpen(const LLSD& key) override;
|
||||
|
||||
void selectClassified(const LLUUID& classified_id, bool edit);
|
||||
|
||||
void createClassified();
|
||||
|
||||
void processProperties(void* data, EAvatarProcessorType type) override;
|
||||
|
||||
void resetData() override;
|
||||
|
||||
void updateButtons();
|
||||
|
||||
void updateData() override;
|
||||
|
||||
bool hasNewClassifieds();
|
||||
bool hasUnsavedChanges() override;
|
||||
// commits changes to existing classifieds, but does not publish new classified!
|
||||
void commitUnsavedChanges() override;
|
||||
|
||||
private:
|
||||
void onClickNewBtn();
|
||||
void onClickDelete();
|
||||
void callbackDeleteClassified(const LLSD& notification, const LLSD& response);
|
||||
|
||||
bool canAddNewClassified();
|
||||
bool canDeleteClassified();
|
||||
|
||||
LLTabContainer* mTabContainer;
|
||||
LLUICtrl* mNoItemsLabel;
|
||||
LLButton* mNewButton;
|
||||
LLButton* mDeleteButton;
|
||||
|
||||
LLUUID mClassifiedToSelectOnLoad;
|
||||
bool mClassifiedEditOnLoad;
|
||||
bool mSheduledClassifiedCreation;
|
||||
};
|
||||
|
||||
|
||||
class LLPanelProfileClassified
|
||||
: public LLPanelProfilePropertiesProcessorTab
|
||||
{
|
||||
public:
|
||||
|
||||
static LLPanelProfileClassified* create();
|
||||
|
||||
LLPanelProfileClassified();
|
||||
|
||||
/*virtual*/ ~LLPanelProfileClassified();
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void onOpen(const LLSD& key) override;
|
||||
|
||||
void processProperties(void* data, EAvatarProcessorType type) override;
|
||||
|
||||
void setSnapshotId(const LLUUID& id);
|
||||
|
||||
LLUUID getSnapshotId();
|
||||
|
||||
void setClassifiedId(const LLUUID& id) { mClassifiedId = id; }
|
||||
|
||||
LLUUID& getClassifiedId() { return mClassifiedId; }
|
||||
|
||||
void setClassifiedName(const std::string& name);
|
||||
|
||||
std::string getClassifiedName();
|
||||
|
||||
void setDescription(const std::string& desc);
|
||||
|
||||
std::string getDescription();
|
||||
|
||||
void setClassifiedLocation(const std::string& location);
|
||||
|
||||
std::string getClassifiedLocation();
|
||||
|
||||
void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
|
||||
|
||||
LLVector3d& getPosGlobal() { return mPosGlobal; }
|
||||
|
||||
void setParcelId(const LLUUID& id) { mParcelId = id; }
|
||||
|
||||
LLUUID getParcelId() { return mParcelId; }
|
||||
|
||||
void setSimName(const std::string& sim_name) { mSimName = sim_name; }
|
||||
|
||||
std::string getSimName() { return mSimName; }
|
||||
|
||||
void setFromSearch(bool val) { mFromSearch = val; }
|
||||
|
||||
bool fromSearch() { return mFromSearch; }
|
||||
|
||||
bool getInfoLoaded() { return mInfoLoaded; }
|
||||
|
||||
void setInfoLoaded(bool loaded) { mInfoLoaded = loaded; }
|
||||
|
||||
BOOL isDirty() const override;
|
||||
|
||||
void resetDirty() override;
|
||||
|
||||
bool isNew() { return mIsNew; }
|
||||
|
||||
bool isNewWithErrors() { return mIsNewWithErrors; }
|
||||
|
||||
bool canClose();
|
||||
|
||||
U32 getCategory();
|
||||
|
||||
void setCategory(U32 category);
|
||||
|
||||
U32 getContentType();
|
||||
|
||||
void setContentType(bool mature);
|
||||
|
||||
bool getAutoRenew();
|
||||
|
||||
S32 getPriceForListing() { return mPriceForListing; }
|
||||
|
||||
void setEditMode(BOOL edit_mode);
|
||||
bool getEditMode() {return mEditMode;}
|
||||
|
||||
static void setClickThrough(
|
||||
const LLUUID& classified_id,
|
||||
S32 teleport,
|
||||
S32 map,
|
||||
S32 profile,
|
||||
bool from_new_table);
|
||||
|
||||
static void sendClickMessage(
|
||||
const std::string& type,
|
||||
bool from_search,
|
||||
const LLUUID& classified_id,
|
||||
const LLUUID& parcel_id,
|
||||
const LLVector3d& global_pos,
|
||||
const std::string& sim_name);
|
||||
|
||||
void doSave();
|
||||
|
||||
protected:
|
||||
|
||||
void resetData() override;
|
||||
|
||||
void resetControls();
|
||||
|
||||
void updateButtons();
|
||||
void updateInfoRect();
|
||||
|
||||
static std::string createLocationText(
|
||||
const std::string& original_name,
|
||||
const std::string& sim_name,
|
||||
const LLVector3d& pos_global);
|
||||
|
||||
void sendClickMessage(const std::string& type);
|
||||
|
||||
void scrollToTop();
|
||||
|
||||
void onEditClick();
|
||||
void onCancelClick();
|
||||
void onSaveClick();
|
||||
void onMapClick();
|
||||
void onTeleportClick();
|
||||
|
||||
void sendUpdate();
|
||||
|
||||
void enableSave(bool enable);
|
||||
|
||||
void enableEditing(bool enable);
|
||||
|
||||
std::string makeClassifiedName();
|
||||
|
||||
void setPriceForListing(S32 price) { mPriceForListing = price; }
|
||||
|
||||
U8 getFlags();
|
||||
|
||||
std::string getLocationNotice();
|
||||
|
||||
bool isValidName();
|
||||
|
||||
void notifyInvalidName();
|
||||
|
||||
void onSetLocationClick();
|
||||
void onChange();
|
||||
|
||||
void onPublishFloaterPublishClicked();
|
||||
|
||||
void onTexturePickerMouseEnter();
|
||||
void onTexturePickerMouseLeave();
|
||||
|
||||
void onTextureSelected();
|
||||
|
||||
void updateTabLabel(const std::string& title);
|
||||
|
||||
private:
|
||||
|
||||
LLTextureCtrl* mSnapshotCtrl;
|
||||
LLUICtrl* mEditIcon;
|
||||
LLUICtrl* mClassifiedNameText;
|
||||
LLTextEditor* mClassifiedDescText;
|
||||
LLLineEditor* mClassifiedNameEdit;
|
||||
LLTextEditor* mClassifiedDescEdit;
|
||||
LLUICtrl* mLocationText;
|
||||
LLUICtrl* mLocationEdit;
|
||||
LLUICtrl* mCategoryText;
|
||||
LLComboBox* mCategoryCombo;
|
||||
LLUICtrl* mContentTypeText;
|
||||
LLIconCtrl* mContentTypeM;
|
||||
LLIconCtrl* mContentTypeG;
|
||||
LLComboBox* mContentTypeCombo;
|
||||
LLUICtrl* mPriceText;
|
||||
LLUICtrl* mAutoRenewText;
|
||||
LLUICtrl* mAutoRenewEdit;
|
||||
|
||||
LLButton* mMapButton;
|
||||
LLButton* mTeleportButton;
|
||||
LLButton* mEditButton;
|
||||
LLButton* mSaveButton;
|
||||
LLButton* mSetLocationButton;
|
||||
LLButton* mCancelButton;
|
||||
|
||||
LLPanel* mUtilityBtnCnt;
|
||||
LLPanel* mPublishBtnsCnt;
|
||||
LLPanel* mSaveBtnCnt;
|
||||
LLPanel* mCancelBtnCnt;
|
||||
|
||||
LLScrollContainer* mScrollContainer;
|
||||
LLView* mInfoPanel;
|
||||
LLPanel* mInfoScroll;
|
||||
LLPanel* mEditPanel;
|
||||
|
||||
|
||||
LLUUID mClassifiedId;
|
||||
LLVector3d mPosGlobal;
|
||||
LLUUID mParcelId;
|
||||
std::string mSimName;
|
||||
bool mFromSearch;
|
||||
bool mInfoLoaded;
|
||||
bool mEditMode;
|
||||
|
||||
// Needed for stat tracking
|
||||
S32 mTeleportClicksOld;
|
||||
S32 mMapClicksOld;
|
||||
S32 mProfileClicksOld;
|
||||
S32 mTeleportClicksNew;
|
||||
S32 mMapClicksNew;
|
||||
S32 mProfileClicksNew;
|
||||
|
||||
S32 mPriceForListing;
|
||||
|
||||
static void handleSearchStatResponse(LLUUID classifiedId, LLSD result);
|
||||
|
||||
typedef std::list<LLPanelProfileClassified*> panel_list_t;
|
||||
static panel_list_t sAllPanels;
|
||||
|
||||
|
||||
bool mIsNew;
|
||||
bool mIsNewWithErrors;
|
||||
bool mCanClose;
|
||||
bool mEditOnLoad;
|
||||
|
||||
LLPublishClassifiedFloater* mPublishFloater;
|
||||
};
|
||||
|
||||
#endif // LL_PANELPROFILECLASSIFIEDS_H
|
||||
|
|
@ -0,0 +1,883 @@
|
|||
/**
|
||||
* @file llpanelprofilepicks.cpp
|
||||
* @brief LLPanelProfilePicks and related class implementations
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llpanelprofilepicks.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llagentpicksinfo.h"
|
||||
#include "llavataractions.h"
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
#include "llcommandhandler.h"
|
||||
#include "lldispatcher.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloaterworldmap.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llpanelavatar.h"
|
||||
#include "llpanelprofile.h"
|
||||
#include "llparcel.h"
|
||||
#include "llstartup.h"
|
||||
#include "lltabcontainer.h"
|
||||
#include "lltextbox.h"
|
||||
#include "lltexteditor.h"
|
||||
#include "lltexturectrl.h"
|
||||
#include "lltexturectrl.h"
|
||||
#include "lltrans.h"
|
||||
#include "llviewergenericmessage.h" // send_generic_message
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llviewerregion.h"
|
||||
|
||||
static LLPanelInjector<LLPanelProfilePicks> t_panel_profile_picks("panel_profile_picks");
|
||||
static LLPanelInjector<LLPanelProfilePick> t_panel_profile_pick("panel_profile_pick");
|
||||
|
||||
|
||||
class LLPickHandler : public LLCommandHandler
|
||||
{
|
||||
public:
|
||||
|
||||
// requires trusted browser to trigger
|
||||
LLPickHandler() : LLCommandHandler("pick", UNTRUSTED_THROTTLE) { }
|
||||
|
||||
bool handle(const LLSD& params, const LLSD& query_map,
|
||||
LLMediaCtrl* web)
|
||||
{
|
||||
if (LLStartUp::getStartupState() < STATE_STARTED)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks"))
|
||||
{
|
||||
LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
|
||||
return true;
|
||||
}
|
||||
|
||||
// handle app/pick/create urls first
|
||||
if (params.size() == 1 && params[0].asString() == "create")
|
||||
{
|
||||
LLAvatarActions::createPick();
|
||||
return true;
|
||||
}
|
||||
|
||||
// then handle the general app/pick/{UUID}/{CMD} urls
|
||||
if (params.size() < 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the ID for the pick_id
|
||||
LLUUID pick_id;
|
||||
if (!pick_id.set(params[0], FALSE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// edit the pick in the side tray.
|
||||
// need to ask the server for more info first though...
|
||||
const std::string verb = params[1].asString();
|
||||
if (verb == "edit")
|
||||
{
|
||||
LLAvatarActions::showPick(gAgent.getID(), pick_id);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "unknown verb " << verb << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
LLPickHandler gPickHandler;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLPanelProfilePicks
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
LLPanelProfilePicks::LLPanelProfilePicks()
|
||||
: LLPanelProfilePropertiesProcessorTab()
|
||||
, mPickToSelectOnLoad(LLUUID::null)
|
||||
{
|
||||
}
|
||||
|
||||
LLPanelProfilePicks::~LLPanelProfilePicks()
|
||||
{
|
||||
}
|
||||
|
||||
void LLPanelProfilePicks::onOpen(const LLSD& key)
|
||||
{
|
||||
LLPanelProfilePropertiesProcessorTab::onOpen(key);
|
||||
|
||||
resetData();
|
||||
|
||||
bool own_profile = getSelfProfile();
|
||||
if (own_profile)
|
||||
{
|
||||
mNewButton->setVisible(TRUE);
|
||||
mNewButton->setEnabled(FALSE);
|
||||
|
||||
mDeleteButton->setVisible(TRUE);
|
||||
mDeleteButton->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
childSetVisible("buttons_header", own_profile);
|
||||
}
|
||||
|
||||
void LLPanelProfilePicks::createPick(const LLPickData &data)
|
||||
{
|
||||
if (getIsLoaded())
|
||||
{
|
||||
if (canAddNewPick())
|
||||
{
|
||||
mNoItemsLabel->setVisible(FALSE);
|
||||
LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
|
||||
pick_panel->setAvatarId(getAvatarId());
|
||||
pick_panel->processProperties(&data);
|
||||
mTabContainer->addTabPanel(
|
||||
LLTabContainer::TabPanelParams().
|
||||
panel(pick_panel).
|
||||
select_tab(true).
|
||||
label(pick_panel->getPickName()));
|
||||
updateButtons();
|
||||
}
|
||||
else
|
||||
{
|
||||
// This means that something doesn't properly check limits
|
||||
// before creating a pick
|
||||
LL_WARNS() << "failed to add pick" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mSheduledPickCreation.push_back(data);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfilePicks::selectPick(const LLUUID& pick_id)
|
||||
{
|
||||
if (getIsLoaded())
|
||||
{
|
||||
for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
|
||||
{
|
||||
LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
|
||||
if (pick_panel)
|
||||
{
|
||||
if (pick_panel->getPickId() == pick_id)
|
||||
{
|
||||
mTabContainer->selectTabPanel(pick_panel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mPickToSelectOnLoad = pick_id;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLPanelProfilePicks::postBuild()
|
||||
{
|
||||
mTabContainer = getChild<LLTabContainer>("tab_picks");
|
||||
mNoItemsLabel = getChild<LLUICtrl>("picks_panel_text");
|
||||
mNewButton = getChild<LLButton>("new_btn");
|
||||
mDeleteButton = getChild<LLButton>("delete_btn");
|
||||
|
||||
mNewButton->setCommitCallback(boost::bind(&LLPanelProfilePicks::onClickNewBtn, this));
|
||||
mDeleteButton->setCommitCallback(boost::bind(&LLPanelProfilePicks::onClickDelete, this));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelProfilePicks::onClickNewBtn()
|
||||
{
|
||||
mNoItemsLabel->setVisible(FALSE);
|
||||
LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
|
||||
pick_panel->setAvatarId(getAvatarId());
|
||||
mTabContainer->addTabPanel(
|
||||
LLTabContainer::TabPanelParams().
|
||||
panel(pick_panel).
|
||||
select_tab(true).
|
||||
label(pick_panel->getPickName()));
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
void LLPanelProfilePicks::onClickDelete()
|
||||
{
|
||||
LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getCurrentPanel());
|
||||
if (pick_panel)
|
||||
{
|
||||
LLUUID pick_id = pick_panel->getPickId();
|
||||
LLSD args;
|
||||
args["PICK"] = pick_panel->getPickName();
|
||||
LLSD payload;
|
||||
payload["pick_id"] = pick_id;
|
||||
payload["tab_idx"] = mTabContainer->getCurrentPanelIndex();
|
||||
LLNotificationsUtil::add("ProfileDeletePick", args, payload,
|
||||
boost::bind(&LLPanelProfilePicks::callbackDeletePick, this, _1, _2));
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfilePicks::callbackDeletePick(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
|
||||
if (0 == option)
|
||||
{
|
||||
LLUUID pick_id = notification["payload"]["pick_id"].asUUID();
|
||||
S32 tab_idx = notification["payload"]["tab_idx"].asInteger();
|
||||
|
||||
LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
|
||||
if (pick_panel && pick_panel->getPickId() == pick_id)
|
||||
{
|
||||
mTabContainer->removeTabPanel(pick_panel);
|
||||
}
|
||||
|
||||
if (pick_id.notNull())
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->sendPickDelete(pick_id);
|
||||
}
|
||||
|
||||
updateButtons();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfilePicks::processProperties(void* data, EAvatarProcessorType type)
|
||||
{
|
||||
if (APT_PICKS == type)
|
||||
{
|
||||
LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
|
||||
if (avatar_picks && getAvatarId() == avatar_picks->target_id)
|
||||
{
|
||||
processProperties(avatar_picks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfilePicks::processProperties(const LLAvatarPicks* avatar_picks)
|
||||
{
|
||||
LLUUID selected_id = mPickToSelectOnLoad;
|
||||
bool has_selection = false;
|
||||
if (mPickToSelectOnLoad.isNull())
|
||||
{
|
||||
if (mTabContainer->getTabCount() > 0)
|
||||
{
|
||||
LLPanelProfilePick* active_pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getCurrentPanel());
|
||||
if (active_pick_panel)
|
||||
{
|
||||
selected_id = active_pick_panel->getPickId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mTabContainer->deleteAllTabs();
|
||||
|
||||
LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
|
||||
for (; avatar_picks->picks_list.end() != it; ++it)
|
||||
{
|
||||
LLUUID pick_id = it->first;
|
||||
std::string pick_name = it->second;
|
||||
|
||||
LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
|
||||
|
||||
pick_panel->setPickId(pick_id);
|
||||
pick_panel->setPickName(pick_name);
|
||||
pick_panel->setAvatarId(getAvatarId());
|
||||
|
||||
mTabContainer->addTabPanel(
|
||||
LLTabContainer::TabPanelParams().
|
||||
panel(pick_panel).
|
||||
select_tab(selected_id == pick_id).
|
||||
label(pick_name));
|
||||
|
||||
if (selected_id == pick_id)
|
||||
{
|
||||
has_selection = true;
|
||||
}
|
||||
}
|
||||
|
||||
while (!mSheduledPickCreation.empty() && canAddNewPick())
|
||||
{
|
||||
const LLPickData data =
|
||||
mSheduledPickCreation.back();
|
||||
|
||||
LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
|
||||
pick_panel->setAvatarId(getAvatarId());
|
||||
pick_panel->processProperties(&data);
|
||||
mTabContainer->addTabPanel(
|
||||
LLTabContainer::TabPanelParams().
|
||||
panel(pick_panel).
|
||||
select_tab(!has_selection).
|
||||
label(pick_panel->getPickName()));
|
||||
|
||||
mSheduledPickCreation.pop_back();
|
||||
has_selection = true;
|
||||
}
|
||||
|
||||
// reset 'do on load' values
|
||||
mPickToSelectOnLoad = LLUUID::null;
|
||||
mSheduledPickCreation.clear();
|
||||
|
||||
if (getSelfProfile())
|
||||
{
|
||||
mNoItemsLabel->setValue(LLTrans::getString("NoPicksText"));
|
||||
}
|
||||
else
|
||||
{
|
||||
mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksText"));
|
||||
}
|
||||
|
||||
bool has_data = mTabContainer->getTabCount() > 0;
|
||||
mNoItemsLabel->setVisible(!has_data);
|
||||
if (has_data && !has_selection)
|
||||
{
|
||||
mTabContainer->selectFirstTab();
|
||||
}
|
||||
|
||||
setLoaded();
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
void LLPanelProfilePicks::resetData()
|
||||
{
|
||||
resetLoading();
|
||||
mTabContainer->deleteAllTabs();
|
||||
}
|
||||
|
||||
void LLPanelProfilePicks::updateButtons()
|
||||
{
|
||||
if (getSelfProfile())
|
||||
{
|
||||
mNewButton->setEnabled(canAddNewPick());
|
||||
mDeleteButton->setEnabled(canDeletePick());
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfilePicks::apply()
|
||||
{
|
||||
if (getIsLoaded())
|
||||
{
|
||||
for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
|
||||
{
|
||||
LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
|
||||
if (pick_panel)
|
||||
{
|
||||
pick_panel->apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfilePicks::updateData()
|
||||
{
|
||||
// Send picks request only once
|
||||
LLUUID avatar_id = getAvatarId();
|
||||
if (!getStarted() && avatar_id.notNull())
|
||||
{
|
||||
setIsLoading();
|
||||
|
||||
LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(avatar_id);
|
||||
}
|
||||
if (!getIsLoaded())
|
||||
{
|
||||
mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
|
||||
mNoItemsLabel->setVisible(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLPanelProfilePicks::hasUnsavedChanges()
|
||||
{
|
||||
for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
|
||||
{
|
||||
LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
|
||||
if (pick_panel && (pick_panel->isDirty() || pick_panel->isDirty()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLPanelProfilePicks::commitUnsavedChanges()
|
||||
{
|
||||
for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
|
||||
{
|
||||
LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
|
||||
if (pick_panel)
|
||||
{
|
||||
pick_panel->apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LLPanelProfilePicks::canAddNewPick()
|
||||
{
|
||||
return (!LLAgentPicksInfo::getInstance()->isPickLimitReached() &&
|
||||
mTabContainer->getTabCount() < LLAgentPicksInfo::getInstance()->getMaxNumberOfPicks());
|
||||
}
|
||||
|
||||
bool LLPanelProfilePicks::canDeletePick()
|
||||
{
|
||||
return (mTabContainer->getTabCount() > 0);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLPanelProfilePick
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
LLPanelProfilePick::LLPanelProfilePick()
|
||||
: LLPanelProfilePropertiesProcessorTab()
|
||||
, LLRemoteParcelInfoObserver()
|
||||
, mSnapshotCtrl(NULL)
|
||||
, mPickId(LLUUID::null)
|
||||
, mParcelId(LLUUID::null)
|
||||
, mRequestedId(LLUUID::null)
|
||||
, mLocationChanged(false)
|
||||
, mNewPick(false)
|
||||
, mIsEditing(false)
|
||||
{
|
||||
}
|
||||
|
||||
//static
|
||||
LLPanelProfilePick* LLPanelProfilePick::create()
|
||||
{
|
||||
LLPanelProfilePick* panel = new LLPanelProfilePick();
|
||||
panel->buildFromFile("panel_profile_pick.xml");
|
||||
return panel;
|
||||
}
|
||||
|
||||
LLPanelProfilePick::~LLPanelProfilePick()
|
||||
{
|
||||
if (mParcelId.notNull())
|
||||
{
|
||||
LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::setAvatarId(const LLUUID& avatar_id)
|
||||
{
|
||||
if (avatar_id.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id);
|
||||
|
||||
// creating new Pick
|
||||
if (getPickId().isNull() && getSelfProfile())
|
||||
{
|
||||
mNewPick = true;
|
||||
|
||||
setPosGlobal(gAgent.getPositionGlobal());
|
||||
|
||||
LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null;
|
||||
std::string pick_name, pick_desc, region_name;
|
||||
|
||||
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
||||
if (parcel)
|
||||
{
|
||||
parcel_id = parcel->getID();
|
||||
pick_name = parcel->getName();
|
||||
pick_desc = parcel->getDesc();
|
||||
snapshot_id = parcel->getSnapshotID();
|
||||
}
|
||||
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region)
|
||||
{
|
||||
region_name = region->getName();
|
||||
}
|
||||
|
||||
setParcelID(parcel_id);
|
||||
setPickName(pick_name.empty() ? region_name : pick_name);
|
||||
setPickDesc(pick_desc);
|
||||
setSnapshotId(snapshot_id);
|
||||
setPickLocation(createLocationText(getLocationNotice(), pick_name, region_name, getPosGlobal()));
|
||||
|
||||
enableSaveButton(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(getAvatarId(), getPickId());
|
||||
|
||||
enableSaveButton(FALSE);
|
||||
}
|
||||
|
||||
resetDirty();
|
||||
|
||||
if (getSelfProfile())
|
||||
{
|
||||
mPickName->setEnabled(TRUE);
|
||||
mPickDescription->setEnabled(TRUE);
|
||||
mSetCurrentLocationButton->setVisible(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
mSnapshotCtrl->setEnabled(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLPanelProfilePick::postBuild()
|
||||
{
|
||||
mPickName = getChild<LLLineEditor>("pick_name");
|
||||
mPickDescription = getChild<LLTextEditor>("pick_desc");
|
||||
mSaveButton = getChild<LLButton>("save_changes_btn");
|
||||
mCreateButton = getChild<LLButton>("create_changes_btn");
|
||||
mCancelButton = getChild<LLButton>("cancel_changes_btn");
|
||||
mSetCurrentLocationButton = getChild<LLButton>("set_to_curr_location_btn");
|
||||
|
||||
mSnapshotCtrl = getChild<LLTextureCtrl>("pick_snapshot");
|
||||
mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelProfilePick::onSnapshotChanged, this));
|
||||
|
||||
childSetAction("teleport_btn", boost::bind(&LLPanelProfilePick::onClickTeleport, this));
|
||||
childSetAction("show_on_map_btn", boost::bind(&LLPanelProfilePick::onClickMap, this));
|
||||
|
||||
mSaveButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this));
|
||||
mCreateButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this));
|
||||
mCancelButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickCancel, this));
|
||||
mSetCurrentLocationButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSetLocation, this));
|
||||
|
||||
mPickName->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1), NULL);
|
||||
mPickName->setEnabled(FALSE);
|
||||
|
||||
mPickDescription->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1));
|
||||
mPickDescription->setFocusReceivedCallback(boost::bind(&LLPanelProfilePick::onDescriptionFocusReceived, this));
|
||||
|
||||
getChild<LLUICtrl>("pick_location")->setEnabled(FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::onDescriptionFocusReceived()
|
||||
{
|
||||
if (!mIsEditing && getSelfProfile())
|
||||
{
|
||||
mIsEditing = true;
|
||||
mPickDescription->setParseHTML(false);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::processProperties(void* data, EAvatarProcessorType type)
|
||||
{
|
||||
if (APT_PICK_INFO != type)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLPickData* pick_info = static_cast<LLPickData*>(data);
|
||||
if (!pick_info
|
||||
|| pick_info->creator_id != getAvatarId()
|
||||
|| pick_info->pick_id != getPickId())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
processProperties(pick_info);
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::processProperties(const LLPickData* pick_info)
|
||||
{
|
||||
mIsEditing = false;
|
||||
mPickDescription->setParseHTML(true);
|
||||
mParcelId = pick_info->parcel_id;
|
||||
setSnapshotId(pick_info->snapshot_id);
|
||||
if (!getSelfProfile())
|
||||
{
|
||||
mSnapshotCtrl->setEnabled(FALSE);
|
||||
}
|
||||
setPickName(pick_info->name);
|
||||
setPickDesc(pick_info->desc);
|
||||
setPosGlobal(pick_info->pos_global);
|
||||
|
||||
// Send remote parcel info request to get parcel name and sim (region) name.
|
||||
sendParcelInfoRequest();
|
||||
|
||||
// *NOTE dzaporozhan
|
||||
// We want to keep listening to APT_PICK_INFO because user may
|
||||
// edit the Pick and we have to update Pick info panel.
|
||||
// revomeObserver is called from onClickBack
|
||||
|
||||
setLoaded();
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::apply()
|
||||
{
|
||||
if ((mNewPick || getIsLoaded()) && isDirty())
|
||||
{
|
||||
sendUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::setSnapshotId(const LLUUID& id)
|
||||
{
|
||||
mSnapshotCtrl->setImageAssetID(id);
|
||||
mSnapshotCtrl->setValid(TRUE);
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::setPickName(const std::string& name)
|
||||
{
|
||||
mPickName->setValue(name);
|
||||
}
|
||||
|
||||
const std::string LLPanelProfilePick::getPickName()
|
||||
{
|
||||
return mPickName->getValue().asString();
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::setPickDesc(const std::string& desc)
|
||||
{
|
||||
mPickDescription->setValue(desc);
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::setPickLocation(const std::string& location)
|
||||
{
|
||||
getChild<LLUICtrl>("pick_location")->setValue(location);
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::onClickMap()
|
||||
{
|
||||
LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
|
||||
LLFloaterReg::showInstance("world_map", "center");
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::onClickTeleport()
|
||||
{
|
||||
if (!getPosGlobal().isExactlyZero())
|
||||
{
|
||||
gAgent.teleportViaLocation(getPosGlobal());
|
||||
LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::enableSaveButton(BOOL enable)
|
||||
{
|
||||
childSetVisible("save_changes_lp", enable);
|
||||
|
||||
childSetVisible("save_btn_lp", enable && !mNewPick);
|
||||
childSetVisible("create_btn_lp", enable && mNewPick);
|
||||
childSetVisible("cancel_btn_lp", enable && !mNewPick);
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::onSnapshotChanged()
|
||||
{
|
||||
enableSaveButton(TRUE);
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::onPickChanged(LLUICtrl* ctrl)
|
||||
{
|
||||
if (ctrl && ctrl == mPickName)
|
||||
{
|
||||
updateTabLabel(mPickName->getText());
|
||||
}
|
||||
|
||||
enableSaveButton(isDirty());
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::resetDirty()
|
||||
{
|
||||
LLPanel::resetDirty();
|
||||
|
||||
mPickName->resetDirty();
|
||||
mPickDescription->resetDirty();
|
||||
mSnapshotCtrl->resetDirty();
|
||||
mLocationChanged = false;
|
||||
}
|
||||
|
||||
BOOL LLPanelProfilePick::isDirty() const
|
||||
{
|
||||
if (mNewPick
|
||||
|| LLPanel::isDirty()
|
||||
|| mLocationChanged
|
||||
|| mSnapshotCtrl->isDirty()
|
||||
|| mPickName->isDirty()
|
||||
|| mPickDescription->isDirty())
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::onClickSetLocation()
|
||||
{
|
||||
// Save location for later use.
|
||||
setPosGlobal(gAgent.getPositionGlobal());
|
||||
|
||||
std::string parcel_name, region_name;
|
||||
|
||||
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
||||
if (parcel)
|
||||
{
|
||||
mParcelId = parcel->getID();
|
||||
parcel_name = parcel->getName();
|
||||
}
|
||||
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region)
|
||||
{
|
||||
region_name = region->getName();
|
||||
}
|
||||
|
||||
setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal()));
|
||||
|
||||
mLocationChanged = true;
|
||||
enableSaveButton(TRUE);
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::onClickSave()
|
||||
{
|
||||
sendUpdate();
|
||||
|
||||
mLocationChanged = false;
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::onClickCancel()
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(getAvatarId(), getPickId());
|
||||
mLocationChanged = false;
|
||||
enableSaveButton(FALSE);
|
||||
}
|
||||
|
||||
std::string LLPanelProfilePick::getLocationNotice()
|
||||
{
|
||||
static const std::string notice = getString("location_notice");
|
||||
return notice;
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::sendParcelInfoRequest()
|
||||
{
|
||||
if (mParcelId != mRequestedId)
|
||||
{
|
||||
if (mRequestedId.notNull())
|
||||
{
|
||||
LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mRequestedId, this);
|
||||
}
|
||||
LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this);
|
||||
LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId);
|
||||
|
||||
mRequestedId = mParcelId;
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::processParcelInfo(const LLParcelData& parcel_data)
|
||||
{
|
||||
setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name, parcel_data.sim_name, getPosGlobal()));
|
||||
|
||||
// We have received parcel info for the requested ID so clear it now.
|
||||
mRequestedId.setNull();
|
||||
|
||||
if (mParcelId.notNull())
|
||||
{
|
||||
LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::sendUpdate()
|
||||
{
|
||||
LLPickData pick_data;
|
||||
|
||||
// If we don't have a pick id yet, we'll need to generate one,
|
||||
// otherwise we'll keep overwriting pick_id 00000 in the database.
|
||||
if (getPickId().isNull())
|
||||
{
|
||||
getPickId().generate();
|
||||
}
|
||||
|
||||
pick_data.agent_id = gAgentID;
|
||||
pick_data.session_id = gAgent.getSessionID();
|
||||
pick_data.pick_id = getPickId();
|
||||
pick_data.creator_id = gAgentID;;
|
||||
|
||||
//legacy var need to be deleted
|
||||
pick_data.top_pick = FALSE;
|
||||
pick_data.parcel_id = mParcelId;
|
||||
pick_data.name = getPickName();
|
||||
pick_data.desc = mPickDescription->getValue().asString();
|
||||
pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
|
||||
pick_data.pos_global = getPosGlobal();
|
||||
pick_data.sort_order = 0;
|
||||
pick_data.enabled = TRUE;
|
||||
|
||||
LLAvatarPropertiesProcessor::getInstance()->sendPickInfoUpdate(&pick_data);
|
||||
|
||||
if(mNewPick)
|
||||
{
|
||||
// Assume a successful create pick operation, make new number of picks
|
||||
// available immediately. Actual number of picks will be requested in
|
||||
// LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond.
|
||||
LLAgentPicksInfo::getInstance()->incrementNumberOfPicks();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
std::string LLPanelProfilePick::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global)
|
||||
{
|
||||
std::string location_text(owner_name);
|
||||
if (!original_name.empty())
|
||||
{
|
||||
if (!location_text.empty())
|
||||
{
|
||||
location_text.append(", ");
|
||||
}
|
||||
location_text.append(original_name);
|
||||
|
||||
}
|
||||
|
||||
if (!sim_name.empty())
|
||||
{
|
||||
if (!location_text.empty())
|
||||
{
|
||||
location_text.append(", ");
|
||||
}
|
||||
location_text.append(sim_name);
|
||||
}
|
||||
|
||||
if (!location_text.empty())
|
||||
{
|
||||
location_text.append(" ");
|
||||
}
|
||||
|
||||
if (!pos_global.isNull())
|
||||
{
|
||||
S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
|
||||
S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
|
||||
S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
|
||||
location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
|
||||
}
|
||||
return location_text;
|
||||
}
|
||||
|
||||
void LLPanelProfilePick::updateTabLabel(const std::string& title)
|
||||
{
|
||||
setLabel(title);
|
||||
LLTabContainer* parent = dynamic_cast<LLTabContainer*>(getParent());
|
||||
if (parent)
|
||||
{
|
||||
parent->setCurrentTabName(title);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
/**
|
||||
* @file llpanelprofilepicks.h
|
||||
* @brief LLPanelProfilePicks and related class definitions
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2022, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLPANELPICKS_H
|
||||
#define LL_LLPANELPICKS_H
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "lluuid.h"
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
#include "llpanelavatar.h"
|
||||
#include "llremoteparcelrequest.h"
|
||||
|
||||
class LLTabContainer;
|
||||
class LLTextureCtrl;
|
||||
class LLMediaCtrl;
|
||||
class LLLineEditor;
|
||||
class LLTextEditor;
|
||||
|
||||
|
||||
/**
|
||||
* Panel for displaying Avatar's picks.
|
||||
*/
|
||||
class LLPanelProfilePicks
|
||||
: public LLPanelProfilePropertiesProcessorTab
|
||||
{
|
||||
public:
|
||||
LLPanelProfilePicks();
|
||||
/*virtual*/ ~LLPanelProfilePicks();
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void onOpen(const LLSD& key) override;
|
||||
|
||||
void createPick(const LLPickData &data);
|
||||
void selectPick(const LLUUID& pick_id);
|
||||
|
||||
void processProperties(void* data, EAvatarProcessorType type) override;
|
||||
void processProperties(const LLAvatarPicks* avatar_picks);
|
||||
|
||||
void resetData() override;
|
||||
|
||||
void updateButtons();
|
||||
|
||||
/**
|
||||
* Saves changes.
|
||||
*/
|
||||
virtual void apply();
|
||||
|
||||
/**
|
||||
* Sends update data request to server.
|
||||
*/
|
||||
void updateData() override;
|
||||
|
||||
bool hasUnsavedChanges() override;
|
||||
void commitUnsavedChanges() override;
|
||||
|
||||
friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
|
||||
|
||||
private:
|
||||
void onClickNewBtn();
|
||||
void onClickDelete();
|
||||
void callbackDeletePick(const LLSD& notification, const LLSD& response);
|
||||
|
||||
bool canAddNewPick();
|
||||
bool canDeletePick();
|
||||
|
||||
LLTabContainer* mTabContainer;
|
||||
LLUICtrl* mNoItemsLabel;
|
||||
LLButton* mNewButton;
|
||||
LLButton* mDeleteButton;
|
||||
|
||||
LLUUID mPickToSelectOnLoad;
|
||||
std::list<LLPickData> mSheduledPickCreation;
|
||||
};
|
||||
|
||||
|
||||
class LLPanelProfilePick
|
||||
: public LLPanelProfilePropertiesProcessorTab
|
||||
, public LLRemoteParcelInfoObserver
|
||||
{
|
||||
public:
|
||||
|
||||
// Creates new panel
|
||||
static LLPanelProfilePick* create();
|
||||
|
||||
LLPanelProfilePick();
|
||||
|
||||
/*virtual*/ ~LLPanelProfilePick();
|
||||
|
||||
BOOL postBuild() override;
|
||||
|
||||
void setAvatarId(const LLUUID& avatar_id) override;
|
||||
|
||||
void setPickId(const LLUUID& id) { mPickId = id; }
|
||||
virtual LLUUID& getPickId() { return mPickId; }
|
||||
|
||||
virtual void setPickName(const std::string& name);
|
||||
const std::string getPickName();
|
||||
|
||||
void processProperties(void* data, EAvatarProcessorType type) override;
|
||||
void processProperties(const LLPickData* pick_data);
|
||||
|
||||
/**
|
||||
* Returns true if any of Pick properties was changed by user.
|
||||
*/
|
||||
BOOL isDirty() const override;
|
||||
|
||||
/**
|
||||
* Saves changes.
|
||||
*/
|
||||
virtual void apply();
|
||||
|
||||
void updateTabLabel(const std::string& title);
|
||||
|
||||
//This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing
|
||||
void processParcelInfo(const LLParcelData& parcel_data) override;
|
||||
void setParcelID(const LLUUID& parcel_id) override { mParcelId = parcel_id; }
|
||||
void setErrorStatus(S32 status, const std::string& reason) override {};
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Sends remote parcel info request to resolve parcel name from its ID.
|
||||
*/
|
||||
void sendParcelInfoRequest();
|
||||
|
||||
/**
|
||||
* "Location text" is actually the owner name, the original
|
||||
* name that owner gave the parcel, and the location.
|
||||
*/
|
||||
static std::string createLocationText(
|
||||
const std::string& owner_name,
|
||||
const std::string& original_name,
|
||||
const std::string& sim_name,
|
||||
const LLVector3d& pos_global);
|
||||
|
||||
/**
|
||||
* Sets snapshot id.
|
||||
*
|
||||
* Will mark snapshot control as valid if id is not null.
|
||||
* Will mark snapshot control as invalid if id is null. If null id is a valid value,
|
||||
* you have to manually mark snapshot is valid.
|
||||
*/
|
||||
virtual void setSnapshotId(const LLUUID& id);
|
||||
virtual void setPickDesc(const std::string& desc);
|
||||
virtual void setPickLocation(const std::string& location);
|
||||
|
||||
virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
|
||||
virtual LLVector3d& getPosGlobal() { return mPosGlobal; }
|
||||
|
||||
/**
|
||||
* Callback for "Map" button, opens Map
|
||||
*/
|
||||
void onClickMap();
|
||||
|
||||
/**
|
||||
* Callback for "Teleport" button, teleports user to Pick location.
|
||||
*/
|
||||
void onClickTeleport();
|
||||
|
||||
/**
|
||||
* Enables/disables "Save" button
|
||||
*/
|
||||
void enableSaveButton(BOOL enable);
|
||||
|
||||
/**
|
||||
* Called when snapshot image changes.
|
||||
*/
|
||||
void onSnapshotChanged();
|
||||
|
||||
/**
|
||||
* Callback for Pick snapshot, name and description changed event.
|
||||
*/
|
||||
void onPickChanged(LLUICtrl* ctrl);
|
||||
|
||||
/**
|
||||
* Resets panel and all cantrols to unedited state
|
||||
*/
|
||||
void resetDirty() override;
|
||||
|
||||
/**
|
||||
* Callback for "Set Location" button click
|
||||
*/
|
||||
void onClickSetLocation();
|
||||
|
||||
/**
|
||||
* Callback for "Save" and "Create" button click
|
||||
*/
|
||||
void onClickSave();
|
||||
|
||||
/**
|
||||
* Callback for "Save" button click
|
||||
*/
|
||||
void onClickCancel();
|
||||
|
||||
std::string getLocationNotice();
|
||||
|
||||
/**
|
||||
* Sends Pick properties to server.
|
||||
*/
|
||||
void sendUpdate();
|
||||
|
||||
protected:
|
||||
|
||||
LLTextureCtrl* mSnapshotCtrl;
|
||||
LLLineEditor* mPickName;
|
||||
LLTextEditor* mPickDescription;
|
||||
LLButton* mSetCurrentLocationButton;
|
||||
LLButton* mSaveButton;
|
||||
LLButton* mCreateButton;
|
||||
LLButton* mCancelButton;
|
||||
|
||||
LLVector3d mPosGlobal;
|
||||
LLUUID mParcelId;
|
||||
LLUUID mPickId;
|
||||
LLUUID mRequestedId;
|
||||
|
||||
bool mLocationChanged;
|
||||
bool mNewPick;
|
||||
bool mIsEditing;
|
||||
|
||||
void onDescriptionFocusReceived();
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELPICKS_H
|
||||
|
|
@ -367,7 +367,10 @@ void LLPreviewTexture::reshape(S32 width, S32 height, BOOL called_from_parent)
|
|||
|
||||
// add space for dimensions and aspect ratio
|
||||
S32 info_height = dim_rect.mTop + CLIENT_RECT_VPAD;
|
||||
|
||||
if (getChild<LLLayoutPanel>("buttons_panel")->getVisible())
|
||||
{
|
||||
info_height += getChild<LLLayoutPanel>("buttons_panel")->getRect().getHeight();
|
||||
}
|
||||
LLRect client_rect(horiz_pad, getRect().getHeight(), getRect().getWidth() - horiz_pad, 0);
|
||||
client_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);
|
||||
client_rect.mBottom += PREVIEW_BORDER + CLIENT_RECT_VPAD + info_height ;
|
||||
|
|
@ -412,6 +415,16 @@ void LLPreviewTexture::openToSave()
|
|||
mPreviewToSave = TRUE;
|
||||
}
|
||||
|
||||
void LLPreviewTexture::hideCtrlButtons()
|
||||
{
|
||||
getChildView("desc txt")->setVisible(false);
|
||||
getChildView("desc")->setVisible(false);
|
||||
getChild<LLLayoutStack>("preview_stack")->collapsePanel(getChild<LLLayoutPanel>("buttons_panel"), true);
|
||||
getChild<LLLayoutPanel>("buttons_panel")->setVisible(false);
|
||||
getChild<LLComboBox>("combo_aspect_ratio")->setCurrentByIndex(0); //unconstrained
|
||||
reshape(getRect().getWidth(), getRect().getHeight());
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPreviewTexture::onFileLoadedForSave(BOOL success,
|
||||
LLViewerFetchedTexture *src_vi,
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ public:
|
|||
|
||||
static void onSaveAsBtn(void* data);
|
||||
|
||||
void hideCtrlButtons();
|
||||
|
||||
/*virtual*/ void setObjectID(const LLUUID& object_id);
|
||||
protected:
|
||||
void init();
|
||||
|
|
|
|||
|
|
@ -213,7 +213,12 @@ void LLRemoteParcelInfoProcessor::regionParcelInfoCoro(std::string url,
|
|||
|
||||
if (!status)
|
||||
{
|
||||
observer->setErrorStatus(status.getStatus(), status.getMessage());
|
||||
std::string message = status.getMessage();
|
||||
if (message.empty())
|
||||
{
|
||||
message = status.toString();
|
||||
}
|
||||
observer->setErrorStatus(status.getStatus(), message);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@
|
|||
#include "llfloateravatarpicker.h"
|
||||
#include "llcallbacklist.h"
|
||||
#include "llcallingcard.h"
|
||||
#include "llclassifiedinfo.h"
|
||||
#include "llconsole.h"
|
||||
#include "llcontainerview.h"
|
||||
#include "llconversationlog.h"
|
||||
|
|
@ -124,8 +125,6 @@
|
|||
#include "llpanellogin.h"
|
||||
#include "llmutelist.h"
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
#include "llpanelclassified.h"
|
||||
#include "llpanelpick.h"
|
||||
#include "llpanelgrouplandmoney.h"
|
||||
#include "llpanelgroupnotices.h"
|
||||
#include "llparcel.h"
|
||||
|
|
@ -194,6 +193,7 @@
|
|||
#include "llavatariconctrl.h"
|
||||
#include "llvoicechannel.h"
|
||||
#include "llpathfindingmanager.h"
|
||||
#include "llremoteparcelrequest.h"
|
||||
|
||||
#include "lllogin.h"
|
||||
#include "llevents.h"
|
||||
|
|
@ -2652,7 +2652,6 @@ void register_viewer_callbacks(LLMessageSystem* msg)
|
|||
msg->setHandlerFunc("EventInfoReply", LLEventNotifier::processEventInfoReply);
|
||||
|
||||
msg->setHandlerFunc("PickInfoReply", &LLAvatarPropertiesProcessor::processPickInfoReply);
|
||||
// msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply);
|
||||
msg->setHandlerFunc("ClassifiedInfoReply", LLAvatarPropertiesProcessor::processClassifiedInfoReply);
|
||||
msg->setHandlerFunc("ParcelInfoReply", LLRemoteParcelInfoProcessor::processParcelInfoReply);
|
||||
msg->setHandlerFunc("ScriptDialog", process_script_dialog);
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include "llviewerinventory.h"
|
||||
#include "llviewermenufile.h" // LLFilePickerReplyThread
|
||||
#include "llpermissions.h"
|
||||
#include "llpreviewtexture.h"
|
||||
#include "llsaleinfo.h"
|
||||
#include "llassetstorage.h"
|
||||
#include "lltextbox.h"
|
||||
|
|
@ -1328,6 +1329,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
|
|||
mNeedsRawImageData( FALSE ),
|
||||
mValid( TRUE ),
|
||||
mShowLoadingPlaceholder( TRUE ),
|
||||
mOpenTexPreview(false),
|
||||
mImageAssetID(p.image_id),
|
||||
mDefaultImageAssetID(p.default_image_id),
|
||||
mDefaultImageName(p.default_image_name),
|
||||
|
|
@ -1584,12 +1586,31 @@ BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
|
||||
if (!handled && mBorder->parentPointInView(x, y))
|
||||
{
|
||||
showPicker(FALSE);
|
||||
//grab textures first...
|
||||
LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
|
||||
//...then start full inventory fetch.
|
||||
LLInventoryModelBackgroundFetch::instance().start();
|
||||
handled = TRUE;
|
||||
if (!mOpenTexPreview)
|
||||
{
|
||||
showPicker(FALSE);
|
||||
//grab textures first...
|
||||
LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
|
||||
//...then start full inventory fetch.
|
||||
LLInventoryModelBackgroundFetch::instance().start();
|
||||
handled = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (getImageAssetID().notNull())
|
||||
{
|
||||
LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", getValue());
|
||||
if (preview_texture && !preview_texture->isDependent())
|
||||
{
|
||||
LLFloater* root_floater = gFloaterView->getParentFloater(this);
|
||||
if (root_floater)
|
||||
{
|
||||
root_floater->addDependentFloater(preview_texture);
|
||||
preview_texture->hideCtrlButtons();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
|
|
|
|||
|
|
@ -169,6 +169,8 @@ public:
|
|||
void setBlankImageAssetID( const LLUUID& id ) { mBlankImageAssetID = id; }
|
||||
const LLUUID& getBlankImageAssetID() const { return mBlankImageAssetID; }
|
||||
|
||||
void setOpenTexPreview(bool open_preview) { mOpenTexPreview = open_preview; }
|
||||
|
||||
void setCaption(const std::string& caption);
|
||||
void setCanApplyImmediately(BOOL b);
|
||||
|
||||
|
|
@ -248,6 +250,8 @@ private:
|
|||
BOOL mShowLoadingPlaceholder;
|
||||
std::string mLoadingPlaceholderString;
|
||||
S32 mLabelWidth;
|
||||
bool mOpenTexPreview;
|
||||
BOOL mBakeTextureEnabled;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -0,0 +1,226 @@
|
|||
/**
|
||||
* @file llviewerdisplayname.cpp
|
||||
* @brief Wrapper for display name functionality
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llviewerdisplayname.h"
|
||||
|
||||
// viewer includes
|
||||
#include "llagent.h"
|
||||
#include "llfloaterprofile.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llvoavatar.h"
|
||||
|
||||
// library includes
|
||||
#include "llavatarnamecache.h"
|
||||
#include "llhttpnode.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llui.h" // getLanguage()
|
||||
|
||||
namespace LLViewerDisplayName
|
||||
{
|
||||
// Fired when viewer receives server response to display name change
|
||||
set_name_signal_t sSetDisplayNameSignal;
|
||||
|
||||
// Fired when there is a change in the agent's name
|
||||
name_changed_signal_t sNameChangedSignal;
|
||||
|
||||
void addNameChangedCallback(const name_changed_signal_t::slot_type& cb)
|
||||
{
|
||||
sNameChangedSignal.connect(cb);
|
||||
}
|
||||
|
||||
void doNothing() { }
|
||||
}
|
||||
|
||||
void LLViewerDisplayName::set(const std::string& display_name, const set_name_slot_t& slot)
|
||||
{
|
||||
// TODO: simple validation here
|
||||
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
llassert(region);
|
||||
std::string cap_url = region->getCapability("SetDisplayName");
|
||||
if (cap_url.empty())
|
||||
{
|
||||
// this server does not support display names, report error
|
||||
slot(false, "unsupported", LLSD());
|
||||
return;
|
||||
}
|
||||
|
||||
// People API requires both the old and new value to change a variable.
|
||||
// Our display name will be in cache before the viewer's UI is available
|
||||
// to request a change, so we can use direct lookup without callback.
|
||||
LLAvatarName av_name;
|
||||
if (!LLAvatarNameCache::get( gAgent.getID(), &av_name))
|
||||
{
|
||||
slot(false, "name unavailable", LLSD());
|
||||
return;
|
||||
}
|
||||
|
||||
// People API expects array of [ "old value", "new value" ]
|
||||
LLSD change_array = LLSD::emptyArray();
|
||||
change_array.append(av_name.getDisplayName());
|
||||
change_array.append(display_name);
|
||||
|
||||
LL_INFOS() << "Set name POST to " << cap_url << LL_ENDL;
|
||||
|
||||
// Record our caller for when the server sends back a reply
|
||||
sSetDisplayNameSignal.connect(slot);
|
||||
|
||||
// POST the requested change. The sim will not send a response back to
|
||||
// this request directly, rather it will send a separate message after it
|
||||
// communicates with the back-end.
|
||||
LLSD body;
|
||||
body["display_name"] = change_array;
|
||||
LLCoros::instance().launch("LLViewerDisplayName::SetDisplayNameCoro",
|
||||
boost::bind(&LLViewerDisplayName::setDisplayNameCoro, cap_url, body));
|
||||
}
|
||||
|
||||
void LLViewerDisplayName::setDisplayNameCoro(const std::string& cap_url, const LLSD& body)
|
||||
{
|
||||
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
|
||||
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("SetDisplayNameCoro", httpPolicy));
|
||||
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
|
||||
LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
|
||||
|
||||
// People API can return localized error messages. Indicate our
|
||||
// language preference via header.
|
||||
httpHeaders->append(HTTP_OUT_HEADER_ACCEPT_LANGUAGE, LLUI::getLanguage());
|
||||
|
||||
LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, body, httpHeaders);
|
||||
|
||||
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
|
||||
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
LL_WARNS() << "Unable to set display name. Status: " << status.toString() << LL_ENDL;
|
||||
LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD());
|
||||
LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
|
||||
}
|
||||
}
|
||||
|
||||
class LLSetDisplayNameReply : public LLHTTPNode
|
||||
{
|
||||
LOG_CLASS(LLSetDisplayNameReply);
|
||||
public:
|
||||
/*virtual*/ void post(
|
||||
LLHTTPNode::ResponsePtr response,
|
||||
const LLSD& context,
|
||||
const LLSD& input) const
|
||||
{
|
||||
LLSD body = input["body"];
|
||||
|
||||
S32 status = body["status"].asInteger();
|
||||
bool success = (status == HTTP_OK);
|
||||
std::string reason = body["reason"].asString();
|
||||
LLSD content = body["content"];
|
||||
|
||||
LL_INFOS() << "status " << status << " reason " << reason << LL_ENDL;
|
||||
|
||||
// If viewer's concept of display name is out-of-date, the set request
|
||||
// will fail with 409 Conflict. If that happens, fetch up-to-date
|
||||
// name information.
|
||||
if (status == HTTP_CONFLICT)
|
||||
{
|
||||
LLUUID agent_id = gAgent.getID();
|
||||
// Flush stale data
|
||||
LLAvatarNameCache::getInstance()->erase( agent_id );
|
||||
// Queue request for new data: nothing to do on callback though...
|
||||
// Note: no need to disconnect the callback as it never gets out of scope
|
||||
LLAvatarNameCache::getInstance()->get(agent_id, boost::bind(&LLViewerDisplayName::doNothing));
|
||||
// Kill name tag, as it is wrong
|
||||
LLVOAvatar::invalidateNameTag( agent_id );
|
||||
}
|
||||
|
||||
// inform caller of result
|
||||
LLViewerDisplayName::sSetDisplayNameSignal(success, reason, content);
|
||||
LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class LLDisplayNameUpdate : public LLHTTPNode
|
||||
{
|
||||
/*virtual*/ void post(
|
||||
LLHTTPNode::ResponsePtr response,
|
||||
const LLSD& context,
|
||||
const LLSD& input) const
|
||||
{
|
||||
LLSD body = input["body"];
|
||||
LLUUID agent_id = body["agent_id"];
|
||||
std::string old_display_name = body["old_display_name"];
|
||||
// By convention this record is called "agent" in the People API
|
||||
LLSD name_data = body["agent"];
|
||||
|
||||
// Inject the new name data into cache
|
||||
LLAvatarName av_name;
|
||||
av_name.fromLLSD( name_data );
|
||||
|
||||
LL_INFOS() << "name-update now " << LLDate::now()
|
||||
<< " next_update " << LLDate(av_name.mNextUpdate)
|
||||
<< LL_ENDL;
|
||||
|
||||
// Name expiration time may be provided in headers, or we may use a
|
||||
// default value
|
||||
// *TODO: get actual headers out of ResponsePtr
|
||||
//LLSD headers = response->mHeaders;
|
||||
LLSD headers;
|
||||
av_name.mExpires =
|
||||
LLAvatarNameCache::getInstance()->nameExpirationFromHeaders(headers);
|
||||
|
||||
LLAvatarNameCache::getInstance()->insert(agent_id, av_name);
|
||||
|
||||
// force name tag to update
|
||||
LLVOAvatar::invalidateNameTag(agent_id);
|
||||
|
||||
LLSD args;
|
||||
args["OLD_NAME"] = old_display_name;
|
||||
args["SLID"] = av_name.getUserName();
|
||||
args["NEW_NAME"] = av_name.getDisplayName();
|
||||
LLNotificationsUtil::add("DisplayNameUpdate", args);
|
||||
if (agent_id == gAgent.getID())
|
||||
{
|
||||
LLViewerDisplayName::sNameChangedSignal();
|
||||
}
|
||||
|
||||
LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id)));
|
||||
if (profile_floater)
|
||||
{
|
||||
profile_floater->refreshName();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
LLHTTPRegistration<LLSetDisplayNameReply>
|
||||
gHTTPRegistrationMessageSetDisplayNameReply(
|
||||
"/message/SetDisplayNameReply");
|
||||
|
||||
LLHTTPRegistration<LLDisplayNameUpdate>
|
||||
gHTTPRegistrationMessageDisplayNameUpdate(
|
||||
"/message/DisplayNameUpdate");
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* @file llviewerdisplayname.h
|
||||
* @brief Wrapper for display name functionality
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LLVIEWERDISPLAYNAME_H
|
||||
#define LLVIEWERDISPLAYNAME_H
|
||||
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
class LLSD;
|
||||
class LLUUID;
|
||||
|
||||
namespace LLViewerDisplayName
|
||||
{
|
||||
typedef boost::signals2::signal<
|
||||
void (bool success, const std::string& reason, const LLSD& content)>
|
||||
set_name_signal_t;
|
||||
typedef set_name_signal_t::slot_type set_name_slot_t;
|
||||
|
||||
typedef boost::signals2::signal<void (void)> name_changed_signal_t;
|
||||
typedef name_changed_signal_t::slot_type name_changed_slot_t;
|
||||
|
||||
// Sends an update to the server to change a display name
|
||||
// and call back when done. May not succeed due to service
|
||||
// unavailable or name not available.
|
||||
void set(const std::string& display_name, const set_name_slot_t& slot);
|
||||
|
||||
void setDisplayNameCoro(const std::string& cap_url, const LLSD& body);
|
||||
|
||||
void addNameChangedCallback(const name_changed_signal_t::slot_type& cb);
|
||||
}
|
||||
|
||||
#endif // LLVIEWERDISPLAYNAME_H
|
||||
|
|
@ -57,11 +57,13 @@
|
|||
#include "llfloatercamera.h"
|
||||
#include "llfloatercamerapresets.h"
|
||||
#include "llfloaterchatvoicevolume.h"
|
||||
#include "llfloaterclassified.h"
|
||||
#include "llfloaterconversationlog.h"
|
||||
#include "llfloaterconversationpreview.h"
|
||||
#include "llfloatercreatelandmark.h"
|
||||
#include "llfloaterdeleteprefpreset.h"
|
||||
#include "llfloaterdestinations.h"
|
||||
#include "llfloaterdisplayname.h"
|
||||
#include "llfloatereditextdaycycle.h"
|
||||
#include "llfloaterenvironmentadjust.h"
|
||||
#include "llfloaterexperienceprofile.h"
|
||||
|
|
@ -111,6 +113,7 @@
|
|||
#include "llfloaterpreference.h"
|
||||
#include "llfloaterpreferenceviewadvanced.h"
|
||||
#include "llfloaterpreviewtrash.h"
|
||||
#include "llfloaterprofile.h"
|
||||
#include "llfloaterproperties.h"
|
||||
#include "llfloaterregiondebugconsole.h"
|
||||
#include "llfloaterregioninfo.h"
|
||||
|
|
@ -140,7 +143,6 @@
|
|||
#include "llfloateruipreview.h"
|
||||
#include "llfloatervoiceeffect.h"
|
||||
#include "llfloaterwebcontent.h"
|
||||
#include "llfloaterwebprofile.h"
|
||||
#include "llfloatervoicevolume.h"
|
||||
#include "llfloaterwhitelistentry.h"
|
||||
#include "llfloaterwindowsize.h"
|
||||
|
|
@ -155,7 +157,7 @@
|
|||
#include "llmoveview.h"
|
||||
#include "llfloaterimnearbychat.h"
|
||||
#include "llpanelblockedlist.h"
|
||||
#include "llpanelclassified.h"
|
||||
#include "llpanelprofileclassifieds.h"
|
||||
#include "llpreviewanim.h"
|
||||
#include "llpreviewgesture.h"
|
||||
#include "llpreviewnotecard.h"
|
||||
|
|
@ -228,6 +230,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("camera_presets", "floater_camera_presets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCameraPresets>);
|
||||
LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>);
|
||||
LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater);
|
||||
LLFloaterReg::add("classified", "floater_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterClassified>);
|
||||
LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
|
||||
LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
|
||||
LLFloaterReg::add("add_landmark", "floater_create_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCreateLandmark>);
|
||||
|
|
@ -275,6 +278,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLInspectRemoteObjectUtil::registerFloater();
|
||||
LLFloaterVoiceVolumeUtil::registerFloater();
|
||||
LLNotificationsUI::registerFloater();
|
||||
LLFloaterDisplayNameUtil::registerFloater();
|
||||
|
||||
LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);
|
||||
LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
|
||||
|
|
@ -316,7 +320,6 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>);
|
||||
LLFloaterReg::add("prefs_spellchecker", "floater_spellcheck.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerSettings>);
|
||||
LLFloaterReg::add("prefs_autoreplace", "floater_autoreplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAutoReplaceSettings>);
|
||||
LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
|
||||
LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>);
|
||||
LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview");
|
||||
LLFloaterReg::add("preview_conversation", "floater_conversation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationPreview>);
|
||||
|
|
@ -365,8 +368,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
|
||||
LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>);
|
||||
LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
|
||||
LLFloaterReg::add("my_profile", "floater_my_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
|
||||
LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
|
||||
LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>);
|
||||
LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>);
|
||||
|
||||
LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
#include "llmutelist.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llpanelprofile.h"
|
||||
#include "llavataractions.h"
|
||||
#include "llparcel.h"
|
||||
#include "llpluginclassmedia.h"
|
||||
#include "llurldispatcher.h"
|
||||
|
|
|
|||
|
|
@ -3611,6 +3611,11 @@ bool my_profile_visible()
|
|||
return floaterp && floaterp->isInVisibleChain();
|
||||
}
|
||||
|
||||
bool picks_tab_visible()
|
||||
{
|
||||
return my_profile_visible() && LLAvatarActions::isPickTabSelected(gAgentID);
|
||||
}
|
||||
|
||||
bool enable_freeze_eject(const LLSD& avatar_id)
|
||||
{
|
||||
// Use avatar_id if available, otherwise default to right-click avatar
|
||||
|
|
@ -6304,6 +6309,29 @@ class LLAvatarToggleMyProfile : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
class LLAvatarTogglePicks : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
LLFloater * instance = LLAvatarActions::getProfileFloater(gAgent.getID());
|
||||
if (LLFloater::isMinimized(instance) || (instance && !instance->hasFocus() && !instance->getIsChrome()))
|
||||
{
|
||||
instance->setMinimized(FALSE);
|
||||
instance->setFocus(TRUE);
|
||||
LLAvatarActions::showPicks(gAgent.getID());
|
||||
}
|
||||
else if (picks_tab_visible())
|
||||
{
|
||||
instance->closeFloater();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLAvatarActions::showPicks(gAgent.getID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLAvatarToggleSearch : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
|
|
@ -6774,6 +6802,15 @@ class LLShowAgentProfile : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
class LLShowAgentProfilePicks : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
LLAvatarActions::showPicks(gAgent.getID());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLToggleAgentProfile : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
|
|
@ -9514,12 +9551,14 @@ void initialize_menus()
|
|||
enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall));
|
||||
view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse");
|
||||
view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile");
|
||||
view_listener_t::addMenu(new LLAvatarTogglePicks(), "Avatar.TogglePicks");
|
||||
view_listener_t::addMenu(new LLAvatarToggleSearch(), "Avatar.ToggleSearch");
|
||||
view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton");
|
||||
view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton");
|
||||
view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations");
|
||||
view_listener_t::addMenu(new LLAvatarResetSelfSkeletonAndAnimations(), "Avatar.ResetSelfSkeletonAndAnimations");
|
||||
enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible));
|
||||
enable.add("Avatar.IsPicksTabOpen", boost::bind(&picks_tab_visible));
|
||||
|
||||
commit.add("Avatar.OpenMarketplace", boost::bind(&LLWeb::loadURLExternal, gSavedSettings.getString("MarketplaceURL")));
|
||||
|
||||
|
|
@ -9596,6 +9635,7 @@ void initialize_menus()
|
|||
view_listener_t::addMenu(new LLToggleSpeak(), "ToggleSpeak");
|
||||
view_listener_t::addMenu(new LLPromptShowURL(), "PromptShowURL");
|
||||
view_listener_t::addMenu(new LLShowAgentProfile(), "ShowAgentProfile");
|
||||
view_listener_t::addMenu(new LLShowAgentProfilePicks(), "ShowAgentProfilePicks");
|
||||
view_listener_t::addMenu(new LLToggleAgentProfile(), "ToggleAgentProfile");
|
||||
view_listener_t::addMenu(new LLToggleControl(), "ToggleControl");
|
||||
view_listener_t::addMenu(new LLToggleShaderControl(), "ToggleShaderControl");
|
||||
|
|
|
|||
|
|
@ -266,14 +266,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
|
|||
return;
|
||||
}
|
||||
|
||||
LLWorld *world_inst = LLWorld::getInstance(); // Not a singleton!
|
||||
if (!world_inst)
|
||||
if (!LLWorld::instanceExists())
|
||||
{
|
||||
LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities, but world no longer exists!" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
regionp = world_inst->getRegionFromHandle(regionHandle);
|
||||
regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
|
||||
if (!regionp) //region was removed
|
||||
{
|
||||
LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities for region that no longer exists!" << LL_ENDL;
|
||||
|
|
@ -321,7 +320,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
|
|||
|
||||
regionp = NULL;
|
||||
impl = NULL;
|
||||
world_inst = NULL;
|
||||
result = httpAdapter->postAndSuspend(httpRequest, url, capabilityNames);
|
||||
|
||||
if (STATE_WORLD_INIT > LLStartUp::getStartupState())
|
||||
|
|
@ -332,34 +330,10 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
|
|||
|
||||
if (LLApp::isExiting() || gDisconnected)
|
||||
{
|
||||
LL_DEBUGS("AppInit", "Capabilities") << "Shutting down" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
world_inst = LLWorld::getInstance();
|
||||
if (!world_inst)
|
||||
{
|
||||
LL_WARNS("AppInit", "Capabilities") << "Received capabilities, but world no longer exists!" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
regionp = world_inst->getRegionFromHandle(regionHandle);
|
||||
if (!regionp) //region was removed
|
||||
{
|
||||
LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL;
|
||||
return; // this error condition is not recoverable.
|
||||
}
|
||||
|
||||
impl = regionp->getRegionImplNC();
|
||||
|
||||
++impl->mSeedCapAttempts;
|
||||
|
||||
if (id != impl->mHttpResponderID) // region is no longer referring to this request
|
||||
{
|
||||
LL_WARNS("AppInit", "Capabilities") << "Received results for a stale capabilities request!" << LL_ENDL;
|
||||
// setup for retry.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!result.isMap() || result.has("error"))
|
||||
{
|
||||
LL_WARNS("AppInit", "Capabilities") << "Malformed response" << LL_ENDL;
|
||||
|
|
@ -379,6 +353,30 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
|
|||
// remove the http_result from the llsd
|
||||
result.erase("http_result");
|
||||
|
||||
if (!LLWorld::instanceExists())
|
||||
{
|
||||
LL_WARNS("AppInit", "Capabilities") << "Received capabilities, but world no longer exists!" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
|
||||
if (!regionp) //region was removed
|
||||
{
|
||||
LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL;
|
||||
return; // this error condition is not recoverable.
|
||||
}
|
||||
|
||||
impl = regionp->getRegionImplNC();
|
||||
|
||||
++(impl->mSeedCapAttempts);
|
||||
|
||||
if (id != impl->mHttpResponderID) // region is no longer referring to this request
|
||||
{
|
||||
LL_WARNS("AppInit", "Capabilities") << "Received results for a stale capabilities request!" << LL_ENDL;
|
||||
// setup for retry.
|
||||
continue;
|
||||
}
|
||||
|
||||
LLSD::map_const_iterator iter;
|
||||
for (iter = result.beginMap(); iter != result.endMap(); ++iter)
|
||||
{
|
||||
|
|
@ -3002,6 +3000,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
|
|||
capabilityNames.append("AcceptFriendship");
|
||||
capabilityNames.append("AcceptGroupInvite"); // ReadOfflineMsgs recieved messages only!!!
|
||||
capabilityNames.append("AgentPreferences");
|
||||
capabilityNames.append("AgentProfile");
|
||||
capabilityNames.append("AgentState");
|
||||
capabilityNames.append("AttachmentResources");
|
||||
capabilityNames.append("AvatarPickerSearch");
|
||||
|
|
@ -3096,6 +3095,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
|
|||
capabilityNames.append("UpdateScriptTask");
|
||||
capabilityNames.append("UpdateSettingsAgentInventory");
|
||||
capabilityNames.append("UpdateSettingsTaskInventory");
|
||||
capabilityNames.append("UploadAgentProfileImage");
|
||||
capabilityNames.append("UpdateMaterialAgentInventory");
|
||||
capabilityNames.append("UpdateMaterialTaskInventory");
|
||||
capabilityNames.append("UploadBakedTexture");
|
||||
|
|
|
|||
|
|
@ -1166,7 +1166,8 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
|
|||
|
||||
BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
|
||||
const std::string& out_filename,
|
||||
const U8 codec)
|
||||
const U8 codec,
|
||||
const S32 max_image_dimentions)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
// Load the image
|
||||
|
|
@ -1195,7 +1196,7 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
|
|||
return FALSE;
|
||||
}
|
||||
// Convert to j2c (JPEG2000) and save the file locally
|
||||
LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image);
|
||||
LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image, max_image_dimentions);
|
||||
if (compressedImage.isNull())
|
||||
{
|
||||
image->setLastError("Couldn't convert the image to jpeg2000.");
|
||||
|
|
@ -1220,10 +1221,10 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
|
|||
}
|
||||
|
||||
// note: modifies the argument raw_image!!!!
|
||||
LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image)
|
||||
LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
raw_image->biasedScaleToPowerOfTwo(max_image_dimentions);
|
||||
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C();
|
||||
|
||||
if (gSavedSettings.getBOOL("LosslessJ2CUpload") &&
|
||||
|
|
|
|||
|
|
@ -92,8 +92,11 @@ class LLViewerTextureList
|
|||
friend class LLLocalBitmap;
|
||||
|
||||
public:
|
||||
static BOOL createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec);
|
||||
static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image);
|
||||
static BOOL createUploadFile(const std::string& filename,
|
||||
const std::string& out_filename,
|
||||
const U8 codec,
|
||||
const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
|
||||
static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
|
||||
static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data );
|
||||
static void receiveImageHeader(LLMessageSystem *msg, void **user_data);
|
||||
static void receiveImagePacket(LLMessageSystem *msg, void **user_data);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
#include "llstring.h"
|
||||
|
||||
// newview
|
||||
#include "llpanelprofile.h" // for getProfileURL(). FIXME: move the method to LLAvatarActions
|
||||
#include "llavataractions.h" // for getProfileURL()
|
||||
#include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals
|
||||
|
||||
#include "llcorehttputil.h"
|
||||
|
|
|
|||
|
|
@ -886,6 +886,22 @@
|
|||
name="PanelNotificationListItem"
|
||||
value="0.3 0.3 0.3 .3" />
|
||||
|
||||
<!-- profiles -->
|
||||
<color
|
||||
name="StatusUserOnline"
|
||||
reference="White" />
|
||||
<color
|
||||
name="StatusUserOffline"
|
||||
reference="LtGray_35" />
|
||||
<!-- Groups visible in own profiles -->
|
||||
<color
|
||||
name="GroupVisibleInProfile"
|
||||
reference="TextBgFocusColor" />
|
||||
<color
|
||||
name="GroupHiddenInProfile"
|
||||
reference="Gray" />
|
||||
|
||||
|
||||
<!-- Generic color names (legacy) -->
|
||||
<color
|
||||
name="white"
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 519 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 189 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 507 B |
|
After Width: | Height: | Size: 639 B |
|
After Width: | Height: | Size: 485 B |
|
After Width: | Height: | Size: 609 B |
|
|
@ -191,6 +191,7 @@ with the same filename but different name
|
|||
<texture name="Conv_log_inbox" file_name="icons/Conv_log_inbox.png" preload="false" />
|
||||
|
||||
<texture name="Copy" file_name="icons/Copy.png" preload="false" />
|
||||
<texture name="CopyBright" file_name="icons/CopyBright.png" preload="false" />
|
||||
|
||||
<texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" />
|
||||
|
||||
|
|
@ -513,6 +514,19 @@ with the same filename but different name
|
|||
<texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" />
|
||||
<texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" />
|
||||
|
||||
<texture name="Profile_Group_Visibility_Off" file_name="icons/profile_group_visibility_eye_off.png" preload="true"/>
|
||||
<texture name="Profile_Group_Visibility_Off_Pressed" file_name="icons/profile_group_visibility_eye_off_pressed.png" preload="true"/>
|
||||
<texture name="Profile_Group_Visibility_On" file_name="icons/profile_group_visibility_eye_on.png" preload="true"/>
|
||||
<texture name="Profile_Group_Visibility_On_Pressed" file_name="icons/profile_group_visibility_eye_on_pressed.png" preload="true"/>
|
||||
<texture name="Profile_Friend_Offline" file_name="icons/Profile_Friend_Offline.png" preload="true"/>
|
||||
<texture name="Profile_Friend_Online" file_name="icons/Profile_Friend_Online.png" preload="true"/>
|
||||
<texture name="Profile_Perm_Find_Disabled" file_name="icons/Profile_Perm_Find_Disabled.png" preload="true"/>
|
||||
<texture name="Profile_Perm_Find_Enabled" file_name="icons/Profile_Perm_Find_Enabled.png" preload="true"/>
|
||||
<texture name="Profile_Perm_Objects_Disabled" file_name="icons/Profile_Perm_Objects_Disabled.png" preload="true"/>
|
||||
<texture name="Profile_Perm_Objects_Enabled" file_name="icons/Profile_Perm_Objects_Enabled.png" preload="true"/>
|
||||
<texture name="Profile_Perm_Online_Disabled" file_name="icons/Profile_Perm_Online_Disabled.png" preload="true"/>
|
||||
<texture name="Profile_Perm_Online_Enabled" file_name="icons/Profile_Perm_Online_Enabled.png" preload="true"/>
|
||||
|
||||
<texture name="ProgressBar" file_name="widgets/ProgressBar.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" />
|
||||
<texture name="ProgressBarSolid" file_name="widgets/ProgressBarSolid.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" />
|
||||
<texture name="ProgressTrack" file_name="widgets/ProgressTrack.png" preload="true" scale.left="4" scale.top="13" scale.right="148" scale.bottom="2" />
|
||||
|
|
|
|||