# Conflicts:
#	indra/newview/lllocalbitmaps.cpp
#	indra/newview/lllocalbitmaps.h
#	indra/newview/llviewerregion.cpp
master
Ansariel 2022-08-31 09:03:56 +02:00
commit cefc6c4afc
417 changed files with 14689 additions and 17588 deletions

View File

@ -225,6 +225,7 @@ Ansariel Hiller
MAINT-8723
SL-10385
SL-10891
SL-10675
SL-13364
SL-13858
SL-13697
@ -827,6 +828,7 @@ Jonathan Yap
Kadah Coba
STORM-1060
STORM-1843
SL-10675
Jondan Lundquist
Joosten Briebers
MAINT-7074

View File

@ -276,6 +276,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),
@ -994,7 +995,10 @@ bool LLFloater::applyRectControl()
// </FS:Ansariel>
// 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
@ -3854,8 +3858,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())

View File

@ -477,6 +477,7 @@ public:
protected:
bool mSaveRect;
bool mDefaultRectForGroup;
std::string mRectControl;
std::string mPosXControl;
std::string mPosYControl;

View File

@ -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)

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -41,7 +41,8 @@ public:
{
MP_TOP_LEFT,
MP_TOP_RIGHT,
MP_BOTTOM_LEFT
MP_BOTTOM_LEFT,
MP_BOTTOM_RIGHT
} EMenuPosition;
struct MenuPositions

View File

@ -431,12 +431,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
{
// [SL:KB] - Patch: Control-TabContainer | Checked: 2014-03-17 (Catznip-3.6)
S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
// [/SL:KB]
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
{
if (cur_scroll_pos == 0)
@ -455,12 +456,6 @@ void LLTabContainer::draw()
// clamp so that rightmost tab never leaves right side of screen
target_pixel_scroll = llmin(mTotalTabWidth - available_width_with_arrows, target_pixel_scroll);
}
// [SL:KB] - Patch: Control-TabContainer | Checked: 2014-03-17 (Catznip-3.6)
else
{
target_pixel_scroll = cur_scroll_pos * (BTN_HEIGHT + tabcntrv_pad);
}
// [/SL:KB]
}
// [SL:KB] - Patch: Control-TabContainer | Checked: 2014-03-17 (Catznip-3.6)
@ -1339,16 +1334,15 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
sendChildToFront(mNextArrowBtn);
sendChildToFront(mJumpPrevArrowBtn);
sendChildToFront(mJumpNextArrowBtn);
if( select )
{
// [SL:KB] - Patch: Control-TabContainer | Checked: 2012-08-10 (Catznip-3.3)
selectTabPanel(child);
// [/SL:KB]
// selectLastTab();
}
updateMaxScrollPos();
if( select )
{
selectLastTab();
mScrollPos = mMaxScrollPos;
}
}
void LLTabContainer::addPlaceholder(LLPanel* child, const std::string& label)
@ -2331,9 +2325,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;
}
}

View File

@ -182,6 +182,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),
// <FS:Ansariel> Optional icon position
icon_positioning("icon_positioning", LLTextBaseEnums::RIGHT),
@ -237,6 +238,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 ),
@ -523,8 +525,48 @@ void LLTextBase::drawHighlightsBackground(const highlight_list_t& highlights, co
++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);
}
}
@ -2285,7 +2327,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;
@ -2317,14 +2359,14 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
// add icon before url if need
// <FS:Ansariel> Optional icon position
//LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted());
//LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted() || mAlwaysShowIcons);
//if ((isContentTrusted() || match.isTrusted()) && !match.getIcon().empty() )
//{
// setLastSegmentToolTip(LLTrans::getString("TooltipSLIcon"));
//}
if (mIconPositioning == LLTextBaseEnums::LEFT || match.isTrusted())
if (mIconPositioning == LLTextBaseEnums::LEFT || match.isTrusted() || mAlwaysShowIcons)
{
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"));
@ -2368,7 +2410,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
}
// <FS:Ansariel> Optional icon position
if (mIconPositioning == LLTextBaseEnums::RIGHT && !match.isTrusted())
if (mIconPositioning == LLTextBaseEnums::RIGHT && !match.isTrusted() && !mAlwaysShowIcons)
{
LLTextUtil::processUrlMatch(&match,this,isContentTrusted());
}

View File

@ -345,7 +345,8 @@ public:
parse_highlights,
clip,
clip_partial,
trusted_content;
trusted_content,
always_show_icons;
Optional<S32> v_pad,
h_pad;
@ -396,9 +397,7 @@ public:
virtual void onFocusReceived();
virtual void onFocusLost();
//<FS:KC - expose ParseHTML setting>
void setParseHTML(bool parse_html) { mParseHTML = parse_html; }
//</FS:KC - expose ParseHTML setting>
void setParseHTML(bool parse_html) { mParseHTML = parse_html; }
// LLSpellCheckMenuHandler overrides
/*virtual*/ bool getSpellCheck() const;
@ -764,6 +763,8 @@ protected:
bool mAutoIndent;
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
bool mSkipTripleClick;
bool mAlwaysShowIcons;
bool mSkipLinkUnderline;
// support widgets

View File

@ -174,7 +174,6 @@ set(viewer_SOURCE_FILES
fsfloaterpartialinventory.cpp
fsfloaterplacedetails.cpp
fsfloaterposestand.cpp
fsfloaterprofile.cpp
fsfloaterprotectedfolders.cpp
fsfloaterradar.cpp
fsfloatersearch.cpp
@ -196,13 +195,10 @@ set(viewer_SOURCE_FILES
fsnearbychathub.cpp
fsnearbychatvoicemonitor.cpp
fspanelblocklist.cpp
fspanelclassified.cpp
fspanelcontactsets.cpp
fspanelimcontrolpanel.cpp
fspanellogin.cpp
fspanelprefs.cpp
fspanelprofile.cpp
fspanelprofileclassifieds.cpp
fspanelradar.cpp
fsparticipantlist.cpp
fspose.cpp
@ -349,6 +345,7 @@ set(viewer_SOURCE_FILES
llfloatercamera.cpp
llfloatercamerapresets.cpp
llfloaterchatvoicevolume.cpp
llfloaterclassified.cpp
llfloatercolorpicker.cpp
llfloaterconversationlog.cpp
llfloaterconversationpreview.cpp
@ -413,10 +410,12 @@ set(viewer_SOURCE_FILES
fsfloaterperformance.cpp
llfloaterperms.cpp
llfloaterpostprocess.cpp
llfloaterprofile.cpp
llfloaterpreference.cpp
# llfloaterpreferencesgraphicsadvanced.cpp
llfloaterpreferenceviewadvanced.cpp
llfloaterpreviewtrash.cpp
llfloaterprofiletexture.cpp
llfloaterproperties.cpp
llfloaterregiondebugconsole.cpp
llfloaterregioninfo.cpp
@ -450,7 +449,6 @@ set(viewer_SOURCE_FILES
llfloatervoiceeffect.cpp
llfloatervoicevolume.cpp
llfloaterwebcontent.cpp
llfloaterwebprofile.cpp
llfloaterwhitelistentry.cpp
llfloaterwindowsize.cpp
llfloaterworldmap.cpp
@ -599,7 +597,6 @@ set(viewer_SOURCE_FILES
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
llpanelmediasettingssecurity.cpp
llpanelme.cpp
llpanelnearbymedia.cpp
llpanelobject.cpp
llpanelobjectinventory.cpp
@ -609,8 +606,6 @@ set(viewer_SOURCE_FILES
llpanelpeople.cpp
llpanelpeoplemenus.cpp
llpanelpermissions.cpp
llpanelpick.cpp
llpanelpicks.cpp
llpanelplaceinfo.cpp
llpanelplaceprofile.cpp
llpanelplaces.cpp
@ -619,6 +614,8 @@ set(viewer_SOURCE_FILES
llpanelpresetspulldown.cpp
llpanelprimmediacontrols.cpp
llpanelprofile.cpp
llpanelprofileclassifieds.cpp
llpanelprofilepicks.cpp
llpanelsnapshot.cpp
llpanelsnapshotinventory.cpp
llpanelsnapshotlocal.cpp
@ -955,7 +952,6 @@ set(viewer_HEADER_FILES
fsfloaterpartialinventory.h
fsfloaterplacedetails.h
fsfloaterposestand.h
fsfloaterprofile.h
fsfloaterprotectedfolders.h
fsfloaterradar.h
fsfloatersearch.h
@ -979,12 +975,9 @@ set(viewer_HEADER_FILES
fsnearbychatvoicemonitor.h
fspanelblocklist.h
fspanelcontactsets.h
fspanelclassified.h
fspanelimcontrolpanel.h
fspanellogin.h
fspanelprefs.h
fspanelprofile.h
fspanelprofileclassifieds.h
fspanelradar.h
fsparticipantlist.h
fspose.h
@ -1133,6 +1126,7 @@ set(viewer_HEADER_FILES
llfloatercamerapresets.h
llfloatercamera.h
llfloaterchatvoicevolume.h
llfloaterclassified.h
llfloatercolorpicker.h
llfloaterconversationlog.h
llfloaterconversationpreview.h
@ -1200,10 +1194,12 @@ set(viewer_HEADER_FILES
fsfloaterperformance.h
llfloaterperms.h
llfloaterpostprocess.h
llfloaterprofile.h
llfloaterpreference.h
# llfloaterpreferencesgraphicsadvanced.h
llfloaterpreferenceviewadvanced.h
llfloaterpreviewtrash.h
llfloaterprofiletexture.h
llfloaterproperties.h
llfloaterregiondebugconsole.h
llfloaterregioninfo.h
@ -1237,7 +1233,6 @@ set(viewer_HEADER_FILES
llfloatervoiceeffect.h
llfloatervoicevolume.h
llfloaterwebcontent.h
llfloaterwebprofile.h
llfloaterwhitelistentry.h
llfloaterwindowsize.h
llfloaterworldmap.h
@ -1376,7 +1371,6 @@ set(viewer_HEADER_FILES
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
llpanelmediasettingssecurity.h
llpanelme.h
llpanelnearbymedia.h
llpanelobject.h
llpanelobjectinventory.h
@ -1386,8 +1380,6 @@ set(viewer_HEADER_FILES
llpanelpeople.h
llpanelpeoplemenus.h
llpanelpermissions.h
llpanelpick.h
llpanelpicks.h
llpanelplaceinfo.h
llpanelplaceprofile.h
llpanelplaces.h
@ -1396,6 +1388,8 @@ set(viewer_HEADER_FILES
llpanelpresetspulldown.h
llpanelprimmediacontrols.h
llpanelprofile.h
llpanelprofileclassifieds.h
llpanelprofilepicks.h
llpanelsnapshot.h
llpanelteleporthistory.h
llpaneltiptoast.h

View File

@ -179,10 +179,8 @@
icon="Command_Picks_Icon"
label_ref="Command_Picks_Label"
tooltip_ref="Command_Picks_Tooltip"
execute_function="Floater.Toggle"
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"

View File

@ -355,17 +355,6 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>FSUseWebProfiles</key>
<map>
<key>Comment</key>
<string>Shows web profiles instead of the v1-style profile floater</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSTPHistoryTZ</key>
<map>
<key>Comment</key>

View File

@ -243,18 +243,6 @@
<integer>1</integer>
</map>
<key>FSUseWebProfiles</key>
<map>
<key>Comment</key>
<string>Shows web profiles instead of the v1-style profile floater</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSFolderViewItemHeight</key>
<map>
<key>Comment</key>

View File

@ -219,18 +219,6 @@
<integer>1</integer>
</map>
<key>FSUseWebProfiles</key>
<map>
<key>Comment</key>
<string>Shows web profiles instead of the v1-style profile floater</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSFolderViewItemHeight</key>
<map>
<key>Comment</key>

View File

@ -231,18 +231,6 @@
<integer>1</integer>
</map>
<key>FSUseWebProfiles</key>
<map>
<key>Comment</key>
<string>Shows web profiles instead of the v1-style profile floater</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSFolderViewItemHeight</key>
<map>
<key>Comment</key>

View File

@ -207,18 +207,6 @@
<integer>1</integer>
</map>
<key>FSUseWebProfiles</key>
<map>
<key>Comment</key>
<string>Shows web profiles instead of the v1-style profile floater</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSFolderViewItemHeight</key>
<map>
<key>Comment</key>

View File

@ -254,18 +254,6 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>FSUseWebProfiles</key>
<map>
<key>Comment</key>
<string>Shows web profiles instead of the v1-style profile floater</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FSFontChatLineSpacingPixels</key>
<map>

View File

@ -28,7 +28,7 @@
#ifndef FS_DISPATCHCLASSIFIEDCLICKTHROUGH_H
#define FS_DISPATCHCLASSIFIEDCLICKTHROUGH_H
#include "fspanelclassified.h"
#include "llpanelprofileclassifieds.h"
#include "lldispatcher.h"
// "classifiedclickthrough"
@ -51,7 +51,7 @@ public:
S32 map_clicks = atoi(strings[2].c_str());
S32 profile_clicks = atoi(strings[3].c_str());
FSPanelClassifiedInfo::setClickThrough(
LLPanelProfileClassified::setClickThrough(
classified_id, teleport_clicks, map_clicks, profile_clicks, false);
return true;

View File

@ -34,7 +34,6 @@
#include "llviewerinventory.h"
static LLDefaultChildRegistry::Register<FSCopyTransInventoryDropTarget> r1("fs_copytrans_inventory_drop_target");
static LLDefaultChildRegistry::Register<FSDropTarget> r2("profile_drop_target");
static LLDefaultChildRegistry::Register<FSEmbeddedItemDropTarget> r3("fs_embedded_item_drop_target");
@ -70,29 +69,6 @@ BOOL FSCopyTransInventoryDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask,
return TRUE;
}
FSDropTarget::FSDropTarget(const FSDropTarget::Params& p)
: LLView(p),
mAgentID(p.agent_id)
{}
BOOL FSDropTarget::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);
return TRUE;
}
return FALSE;
}
BOOL FSEmbeddedItemDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,

View File

@ -70,37 +70,6 @@ private:
};
class FSDropTarget : 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);
}
};
FSDropTarget(const Params&);
~FSDropTarget() {}
// 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;
};
class FSEmbeddedItemDropTarget : public LLTextBox
{
public:

View File

@ -46,7 +46,6 @@
#include "lllandmarkactions.h"
#include "lllandmarklist.h"
#include "llnotificationsutil.h"
#include "llpanelpick.h"
#include "llpanelplaceprofile.h"
#include "llpanellandmarkinfo.h"
#include "llparcel.h"
@ -191,8 +190,7 @@ FSFloaterPlaceDetails::FSFloaterPlaceDetails(const LLSD& seed)
mIsInEditMode(false),
mIsInCreateMode(false),
mGlobalPos(),
mDisplayInfo(NONE),
mPickPanel(NULL)
mDisplayInfo(NONE)
{
mParcelObserver = new FSPlaceDetailsPlacesParcelObserver(this);
mRemoteParcelObserver = new FSPlaceDetailsRemoteParcelInfoObserver(this);
@ -566,14 +564,6 @@ void FSFloaterPlaceDetails::setItem(LLInventoryItem* item)
}
}
void FSFloaterPlaceDetails::togglePickPanel(BOOL visible)
{
if (mPickPanel)
{
mPickPanel->setVisible(visible);
}
}
// static
void FSFloaterPlaceDetails::showPlaceDetails(const LLSD& key)
{
@ -785,19 +775,6 @@ void FSFloaterPlaceDetails::onOverflowMenuItemClicked(const LLSD& param)
}
else if (item == "pick")
{
if (mPickPanel == NULL)
{
mPickPanel = LLPanelPickEdit::create();
addChild(mPickPanel);
mPickPanel->setExitCallback(boost::bind(&FSFloaterPlaceDetails::togglePickPanel, this, FALSE));
mPickPanel->setCancelCallback(boost::bind(&FSFloaterPlaceDetails::togglePickPanel, this, FALSE));
mPickPanel->setSaveCallback(boost::bind(&FSFloaterPlaceDetails::togglePickPanel, this, FALSE));
}
togglePickPanel(TRUE);
mPickPanel->onOpen(LLSD());
LLPanelPlaceInfo* panel = mPanelPlaceInfo;
if (mDisplayInfo == LANDMARK)
{
@ -806,11 +783,7 @@ void FSFloaterPlaceDetails::onOverflowMenuItemClicked(const LLSD& param)
if (panel)
{
panel->createPick(mGlobalPos, mPickPanel);
LLRect rect = panel->getRect();
mPickPanel->reshape(rect.getWidth(), rect.getHeight());
mPickPanel->setRect(rect);
panel->createPick(mGlobalPos);
}
}
else if (item == "add_to_favbar")

View File

@ -39,7 +39,6 @@
class LLLandmark;
class LLMenuButton;
class LLPanelLandmarkInfo;
class LLPanelPickEdit;
class LLPanelPlaceProfile;
struct LLParcelData;
class LLToggleableMenu;
@ -61,7 +60,6 @@ public:
void changedGlobalPos(const LLVector3d& global_pos);
void changedParcelSelection();
void processParcelDetails(const LLParcelData& parcel_details);
void togglePickPanel(BOOL visible);
static void showPlaceDetails(const LLSD& key);
@ -95,7 +93,6 @@ private:
void setItem(LLInventoryItem* item);
void onSLURLBuilt(std::string& slurl);
LLPanelPickEdit* mPickPanel;
LLPanelLandmarkInfo* mPanelLandmarkInfo;
LLPanelPlaceProfile* mPanelPlaceInfo;

View File

@ -1,97 +0,0 @@
/**
* @file fsfloaterprofile.cpp
* @brief Legacy Profile Floater
*
* $LicenseInfo:firstyear=2012&license=fsviewerlgpl$
* Phoenix Firestorm Viewer Source Code
* Copyright (C) 2012, Kadah Coba
*
* 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
*
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
* http://www.firestormviewer.org
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "fsfloaterprofile.h"
#include "fspanelprofile.h"
#include "llagent.h" //gAgent
static const std::string PANEL_PROFILE_VIEW = "panel_profile_view";
FSFloaterProfile::FSFloaterProfile(const LLSD& key)
: LLFloater(key),
mAvatarId(key["id"].asUUID()),
mNameCallbackConnection()
{
}
FSFloaterProfile::~FSFloaterProfile()
{
if (mNameCallbackConnection.connected())
{
mNameCallbackConnection.disconnect();
}
}
void FSFloaterProfile::onOpen(const LLSD& key)
{
FSPanelProfile* panel_profile = findChild<FSPanelProfile>(PANEL_PROFILE_VIEW);
panel_profile->onOpen(mAvatarId);
if (mAvatarId == gAgentID)
{
getChild<LLUICtrl>("ok_btn")->setVisible(TRUE);
getChild<LLUICtrl>("cancel_btn")->setVisible(TRUE);
}
// Update the avatar name.
mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&FSFloaterProfile::onAvatarNameCache, this, _1, _2));
}
BOOL FSFloaterProfile::postBuild()
{
childSetAction("ok_btn", boost::bind(&FSFloaterProfile::onOKBtn, this));
childSetAction("cancel_btn", boost::bind(&FSFloaterProfile::onCancelBtn, this));
return TRUE;
}
void FSFloaterProfile::onOKBtn()
{
if (mAvatarId == gAgentID)
{
FSPanelProfile* panel_profile = findChild<FSPanelProfile>(PANEL_PROFILE_VIEW);
panel_profile->apply();
}
closeFloater();
}
void FSFloaterProfile::onCancelBtn()
{
closeFloater();
}
void FSFloaterProfile::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
{
mNameCallbackConnection.disconnect();
setTitle(av_name.getCompleteName());
}
// eof

View File

@ -1,55 +0,0 @@
/**
* @file fsfloaterprofile.h
* @brief Legacy Profile Floater
*
* $LicenseInfo:firstyear=2012&license=fsviewerlgpl$
* Phoenix Firestorm Viewer Source Code
* Copyright (C) 2012, Kadah Coba
*
* 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
*
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
* http://www.firestormviewer.org
* $/LicenseInfo$
*/
#ifndef FS_FLOATERPROFILE_H
#define FS_FLOATERPROFILE_H
#include "llavatarnamecache.h"
#include "llfloater.h"
class FSFloaterProfile : public LLFloater
{
LOG_CLASS(FSFloaterProfile);
public:
FSFloaterProfile(const LLSD& key);
virtual ~FSFloaterProfile();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ BOOL postBuild();
protected:
void onOKBtn();
void onCancelBtn();
private:
LLAvatarNameCache::callback_connection_t mNameCallbackConnection;
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
LLUUID mAvatarId;
};
#endif // FS_FLOATERPROFILE_H

View File

@ -31,8 +31,6 @@
#include "fsavatarsearchmenu.h"
#include "fsdispatchclassifiedclickthrough.h"
#include "fspanelclassified.h"
#include "fspanelprofile.h"
#include "fsscrolllistctrl.h"
#include "lfsimfeaturehandler.h"
#include "llagent.h"
@ -53,7 +51,8 @@
#include "llloadingindicator.h"
#include "lllogininstance.h"
#include "llnotificationsutil.h"
#include "llpanelclassified.h"
#include "llpanelprofile.h"
#include "llpanelprofileclassifieds.h"
#include "llparcel.h"
#include "llproductinforequest.h"
#include "llqueryflags.h"
@ -183,7 +182,7 @@ public:
LL_INFOS("Search") << "Classified stat request via capability" << LL_ENDL;
LLSD body;
body["classified_id"] = c_info->classified_id;
LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body, boost::bind(&LLPanelClassifiedInfo::handleSearchStatResponse, c_info->classified_id, _1));
LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body, boost::bind(&LLPanelProfileClassified::handleSearchStatResponse, c_info->classified_id, _1));
}
}
}
@ -309,15 +308,6 @@ BOOL FSFloaterSearch::postBuild()
mPanelClassifieds = findChild<FSPanelSearchClassifieds>("panel_ls_classifieds");
mPanelWeb = findChild<FSPanelSearchWeb>("panel_ls_web");
// <KC> If skin has legacy full profile view, use it
mPanelProfile = mPanelPeople->findChild<FSPanelProfile>("panel_profile_view");
if (mPanelProfile)
{
mPanelProfile->setVisible(false);
mPanelProfile->setEmbedded(true);
mPanelPeople->childSetAction("people_profile_btn", boost::bind(&FSFloaterSearch::onBtnPeopleProfile, this));
}
mDetailsPanel = getChild<LLPanel>("panel_ls_details");
mDetailTitle = getChild<LLTextEditor>("title");
mDetailDesc = getChild<LLTextEditor>("desc");
@ -354,12 +344,7 @@ void FSFloaterSearch::onTabChange()
mDetailsPanel->setVisible(false);
mPanelWeb->resetFocusOnLoad();
}
// <KC> If on legacy people search and skin uses full profile preview, hide preview panel
else if (active_panel == mPanelPeople && mPanelProfile)
{
mDetailsPanel->setVisible(false);
}
else
else if (active_panel == mPanelPeople)
{
mDetailsPanel->setVisible(mHasSelection);
}
@ -402,19 +387,8 @@ void FSFloaterSearch::onSelectedItem(const LLUUID& selected_item, ESearchCategor
switch (type)
{
case SC_AVATAR:
{
// <KC> If skin has legacy full profile view, use it
if (mPanelProfile)
{
mPanelProfile->setVisible(true);
mPanelProfile->onOpen(selected_item);
}
else
{
LLAvatarPropertiesProcessor::getInstance()->addObserver(selected_item, mAvatarPropertiesObserver);
LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(selected_item);
}
}
LLAvatarPropertiesProcessor::getInstance()->addObserver(selected_item, mAvatarPropertiesObserver);
LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(selected_item);
break;
case SC_GROUP:
mGroupPropertiesRequest = new FSSearchGroupInfoObserver(selected_item, this);

View File

@ -48,7 +48,7 @@ class LLGroupMgrObserver;
class LLSearchEditor;
class LLSearchComboBox;
class FSFloaterSearch;
class FSPanelProfile;
class LLPanelProfile;
class FSScrollListCtrl;
struct SearchQuery : public LLInitParam::Block<SearchQuery>
@ -412,7 +412,6 @@ private:
LLTextureCtrl* mDetailSnapshotParcel;
LLIconCtrl* mDetailMaturity;
LLTabContainer* mTabContainer;
FSPanelProfile* mPanelProfile;
};
#endif // FS_FLOATERSEARCH_H

File diff suppressed because it is too large Load Diff

View File

@ -1,300 +0,0 @@
/**
* @file fspanelclassified.h
* @brief FSPanelClassified class definition
*
* $LicenseInfo:firstyear=2005&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 classified used both for the global view in the
// Find directory, and also for each individual user's classified in their
// profile.
#ifndef FS_PANELCLASSIFIED_H
#define FS_PANELCLASSIFIED_H
#include "llavatarpropertiesprocessor.h"
#include "llclassifiedinfo.h"
#include "llfloater.h"
#include "llpanel.h"
#include "llrect.h"
#include "lluuid.h"
#include "v3dmath.h"
class LLScrollContainer;
class LLTextureCtrl;
class LLUICtrl;
class FSPublishClassifiedFloater : public LLFloater
{
public:
FSPublishClassifiedFloater(const LLSD& key);
virtual ~FSPublishClassifiedFloater();
/*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 FSPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver
{
LOG_CLASS(FSPanelClassifiedInfo);
public:
static FSPanelClassifiedInfo* create();
virtual ~FSPanelClassifiedInfo();
/*virtual*/ void onOpen(const LLSD& key);
void updateData();
/*virtual*/ BOOL postBuild();
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
LLUUID& getAvatarId() { return mAvatarId; }
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; }
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 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:
FSPanelClassifiedInfo();
virtual void resetData();
virtual void resetControls();
static std::string createLocationText(
const std::string& original_name,
const std::string& sim_name,
const LLVector3d& pos_global);
void stretchSnapshot();
void sendClickMessage(const std::string& type);
LLRect getDefaultSnapshotRect();
void scrollToTop();
void onMapClick();
void onTeleportClick();
void onExit();
bool mSnapshotStreched;
LLRect mSnapshotRect;
LLTextureCtrl* mSnapshotCtrl;
private:
LLUUID mAvatarId;
LLUUID mClassifiedId;
LLVector3d mPosGlobal;
LLUUID mParcelId;
std::string mSimName;
bool mFromSearch;
bool mInfoLoaded;
LLScrollContainer* mScrollContainer;
LLPanel* mScrollingPanel;
S32 mScrollingPanelMinHeight;
S32 mScrollingPanelWidth;
// Needed for stat tracking
S32 mTeleportClicksOld;
S32 mMapClicksOld;
S32 mProfileClicksOld;
S32 mTeleportClicksNew;
S32 mMapClicksNew;
S32 mProfileClicksNew;
typedef std::list<FSPanelClassifiedInfo*> panel_list_t;
static panel_list_t sAllPanels;
};
class FSPanelClassifiedEdit : public FSPanelClassifiedInfo
{
LOG_CLASS(FSPanelClassifiedEdit);
public:
static FSPanelClassifiedEdit* create();
virtual ~FSPanelClassifiedEdit();
/*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:
FSPanelClassifiedEdit();
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:
S32 getClassifiedFee(); // <FS:CR> FIRE-9814 - Don't hardcode a classified listing fee
bool mIsNew;
bool mIsNewWithErrors;
bool mCanClose;
FSPublishClassifiedFloater* mPublishFloater;
commit_signal_t mSaveButtonClickedSignal;
};
#endif // FS_PANELCLASSIFIED_H

File diff suppressed because it is too large Load Diff

View File

@ -1,665 +0,0 @@
/**
* @file fspanelprofile.h
* @brief Legacy Profile Floater
*
* $LicenseInfo:firstyear=2012&license=fsviewerlgpl$
* Phoenix Firestorm Viewer Source Code
* Copyright (C) 2012, Kadah Coba
*
* 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
*
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
* http://www.firestormviewer.org
* $/LicenseInfo$
*/
#ifndef FS_PANELPROFILE_H
#define FS_PANELPROFILE_H
#include "llfloater.h"
#include "llavatarpropertiesprocessor.h"
#include "llcallingcard.h"
#include "llvoiceclient.h"
#include "llmediactrl.h"
#include "llremoteparcelrequest.h"
#include "rlvhandler.h"
class LLAvatarName;
class LLCheckBoxCtrl;
class LLTabContainer;
class LLTextBox;
class LLTextureCtrl;
class LLMediaCtrl;
class LLGroupList;
class LLTextBase;
class LLMenuButton;
class LLLineEditor;
class LLTextEditor;
class FSPanelClassifieds;
/**
* Base class for any Profile View or My Profile Panel.
*/
class FSPanelProfileTab
: public LLPanel
, public LLAvatarPropertiesObserver
{
public:
/**
* Sets avatar ID, sets panel as observer of avatar related info replies from server.
*/
virtual void setAvatarId(const LLUUID& id);
/**
* Sends update data request to server.
*/
virtual void updateData() { }
/**
* Processes data received from server.
*/
virtual void processProperties(void* data, EAvatarProcessorType type) = 0;
/**
* Returns avatar ID.
*/
const LLUUID& getAvatarId() { return mAvatarId; }
/**
* Clears panel data if viewing avatar info for first time and sends update data request.
*/
virtual void onOpen(const LLSD& key);
/*virtual*/ ~FSPanelProfileTab();
void setEmbedded(bool embedded) { mEmbedded = embedded; }
protected:
FSPanelProfileTab();
virtual void enableControls();
// 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
bool getIsLoading() { return mLoading; }
void setIsLoading() { mLoading = true; }
bool getIsLoaded() { return mLoaded; }
void resetLoading() { mLoading = false; mLoaded = false; }
const bool getEmbedded() const { return mEmbedded; }
const bool getSelfProfile() const { return mSelfProfile; }
void setApplyProgress(bool started);
private:
LLUUID mAvatarId;
bool mLoading;
bool mLoaded;
bool mEmbedded;
bool mSelfProfile;
};
/**
* Panel for displaying Avatar's second life related info.
*/
class FSPanelProfileSecondLife
: public FSPanelProfileTab
, public LLFriendObserver
, public LLVoiceClientStatusObserver
{
public:
FSPanelProfileSecondLife();
/*virtual*/ ~FSPanelProfileSecondLife();
/*virtual*/ void onOpen(const LLSD& key);
/**
* Saves changes.
*/
void apply(LLAvatarData* data);
/**
* LLFriendObserver trigger
*/
virtual void changed(U32 mask);
// Implements LLVoiceClientStatusObserver::onChange() to enable the call
// button when voice is available
/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
/*virtual*/ void setAvatarId(const LLUUID& id);
/*virtual*/ BOOL postBuild();
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
void resetData();
/**
* Sends update data request to server.
*/
/*virtual*/ void updateData();
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
protected:
/**
* Process profile related data received from server.
*/
virtual void processProfileProperties(const LLAvatarData* avatar_data);
/**
* Processes group related data received from server.
*/
virtual void processGroupProperties(const LLAvatarGroups* avatar_groups);
/**
* Fills common for Avatar profile and My Profile fields.
*/
virtual void fillCommonData(const LLAvatarData* avatar_data);
/**
* Fills partner data.
*/
virtual void fillPartnerData(const LLAvatarData* avatar_data);
/**
* Fills account status.
*/
virtual void fillAccountStatus(const LLAvatarData* avatar_data);
void onMapButtonClick();
/**
* Opens "Pay Resident" dialog.
*/
void pay();
/**
* Add/remove resident to/from your block list.
*/
void toggleBlock();
void updateButtons();
void onAddFriendButtonClick();
void onIMButtonClick();
void onTeleportButtonClick();
void onCopyToClipboard();
void onCopyURI();
void onGroupInvite();
bool isGrantedToSeeOnlineStatus();
/**
* 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 online);
virtual void enableControls();
private:
void onClickSetName();
void onAvatarNameCacheSetName(const LLUUID& id, const LLAvatarName& av_name);
private:
typedef std::map<std::string, LLUUID> group_map_t;
group_map_t mGroups;
void openGroupProfile();
LLTextBox* mStatusText;
LLGroupList* mGroupList;
LLCheckBoxCtrl* mShowInSearchCheckbox;
LLTextureCtrl* mSecondLifePic;
LLTextBase* mDescriptionEdit;
LLButton* mTeleportButton;
LLButton* mShowOnMapButton;
LLButton* mBlockButton;
LLButton* mUnblockButton;
LLButton* mDisplayNameButton;
LLButton* mAddFriendButton;
LLButton* mGroupInviteButton;
LLButton* mPayButton;
LLButton* mIMButton;
LLMenuButton* mOverflowButton;
bool mVoiceStatus;
boost::signals2::connection mRlvBehaviorCallbackConnection;
void updateRlvRestrictions(ERlvBehaviour behavior);
};
/**
* Panel for displaying Avatar's web profile and home page.
*/
class FSPanelProfileWeb
: public FSPanelProfileTab
, public LLViewerMediaObserver
{
public:
FSPanelProfileWeb();
/*virtual*/ ~FSPanelProfileWeb();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ BOOL postBuild();
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
void resetData();
/**
* Saves changes.
*/
void apply(LLAvatarData* data);
/**
* Loads web profile.
*/
/*virtual*/ void updateData();
/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
virtual void enableControls();
protected:
void onCommitLoad(LLUICtrl* ctrl);
void onCommitWebProfile(LLUICtrl* ctrl);
private:
std::string mURLHome;
std::string mURLWebProfile;
LLMediaCtrl* mWebBrowser;
LLUICtrl* mWebProfileButton;
LLUICtrl* mLoadButton;
LLLineEditor* mUrlEdit;
LLFrameTimer mPerformanceTimer;
bool mFirstNavigate;
};
/**
* Panel for displaying Avatar's interests.
*/
class FSPanelProfileInterests
: public FSPanelProfileTab
{
public:
FSPanelProfileInterests();
/*virtual*/ ~FSPanelProfileInterests();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ BOOL postBuild();
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
void resetData();
/**
* Saves changes.
*/
virtual void apply();
protected:
virtual void enableControls();
private:
LLCheckBoxCtrl* mWantChecks[8];
LLCheckBoxCtrl* mSkillChecks[6];
LLLineEditor* mWantToEditor;
LLLineEditor* mSkillsEditor;
LLLineEditor* mLanguagesEditor;
};
/**
* Panel for displaying Avatar's picks.
*/
class FSPanelPick
: public FSPanelProfileTab
, public LLRemoteParcelInfoObserver
{
public:
// Creates new panel
static FSPanelPick* create();
/*virtual*/ ~FSPanelPick();
/*virtual*/ BOOL postBuild();
void setAvatarId(const LLUUID& avatar_id);
void setPickId(const LLUUID& id) { mPickId = id; }
virtual LLUUID& getPickId() { return mPickId; }
virtual void setPickName(const std::string& name);
const std::string getPickName();
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
/**
* 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
/*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:
FSPanelPick();
/**
* 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
*/
/*virtual*/ void resetDirty();
/**
* Returns true if any of Pick properties was changed by user.
*/
/*virtual*/ BOOL isDirty() const;
/**
* Callback for "Set Location" button click
*/
void onClickSetLocation();
/**
* Callback for "Save" button click
*/
void onClickSave();
std::string getLocationNotice();
/**
* Sends Pick properties to server.
*/
void sendUpdate();
protected:
LLTextureCtrl* mSnapshotCtrl;
LLLineEditor* mPickName;
LLTextEditor* mPickDescription;
LLButton* mSetCurrentLocationButton;
LLButton* mSaveButton;
LLVector3d mPosGlobal;
LLUUID mParcelId;
LLUUID mPickId;
LLUUID mRequestedId;
bool mLocationChanged;
bool mNewPick;
bool mIsEditing;
std::string mCurrentPickDescription;
void onDescriptionFocusReceived();
};
class FSPanelProfilePicks
: public FSPanelProfileTab
{
public:
FSPanelProfilePicks();
/*virtual*/ ~FSPanelProfilePicks();
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
void resetData();
/**
* Saves changes.
*/
virtual void apply();
/**
* Sends update data request to server.
*/
/*virtual*/ void updateData();
private:
void onClickNewBtn();
void onClickDelete();
void callbackDeletePick(const LLSD& notification, const LLSD& response);
boost::signals2::connection mRlvBehaviorCallbackConnection;
void updateRlvRestrictions(ERlvBehaviour behavior, ERlvParamType type);
bool canAddNewPick();
bool canDeletePick();
LLTabContainer* mTabContainer;
LLUICtrl* mNoItemsLabel;
LLButton* mNewButton;
LLButton* mDeleteButton;
};
/**
* Panel for displaying Avatar's first life related info.
*/
class FSPanelProfileFirstLife
: public FSPanelProfileTab
{
public:
FSPanelProfileFirstLife();
/*virtual*/ ~FSPanelProfileFirstLife();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ BOOL postBuild();
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
void resetData();
/**
* Saves changes.
*/
void apply(LLAvatarData* data);
protected:
virtual void enableControls();
void onDescriptionFocusReceived();
LLTextEditor* mDescriptionEdit;
LLTextureCtrl* mPicture;
bool mIsEditing;
std::string mCurrentDescription;
};
/**
* Panel for displaying Avatar's notes and modifying friend's rights.
*/
class FSPanelAvatarNotes
: public FSPanelProfileTab
, public LLFriendObserver
{
public:
FSPanelAvatarNotes();
/*virtual*/ ~FSPanelAvatarNotes();
virtual void setAvatarId(const LLUUID& id);
/**
* LLFriendObserver trigger
*/
virtual void changed(U32 mask);
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ BOOL postBuild();
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
void resetData();
/*virtual*/ void updateData();
/**
* Saves changes.
*/
virtual void apply();
protected:
/**
* Fills rights data for friends.
*/
void fillRightsData();
void rightsConfirmationCallback(const LLSD& notification, const LLSD& response, S32 rights);
void confirmModifyRights(bool grant, S32 rights);
void onCommitRights();
void onCommitNotes();
void enableCheckboxes(bool enable);
LLCheckBoxCtrl* mOnlineStatus;
LLCheckBoxCtrl* mMapRights;
LLCheckBoxCtrl* mEditObjectRights;
LLTextEditor* mNotesEditor;
};
/*
*
* Container panel for the profile tabs
*/
class FSPanelProfile
: public FSPanelProfileTab
{
public:
FSPanelProfile();
/*virtual*/ ~FSPanelProfile();
/*virtual*/ BOOL postBuild();
/*virtual*/ void updateData();
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
/*virtual*/ void onOpen(const LLSD& key);
/**
* Saves changes.
*/
void apply();
private:
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
void onTabChange();
FSPanelProfileSecondLife* mPanelSecondlife;
FSPanelProfileWeb* mPanelWeb;
FSPanelProfileInterests* mPanelInterests;
FSPanelProfilePicks* mPanelPicks;
FSPanelClassifieds* mPanelClassifieds;
FSPanelProfileFirstLife* mPanelFirstlife;
FSPanelAvatarNotes* mPanelNotes;
LLTabContainer* mTabContainer;
boost::signals2::connection mAvatarNameCacheConnection;
};
#endif // FS_PANELPROFILE_H

View File

@ -1,781 +0,0 @@
/**
* @file fspanelprofileclassifieds.cpp
* @brief FSPanelClassifieds 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 "fspanelprofileclassifieds.h"
#include "llagent.h"
#include "llflatlistview.h"
#include "llfloaterreg.h"
#include "llfloaterworldmap.h"
#include "llnotificationsutil.h"
#include "lltrans.h"
#include "llmenugl.h"
#include "llviewermenu.h"
#include "llviewergenericmessage.h"
#include "llregistry.h"
#include "llavatarpropertiesprocessor.h"
#include "fsdispatchclassifiedclickthrough.h"
#include "fspanelprofile.h"
#include "fspanelclassified.h"
static const std::string XML_BTN_NEW = "new_btn";
static const std::string XML_BTN_DELETE = "trash_btn";
static const std::string XML_BTN_INFO = "info_btn";
static const std::string XML_BTN_TELEPORT = "teleport_btn";
static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn";
static const std::string PICK_ID("pick_id");
static const std::string PICK_CREATOR_ID("pick_creator_id");
static const std::string PICK_NAME("pick_name");
static const std::string CLASSIFIED_ID("classified_id");
static const std::string CLASSIFIED_NAME("classified_name");
static FSDispatchClassifiedClickThrough sClassifiedClickThrough;
static LLPanelInjector<FSPanelClassifieds> t_panel_fs_classifieds("panel_fs_profile_classified");
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// FSPanelClassifieds
//-----------------------------------------------------------------------------
FSPanelClassifieds::FSPanelClassifieds()
: FSPanelProfileTab(),
mPopupMenu(NULL),
mClassifiedsList(NULL),
mPanelClassifiedInfo(NULL),
mNoClassifieds(false),
mRlvBehaviorCallbackConnection()
{
}
FSPanelClassifieds::~FSPanelClassifieds()
{
if (getAvatarId().notNull())
{
LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
}
if (mRlvBehaviorCallbackConnection.connected())
{
mRlvBehaviorCallbackConnection.disconnect();
}
gGenericDispatcher.addHandler("classifiedclickthrough", NULL);
}
void FSPanelClassifieds::updateData()
{
// Send Picks request only when we need to, not on every onOpen(during tab switch).
if (isDirty())
{
mNoClassifieds = false;
mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
mNoItemsLabel->setVisible(TRUE);
mClassifiedsList->clear();
LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(getAvatarId());
}
}
void FSPanelClassifieds::processProperties(void* data, EAvatarProcessorType type)
{
if (APT_CLASSIFIEDS == type)
{
LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data);
if (c_info && getAvatarId() == c_info->target_id)
{
// do not clear classified list in case we will receive two or more data packets.
// list has been cleared in updateData(). (fix for EXT-6436)
LLAvatarClassifieds::classifieds_list_t::const_iterator it = c_info->classifieds_list.begin();
for (; c_info->classifieds_list.end() != it; ++it)
{
LLAvatarClassifieds::classified_data c_data = *it;
FSClassifiedItem* c_item = new FSClassifiedItem(getAvatarId(), c_data.classified_id);
c_item->childSetAction("info_chevron", boost::bind(&FSPanelClassifieds::onClickInfo, this));
c_item->setClassifiedName(c_data.name);
LLSD pick_value = LLSD();
pick_value.insert(CLASSIFIED_ID, c_data.classified_id);
pick_value.insert(CLASSIFIED_NAME, c_data.name);
if (!findClassifiedById(c_data.classified_id))
{
mClassifiedsList->addItem(c_item, pick_value);
}
c_item->setDoubleClickCallback(boost::bind(&FSPanelClassifieds::onDoubleClickClassifiedItem, this, _1));
c_item->setRightMouseUpCallback(boost::bind(&FSPanelClassifieds::onRightMouseUpItem, this, _1, _2, _3, _4));
c_item->setMouseUpCallback(boost::bind(&FSPanelClassifieds::updateButtons, this));
}
resetDirty();
updateButtons();
}
mNoClassifieds = !mClassifiedsList->size();
bool no_data = mNoClassifieds;
mNoItemsLabel->setVisible(no_data);
if (no_data)
{
if (getAvatarId() == gAgentID)
{
mNoItemsLabel->setValue(LLTrans::getString("NoClassifiedsText"));
}
else
{
mNoItemsLabel->setValue(LLTrans::getString("NoAvatarClassifiedsText"));
}
}
enableControls();
}
}
FSClassifiedItem* FSPanelClassifieds::getSelectedClassifiedItem()
{
LLPanel* selected_item = mClassifiedsList->getSelectedItem();
if (!selected_item)
{
return NULL;
}
return dynamic_cast<FSClassifiedItem*>(selected_item);
}
BOOL FSPanelClassifieds::postBuild()
{
mClassifiedsList = getChild<LLFlatListView>("classifieds_list");
mClassifiedsList->setCommitOnSelectionChange(true);
mClassifiedsList->setCommitCallback(boost::bind(&FSPanelClassifieds::onListCommit, this, mClassifiedsList));
mClassifiedsList->setNoItemsCommentText(getString("no_classifieds"));
mNoItemsLabel = getChild<LLUICtrl>("picks_panel_text");
childSetAction(XML_BTN_NEW, boost::bind(&FSPanelClassifieds::createNewClassified, this));
childSetAction(XML_BTN_DELETE, boost::bind(&FSPanelClassifieds::onClickDelete, this));
childSetAction(XML_BTN_TELEPORT, boost::bind(&FSPanelClassifieds::onClickTeleport, this));
childSetAction(XML_BTN_SHOW_ON_MAP, boost::bind(&FSPanelClassifieds::onClickMap, this));
childSetAction(XML_BTN_INFO, boost::bind(&FSPanelClassifieds::onClickInfo, this));
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar;
registar.add("Classified.Info", boost::bind(&FSPanelClassifieds::onClickInfo, this));
registar.add("Classified.Edit", boost::bind(&FSPanelClassifieds::onClickMenuEdit, this));
registar.add("Classified.Teleport", boost::bind(&FSPanelClassifieds::onClickTeleport, this));
registar.add("Classified.Map", boost::bind(&FSPanelClassifieds::onClickMap, this));
registar.add("Classified.Delete", boost::bind(&FSPanelClassifieds::onClickDelete, this));
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registar;
enable_registar.add("Classified.Enable", boost::bind(&FSPanelClassifieds::onEnableMenuItem, this, _2));
mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_classifieds.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mRlvBehaviorCallbackConnection = gRlvHandler.setBehaviourCallback(boost::bind(&FSPanelClassifieds::updateRlvRestrictions, this, _1, _2));
childSetEnabled(XML_BTN_NEW, !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC));
return TRUE;
}
bool FSPanelClassifieds::isClassifiedPublished(FSClassifiedItem* c_item)
{
if (c_item)
{
FSPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()];
if (panel)
{
return !panel->isNewWithErrors();
}
// we've got this classified from server - it's published
return true;
}
return false;
}
void FSPanelClassifieds::onOpen(const LLSD& key)
{
const LLUUID id(key.asUUID());
BOOL self = (gAgentID == id);
// only agent can edit her picks
getChildView("edit_panel")->setEnabled(self);
getChildView("edit_panel")->setVisible( self);
// Disable buttons when viewing profile for first time
if (getAvatarId() != id)
{
getChildView(XML_BTN_INFO)->setEnabled(FALSE);
getChildView(XML_BTN_TELEPORT)->setEnabled(FALSE);
getChildView(XML_BTN_SHOW_ON_MAP)->setEnabled(FALSE);
}
if (getAvatarId() != id)
{
mClassifiedsList->goToTop();
// Set dummy value to make panel dirty and make it reload picks
setValue(LLSD());
}
FSPanelProfileTab::onOpen(key);
gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough);
updateData();
updateButtons();
}
void FSPanelClassifieds::onClosePanel()
{
if (mPanelClassifiedInfo)
{
onPanelClassifiedClose(mPanelClassifiedInfo);
}
}
void FSPanelClassifieds::onListCommit(const LLFlatListView* f_list)
{
updateButtons();
}
//static
void FSPanelClassifieds::onClickDelete()
{
LLSD value = mClassifiedsList->getSelectedValue();
if (value.isDefined())
{
LLSD args;
args["NAME"] = value[CLASSIFIED_NAME];
LLNotificationsUtil::add("DeleteClassified", args, LLSD(), boost::bind(&FSPanelClassifieds::callbackDeleteClassified, this, _1, _2));
return;
}
}
bool FSPanelClassifieds::callbackDeleteClassified(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
LLSD value = mClassifiedsList->getSelectedValue();
if (0 == option)
{
LLAvatarPropertiesProcessor::instance().sendClassifiedDelete(value[CLASSIFIED_ID]);
mClassifiedsList->removeItemByValue(value);
}
mNoItemsLabel->setVisible(!mClassifiedsList->size());
updateButtons();
return false;
}
bool FSPanelClassifieds::callbackTeleport( const LLSD& notification, const LLSD& response )
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (0 == option)
{
onClickTeleport();
}
return false;
}
//static
void FSPanelClassifieds::onClickTeleport()
{
FSClassifiedItem* c_item = getSelectedClassifiedItem();
LLVector3d pos;
if (c_item)
{
pos = c_item->getPosGlobal();
FSPanelClassifiedInfo::sendClickMessage("teleport", false,
c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null);
}
if (!pos.isExactlyZero())
{
gAgent.teleportViaLocation(pos);
LLFloaterWorldMap::getInstance()->trackLocation(pos);
}
}
//static
void FSPanelClassifieds::onClickMap()
{
FSClassifiedItem* c_item = getSelectedClassifiedItem();
LLVector3d pos;
if (c_item)
{
FSPanelClassifiedInfo::sendClickMessage("map", false,
c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null);
pos = c_item->getPosGlobal();
}
LLFloaterWorldMap::getInstance()->trackLocation(pos);
LLFloaterReg::showInstance("world_map", "center");
}
void FSPanelClassifieds::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
{
updateButtons();
if (mPopupMenu)
{
mPopupMenu->buildDrawLabels();
mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
((LLContextMenu*)mPopupMenu)->show(x, y);
LLMenuGL::showPopup(item, mPopupMenu, x, y);
}
}
void FSPanelClassifieds::onDoubleClickClassifiedItem(LLUICtrl* item)
{
LLSD value = mClassifiedsList->getSelectedValue();
if (value.isUndefined()) return;
LLSD args;
args["CLASSIFIED"] = value[CLASSIFIED_NAME];
LLNotificationsUtil::add("TeleportToClassified", args, LLSD(), boost::bind(&FSPanelClassifieds::callbackTeleport, this, _1, _2));
}
void FSPanelClassifieds::updateButtons()
{
bool has_selected = mClassifiedsList->numSelected() > 0;
if (getAvatarId() == gAgentID)
{
getChildView(XML_BTN_DELETE)->setEnabled(has_selected);
}
getChildView(XML_BTN_INFO)->setEnabled(has_selected);
getChildView(XML_BTN_TELEPORT)->setEnabled(has_selected);
getChildView(XML_BTN_SHOW_ON_MAP)->setEnabled(has_selected);
FSClassifiedItem* c_item = dynamic_cast<FSClassifiedItem*>(mClassifiedsList->getSelectedItem());
if (c_item)
{
getChildView(XML_BTN_INFO)->setEnabled(isClassifiedPublished(c_item));
}
}
void FSPanelClassifieds::createNewClassified()
{
FSPanelClassifiedEdit* panel = NULL;
createClassifiedEditPanel(&panel);
openPanel(panel, LLSD());
}
void FSPanelClassifieds::onClickInfo()
{
if (mClassifiedsList->numSelected() > 0)
{
openClassifiedInfo();
}
}
void FSPanelClassifieds::openClassifiedInfo()
{
LLSD selected_value = mClassifiedsList->getSelectedValue();
if (selected_value.isUndefined())
{
return;
}
FSClassifiedItem* c_item = getSelectedClassifiedItem();
LLSD params;
params["classified_id"] = c_item->getClassifiedId();
params["classified_creator_id"] = c_item->getAvatarId();
params["classified_snapshot_id"] = c_item->getSnapshotId();
params["classified_name"] = c_item->getClassifiedName();
params["classified_desc"] = c_item->getDescription();
params["from_search"] = false;
openClassifiedInfo(params);
}
void FSPanelClassifieds::openClassifiedInfo(const LLSD &params)
{
createClassifiedInfoPanel();
openPanel(mPanelClassifiedInfo, params);
}
void FSPanelClassifieds::openClassifiedEdit(const LLSD& params)
{
LLUUID classified_id = params["classified_id"].asUUID();;
LL_INFOS("FSPanelClassifieds") << "opening classified " << classified_id << " for edit" << LL_ENDL;
editClassified(classified_id);
}
void FSPanelClassifieds::onPanelPickClose(LLPanel* panel)
{
closePanel(panel);
}
void FSPanelClassifieds::onPanelClassifiedSave(FSPanelClassifiedEdit* panel)
{
if (!panel->canClose())
{
return;
}
if (panel->isNew())
{
mEditClassifiedPanels[panel->getClassifiedId()] = panel;
FSClassifiedItem* c_item = new FSClassifiedItem(getAvatarId(), panel->getClassifiedId());
c_item->fillIn(panel);
LLSD c_value;
c_value.insert(CLASSIFIED_ID, c_item->getClassifiedId());
c_value.insert(CLASSIFIED_NAME, c_item->getClassifiedName());
mClassifiedsList->addItem(c_item, c_value, ADD_TOP);
c_item->setDoubleClickCallback(boost::bind(&FSPanelClassifieds::onDoubleClickClassifiedItem, this, _1));
c_item->setRightMouseUpCallback(boost::bind(&FSPanelClassifieds::onRightMouseUpItem, this, _1, _2, _3, _4));
c_item->setMouseUpCallback(boost::bind(&FSPanelClassifieds::updateButtons, this));
c_item->childSetAction("info_chevron", boost::bind(&FSPanelClassifieds::onClickInfo, this));
mNoItemsLabel->setVisible(FALSE);
}
else if (panel->isNewWithErrors())
{
FSClassifiedItem* c_item = dynamic_cast<FSClassifiedItem*>(mClassifiedsList->getSelectedItem());
llassert(c_item);
if (c_item)
{
c_item->fillIn(panel);
}
}
else
{
onPanelClassifiedClose(panel);
return;
}
onPanelPickClose(panel);
updateButtons();
}
void FSPanelClassifieds::onPanelClassifiedClose(FSPanelClassifiedInfo* panel)
{
if (panel->getInfoLoaded() && !panel->isDirty())
{
std::vector<LLSD> values;
mClassifiedsList->getValues(values);
for (size_t n = 0; n < values.size(); ++n)
{
LLUUID c_id = values[n][CLASSIFIED_ID].asUUID();
if (panel->getClassifiedId() == c_id)
{
FSClassifiedItem* c_item = dynamic_cast<FSClassifiedItem*>(mClassifiedsList->getItemByValue(values[n]));
llassert(c_item);
if (c_item)
{
c_item->setClassifiedName(panel->getClassifiedName());
c_item->setDescription(panel->getDescription());
c_item->setSnapshotId(panel->getSnapshotId());
}
}
}
}
onPanelPickClose(panel);
updateButtons();
}
void FSPanelClassifieds::createClassifiedInfoPanel()
{
mPanelClassifiedInfo = FSPanelClassifiedInfo::create();
mPanelClassifiedInfo->setExitCallback(boost::bind(&FSPanelClassifieds::onPanelClassifiedClose, this, mPanelClassifiedInfo));
mPanelClassifiedInfo->setEditClassifiedCallback(boost::bind(&FSPanelClassifieds::onPanelClassifiedEdit, this));
mPanelClassifiedInfo->setVisible(FALSE);
}
void FSPanelClassifieds::createClassifiedEditPanel(FSPanelClassifiedEdit** panel)
{
if (panel)
{
FSPanelClassifiedEdit* new_panel = FSPanelClassifiedEdit::create();
new_panel->setExitCallback(boost::bind(&FSPanelClassifieds::onPanelClassifiedClose, this, new_panel));
new_panel->setSaveCallback(boost::bind(&FSPanelClassifieds::onPanelClassifiedSave, this, new_panel));
new_panel->setCancelCallback(boost::bind(&FSPanelClassifieds::onPanelClassifiedClose, this, new_panel));
new_panel->setVisible(FALSE);
*panel = new_panel;
}
}
void FSPanelClassifieds::onPanelClassifiedEdit()
{
LLSD selected_value = mClassifiedsList->getSelectedValue();
if (selected_value.isUndefined())
{
return;
}
FSClassifiedItem* c_item = dynamic_cast<FSClassifiedItem*>(mClassifiedsList->getSelectedItem());
llassert(c_item);
if (!c_item)
{
return;
}
editClassified(c_item->getClassifiedId());
}
FSClassifiedItem *FSPanelClassifieds::findClassifiedById(const LLUUID& classified_id)
{
// HACK - find item by classified id. Should be a better way.
std::vector<LLPanel*> items;
mClassifiedsList->getItems(items);
FSClassifiedItem* c_item = NULL;
for (std::vector<LLPanel*>::iterator it = items.begin(); it != items.end(); ++it)
{
FSClassifiedItem *test_item = dynamic_cast<FSClassifiedItem*>(*it);
if (test_item && test_item->getClassifiedId() == classified_id)
{
c_item = test_item;
break;
}
}
return c_item;
}
void FSPanelClassifieds::editClassified(const LLUUID& classified_id)
{
FSClassifiedItem* c_item = findClassifiedById(classified_id);
if (!c_item)
{
LL_WARNS("FSPanelClassifieds") << "item not found for classified_id " << classified_id << LL_ENDL;
return;
}
LLSD params;
params["classified_id"] = c_item->getClassifiedId();
params["classified_creator_id"] = c_item->getAvatarId();
params["snapshot_id"] = c_item->getSnapshotId();
params["name"] = c_item->getClassifiedName();
params["desc"] = c_item->getDescription();
params["category"] = (S32)c_item->getCategory();
params["content_type"] = (S32)c_item->getContentType();
params["auto_renew"] = c_item->getAutoRenew();
params["price_for_listing"] = c_item->getPriceForListing();
params["location_text"] = c_item->getLocationText();
FSPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()];
if (!panel)
{
createClassifiedEditPanel(&panel);
mEditClassifiedPanels[c_item->getClassifiedId()] = panel;
}
openPanel(panel, params);
panel->setPosGlobal(c_item->getPosGlobal());
}
void FSPanelClassifieds::onClickMenuEdit()
{
if (getSelectedClassifiedItem())
{
onPanelClassifiedEdit();
}
}
bool FSPanelClassifieds::onEnableMenuItem(const LLSD& user_data)
{
std::string param = user_data.asString();
FSClassifiedItem* c_item = dynamic_cast<FSClassifiedItem*>(mClassifiedsList->getSelectedItem());
if (c_item && "info" == param)
{
// dont show Info panel if classified was not created
return isClassifiedPublished(c_item);
}
return true;
}
//hack
void FSPanelClassifieds::openPanel(LLPanel* panel, const LLSD& params)
{
// Add the panel or bring it to front.
if (panel->getParent() != this)
{
addChild(panel);
}
else
{
sendChildToFront(panel);
}
panel->setVisible(TRUE);
panel->setFocus(TRUE); // prevent losing focus by the floater
panel->onOpen(params);
LLRect new_rect = getRect();
panel->reshape(new_rect.getWidth(), new_rect.getHeight());
new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight());
panel->setRect(new_rect);
}
//hack
void FSPanelClassifieds::closePanel(LLPanel* panel)
{
panel->setVisible(FALSE);
if (panel->getParent() == this)
{
removeChild(panel);
// Prevent losing focus by the floater
const child_list_t* child_list = getChildList();
if (child_list->size() > 0)
{
child_list->front()->setFocus(TRUE);
}
else
{
LL_WARNS("FSPanelClassifieds") << "No underlying panel to focus." << LL_ENDL;
}
}
}
void FSPanelClassifieds::updateRlvRestrictions(ERlvBehaviour behavior, ERlvParamType type)
{
if (behavior == RLV_BHVR_SHOWLOC)
{
childSetEnabled(XML_BTN_NEW, type != RLV_TYPE_ADD);
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
FSClassifiedItem::FSClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id)
: LLPanel()
, mAvatarId(avatar_id)
, mClassifiedId(classified_id)
{
buildFromFile("panel_classifieds_list_item.xml");
LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
}
FSClassifiedItem::~FSClassifiedItem()
{
LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
}
void FSClassifiedItem::processProperties(void* data, EAvatarProcessorType type)
{
if (APT_CLASSIFIED_INFO != type)
{
return;
}
LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
if (!c_info || c_info->classified_id != getClassifiedId())
{
return;
}
setClassifiedName(c_info->name);
setDescription(c_info->description);
setSnapshotId(c_info->snapshot_id);
setPosGlobal(c_info->pos_global);
LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
}
void set_child_visible2(LLView* parent, const std::string& child_name, bool visible)
{
parent->getChildView(child_name)->setVisible(visible);
}
BOOL FSClassifiedItem::postBuild()
{
setMouseEnterCallback(boost::bind(&set_child_visible2, this, "hovered_icon", true));
setMouseLeaveCallback(boost::bind(&set_child_visible2, this, "hovered_icon", false));
return TRUE;
}
void FSClassifiedItem::setValue(const LLSD& value)
{
if (!value.isMap())
{
return;
}
if (!value.has("selected"))
{
return;
}
getChildView("selected_icon")->setVisible( value["selected"]);
}
void FSClassifiedItem::fillIn(FSPanelClassifiedEdit* panel)
{
if (!panel)
{
return;
}
setClassifiedName(panel->getClassifiedName());
setDescription(panel->getDescription());
setSnapshotId(panel->getSnapshotId());
setCategory(panel->getCategory());
setContentType(panel->getContentType());
setAutoRenew(panel->getAutoRenew());
setPriceForListing(panel->getPriceForListing());
setPosGlobal(panel->getPosGlobal());
setLocationText(panel->getClassifiedLocation());
}
void FSClassifiedItem::setClassifiedName(const std::string& name)
{
getChild<LLUICtrl>("name")->setValue(name);
}
void FSClassifiedItem::setDescription(const std::string& desc)
{
getChild<LLUICtrl>("description")->setValue(desc);
}
void FSClassifiedItem::setSnapshotId(const LLUUID& snapshot_id)
{
getChild<LLUICtrl>("picture")->setValue(snapshot_id);
}
LLUUID FSClassifiedItem::getSnapshotId()
{
return getChild<LLUICtrl>("picture")->getValue();
}
//EOF

View File

@ -1,206 +0,0 @@
/**
* @file fspanelprofileclassifieds.h
* @brief FSPanelClassifieds 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 FS_PANELCLASSIFIEDS_H
#define FS_PANELCLASSIFIEDS_H
#include "llpanel.h"
#include "v3dmath.h"
#include "lluuid.h"
#include "llavatarpropertiesprocessor.h"
#include "fspanelprofile.h"
#include "llregistry.h"
class LLMessageSystem;
class LLVector3d;
class FSPanelProfileTab;
class LLAgent;
class LLMenuGL;
class FSClassifiedItem;
class LLFlatListView;
class FSPanelClassifiedInfo;
class FSPanelClassifiedEdit;
// *TODO
// Panel Picks has been consolidated with Classifieds (EXT-2095), give FSPanelClassifieds
// and corresponding files (cpp, h, xml) a new name. (new name is TBD at the moment)
class FSPanelClassifieds
: public FSPanelProfileTab
{
public:
FSPanelClassifieds();
~FSPanelClassifieds();
/*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
FSClassifiedItem* getSelectedClassifiedItem();
FSClassifiedItem* findClassifiedById(const LLUUID& classified_id);
void createNewClassified();
protected:
/*virtual*/void updateButtons();
private:
void onClickDelete();
void onClickTeleport();
void onClickMap();
bool isClassifiedPublished(FSClassifiedItem* c_item);
void onListCommit(const LLFlatListView* f_list);
boost::signals2::connection mRlvBehaviorCallbackConnection;
void updateRlvRestrictions(ERlvBehaviour behavior, ERlvParamType type);
//------------------------------------------------
// Callbacks which require panel toggling
//------------------------------------------------
void onClickInfo();
void onPanelPickClose(LLPanel* panel);
void onPanelClassifiedSave(FSPanelClassifiedEdit* panel);
void onPanelClassifiedClose(FSPanelClassifiedInfo* panel);
void onPanelClassifiedEdit();
void editClassified(const LLUUID& classified_id);
void onClickMenuEdit();
bool onEnableMenuItem(const LLSD& user_data);
void openClassifiedInfo();
void openClassifiedInfo(const LLSD& params);
void openClassifiedEdit(const LLSD& params);
bool callbackDeleteClassified(const LLSD& notification, const LLSD& response);
bool callbackTeleport(const LLSD& notification, const LLSD& response);
virtual void onDoubleClickClassifiedItem(LLUICtrl* item);
virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
void createClassifiedInfoPanel();
void createClassifiedEditPanel(FSPanelClassifiedEdit** panel);
void openPanel(LLPanel* panel, const LLSD& params);
void closePanel(LLPanel* panel);
LLMenuGL* mPopupMenu;
LLFlatListView* mClassifiedsList;
FSPanelClassifiedInfo* mPanelClassifiedInfo;
LLUICtrl* mNoItemsLabel;
// <classified_id, edit_panel>
typedef std::map<LLUUID, FSPanelClassifiedEdit*> 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 FSPanelClassifiedEdit::processProperties callback.
panel_classified_edit_map_t mEditClassifiedPanels;
//true if classifieds list is empty after processing classifieds
bool mNoClassifieds;
};
class FSClassifiedItem : public LLPanel, public LLAvatarPropertiesObserver
{
public:
FSClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id);
virtual ~FSClassifiedItem();
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
/*virtual*/ BOOL postBuild();
/*virtual*/ void setValue(const LLSD& value);
void fillIn(FSPanelClassifiedEdit* 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 // FS_PANELCLASSIFIEDS_H

View File

@ -74,10 +74,10 @@ public:
void decrementNumberOfPicks() { --mNumberOfPicks; }
private:
void onServerRespond(LLAvatarPicks* picks);
private:
/**
* Sets number of Picks.
*/

View File

@ -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"
@ -83,7 +87,6 @@
// Firestorm includes
#include "fsfloaterim.h"
#include "fsfloaterimcontainer.h"
#include "fsfloaterprofile.h"
#include "fslslbridge.h"
#include "fsradar.h"
#include "fsassetblacklist.h"
@ -103,6 +106,48 @@ 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)
{
// <FS:Ansariel> OpenSim support
//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" : "";
std::string url;
LLSD subs;
#ifdef OPENSIM
if (LLGridManager::instance().isInOpenSim())
{
url = LLGridManager::getInstance()->getWebProfileURL();
if (url.empty())
{
return LLStringUtil::null;
}
std::string match = "?name=[AGENT_NAME]";
if (url.find(match) == std::string::npos)
{
url += match;
}
}
else
#endif
{
url = "[WEB_PROFILE_URL][AGENT_NAME][FEED_ONLY]";
subs["FEED_ONLY"] = feed_only ? "/?feed_only=true" : "";
subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL();
}
// </FS:Ansariel>
subs["AGENT_NAME"] = agent_name;
url = LLWeb::expandURLSubstitutions(url, subs);
LLStringUtil::toLower(url);
return url;
}
// static
void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
{
@ -420,94 +465,144 @@ const LLUUID LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUI
return session_id;
}
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())
{
//<FS:KC legacy profiles>
// LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_show_profile, _1, _2));
if (gSavedSettings.getBOOL("FSUseWebProfiles"))
{
showProfileWeb(id);
}
else
{
showProfileLegacy(id);
}
//</FS:KC legacy profiles>
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)
{
//<FS:KC legacy profiles>
if (!gSavedSettings.getBOOL("FSUseWebProfiles"))
{
FSFloaterProfile* browser = LLFloaterReg::findTypedInstance<FSFloaterProfile>("fs_floater_profile", LLSD().with("id", id));
return browser;
}
//</FS:KC legacy profiles>
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;
}
//<FS:KC legacy profiles>
// static
void LLAvatarActions::showProfileWeb(const LLUUID& id)
{
if (id.notNull())
{
LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_show_profile, _1, _2));
}
}
// static
void LLAvatarActions::showProfileLegacy(const LLUUID& id)
{
if (id.notNull())
{
LLFloaterReg::showInstance("fs_floater_profile", LLSD().with("id", id));
}
}
//</FS:KC legacy profiles>
//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();
}
}
@ -1235,7 +1330,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);
@ -1245,10 +1340,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;
}
}

View File

@ -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)
*/
@ -97,17 +99,20 @@ public:
static const LLUUID startConference(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null);
// </FS:Ansariel>
/**
* 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);
//<FS:KC legacy profiles>
static void showProfileWeb(const LLUUID& id);
static void showProfileLegacy(const LLUUID& id);
//</FS:KC legacy profiles>
/**
* 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.
@ -136,9 +141,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.

View File

@ -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,8 +464,8 @@ 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
*/
//<FS:KC legacy profiles>
FSInterestsData interests_data;
LLInterestsData interests_data;
msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, interests_data.agent_id );
msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AvatarID, interests_data.avatar_id );
@ -326,8 +478,7 @@ void LLAvatarPropertiesProcessor::processAvatarInterestsReply(LLMessageSystem* m
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);
//</FS:KC legacy profiles>
self->notifyObservers(interests_data.avatar_id, &interests_data, APT_INTERESTS_INFO);
}
void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem* msg, void**)
@ -405,7 +556,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);
@ -571,6 +722,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;
@ -694,28 +868,3 @@ void LLAvatarPropertiesProcessor::removePendingRequest(const LLUUID& avatar_id,
timestamp_map_t::key_type key = std::make_pair(avatar_id, type);
mRequestTimestamps.erase(key);
}
//<FS:KC legacy profiles>
void LLAvatarPropertiesProcessor::sendInterestsInfoUpdate(const FSInterestsData* 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();
}
//</FS:KC legacy profiles>

View File

@ -56,15 +56,12 @@ enum EAvatarProcessorType
APT_PICKS,
APT_PICK_INFO,
APT_TEXTURES,
//<FS:KC legacy profiles>
APT_INTERESTS_INFO,
//</FS:KC legacy profiles>
APT_CLASSIFIEDS,
APT_CLASSIFIED_INFO
};
//<FS:KC legacy profiles>
struct FSInterestsData
struct LLInterestsData
{
LLUUID agent_id;
LLUUID avatar_id; //target id
@ -74,7 +71,6 @@ struct FSInterestsData
std::string skills_text;
std::string languages_text;
};
//</FS:KC legacy profiles>
struct LLAvatarData
{
@ -239,9 +235,7 @@ public:
void sendClassifiedDelete(const LLUUID& classified_id);
//<FS:KC legacy profiles>
void sendInterestsInfoUpdate(const FSInterestsData* interests_data);
//</FS:KC legacy profiles>
void sendInterestsInfoUpdate(const LLInterestsData* interests_data);
// Returns translated, human readable string for account type, such
// as "Resident" or "Linden Employee". Used for profiles, inspectors.
@ -254,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**);
@ -272,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);

View File

@ -713,10 +713,6 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
if(mBuddyInfo.find(agent_related) != mBuddyInfo.end())
{
(mBuddyInfo[agent_related])->setRightsTo(new_rights);
// I'm not totally sure why it adds the agents id to the changed list
// nor why it doesn't add the friends's ID.
// Add the friend's id to the changed list for contacts list -KC
mChangedBuddyIDs.insert(agent_related);
}
}

View File

@ -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()

View File

@ -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

View File

@ -1,50 +1,45 @@
/**
* @file llpanelme.h
* @brief Side tray "Me" (My Profile) panel
/**
* @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_LLPANELMEPROFILE_H
#define LL_LLPANELMEPROFILE_H
#ifndef LL_LLFLOATERCLASSIFIED_H
#define LL_LLFLOATERCLASSIFIED_H
#include "llpanel.h"
#include "llpanelprofile.h"
#include "llfloater.h"
/**
* Panel for displaying Agent's Picks and Classifieds panel.
* LLPanelMe allows user to edit his picks and classifieds.
*/
class LLPanelMe : public LLPanelProfile
class LLFloaterClassified : public LLFloater
{
LOG_CLASS(LLPanelMe);
LOG_CLASS(LLFloaterClassified);
public:
LLFloaterClassified(const LLSD& key);
virtual ~LLFloaterClassified();
LLPanelMe();
void onOpen(const LLSD& key) override;
BOOL postBuild() override;
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ BOOL postBuild();
bool matchesKey(const LLSD& key) override;
};
#endif // LL_LLPANELMEPROFILE_H
#endif // LL_LLFLOATERCLASSIFIED_H

View File

@ -47,7 +47,6 @@ public:
virtual ~LLFloaterDisplayName() { }
/*virtual*/ BOOL postBuild();
void onSave();
void onReset();
void onCancel();
/*virtual*/ void onOpen(const LLSD& key);
@ -102,7 +101,6 @@ void LLFloaterDisplayName::onOpen(const LLSD& key)
BOOL LLFloaterDisplayName::postBuild()
{
getChild<LLUICtrl>("reset_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onReset, this));
getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onCancel, this));
getChild<LLUICtrl>("save_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onSave, this));
@ -158,21 +156,6 @@ void LLFloaterDisplayName::onCancel()
setVisible(false);
}
void LLFloaterDisplayName::onReset()
{
if (LLAvatarNameCache::getInstance()->hasNameLookupURL())
{
LLViewerDisplayName::set("",boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
}
else
{
LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
}
setVisible(false);
}
void LLFloaterDisplayName::onSave()
{
std::string display_name_utf8 = getChild<LLUICtrl>("display_name_editor")->getValue().asString();
@ -194,7 +177,7 @@ void LLFloaterDisplayName::onSave()
return;
}
if (LLAvatarNameCache::getInstance()->hasNameLookupURL())
if (LLAvatarNameCache::getInstance()->hasNameLookupURL())
{
LLViewerDisplayName::set(display_name_utf8,boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
}

View File

@ -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));

View File

@ -43,7 +43,6 @@
#include "llviewercontrol.h"
#include "lltoolfocus.h"
#include "lltoolmgr.h"
#include "llwebprofile.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs

View File

@ -555,60 +555,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 (gAgent.isInitialized() && (gAgent.getID() != LLUUID::null) && (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()
@ -1518,7 +1517,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;
}
// <FS:Ansariel> [FS Login Panel]
@ -2720,13 +2719,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;
}
@ -2746,7 +2745,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;
}
@ -4004,7 +4003,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;
@ -4031,7 +4030,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;
@ -4137,7 +4136,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");
@ -4177,7 +4176,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

View File

@ -111,9 +111,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);
@ -313,7 +312,7 @@ private:
bool mOriginalHideOnlineStatus;
std::string mDirectoryVisibility;
LLAvatarData mAvatarProperties;
bool mAllowPublish; // Allow showing agent in search
std::string mSavedGraphicsPreset;
LOG_CLASS(LLFloaterPreference);

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,241 @@
/**
* @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"
#include "llviewermenu.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->forceActive(); // <FS:Ansariel> Make sure it can get discarded
mImage = NULL;
}
}
// virtual
BOOL LLFloaterProfileTexture::postBuild()
{
mProfileIcon = getChild<LLIconCtrl>("profile_pic");
mCloseButton = getChild<LLButton>("close_btn");
mCloseButton->setCommitCallback([this](LLUICtrl*, void*) { closeFloater(); }, nullptr);
// <FS:Ansariel> Add refresh function
getChild<LLButton>("btn_refresh")->setCommitCallback([this](LLUICtrl*, void*) { refresh(); }, 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->forceActive(); // <FS:Ansariel> Make sure it can get discarded
mImage = NULL;
}
}
void LLFloaterProfileTexture::loadAsset(const LLUUID &image_id)
{
if (mImageID != image_id)
{
if (mImage.notNull())
{
mImage->setBoostLevel(mImageOldBoostLevel);
mImage->forceActive(); // <FS:Ansariel> Make sure it can get discarded
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;
}
}
// <FS:Ansariel> Add refresh function
void LLFloaterProfileTexture::refresh()
{
if (mImageID.notNull() && mImage.notNull())
{
destroy_texture(mImageID);
mImage->forceToRefetchTexture();
}
}
// </FS:Ansariel>

View File

@ -0,0 +1,84 @@
/**
* @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);
// <FS:Ansariel> Add refresh function
void refresh();
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

View File

@ -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();

View File

@ -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);
}

View File

@ -1,59 +0,0 @@
/**
* @file llfloaterwebprofile.h
* @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$
*/
#ifndef LL_LLFLOATERWEBPROFILE_H
#define LL_LLFLOATERWEBPROFILE_H
#include "llfloaterwebcontent.h"
#include "llviewermediaobserver.h"
#include <string>
class LLMediaCtrl;
/**
* Displays avatar profile web page.
*/
class LLFloaterWebProfile
: public LLFloaterWebContent
{
LOG_CLASS(LLFloaterWebProfile);
public:
typedef LLFloaterWebContent::Params Params;
LLFloaterWebProfile(const Params& key);
/*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();
};
#endif // LL_LLFLOATERWEBPROFILE_H

View File

@ -50,7 +50,6 @@
#include "llurlaction.h"
static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
S32 LLGroupListItem::sIconWidth = 0;
class LLGroupComparator : public LLFlatListView::ItemComparator
{
@ -70,8 +69,35 @@ public:
}
};
//static const LLGroupComparator GROUP_COMPARATOR;
static LLGroupComparator GROUP_COMPARATOR; // <ND/> const makes GCC >= 4.6 very angry about not user defined default ctor.
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)
@ -80,7 +106,7 @@ LLGroupList::Params::Params()
LLGroupList::LLGroupList(const Params& p)
: LLFlatListViewEx(p)
, mForAgent(p.for_agent)
, mForAgent(p.for_agent)
, mDirty(true) // to force initial update
, mShowIcons(false)
, mShowNone(true)
@ -88,7 +114,15 @@ LLGroupList::LLGroupList(const Params& p)
setCommitOnSelectionChange(true);
// Set default sort order.
setComparator(&GROUP_COMPARATOR);
if (mForAgent)
{
setComparator(&GROUP_COMPARATOR);
}
else
{
// shared groups first
setComparator(&SHARED_GROUP_COMPARATOR);
}
if (mForAgent)
{
@ -98,18 +132,18 @@ LLGroupList::LLGroupList(const Params& p)
LLGroupList::~LLGroupList()
{
if (mForAgent) gAgent.removeListener(this);
if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
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;
mShowIcons = mForAgent && gSavedSettings.getBOOL("GroupListShowIcons") && show_icons;
// Listen for agent group changes.
gAgent.addListener(this, "new group");
// Listen for agent group changes.
gAgent.addListener(this, "new group");
// Set up context menu.
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
@ -138,15 +172,15 @@ BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
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);
}
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;
@ -159,7 +193,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);
}
@ -191,51 +225,49 @@ static bool findInsensitive(std::string haystack, const std::string& needle_uppe
void LLGroupList::refresh()
{
if (mForAgent)
{
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;
// <FS:Ansariel> Mark groups hidden in profile
//addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM);
addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM, group_data.mListInProfile);
}
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 && mShowNone)
{
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);
}
else
{
clear();
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);
}
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();
}
// Sort the list.
sort();
}
setDirty(false);
onCommit();
@ -258,19 +290,17 @@ void LLGroupList::toggleIcons()
void LLGroupList::setGroups(const std::map< std::string,LLUUID> group_list)
{
mGroups = group_list;
setDirty(true);
mGroups = group_list;
setDirty(true);
}
//////////////////////////////////////////////////////////////////////////
// PRIVATE Section
//////////////////////////////////////////////////////////////////////////
// <FS:Ansariel> Mark groups hidden in profile
//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(mForAgent && mShowIcons);
LLGroupListItem* item = new LLGroupListItem(mForAgent, mShowIcons);
item->setGroupID(id);
item->setName(name, mNameFilter);
@ -279,7 +309,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);
}
// <FS:Ansariel> Mark groups hidden in profile
item->setVisibleInProfile(visible_in_profile);
// </FS:Ansariel> Mark groups hidden in profile
@ -299,30 +332,28 @@ bool LLGroupList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD&
return true;
}
// <FS:Ansariel> Mark groups hidden in profile
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();
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;
}
// </FS:Ansariel>
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;
}
@ -387,24 +418,25 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)
/* LLGroupListItem implementation */
/************************************************************************/
LLGroupListItem::LLGroupListItem(bool for_agent)
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)
{
if (for_agent)
buildFromFile( "panel_group_list_item.xml");
else
buildFromFile( "panel_group_list_item_short.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()
@ -421,7 +453,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;
}
@ -440,7 +490,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);
@ -450,7 +509,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);
}
@ -468,7 +532,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);
}
@ -489,31 +563,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);
}
// <FS:Ansariel> Mark groups hidden in profile
void LLGroupListItem::setVisibleInProfile(bool visible)
{
mGroupNameBox->setColor(LLUIColorTable::instance().getColor((visible ? "GroupVisibleInProfile" : "GroupHiddenInProfile"), LLColor4::red).get());
mGroupNameBox->setColor(LLUIColorTable::instance().getColor((visible ? "GroupVisibleInProfile" : "GroupHiddenInProfile"), LLColor4::red).get());
}
// </FS:Ansariel> Mark groups hidden in profile
//////////////////////////////////////////////////////////////////////////
// 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;
@ -533,14 +604,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);
// <FS:Ansariel> FIRE-22148: Only update group icon if the received group data actually contains group icon info
//if (group_data)
if ((gc == GC_ALL || gc == GC_PROPERTIES) && group_data)
// </FS:Ansariel>
setGroupIconID(group_data->mInsigniaID);
{
setGroupIconID(group_data->mInsigniaID);
}
}
//EOF

View File

@ -50,8 +50,8 @@ class LLGroupList: public LLFlatListViewEx, public LLOldEvents::LLSimpleListener
public:
struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
{
Optional<bool> for_agent;
Params();
Optional<bool> for_agent;
Params();
};
LLGroupList(const Params& p);
@ -66,17 +66,15 @@ 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);
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();
// <FS:Ansariel> Mark groups hidden in profile
//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
@ -89,10 +87,10 @@ private:
bool mDirty;
std::string mNameFilter;
bool mForAgent;
bool mForAgent;
bool mShowNone;
typedef std::map< std::string,LLUUID> group_map_t;
group_map_t mGroups;
typedef std::map< std::string,LLUUID> group_map_t;
group_map_t mGroups;
};
class LLButton;
@ -103,7 +101,7 @@ class LLGroupListItem : public LLPanel
, public LLGroupMgrObserver
{
public:
LLGroupListItem(bool for_agent);
LLGroupListItem(bool for_agent, bool show_icons);
~LLGroupListItem();
/*virtual*/ BOOL postBuild();
/*virtual*/ void setValue(const LLSD& value);
@ -120,22 +118,25 @@ public:
virtual void changed(LLGroupChange gc);
// <FS:Ansariel> Mark groups hidden in profile
void setVisibleInProfile(bool visible);
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

View File

@ -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();
}

View File

@ -49,6 +49,8 @@ public:
/// Inspectors close themselves when they lose focus
/*virtual*/ void onFocusLost();
void repositionInspector(const LLSD& data);
protected:

View File

@ -45,7 +45,6 @@
#include "llfloater.h"
#include "llfloaterreg.h"
#include "lltextbox.h"
#include "lltooltip.h" // positionViewNearMouse()
#include "lltrans.h"
// <FS:Ansariel> Undo CHUI-90 and make avatar inspector useful again
@ -329,17 +328,7 @@ void LLInspectAvatar::onOpen(const LLSD& data)
}
// </FS:Ansariel>
// 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.
// <FS:Ansariel> Undo CHUI-90 and make avatar inspector useful again

View File

@ -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();

View File

@ -56,7 +56,6 @@
#include "lltextbox.h" // for description truncation
#include "lltoggleablemenu.h"
#include "lltrans.h"
#include "llui.h" // positionViewNearMouse()
#include "lluictrl.h"
class LLViewerObject;
@ -204,17 +203,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

View File

@ -124,17 +124,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()

View File

@ -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

View File

@ -118,6 +118,7 @@ public:
bool addUnit();
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);

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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,38 +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"
#ifdef OPENSIM
#include "llviewernetwork.h"
#endif // OPENSIM
#include "fspanelclassified.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
@ -121,25 +104,10 @@ LLPanelClassifiedInfo::LLPanelClassifiedInfo()
LLPanelClassifiedInfo::~LLPanelClassifiedInfo()
{
sAllPanels.remove(this);
// [SL:KB] - Patch : UI-ProfileGroupFloater | Checked: 2010-11-28 (Catznip-2.4.0g) | Added: Catznip-2.4.0g
if(getAvatarId().notNull())
{
LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
}
// [/SL:KB]
}
// 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));
@ -155,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);
@ -256,14 +214,6 @@ void LLPanelClassifiedInfo::handleSearchStatResponse(LLUUID classifiedId, LLSD r
map + search_map,
profile + search_profile,
true);
// <FS:Ansariel> FIRE-8787: Also update legacy profiles
FSPanelClassifiedInfo::setClickThrough(classifiedId,
teleport + search_teleport,
map + search_map,
profile + search_profile,
true);
// </FS:Ansariel>
}
void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType type)
@ -305,6 +255,8 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t
getChild<LLUICtrl>("creation_date")->setValue(date_str);
setInfoLoaded(true);
LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
}
}
}
@ -609,605 +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);
// <FS:CR> FIRE-9814 - Don't hardcode a classified listing fee
//getChild<LLUICtrl>("price_for_listing")->setValue(MINIMUM_PRICE_FOR_LISTING);
getChild<LLUICtrl>("price_for_listing")->setValue(getClassifiedFee());
// </FS:CR>
getChildView("price_for_listing")->setEnabled(TRUE);
}
// <FS:CR> FIRE-9814 - Don't hardcode a classified listing fee
S32 LLPanelClassifiedEdit::getClassifiedFee()
{
S32 fee = MINIMUM_PRICE_FOR_LISTING;
#ifdef OPENSIM
if (LLGridManager::getInstance()->isInOpenSim())
{
fee = LLGridManager::getInstance()->getClassifiedFee();
}
#endif // OPENSIM
return fee;
}
// </FS:CR>
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

View File

@ -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;
@ -195,109 +165,11 @@ private:
S32 mMapClicksNew;
S32 mProfileClicksNew;
public: // <FS:ND> Need this public for fspanelclassified
static void handleSearchStatResponse(LLUUID classifiedId, LLSD result);
static void handleSearchStatResponse(LLUUID classifiedId, LLSD result);
private: // </FS:ND>
typedef std::list<LLPanelClassifiedInfo*> panel_list_t;
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:
S32 getClassifiedFee(); // <FS:CR> FIRE-9814 - Don't hardcode a classified listing fee
bool mIsNew;
bool mIsNewWithErrors;
bool mCanClose;
LLPublishClassifiedFloater* mPublishFloater;
commit_signal_t mSaveButtonClickedSignal;
};
#endif // LL_LLPANELCLASSIFIED_H

View File

@ -29,7 +29,6 @@
#include "llaccordionctrltab.h"
#include "llflatlistview.h"
#include "llpanelavatar.h"
class LLExperienceItem;
class LLPanelProfile;

View File

@ -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

View File

@ -29,6 +29,7 @@
#include "llpanellandmarks.h"
#include "llbutton.h"
#include "llfloaterprofile.h"
#include "llfloaterreg.h"
#include "llnotificationsutil.h"
#include "llsdutil.h"
@ -1080,17 +1081,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;
@ -1158,49 +1148,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)

View File

@ -34,7 +34,6 @@
#include "llinventorymodel.h"
#include "lllandmarklist.h"
#include "llpanelplacestab.h"
#include "llpanelpick.h"
#include "llremoteparcelrequest.h"
class LLAccordionCtrlTab;
@ -139,7 +138,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.

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -1,321 +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"
#include "rlvdefines.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);
// <FS:Ansariel> FIRE-15556: Picks can circumvent RLVa @showloc restriction
boost::signals2::connection mRlvBehaviorCallbackConnection;
void updateRlvRestrictions(ERlvBehaviour behavior, ERlvParamType type);
// </FS:Ansariel>
//------------------------------------------------
// 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

View File

@ -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"
@ -360,7 +361,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;
@ -369,7 +370,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

View File

@ -38,7 +38,6 @@ class LLAvatarName;
class LLExpandableTextBox;
class LLIconCtrl;
class LLInventoryItem;
class LLPanelPickEdit;
class LLParcel;
class LLScrollContainer;
class LLTextBox;
@ -99,7 +98,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);
// <FS:Ansariel> FIRE-817: Separate place details floater
void setHeaderVisible(BOOL visible);

View File

@ -64,7 +64,6 @@
#include "lllayoutstack.h"
#include "llpanellandmarkinfo.h"
#include "llpanellandmarks.h"
#include "llpanelpick.h"
#include "llpanelplaceprofile.h"
#include "llpanelteleporthistory.h"
#include "llremoteparcelrequest.h"
@ -251,7 +250,6 @@ LLPanelPlaces::LLPanelPlaces()
mFilterEditor(NULL),
mPlaceProfile(NULL),
mLandmarkInfo(NULL),
mPickPanel(NULL),
mItem(NULL),
mPlaceMenu(NULL),
mLandmarkMenu(NULL),
@ -1019,28 +1017,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")
{
@ -1117,18 +1098,6 @@ bool LLPanelPlaces::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_t
return false;
}
void LLPanelPlaces::togglePickPanel(BOOL visible)
{
if (mPickPanel)
{
mPickPanel->setVisible(visible);
// <FS:Ansariel> FIRE-31687: Place profile overlaps landmark panel in places floater when closing create pick panel
//mPlaceProfile->setVisible(!visible);
updateVerbs();
}
}
void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
{
if (!mPlaceProfile || !mLandmarkInfo)
@ -1390,20 +1359,16 @@ 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);
// <FS:Ansariel> FIRE-31033: Keep Teleport/Map/Profile buttons on places floater
mPlaceInfoBtn->setVisible(!is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
mPlaceInfoBtn->setVisible(!is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn);
mShowOnMapBtn->setEnabled(!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWWORLDMAP));
bool show_options_btn = is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn;

View File

@ -38,7 +38,6 @@ class LLLandmark;
class LLPanelLandmarkInfo;
class LLPanelPlaceProfile;
class LLPanelPickEdit;
class LLPanelPlaceInfo;
class LLPanelPlacesTab;
class LLParcelSelection;
@ -102,7 +101,6 @@ private:
void onOverflowButtonClicked();
void onOverflowMenuItemClicked(const LLSD& param);
bool onOverflowMenuItemEnable(const LLSD& param);
void onCreateLandmarkButtonClicked(const LLUUID& folder_id);
void onBackButtonClicked();
void onProfileButtonClicked(); // <FS:Ansariel> FIRE-31033: Keep Teleport/Map/Profile buttons on places floater
void onGearMenuClick();
@ -111,9 +109,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);
@ -130,7 +125,6 @@ private:
LLPanelPlaceProfile* mPlaceProfile;
LLPanelLandmarkInfo* mLandmarkInfo;
LLPanelPickEdit* mPickPanel;
LLToggleableMenu* mPlaceMenu;
LLToggleableMenu* mLandmarkMenu;

File diff suppressed because it is too large Load Diff

View File

@ -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,80 +27,411 @@
#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"
#include "rlvhandler.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;
// [RLVa:KB] - Checked: 2010-04-20 (RLVa-1.2.0f) | Added: RVLa-1.2.0f
const LLUUID& getAvatarId() const { return mAvatarId; }
// [/RLVa:KB]
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(); // <FS:Ansariel> Doesn't exist (anymore)
bool push();
bool pop();
void preParentReshape();
void postParentReshape();
// <FS:Ansariel> Fix LL UI/UX design accident
void updateButtons();
private:
void dump();
private:
typedef std::map<std::string, LLUUID> group_map_t;
group_map_t mGroups;
void openGroupProfile();
typedef LLView::child_list_t view_list_t;
typedef std::list<view_list_t> stack_t;
LLTextBox* mStatusText; // <FS:Ansariel> Fix LL UI/UX design accident
LLGroupList* mGroupList;
// <FS:Ansariel> Fix LL UI/UX design accident
//LLComboBox* mShowInSearchCombo;
LLCheckBoxCtrl* mShowInSearchCheckbox;
// </FS:Ansariel>
LLIconCtrl* mSecondLifePic;
LLPanel* mSecondLifePicLayout;
LLTextEditor* mDescriptionEdit;
//LLMenuButton* mAgentActionMenuButton; // <FS:Ansariel> Fix LL UI/UX design accident
LLButton* mSaveDescriptionChanges;
LLButton* mDiscardDescriptionChanges;
LLIconCtrl* mCanSeeOnlineIcon;
LLIconCtrl* mCantSeeOnlineIcon;
LLIconCtrl* mCanSeeOnMapIcon;
LLIconCtrl* mCantSeeOnMapIcon;
LLIconCtrl* mCanEditObjectsIcon;
LLIconCtrl* mCantEditObjectsIcon;
// <FS:Ansariel> Fix LL UI/UX design accident
LLMenuButton* mCopyMenuButton;
LLButton* mGroupInviteButton;
LLButton* mDisplayNameButton;
LLMenuButton* mImageActionMenuButton;
LLButton* mTeleportButton;
LLButton* mShowOnMapButton;
LLButton* mBlockButton;
LLButton* mUnblockButton;
LLButton* mAddFriendButton;
LLButton* mPayButton;
LLButton* mIMButton;
LLMenuButton* mOverflowButton;
// </FS:Ansariel>
stack_t mStack;
stack_t mSavedStack;
LLPanel* mParent;
};
//-- ChildStack ends ------------------------------------------------------
LLHandle<LLFloater> mFloaterPermissionsHandle;
LLHandle<LLFloater> mFloaterProfileTextureHandle;
LLHandle<LLFloater> mFloaterTexturePickerHandle;
profile_tabs_t mTabContainer;
ChildStack mChildStack;
LLUUID mAvatarId;
bool mHasUnsavedDescriptionChanges;
bool mVoiceStatus;
bool mWaitingForImageUpload;
bool mAllowPublish;
std::string mDescriptionText;
LLUUID mImageId;
boost::signals2::connection mAvatarNameCacheConnection;
// <FS:Ansariel> RLVa support
boost::signals2::connection mRlvBehaviorCallbackConnection;
void updateRlvRestrictions(ERlvBehaviour behavior);
// </FS:Ansariel>
};
/**
* 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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,352 @@
/**
* @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"
#include "rlvhandler.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();
// <FS:Ansariel> RLVa support
boost::signals2::connection mRlvBehaviorCallbackConnection;
void updateRlvRestrictions(ERlvBehaviour behavior, ERlvParamType type);
// </FS:Ansariel>
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;
public: // <FS:ND> Need this public for fspanelclassified
static void handleSearchStatResponse(LLUUID classifiedId, LLSD result);
private: // </FS:ND>
typedef std::list<LLPanelProfileClassified*> panel_list_t;
static panel_list_t sAllPanels;
bool mIsNew;
bool mIsNewWithErrors;
bool mCanClose;
bool mEditOnLoad;
LLPublishClassifiedFloater* mPublishFloater;
S32 getClassifiedFee(); // <FS:CR> FIRE-9814 - Don't hardcode a classified listing fee
};
#endif // LL_PANELPROFILECLASSIFIEDS_H

View File

@ -0,0 +1,916 @@
/**
* @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 "llagentbenefits.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 "llstartup.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)
, mRlvBehaviorCallbackConnection() // <FS:Ansariel> FIRE-15556: Picks can circumvent RLVa @showloc restriction
{
}
LLPanelProfilePicks::~LLPanelProfilePicks()
{
// <FS:Ansariel> FIRE-15556: Picks can circumvent RLVa @showloc restriction
if (mRlvBehaviorCallbackConnection.connected())
{
mRlvBehaviorCallbackConnection.disconnect();
}
// </FS:Ansariel>
}
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));
// <FS:Ansariel> FIRE-15556: Picks can circumvent RLVa @showloc restriction
mRlvBehaviorCallbackConnection = gRlvHandler.setBehaviourCallback(boost::bind(&LLPanelProfilePicks::updateRlvRestrictions, this, _1, _2));
// <FS:Ansariel> Replace hardcoded "Second Life" with grid label
LLTextBox* intro_txt = getChild<LLTextBox>("header_text");
intro_txt->setTextArg("[GRID]", LLTrans::getString("SECOND_LIFE"));
// </FS:Ansariel>
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())
{
// <FS:Ansariel> RLVa support
//mNewButton->setEnabled(canAddNewPick());
mNewButton->setEnabled(canAddNewPick() && !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC));
// </FS:Ansariel>
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();
}
}
}
// <FS:Ansariel> FIRE-15556: Picks can circumvent RLVa @showloc restriction
void LLPanelProfilePicks::updateRlvRestrictions(ERlvBehaviour behavior, ERlvParamType type)
{
if (behavior == RLV_BHVR_SHOWLOC)
{
updateButtons();
}
}
bool LLPanelProfilePicks::canAddNewPick()
{
return (!LLAgentPicksInfo::getInstance()->isPickLimitReached() &&
// <FS:Ansariel> FIRE-15556: Picks can circumvent RLVa @showloc restriction
//mTabContainer->getTabCount() < LLAgentBenefitsMgr::current().getPicksLimit());
mTabContainer->getTabCount() < LLAgentBenefitsMgr::current().getPicksLimit() &&
!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC));
// </FS:Ansariel>
}
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);
}
}

View File

@ -0,0 +1,255 @@
/**
* @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"
#include "rlvhandler.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);
// <FS:Ansariel> FIRE-15556: Picks can circumvent RLVa @showloc restriction
boost::signals2::connection mRlvBehaviorCallbackConnection;
void updateRlvRestrictions(ERlvBehaviour behavior, ERlvParamType type);
// </FS:Ansariel>
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

View File

@ -542,7 +542,12 @@ 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;
// <FS:Ansariel> Texture preview mode
//if (getChild<LLLayoutPanel>("buttons_panel")->getVisible())
//{
// info_height += getChild<LLLayoutPanel>("buttons_panel")->getRect().getHeight();
//}
// </FS:Ansariel>
LLRect client_rect(horiz_pad, getRect().getHeight(), getRect().getWidth() - horiz_pad, 0);
client_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);
@ -605,6 +610,18 @@ void LLPreviewTexture::openToSave()
mPreviewToSave = TRUE;
}
// <FS:Ansariel> Texture preview mode
//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());
//}
// </FS:Ansariel>
// static
void LLPreviewTexture::onFileLoadedForSaveTGA(BOOL success,
LLViewerFetchedTexture *src_vi,

View File

@ -93,6 +93,9 @@ public:
static void onSaveAsBtn(LLUICtrl* ctrl, void* data);
// <FS:Ansariel> Texture preview mode
//void hideCtrlButtons();
/*virtual*/ void setObjectID(const LLUUID& object_id);
// <FS:Techwolf Lupindo> texture comment metadata reader

View File

@ -215,7 +215,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
{

View File

@ -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"
@ -128,8 +129,6 @@
// <FS:Ansariel> [FS Login Panel]
#include "llmutelist.h"
#include "llavatarpropertiesprocessor.h"
#include "llpanelclassified.h"
#include "llpanelpick.h"
#include "llpanelgrouplandmoney.h"
#include "llpanelgroupnotices.h"
#include "llparcel.h"
@ -198,6 +197,7 @@
#include "llavatariconctrl.h"
#include "llvoicechannel.h"
#include "llpathfindingmanager.h"
#include "llremoteparcelrequest.h"
// [RLVa:KB] - Checked: RLVa-1.2.0
#include "rlvhandler.h"
// [/RLVa:KB]
@ -3572,7 +3572,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);

View File

@ -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"
@ -1473,14 +1474,13 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mNeedsRawImageData( FALSE ),
mValid( TRUE ),
mShowLoadingPlaceholder( TRUE ),
mOpenTexPreview(!p.enabled), // <FS:Ansariel> For texture preview mode
mImageAssetID(p.image_id),
mDefaultImageAssetID(p.default_image_id),
mDefaultImageName(p.default_image_name),
mFallbackImage(p.fallback_image),
// <FS:Ansariel> Mask texture if desired
mIsMasked(FALSE),
// </FS:Ansariel> Mask texture if desired
mPreviewMode(!p.enabled) // <FS:Ansariel> For texture preview mode
mIsMasked(FALSE)
{
// Default of defaults is white image for diff tex
@ -1606,7 +1606,7 @@ void LLTextureCtrl::setEnabled( BOOL enabled )
// <FS:Ansariel> Texture preview mode
//LLView::setEnabled( enabled );
LLView::setEnabled( (enabled || getValue().asUUID().notNull()) );
mPreviewMode = !enabled;
mOpenTexPreview = !enabled;
// </FS:Ansariel>
}
@ -1744,13 +1744,7 @@ BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
if (!handled && mBorder->parentPointInView(x, y))
{
// <FS:Ansariel> Texture preview mode
//showPicker(FALSE);
////grab textures first...
//LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
////...then start full inventory fetch.
//LLInventoryModelBackgroundFetch::instance().start();
if (!mPreviewMode)
if (!mOpenTexPreview)
{
showPicker(FALSE);
//grab textures first...
@ -1758,6 +1752,23 @@ BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
//...then start full inventory fetch.
LLInventoryModelBackgroundFetch::instance().start();
}
// <FS:Ansariel> Texture preview mode
//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();
// }
// }
// }
//}
else if (!mIsMasked)
{
// Open the preview floater for the texture
@ -1955,7 +1966,7 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
// <FS:Ansariel> FIRE-10125: Texture picker allows dragging of textures while in preview mode
//if (getEnabled() &&
if (getEnabled() && !mPreviewMode &&
if (getEnabled() && !mOpenTexPreview &&
// </FS:Ansariel>
((cargo_type == DAD_TEXTURE) || is_mesh) &&
allowDrop(item))
@ -2171,7 +2182,7 @@ BOOL LLTextureCtrl::handleUnicodeCharHere(llwchar uni_char)
{
// <FS:Ansariel> Texture preview mode
//showPicker(TRUE);
if (!mPreviewMode)
if (!mOpenTexPreview)
{
showPicker(TRUE);
//grab textures first...
@ -2199,7 +2210,7 @@ void LLTextureCtrl::setValue( const LLSD& value )
//setImageAssetID(value.asUUID());
LLUUID uuid = value.asUUID();
setImageAssetID(uuid);
LLView::setEnabled( (!mPreviewMode || uuid.notNull()) );
LLView::setEnabled( (!mOpenTexPreview || uuid.notNull()) );
// </FS:Ansariel>
}

View File

@ -170,6 +170,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);
@ -252,9 +254,8 @@ private:
BOOL mShowLoadingPlaceholder;
std::string mLoadingPlaceholderString;
S32 mLabelWidth;
// <FS:Ansariel> Texture preview mode
BOOL mPreviewMode;
bool mOpenTexPreview;
BOOL mBakeTextureEnabled;
// <FS:Ansariel> Mask texture if desired
BOOL mIsMasked;

View File

@ -32,6 +32,8 @@
#include "fsradar.h"
#include "lggcontactsets.h"
#include "llagent.h"
#include "llfloaterprofile.h"
#include "llfloaterreg.h"
#include "llviewercontrol.h"
#include "llviewerregion.h"
#include "llvoavatar.h"
@ -223,12 +225,14 @@ class LLDisplayNameUpdate : public LLHTTPNode
}
else
{
FSRadar* radar = FSRadar::getInstance();
if (radar)
{
radar->updateName(agent_id);
}
FSRadar::getInstance()->updateName(agent_id);
}
LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id)));
if (profile_floater)
{
profile_floater->refreshName();
}
}
};

View File

@ -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"
@ -114,6 +116,7 @@
#include "llfloaterpreferencesgraphicsadvanced.h"
#include "llfloaterpreferenceviewadvanced.h"
#include "llfloaterpreviewtrash.h"
#include "llfloaterprofile.h"
#include "llfloaterproperties.h"
#include "llfloaterregiondebugconsole.h"
#include "llfloaterregioninfo.h"
@ -143,7 +146,6 @@
#include "llfloateruipreview.h"
#include "llfloatervoiceeffect.h"
#include "llfloaterwebcontent.h"
#include "llfloaterwebprofile.h"
#include "llfloatervoicevolume.h"
#include "llfloaterwhitelistentry.h"
#include "llfloaterwindowsize.h"
@ -161,7 +163,7 @@
#include "fsfloaternearbychat.h"
// <FS:Ansariel> [FS communication UI]
#include "llpanelblockedlist.h"
#include "llpanelclassified.h"
#include "llpanelprofileclassifieds.h"
#include "llpreviewanim.h"
#include "llpreviewgesture.h"
#include "llpreviewnotecard.h"
@ -198,7 +200,6 @@
#include "fsfloaterpartialinventory.h"
#include "fsfloaterplacedetails.h"
#include "fsfloaterposestand.h"
#include "fsfloaterprofile.h"
#include "fsfloaterprotectedfolders.h"
#include "fsfloaterradar.h"
#include "fsfloatersearch.h"
@ -209,7 +210,7 @@
#include "fsfloatervramusage.h"
#include "fsfloaterwearablefavorites.h"
#include "fsmoneytracker.h"
#include "fspanelclassified.h"
//#include "fspanelclassified.h"
#include "lggbeamcolormapfloater.h"
#include "lggbeammapfloater.h"
#include "llfloaterdisplayname.h"
@ -289,6 +290,7 @@ void LLViewerFloaterReg::registerFloaters()
//LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater);
LLFloaterReg::add("fs_nearby_chat", "floater_fs_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterNearbyChat>);
// </FS:Ansariel> [FS communication UI]
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>);
@ -343,7 +345,7 @@ void LLViewerFloaterReg::registerFloaters()
LLInspectRemoteObjectUtil::registerFloater();
LLFloaterVoiceVolumeUtil::registerFloater();
LLNotificationsUI::registerFloater();
LLFloaterDisplayNameUtil::registerFloater(); // <FS:Ansariel> Bring back display name floater
LLFloaterDisplayNameUtil::registerFloater();
LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);
LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
@ -396,7 +398,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>);
@ -455,8 +456,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>);
// <FS:CR> Search floater is deferred to login now so we can tell what grid we're in.
//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>);
@ -484,7 +484,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("export_collada", "floater_export_collada.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ColladaExportFloater>);
LLFloaterReg::add("delete_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeleteQueue>);
LLFloaterReg::add("flickr", "floater_flickr.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFlickr>);
LLFloaterReg::add("fs_floater_profile", "floater_fs_profile_view.xml", &LLFloaterReg::build<FSFloaterProfile>);
LLFloaterReg::add("fs_asset_blacklist", "floater_fs_asset_blacklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterAssetBlacklist>);
LLFloaterReg::add("fs_avatar_render_settings", "floater_fs_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterAvatarRenderSettings>);
LLFloaterReg::add("fs_blocklist", "floater_fs_blocklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterBlocklist>);
@ -513,7 +512,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("performance", "floater_performance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterPerformance>);
LLFloaterReg::add(PHOTOTOOLS_FLOATER, "floater_phototools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FloaterQuickPrefs>);
LLFloaterReg::add("phototools_camera", "floater_phototools_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
LLFloaterReg::add("publish_classified_fs", "floater_publish_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSPublishClassifiedFloater>);
LLFloaterReg::add("quickprefs", "floater_quickprefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FloaterQuickPrefs>);
LLFloaterReg::add("region_tracker", "floater_region_tracker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ALFloaterRegionTracker>);
LLFloaterReg::add("search_replace", "floater_search_replace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearchReplace>);

View File

@ -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"

View File

@ -4411,6 +4411,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)
{
// [SL:KB] - Patch: UI-AvatarNearbyActions | Checked: 2011-05-13 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
@ -7809,6 +7814,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)
@ -8396,6 +8424,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)
@ -12281,12 +12318,14 @@ void initialize_menus()
view_listener_t::addMenu(new LLAvatarTexRefresh(), "Avatar.TexRefresh"); // ## Zi: Texture Refresh
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")));
@ -12371,6 +12410,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");

View File

@ -273,14 +273,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;
@ -328,7 +327,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())
@ -339,41 +337,14 @@ 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();
// <FS:Ansariel> Fix seed cap retry count
//++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.
++(impl->mSeedCapAttempts); // <FS:Ansariel> Fix seed cap retry count
continue;
}
if (!result.isMap() || result.has("error"))
{
LL_WARNS("AppInit", "Capabilities") << "Malformed response" << LL_ENDL;
// setup for retry.
++(impl->mSeedCapAttempts); // <FS:Ansariel> Fix seed cap retry count
continue;
}
@ -383,13 +354,38 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
{
LL_WARNS("AppInit", "Capabilities") << "HttpStatus error " << LL_ENDL;
// setup for retry.
++(impl->mSeedCapAttempts); // <FS:Ansariel> Fix seed cap retry count
continue;
}
// 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();
// <FS:Ansariel> Fix seed cap retry count
//++(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.
++(impl->mSeedCapAttempts); // <FS:Ansariel> Fix seed cap retry count
continue;
}
LLSD::map_const_iterator iter;
for (iter = result.beginMap(); iter != result.endMap(); ++iter)
{
@ -3223,6 +3219,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");
@ -3329,6 +3326,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");

View File

@ -1178,7 +1178,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
@ -1207,7 +1208,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.");
@ -1232,10 +1233,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") &&

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